Plugin Directory

Changeset 3475253


Ignore:
Timestamp:
03/05/2026 08:06:05 AM (4 weeks ago)
Author:
ejointjp
Message:

Update to version 2.3.0 from GitHub

Location:
blogcard-for-wp
Files:
14 edited
1 copied

Legend:

Unmodified
Added
Removed
  • blogcard-for-wp/tags/2.3.0/blogcard-for-wp.php

    r3474088 r3475253  
    55 * Plugin URI: https://wordpress.org/plugins/blogcard-for-wp/
    66 * Description: URLを入力してブログカードを生成するブロックプラグイン
    7  * Version: 2.2.1
     7 * Version: 2.3.0
    88 * Author: Takashi Fujisaki
    99 * License: GPL v2 or later
     
    6666        'external_target' => isset( $options['external_target'] ) ? $options['external_target'] : '_blank',
    6767        'internal_target' => isset( $options['internal_target'] ) ? $options['internal_target'] : '_self',
     68        'home_url'        => home_url(),
     69        'site_favicon'    => wpbc_get_site_favicon(),
     70        'site_og_image'   => wpbc_get_site_og_image(),
    6871    );
    6972
     
    481484    $sorted_posts = array_merge( $posts_sorted, $pages_sorted );
    482485
     486    // サイト共通のFaviconを取得(キャッシュ対応)
     487    $favicon_url = wpbc_get_site_favicon();
     488
    483489    foreach ( $sorted_posts as $post ) {
     490        $thumbnail_id = get_post_thumbnail_id( $post->ID );
     491        $medium_src   = wp_get_attachment_image_src( $thumbnail_id, 'medium' );
     492        // is_intermediate ( $medium_src[3] ) が false の場合、指定サイズが存在せずオリジナルが返されている
     493        $thumbnail_url = ( $medium_src && $medium_src[3] ) ? $medium_src[0] : get_the_post_thumbnail_url( $post->ID, 'thumbnail' );
     494
    484495        $results[] = array(
    485             'id'          => $post->ID,
    486             'title'       => get_the_title( $post->ID ),
    487             'url'         => get_permalink( $post->ID ),
    488             'type'        => get_post_type( $post->ID ),
    489             'date'        => get_the_date( 'Y-m-d', $post->ID ),
    490             'thumbnail'   => get_the_post_thumbnail_url( $post->ID, 'large' ),
    491             'description' => get_the_excerpt( $post->ID ),
     496            'id'              => $post->ID,
     497            'title'           => get_the_title( $post->ID ),
     498            'url'             => get_permalink( $post->ID ),
     499            'type'            => get_post_type( $post->ID ),
     500            'date'            => get_the_date( 'Y-m-d', $post->ID ),
     501            'thumbnail'       => $thumbnail_url,
     502            'thumbnail_large' => get_the_post_thumbnail_url( $post->ID, 'large' ),
     503            'description'     => get_the_excerpt( $post->ID ),
     504            'favicon'         => $favicon_url,
    492505        );
    493506    }
     
    503516 */
    504517function wpbc_fetch_internal_metadata( $url ) {
     518    // URLの正規化(末尾のスラッシュを削除して比較)
     519    $normalized_url = rtrim( $url, '/' );
     520    $home_url       = rtrim( home_url(), '/' );
     521    $site_url       = rtrim( site_url(), '/' );
     522
     523    // ホームURLかどうかの判定
     524    if ( $normalized_url === $home_url || $normalized_url === $site_url ) {
     525        $title         = get_bloginfo( 'name' );
     526        $description   = get_bloginfo( 'description' );
     527        $thumbnail_url = '';
     528
     529        // フロントページが固定ページに設定されているか確認
     530        $front_page_id = get_option( 'page_on_front' );
     531        if ( $front_page_id ) {
     532            // 固定ページのメタデータを優先
     533            $front_page_title = get_the_title( $front_page_id );
     534            if ( $front_page_title ) {
     535                $title = $front_page_title;
     536            }
     537
     538            $front_page_excerpt = get_the_excerpt( $front_page_id );
     539            if ( $front_page_excerpt ) {
     540                $description = $front_page_excerpt;
     541            }
     542
     543            $thumbnail_url = get_the_post_thumbnail_url( $front_page_id, 'large' );
     544        }
     545
     546        // Faviconの取得処理
     547        $favicon_url = wpbc_get_site_favicon();
     548
     549        return array(
     550            'title'       => $title,
     551            'description' => $description,
     552            'thumbnail'   => $thumbnail_url,
     553            'favicon'     => $favicon_url,
     554            'url'         => $url,
     555            'cached'      => false,
     556        );
     557    }
     558
    505559    // URLから投稿IDを取得
    506560    $post_id = url_to_postid( $url );
     
    516570    $excerpt = get_the_excerpt( $post_id );
    517571
    518     // サムネイル画像を取得(thumbnailサイズ)
    519     $thumbnail_id  = get_post_thumbnail_id( $post_id );
    520     $thumbnail_url = '';
    521     if ( $thumbnail_id ) {
    522         $thumbnail_url = wp_get_attachment_image_url( $thumbnail_id, 'thumbnail' );
    523     }
     572    // サムネイル画像を取得(largeサイズ)
     573    $thumbnail_url = get_the_post_thumbnail_url( $post_id, 'large' );
     574
     575    // Faviconの取得処理
     576    $favicon_url = wpbc_get_site_favicon();
    524577
    525578    return array(
     
    527580        'description' => $excerpt,
    528581        'thumbnail'   => $thumbnail_url,
     582        'favicon'     => $favicon_url,
    529583        'url'         => $url,
    530584        'cached'      => false,
     
    547601        );
    548602        $cleared_count = $result;
     603
     604        // サイト内 Favicon / OG Image キャッシュも明示的に削除
     605        delete_transient( 'wpbc_site_favicon' );
     606        delete_transient( 'wpbc_site_og_image' );
    549607
    550608        // オブジェクトキャッシュもクリア
     
    647705 */
    648706function wpbc_check_favicon_exists( $url ) {
    649     $headers = get_headers( $url, 1 );
     707    // ローカル環境などにおいて `get_headers()` が失敗するケース(DNS解決やSSL周り)に対応するため、
     708    // まずは WordPress 標準の HTTP API (cURLベース) を用いて存在確認を試みる
     709    $response = wp_remote_head(
     710        $url,
     711        array(
     712            'timeout'     => 5,
     713            'redirection' => 5,
     714            'sslverify'   => false,
     715        )
     716    );
     717
     718    if ( ! is_wp_error( $response ) ) {
     719        $status_code = wp_remote_retrieve_response_code( $response );
     720        if ( 200 === $status_code ) {
     721            return true;
     722        }
     723    }
     724
     725    // wp_remote_head が想定外のヘッダーを返したり失敗した場合は、従来の get_headers にフォールバックする
     726    $headers = @get_headers( $url, 1 );
     727
     728    // ========= デバッグここから =========
     729    if ( strpos( $url, 'favicon.svg' ) !== false || strpos( $url, 'lovemacjp-2026-haku-child' ) !== false ) {
     730        error_log( 'wpbc_check_favicon_exists (' . $url . ') -> wp_remote_head status: ' . ( isset( $status_code ) ? $status_code : 'error' ) );
     731        error_log( 'wpbc_check_favicon_exists (' . $url . ') -> get_headers: ' . print_r( $headers, true ) );
     732    }
     733    // ========= デバッグここまで =========
     734
    650735    return $headers && false !== strpos( $headers[0], '200 OK' );
    651736}
     737
     738/**
     739 * サイト共通のFaviconを取得し、長期間キャッシュする
     740 */
     741function wpbc_get_site_favicon() {
     742    $cache_key   = 'wpbc_site_favicon';
     743    $favicon_url = get_transient( $cache_key );
     744
     745    if ( false !== $favicon_url ) {
     746        return $favicon_url;
     747    }
     748
     749    $home_url    = home_url();
     750    $favicon_url = '';
     751
     752    // Home URL からメタタグをパースして取得を試みる
     753    $body = _wpbc_fetch_home_page_html();
     754
     755    if ( ! empty( $body ) ) {
     756        $dom                   = new DOMDocument();
     757        $libxml_previous_state = libxml_use_internal_errors( true );
     758        $dom->loadHTML( mb_convert_encoding( $body, 'HTML-ENTITIES', 'UTF-8' ) );
     759        libxml_clear_errors();
     760        libxml_use_internal_errors( $libxml_previous_state );
     761        $xpath = new DOMXPath( $dom );
     762
     763        $parsed_favicon = wpbc_get_favicon_url( $xpath, $home_url );
     764        if ( $parsed_favicon ) {
     765            $favicon_url = $parsed_favicon;
     766        }
     767    }
     768
     769    // パースで取得できなかった場合は get_site_icon_url() を試す
     770    if ( empty( $favicon_url ) ) {
     771        $favicon_url = get_site_icon_url();
     772    }
     773
     774    // 1年間保存
     775    set_transient( $cache_key, $favicon_url, YEAR_IN_SECONDS );
     776
     777    return $favicon_url;
     778}
     779
     780/**
     781 * サイト共通の OG Image を取得し、長期間キャッシュする
     782 */
     783function wpbc_get_site_og_image() {
     784    $cache_key    = 'wpbc_site_og_image';
     785    $og_image_url = get_transient( $cache_key );
     786
     787    if ( false !== $og_image_url ) {
     788        return $og_image_url;
     789    }
     790
     791    $og_image_url = '';
     792
     793    $body = _wpbc_fetch_home_page_html();
     794
     795    if ( ! empty( $body ) ) {
     796        $dom                   = new DOMDocument();
     797        $libxml_previous_state = libxml_use_internal_errors( true );
     798        $dom->loadHTML( mb_convert_encoding( $body, 'HTML-ENTITIES', 'UTF-8' ) );
     799        libxml_clear_errors();
     800        libxml_use_internal_errors( $libxml_previous_state );
     801        $xpath = new DOMXPath( $dom );
     802
     803        $og_image = $xpath->query( '//meta[@property="og:image"]/@content' );
     804        if ( $og_image->length > 0 ) {
     805            $og_image_url = trim( $og_image->item( 0 )->textContent );
     806        }
     807    }
     808
     809    // 1年間保存
     810    set_transient( $cache_key, $og_image_url, YEAR_IN_SECONDS );
     811
     812    return $og_image_url;
     813}
     814
     815/**
     816 * サイトの Home Page の HTML を取得し、同一リクエスト内でキャッシュする
     817 */
     818function _wpbc_fetch_home_page_html() {
     819    static $html_content = null;
     820
     821    if ( null !== $html_content ) {
     822        return $html_content;
     823    }
     824
     825    $home_url = home_url();
     826    $response = wp_remote_get(
     827        $home_url,
     828        array(
     829            'timeout'     => 10,
     830            'redirection' => 5,
     831            'sslverify'   => false,
     832            'user-agent'  => 'Mozilla/5.0 (WordPress/Blogcard-For-WP)',
     833        )
     834    );
     835
     836    if ( ! is_wp_error( $response ) && 200 === wp_remote_retrieve_response_code( $response ) ) {
     837        $html_content = wp_remote_retrieve_body( $response );
     838    } else {
     839        $html_content = ''; // エラー時は空文字をキャッシュして再試行を防ぐ
     840    }
     841
     842    return $html_content;
     843}
  • blogcard-for-wp/tags/2.3.0/build/block.json

    r3474088 r3475253  
    33  "apiVersion": 3,
    44  "name": "su/blogcard",
    5   "version": "2.2.1",
     5  "version": "2.3.0",
    66  "title": "ブログカード",
    77  "category": "su-blocks",
  • blogcard-for-wp/tags/2.3.0/build/index.asset.php

    r3460397 r3475253  
    1 <?php return array('dependencies' => array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n'), 'version' => '5dd1ee7d806b20c47405');
     1<?php return array('dependencies' => array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n'), 'version' => '0dec3f352373e006806d');
  • blogcard-for-wp/tags/2.3.0/build/index.js

    r3460397 r3475253  
    1 (()=>{"use strict";var e,t={486:(e,t,l)=>{const a=window.wp.blocks,n=window.React,r=window.wp.blockEditor,c=window.wp.element,o=window.wp.i18n,s=window.wp.apiFetch;var i=l.n(s);const p=window.wp.components;function m(e){return!(!e||e.length<10)&&URL.canParse(e)}function u(e){if(!e)return!1;try{const t=new URL(e),l=new URL(window.location.href).hostname,a=t.hostname;return l===a||!(!l.endsWith("."+a)&&!a.endsWith("."+l))}catch{return!1}}function d({results:e,isLoading:t,onSelect:l,onClose:a,error:r}){return(0,n.createElement)("div",{className:"wpbc-search-results"},(0,n.createElement)("div",{className:"wpbc-search-results-header"},(0,n.createElement)("span",null,(0,o.__)("検索結果","wpbc")),(0,n.createElement)("button",{type:"button",className:"wpbc-search-close",onClick:a},"×")),t?(0,n.createElement)("div",{className:"wpbc-search-loading"},(0,n.createElement)(p.Spinner,null),(0,o.__)("検索中...","wpbc")):r?(0,n.createElement)("div",{className:"wpbc-search-error",style:{color:"#cc0000",padding:"10px",textAlign:"center"}},r):e&&e.length>0?(0,n.createElement)("ul",{className:"wpbc-search-results-list"},e.map(e=>(0,n.createElement)("li",{key:e.id,className:"wpbc-search-result-item",onClick:()=>l(e)},e.thumbnail&&(0,n.createElement)("div",{className:"wpbc-search-result-thumbnail"},(0,n.createElement)("img",{src:e.thumbnail,alt:e.title,width:"60",height:"60"})),(0,n.createElement)("div",{className:"wpbc-search-result-content"},(0,n.createElement)("div",{className:"wpbc-search-result-title"},e.title),(0,n.createElement)("div",{className:"wpbc-search-result-meta"},(0,n.createElement)("span",{className:"wpbc-search-result-type"},"post"===e.type?(0,o.__)("投稿","wpbc"):(0,o.__)("固定ページ","wpbc")),(0,n.createElement)("span",{className:"wpbc-search-result-date"},e.date)),e.excerpt&&(0,n.createElement)("div",{className:"wpbc-search-result-excerpt"},e.excerpt))))):(0,n.createElement)("div",{className:"wpbc-search-no-results"},(0,o.__)("検索結果が見つかりませんでした","wpbc")))}function b({value:e,onChange:t,onKeyDown:l,onSelectResult:a,placeholder:r=(0,o.__)("https://example.com or キーワード","wpbc"),label:s=(0,o.__)("URLまたはサイト内検索","wpbc"),showSearch:u=!1,disabled:b=!1}){const h=m(e),[w,_]=(0,c.useState)([]),[g,E]=(0,c.useState)(!1),[f,v]=(0,c.useState)(!1),[y,x]=(0,c.useState)(""),C=(0,c.useRef)(null),k=(0,c.useCallback)(async e=>{if(!e||e.length<2)return _([]),v(!1),void x("");C.current&&C.current.abort(),C.current=new AbortController,E(!0),x("");try{const t=await i()({path:`/wpbc/v1/search?q=${encodeURIComponent(e)}`,method:"GET",signal:C.current.signal});t&&t.success?(_(t.data||[]),v(!0),x("")):(_([]),v(!1),x((0,o.__)("検索に失敗しました。","wpbc")))}catch(e){if("AbortError"===e.name)return;_([]),v(!1),x((0,o.__)("検索中にエラーが発生しました。","wpbc"))}finally{E(!1)}},[]);return(0,c.useEffect)(()=>{if(u&&!b){if(!e||""===e.trim())return _([]),v(!1),void x("");if(!h){const t=setTimeout(()=>{k(e)},300);return()=>{clearTimeout(t),C.current&&C.current.abort()}}_([]),v(!1),x("")}},[e,u,b,h,k]),(0,c.useEffect)(()=>{h&&(_([]),v(!1),E(!1),x(""))},[h]),(0,c.useEffect)(()=>()=>{C.current&&C.current.abort()},[]),(0,n.createElement)("div",{className:"wpbc-search-input"},(0,n.createElement)(p.TextControl,{label:s,value:e,onChange:t,onKeyDown:t=>{"Enter"===t.key&&(t.preventDefault(),m(e)&&l&&l(t))},placeholder:r,disabled:b,__next40pxDefaultSize:!0,__nextHasNoMarginBottom:!0}),u&&!b&&e&&""!==e.trim()&&!m(e)&&(f||y)&&(0,n.createElement)(d,{results:w,isLoading:g,onSelect:e=>{t(e.url),a&&a(e),v(!1),_([])},onClose:()=>{v(!1),_([])},error:y}))}function h({attributes:e}){const{url:t,title:l,description:a,thumbnailUrl:r,thumbnailId:c,showThumbnail:o,favicon:s,target:i="_blank",noopener:p=!0,nofollow:m=!1,noreferrer:u=!1,sponsored:d=!1,ugc:b=!1,isSelected:h=!1,isManual:w=!1}=e,_=[];p&&_.push("noopener"),u&&_.push("noreferrer"),m&&_.push("nofollow"),d&&_.push("sponsored"),b&&_.push("ugc");const g=_.length>0?_.join(" "):"",E=r,f=o&&E,v=w&&h&&!l,y=w&&h&&!a;return(0,n.createElement)("article",{className:"wp-blogcard",cite:t},(0,n.createElement)("a",{href:t,target:i||void 0,rel:g||void 0,className:"wp-blogcard-item"},f&&(0,n.createElement)("figure",{className:"wp-blogcard-figure"},(0,n.createElement)("img",{src:E,alt:"","aria-hidden":"true"})),(0,n.createElement)("div",{className:"wp-blogcard-content"},(0,n.createElement)("div",{className:"wp-blogcard-title"},l||(v?(0,n.createElement)("span",{className:"wp-blogcard-placeholder"},"Title Placeholder"):"")),(0,n.createElement)("div",{className:"wp-blogcard-description"},a||(y?(0,n.createElement)("span",{className:"wp-blogcard-placeholder"},"Description Placeholder"):"")),(0,n.createElement)("div",{className:"wp-blogcard-cite"},s&&(0,n.createElement)("img",{className:"wp-blogcard-favicon",src:s||"",alt:"","aria-hidden":"true"}),(0,n.createElement)("div",{className:"wp-blogcard-domain"},function(e){try{return new URL(e).hostname}catch{return""}}(t))))))}function w({url:e,cached:t,onOpenLink:l}){return(0,n.createElement)(p.Flex,{className:"blogcard-preview-footer",justify:"space-between",align:"center",style:{marginTop:"0.25rem"}},(0,n.createElement)(p.FlexItem,null,t?(0,n.createElement)("div",{className:"wpbc-cached-label"},"Cached"):null),(0,n.createElement)(p.FlexItem,null,(0,n.createElement)(p.Button,{type:"button",className:"wpbc-show-link-button",onClick:()=>l(e),disabled:!e,variant:"tertiary",size:"medium"},(0,o.__)("リンク先を確認","wpbc"))))}function _({error:e,errorCode:t}){return e?(0,n.createElement)("div",{style:{color:"#cc0000",fontSize:"14px",margin:"8px 0",padding:"8px 0"}},e,t&&(0,n.createElement)("span",{style:{marginLeft:"8px",color:"#666",fontSize:"12px"}},"(",t,")")):null}function g({message:e=(0,o.__)("メタデータを取得中...","wpbc")}){return(0,n.createElement)("div",{style:{textAlign:"center",padding:"1.25rem"}},(0,n.createElement)(p.Spinner,null),(0,n.createElement)("p",{style:{fontSize:"0.875rem"}},e))}function E({attributes:e,setAttributes:t,inputUrl:l,setInputUrl:a,handleKeyDown:c}){const{target:s,noopener:i,nofollow:m,noreferrer:u,sponsored:d,ugc:b,showThumbnail:h,title:w,description:_,thumbnailUrl:g,thumbnailId:E,favicon:v}=e,y=()=>E&&g?(0,n.createElement)("div",{style:{width:"100%",aspectRatio:"16/9",overflow:"hidden",borderRadius:"4px",backgroundColor:"#f0f0f0",display:"flex",alignItems:"center",justifyContent:"center"}},(0,n.createElement)("img",{src:g,alt:"",style:{width:"100%",height:"100%",objectFit:"cover"}})):(0,n.createElement)("div",{style:{backgroundColor:"#f0f0f0",borderRadius:"4px",display:"flex",alignItems:"center",justifyContent:"center",color:"#666",fontSize:"14px"}},(0,o.__)("サムネイルを設定","wpbc"));return(0,n.createElement)(r.InspectorControls,null,(0,n.createElement)(p.PanelBody,{title:(0,o.__)("ブロック設定","wpbc"),initialOpen:!0},(0,n.createElement)(p.TextControl,{label:(0,o.__)("URL","wpbc"),value:l,onChange:e=>a(e),onKeyDown:c,placeholder:(0,o.__)("https://example.com or キーワード","wpbc")}),(0,n.createElement)("hr",{style:{margin:"20px 0"}}),(0,n.createElement)("h4",null,(0,o.__)("TARGET属性","wpbc")),(0,n.createElement)(p.SelectControl,{label:(0,o.__)("TARGET属性","wpbc"),value:s,onChange:e=>{t("_blank"===e?{target:e,noopener:!0}:{target:e})},options:[{label:(0,o.__)("なし","wpbc"),value:""},{label:(0,o.__)("_blank(別タブ)","wpbc"),value:"_blank"},{label:(0,o.__)("_self (同じタブ)","wpbc"),value:"_self"}]}),(0,n.createElement)("hr",{style:{margin:"20px 0"}}),(0,n.createElement)("h4",null,(0,o.__)("Rel属性","wpbc")),(0,n.createElement)(p.ToggleControl,{label:(0,o.__)("noopener を追加","wpbc"),checked:i,disabled:"_blank"===s,onChange:e=>t({noopener:e})}),"_blank"===s&&(0,n.createElement)("p",{style:{fontSize:"12px",color:"#666",margin:"8px 0"}},(0,o.__)("_blankの場合はセキュリティ上noopenerが必須です","wpbc")),(0,n.createElement)(p.ToggleControl,{label:(0,o.__)("rel=nofollow を追加","wpbc"),checked:m,onChange:e=>t({nofollow:e})}),(0,n.createElement)(p.ToggleControl,{label:(0,o.__)("rel=noreferrer を追加","wpbc"),checked:u,onChange:e=>t({noreferrer:e})}),(0,n.createElement)(p.ToggleControl,{label:(0,o.__)("rel=sponsored を追加","wpbc"),checked:d,onChange:e=>t({sponsored:e})}),(0,n.createElement)(p.ToggleControl,{label:(0,o.__)("rel=ugc を追加","wpbc"),checked:b,onChange:e=>t({ugc:e})}),(0,n.createElement)("hr",{style:{margin:"20px 0"}}),(0,n.createElement)("h4",null,(0,o.__)("サムネイル","wpbc")),(0,n.createElement)(p.ToggleControl,{label:(0,o.__)("サムネイルを表示しない","wpbc"),checked:!h,onChange:e=>t({showThumbnail:!e})}),(0,n.createElement)("hr",{style:{margin:"20px 0"}}),(0,n.createElement)("h4",null,(0,o.__)("タイトルを手動で入力","wpbc")),(0,n.createElement)(p.TextControl,{label:(0,o.__)("タイトル","wpbc"),value:w,onChange:e=>t({title:e}),placeholder:(0,o.__)("タイトルを入力","wpbc")}),(0,n.createElement)("hr",{style:{margin:"20px 0"}}),(0,n.createElement)("h4",null,(0,o.__)("説明文を手動で入力","wpbc")),(0,n.createElement)(p.TextControl,{label:(0,o.__)("説明文","wpbc"),value:_,onChange:e=>t({description:e}),placeholder:(0,o.__)("説明文を入力","wpbc")}),(0,n.createElement)("hr",{style:{margin:"20px 0"}}),(0,n.createElement)("h4",null,(0,o.__)("Faviconを手動で入力","wpbc")),(0,n.createElement)(p.TextControl,{label:(0,o.__)("Favicon URL","wpbc"),value:v,onChange:e=>t({favicon:e}),placeholder:(0,o.__)("https://example.com/favicon.ico","wpbc")}),(0,n.createElement)("hr",{style:{margin:"20px 0"}}),(0,n.createElement)(p.BaseControl,{label:(0,o.__)("サムネイルを手動で設定","wpbc")},(0,n.createElement)(r.MediaUploadCheck,null,(0,n.createElement)(r.MediaUpload,{onSelect:e=>{t({thumbnailId:e.id,thumbnailUrl:e.url,showThumbnail:!0})},allowedTypes:["image"],value:E,render:({open:e})=>(0,n.createElement)(p.Button,{onClick:e,className:"editor-post-featured-image__toggle"},(0,n.createElement)(y,null))})),(0,n.createElement)(p.Button,{style:{marginTop:"0.5rem"},className:"is-tertiary",onClick:()=>{t({thumbnailId:0,thumbnailUrl:"",showThumbnail:!1})}},(0,o.__)("クリア","wpbc"))),(0,n.createElement)("hr",{style:{margin:"20px 0"}}),(0,n.createElement)("h4",null,(0,o.__)("キャッシュ管理","wpbc")),(0,n.createElement)("div",{style:{display:"flex",gap:"10px",flexWrap:"wrap"}},(0,n.createElement)(p.Button,{secondary:!0,onClick:f("plugin"),style:{fontSize:"12px"}},(0,o.__)("このブログカードのキャッシュをクリア","wpbc")),(0,n.createElement)(p.Button,{isDestructive:!0,onClick:()=>{f("all")()}},(0,o.__)("すべてのブログカードのキャッシュをクリア","wpbc")))))}function f(e="plugin"){return async()=>{try{const t=await i()({path:"/wpbc/v1/clear-cache",method:"POST",data:{type:e}});t.success?alert(t.message):alert((0,o.__)("キャッシュのクリアに失敗しました。","wpbc"))}catch(e){console.error("Cache clear error:",e),alert((0,o.__)("キャッシュのクリア中にエラーが発生しました。","wpbc"))}}}const v=()=>window.wpbcSettings||{external_target:"_blank",internal_target:"_self"};(0,a.registerBlockType)("su/blogcard",{edit:function({attributes:e,setAttributes:t}){const{url:l,title:a,description:s,thumbnailUrl:d,showThumbnail:f,favicon:y,isManual:x}=e,[C,k]=(0,c.useState)(l||""),[N,T]=(0,c.useState)(!1),[S,R]=(0,c.useState)(""),[U,O]=(0,c.useState)(""),[I,B]=(0,c.useState)(!1),F=(0,r.useBlockProps)(),L=F.className?.includes("is-selected")||!1,D=async()=>{if(!C||C.trim().length<10||!m(C))return R(""),void O("");T(!0),R(""),O("");try{const e=u(C)?`/wpbc/v1/internal-metadata?url=${encodeURIComponent(C)}`:"/wpbc/v1/metadata",l=await i()({path:e,method:u(C)?"GET":"POST",data:u(C)?void 0:{url:C}});if(l.success){const e=l.data,a=v(),n=u(C)?a.internal_target:a.external_target;t({url:C,title:e.title||C,description:e.description||"",thumbnailUrl:e.thumbnail||"",showThumbnail:!!e.thumbnail,favicon:e.favicon||"",target:n,isManual:!1}),B(!0===e.cached),R(""),O("")}else{const e=l.message||l.data?.message||(0,o.__)("メタデータの取得に失敗しました。","wpbc"),t=l.code||l.data?.code||"UNKNOWN_ERROR";R(e),O(t)}}catch(e){const t=e.status||e.code||"NETWORK_ERROR";let l=e.message||(0,o.__)("メタデータの取得中にエラーが発生しました。","wpbc");e.data&&e.data.message&&(l=e.data.message),R(l),O(t)}finally{T(!1)}},j=e=>{if("Enter"===e.key){if(e.preventDefault(),l)return;m(C)&&D()}};return(0,n.createElement)("div",{...F},(0,n.createElement)(E,{attributes:e,setAttributes:t,inputUrl:C,setInputUrl:k,handleKeyDown:j}),l?(0,n.createElement)(n.Fragment,null,N&&(0,n.createElement)(g,null),L&&(0,n.createElement)("div",{className:"wpbc-input-wrapper"},(0,n.createElement)(b,{key:"locked-search-input",value:C,onChange:k,showSearch:!1,disabled:!0,label:"",placeholder:(0,o.__)("https://example.com","wpbc"),help:(0,o.__)("URLを変更するにはブロックを削除して再作成してください","wpbc")})),(0,n.createElement)(_,{error:S,errorCode:U}),!N&&!S&&(0,n.createElement)("div",{className:"blogcard-preview"},(0,n.createElement)(h,{attributes:{url:l,title:a,description:s,thumbnailUrl:d,showThumbnail:f,favicon:y,isManual:x,isSelected:L}}),L&&(0,n.createElement)(w,{url:l,cached:I,onOpenLink:e=>{window.open(e,"_blank")}}))):(0,n.createElement)(n.Fragment,null,(0,n.createElement)(n.Fragment,null,(0,n.createElement)(b,{key:"placeholder-search-input",value:C,onChange:k,onKeyDown:j,onSelectResult:e=>{k(e.url),R(""),O(""),B(!1);const l=v(),a=u(e.url)?l.internal_target:l.external_target;t({url:e.url,title:e.title||e.url,description:e.description||e.excerpt||"",thumbnailUrl:e.thumbnail||"",showThumbnail:!!e.thumbnail,favicon:e.favicon||"",target:a,isManual:!1})},showSearch:!0,disabled:!1,placeholder:(0,o.__)("https://example.com or 検索キーワード","wpbc")}),C&&m(C)&&(0,n.createElement)(p.Flex,{gap:2,className:"wpbc-search-buttons",justify:"flex-end"},(0,n.createElement)(p.FlexItem,null,(0,n.createElement)(p.Button,{variant:"tertiary",onClick:()=>{C&&t({url:C,title:"",description:"",thumbnailUrl:"",showThumbnail:!1,favicon:"",isManual:!0})},disabled:N},(0,o.__)("手動で作成","wpbc"))),(0,n.createElement)(p.FlexItem,null,(0,n.createElement)(p.Button,{variant:"primary",onClick:D,isBusy:N,disabled:N},(0,o.__)("検索して作成","wpbc")," ",(0,n.createElement)("span",null,"Enter"))))),N&&(0,n.createElement)(g,null),(0,n.createElement)(_,{error:S,errorCode:U})))},save:function(){return null}})}},l={};function a(e){var n=l[e];if(void 0!==n)return n.exports;var r=l[e]={exports:{}};return t[e](r,r.exports,a),r.exports}a.m=t,e=[],a.O=(t,l,n,r)=>{if(!l){var c=1/0;for(p=0;p<e.length;p++){for(var[l,n,r]=e[p],o=!0,s=0;s<l.length;s++)(!1&r||c>=r)&&Object.keys(a.O).every(e=>a.O[e](l[s]))?l.splice(s--,1):(o=!1,r<c&&(c=r));if(o){e.splice(p--,1);var i=n();void 0!==i&&(t=i)}}return t}r=r||0;for(var p=e.length;p>0&&e[p-1][2]>r;p--)e[p]=e[p-1];e[p]=[l,n,r]},a.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return a.d(t,{a:t}),t},a.d=(e,t)=>{for(var l in t)a.o(t,l)&&!a.o(e,l)&&Object.defineProperty(e,l,{enumerable:!0,get:t[l]})},a.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{var e={57:0,350:0};a.O.j=t=>0===e[t];var t=(t,l)=>{var n,r,[c,o,s]=l,i=0;if(c.some(t=>0!==e[t])){for(n in o)a.o(o,n)&&(a.m[n]=o[n]);if(s)var p=s(a)}for(t&&t(l);i<c.length;i++)r=c[i],a.o(e,r)&&e[r]&&e[r][0](),e[r]=0;return a.O(p)},l=globalThis.webpackChunkblogcard_for_wp=globalThis.webpackChunkblogcard_for_wp||[];l.forEach(t.bind(null,0)),l.push=t.bind(null,l.push.bind(l))})();var n=a.O(void 0,[350],()=>a(486));n=a.O(n)})();
     1(()=>{"use strict";var e,t={486:(e,t,n)=>{const l=window.wp.blocks,a=window.React,r=window.wp.blockEditor,c=window.wp.element,o=window.wp.i18n,i=window.wp.apiFetch;var s=n.n(i);const p=window.wp.components;function u(e){return!(!e||e.length<10)&&URL.canParse(e)}function m(e){if(!e)return!1;try{const t=new URL(e),n=new URL(window.location.href).hostname,l=t.hostname;return n===l||!(!n.endsWith("."+l)&&!l.endsWith("."+n))}catch{return!1}}function d(e){if(!e)return!1;try{const t=new URL(e);let n="undefined"!=typeof window&&window.wpbcSettings?.home_url;n||(n=window.location.origin);const l=new URL(n);return t.href.replace(/\/$/,"")===l.href.replace(/\/$/,"")}catch{return!1}}function b({results:e,isLoading:t,onSelect:n,onClose:l,error:r}){return(0,a.createElement)("div",{className:"wpbc-search-results"},(0,a.createElement)("div",{className:"wpbc-search-results-header"},(0,a.createElement)("span",null,(0,o.__)("検索結果","wpbc")),(0,a.createElement)("button",{type:"button",className:"wpbc-search-close",onClick:l},"×")),t?(0,a.createElement)("div",{className:"wpbc-search-loading",style:{textAlign:"center",padding:"1.25rem"}},(0,a.createElement)(p.Spinner,null),(0,a.createElement)("p",{style:{fontSize:"0.875rem",margin:"10px 0 0"}},(0,o.__)("検索中...","wpbc"))):r?(0,a.createElement)("div",{className:"wpbc-search-error",style:{color:"#cc0000",padding:"10px",textAlign:"center"}},r):e&&e.length>0?(0,a.createElement)("ul",{className:"wpbc-search-results-list"},e.map(e=>(0,a.createElement)("li",{key:e.id,className:"wpbc-search-result-item",onClick:()=>n(e)},e.thumbnail&&(0,a.createElement)("div",{className:"wpbc-search-result-thumbnail"},(0,a.createElement)("img",{src:e.thumbnail,alt:e.title,width:"60",height:"60"})),(0,a.createElement)("div",{className:"wpbc-search-result-content"},(0,a.createElement)("div",{className:"wpbc-search-result-title"},e.title),(0,a.createElement)("div",{className:"wpbc-search-result-meta"},(0,a.createElement)("span",{className:"wpbc-search-result-type"},"post"===e.type?(0,o.__)("投稿","wpbc"):(0,o.__)("固定ページ","wpbc")),(0,a.createElement)("span",{className:"wpbc-search-result-date"},e.date)),e.excerpt&&(0,a.createElement)("div",{className:"wpbc-search-result-excerpt"},e.excerpt))))):(0,a.createElement)("div",{className:"wpbc-search-no-results"},(0,o.__)("検索結果が見つかりませんでした","wpbc")))}function h({value:e,onChange:t,onKeyDown:n,onSelectResult:l,placeholder:r=(0,o.__)("https://example.com or キーワード","wpbc"),label:i=(0,o.__)("URLまたはサイト内検索","wpbc"),showSearch:m=!1,disabled:d=!1}){const h=u(e),[w,g]=(0,c.useState)([]),[_,E]=(0,c.useState)(!1),[f,v]=(0,c.useState)(!1),[y,x]=(0,c.useState)(""),C=(0,c.useRef)(null),k=(0,c.useCallback)(async e=>{if(!e||e.length<2)return g([]),v(!1),void x("");C.current&&C.current.abort(),C.current=new AbortController,E(!0),x("");try{const t=await s()({path:`/wpbc/v1/search?q=${encodeURIComponent(e)}`,method:"GET",signal:C.current.signal});t&&t.success?(g(t.data||[]),v(!0),x("")):(g([]),v(!1),x((0,o.__)("検索に失敗しました。","wpbc")))}catch(e){if("AbortError"===e.name)return;g([]),v(!1),x((0,o.__)("検索中にエラーが発生しました。","wpbc"))}finally{E(!1)}},[]);return(0,c.useEffect)(()=>{if(m&&!d){if(!e||""===e.trim())return g([]),v(!1),void x("");if(!h){const t=setTimeout(()=>{k(e)},300);return()=>{clearTimeout(t),C.current&&C.current.abort()}}g([]),v(!1),x("")}},[e,m,d,h,k]),(0,c.useEffect)(()=>{h&&(g([]),v(!1),E(!1),x(""))},[h]),(0,c.useEffect)(()=>()=>{C.current&&C.current.abort()},[]),(0,a.createElement)("div",{className:"wpbc-search-input"},(0,a.createElement)(p.TextControl,{label:i,value:e,onChange:t,onKeyDown:t=>{"Enter"===t.key&&(t.preventDefault(),u(e)&&n&&n(t))},placeholder:r,disabled:d,__next40pxDefaultSize:!0,__nextHasNoMarginBottom:!0}),m&&!d&&e&&""!==e.trim()&&!u(e)&&(_||f||y)&&(0,a.createElement)(b,{results:w,isLoading:_,onSelect:e=>{t(e.url),l&&l(e),v(!1),g([])},onClose:()=>{v(!1),g([])},error:y}))}function w({attributes:e}){const{url:t,title:n,description:l,thumbnailUrl:r,thumbnailId:c,showThumbnail:o,favicon:i,target:s="_blank",noopener:p=!0,nofollow:u=!1,noreferrer:b=!1,sponsored:h=!1,ugc:w=!1,isSelected:g=!1,isManual:_=!1}=e,E=[];p&&E.push("noopener"),b&&E.push("noreferrer"),u&&E.push("nofollow"),h&&E.push("sponsored"),w&&E.push("ugc");const f=E.length>0?E.join(" "):"",v=!r&&d(t)&&"undefined"!=typeof window&&window.wpbcSettings?.site_og_image?window.wpbcSettings.site_og_image:r,y=o&&v,x=_&&g&&!n,C=_&&g&&!l;return(0,a.createElement)("article",{className:"wp-blogcard",cite:t},(0,a.createElement)("a",{href:t,target:s||void 0,rel:f||void 0,className:"wp-blogcard-item"},y&&(0,a.createElement)("figure",{className:"wp-blogcard-figure"},(0,a.createElement)("img",{src:v,alt:"","aria-hidden":"true"})),(0,a.createElement)("div",{className:"wp-blogcard-content"},(0,a.createElement)("div",{className:"wp-blogcard-title"},n||(x?(0,a.createElement)("span",{className:"wp-blogcard-placeholder"},"Title Placeholder"):"")),(0,a.createElement)("div",{className:"wp-blogcard-description"},l||(C?(0,a.createElement)("span",{className:"wp-blogcard-placeholder"},"Description Placeholder"):"")),(0,a.createElement)("div",{className:"wp-blogcard-cite"},(i||"undefined"!=typeof window&&window.wpbcSettings?.site_favicon&&m(t))&&(0,a.createElement)("img",{className:"wp-blogcard-favicon",src:i||("undefined"!=typeof window?window.wpbcSettings?.site_favicon:""),alt:"","aria-hidden":"true"}),(0,a.createElement)("div",{className:"wp-blogcard-domain"},function(e){try{return new URL(e).hostname}catch{return""}}(t))))))}function g({url:e,cached:t,onOpenLink:n}){return(0,a.createElement)(p.Flex,{className:"blogcard-preview-footer",justify:"space-between",align:"center",style:{marginTop:"0.25rem"}},(0,a.createElement)(p.FlexItem,null,t?(0,a.createElement)("div",{className:"wpbc-cached-label"},"Cached"):null),(0,a.createElement)(p.FlexItem,null,(0,a.createElement)(p.Button,{type:"button",className:"wpbc-show-link-button",onClick:()=>n(e),disabled:!e,variant:"tertiary",size:"medium"},(0,o.__)("リンク先を確認","wpbc"))))}function _({error:e,errorCode:t}){return e?(0,a.createElement)("div",{style:{color:"#cc0000",fontSize:"14px",margin:"8px 0",padding:"8px 0"}},e,t&&(0,a.createElement)("span",{style:{marginLeft:"8px",color:"#666",fontSize:"12px"}},"(",t,")")):null}function E({message:e=(0,o.__)("メタデータを取得中...","wpbc")}){return(0,a.createElement)("div",{style:{textAlign:"center",padding:"1.25rem"}},(0,a.createElement)(p.Spinner,null),(0,a.createElement)("p",{style:{fontSize:"0.875rem"}},e))}function f({attributes:e,setAttributes:t,inputUrl:n,setInputUrl:l,handleKeyDown:c}){const{target:i,noopener:s,nofollow:u,noreferrer:m,sponsored:d,ugc:b,showThumbnail:h,title:w,description:g,thumbnailUrl:_,thumbnailId:E,favicon:f}=e,y=()=>E&&_?(0,a.createElement)("div",{style:{width:"100%",aspectRatio:"16/9",overflow:"hidden",borderRadius:"4px",backgroundColor:"#f0f0f0",display:"flex",alignItems:"center",justifyContent:"center"}},(0,a.createElement)("img",{src:_,alt:"",style:{width:"100%",height:"100%",objectFit:"cover"}})):(0,a.createElement)("div",{style:{backgroundColor:"#f0f0f0",borderRadius:"4px",display:"flex",alignItems:"center",justifyContent:"center",color:"#666",fontSize:"14px"}},(0,o.__)("サムネイルを設定","wpbc"));return(0,a.createElement)(r.InspectorControls,null,(0,a.createElement)(p.PanelBody,{title:(0,o.__)("ブロック設定","wpbc"),initialOpen:!0},(0,a.createElement)(p.TextControl,{label:(0,o.__)("URL","wpbc"),value:n,onChange:e=>l(e),onKeyDown:c,placeholder:(0,o.__)("https://example.com or キーワード","wpbc")}),(0,a.createElement)("hr",{style:{margin:"20px 0"}}),(0,a.createElement)("h4",null,(0,o.__)("TARGET属性","wpbc")),(0,a.createElement)(p.SelectControl,{label:(0,o.__)("TARGET属性","wpbc"),value:i,onChange:e=>{t("_blank"===e?{target:e,noopener:!0}:{target:e})},options:[{label:(0,o.__)("なし","wpbc"),value:""},{label:(0,o.__)("_blank(別タブ)","wpbc"),value:"_blank"},{label:(0,o.__)("_self (同じタブ)","wpbc"),value:"_self"}]}),(0,a.createElement)("hr",{style:{margin:"20px 0"}}),(0,a.createElement)("h4",null,(0,o.__)("Rel属性","wpbc")),(0,a.createElement)(p.ToggleControl,{label:(0,o.__)("noopener を追加","wpbc"),checked:s,disabled:"_blank"===i,onChange:e=>t({noopener:e})}),"_blank"===i&&(0,a.createElement)("p",{style:{fontSize:"12px",color:"#666",margin:"8px 0"}},(0,o.__)("_blankの場合はセキュリティ上noopenerが必須です","wpbc")),(0,a.createElement)(p.ToggleControl,{label:(0,o.__)("rel=nofollow を追加","wpbc"),checked:u,onChange:e=>t({nofollow:e})}),(0,a.createElement)(p.ToggleControl,{label:(0,o.__)("rel=noreferrer を追加","wpbc"),checked:m,onChange:e=>t({noreferrer:e})}),(0,a.createElement)(p.ToggleControl,{label:(0,o.__)("rel=sponsored を追加","wpbc"),checked:d,onChange:e=>t({sponsored:e})}),(0,a.createElement)(p.ToggleControl,{label:(0,o.__)("rel=ugc を追加","wpbc"),checked:b,onChange:e=>t({ugc:e})}),(0,a.createElement)("hr",{style:{margin:"20px 0"}}),(0,a.createElement)("h4",null,(0,o.__)("サムネイル","wpbc")),(0,a.createElement)(p.ToggleControl,{label:(0,o.__)("サムネイルを表示しない","wpbc"),checked:!h,onChange:e=>t({showThumbnail:!e})}),(0,a.createElement)("hr",{style:{margin:"20px 0"}}),(0,a.createElement)("h4",null,(0,o.__)("タイトルを手動で入力","wpbc")),(0,a.createElement)(p.TextControl,{label:(0,o.__)("タイトル","wpbc"),value:w,onChange:e=>t({title:e}),placeholder:(0,o.__)("タイトルを入力","wpbc")}),(0,a.createElement)("hr",{style:{margin:"20px 0"}}),(0,a.createElement)("h4",null,(0,o.__)("説明文を手動で入力","wpbc")),(0,a.createElement)(p.TextControl,{label:(0,o.__)("説明文","wpbc"),value:g,onChange:e=>t({description:e}),placeholder:(0,o.__)("説明文を入力","wpbc")}),(0,a.createElement)("hr",{style:{margin:"20px 0"}}),(0,a.createElement)("h4",null,(0,o.__)("Faviconを手動で入力","wpbc")),(0,a.createElement)(p.TextControl,{label:(0,o.__)("Favicon URL","wpbc"),value:f,onChange:e=>t({favicon:e}),placeholder:(0,o.__)("https://example.com/favicon.ico","wpbc")}),(0,a.createElement)("hr",{style:{margin:"20px 0"}}),(0,a.createElement)(p.BaseControl,{label:(0,o.__)("サムネイルを手動で設定","wpbc")},(0,a.createElement)(r.MediaUploadCheck,null,(0,a.createElement)(r.MediaUpload,{onSelect:e=>{t({thumbnailId:e.id,thumbnailUrl:e.url,showThumbnail:!0})},allowedTypes:["image"],value:E,render:({open:e})=>(0,a.createElement)(p.Button,{onClick:e,className:"editor-post-featured-image__toggle"},(0,a.createElement)(y,null))})),(0,a.createElement)(p.Button,{style:{marginTop:"0.5rem"},className:"is-tertiary",onClick:()=>{t({thumbnailId:0,thumbnailUrl:"",showThumbnail:!1})}},(0,o.__)("クリア","wpbc"))),(0,a.createElement)("hr",{style:{margin:"20px 0"}}),(0,a.createElement)("h4",null,(0,o.__)("キャッシュ管理","wpbc")),(0,a.createElement)("div",{style:{display:"flex",gap:"10px",flexWrap:"wrap"}},(0,a.createElement)(p.Button,{secondary:!0,onClick:v("plugin"),style:{fontSize:"12px"}},(0,o.__)("このブログカードのキャッシュをクリア","wpbc")),(0,a.createElement)(p.Button,{isDestructive:!0,onClick:()=>{v("all")()}},(0,o.__)("すべてのブログカードのキャッシュをクリア","wpbc")))))}function v(e="plugin"){return async()=>{try{const t=await s()({path:"/wpbc/v1/clear-cache",method:"POST",data:{type:e}});t.success?alert(t.message):alert((0,o.__)("キャッシュのクリアに失敗しました。","wpbc"))}catch(e){console.error("Cache clear error:",e),alert((0,o.__)("キャッシュのクリア中にエラーが発生しました。","wpbc"))}}}const y=()=>window.wpbcSettings||{external_target:"_blank",internal_target:"_self"};(0,l.registerBlockType)("su/blogcard",{edit:function({attributes:e,setAttributes:t}){const{url:n,title:l,description:i,thumbnailUrl:b,showThumbnail:v,favicon:x,isManual:C}=e,[k,N]=(0,c.useState)(n||""),[T,S]=(0,c.useState)(!1),[R,U]=(0,c.useState)(""),[O,I]=(0,c.useState)(""),[L,B]=(0,c.useState)(!1),F=(0,r.useBlockProps)(),D=F.className?.includes("is-selected")||!1,j=async()=>{if(!k||k.trim().length<10||!u(k))return U(""),void I("");S(!0),U(""),I("");try{const e=m(k)?`/wpbc/v1/internal-metadata?url=${encodeURIComponent(k)}`:"/wpbc/v1/metadata",n=await s()({path:e,method:m(k)?"GET":"POST",data:m(k)?void 0:{url:k}});if(n.success){const e=n.data,l=y(),a=m(k),r=a?l.internal_target:l.external_target;t({url:k,title:e.title||k,description:e.description||"",thumbnailUrl:d(k)?"":e.thumbnail||"",showThumbnail:!!(e.thumbnail||d(k)&&y().site_og_image),favicon:a?"":e.favicon||"",target:r,isManual:!1}),B(!0===e.cached),U(""),I("")}else{const e=n.message||n.data?.message||(0,o.__)("メタデータの取得に失敗しました。","wpbc"),t=n.code||n.data?.code||"UNKNOWN_ERROR";U(e),I(t)}}catch(e){const t=e.status||e.code||"NETWORK_ERROR";let n=e.message||(0,o.__)("メタデータの取得中にエラーが発生しました。","wpbc");e.data&&e.data.message&&(n=e.data.message),U(n),I(t)}finally{S(!1)}},A=e=>{if("Enter"===e.key){if(e.preventDefault(),n)return;u(k)&&j()}};return(0,a.createElement)("div",{...F},(0,a.createElement)(f,{attributes:e,setAttributes:t,inputUrl:k,setInputUrl:N,handleKeyDown:A}),n?(0,a.createElement)(a.Fragment,null,T&&(0,a.createElement)(E,null),D&&(0,a.createElement)("div",{className:"wpbc-input-wrapper"},(0,a.createElement)(h,{key:"locked-search-input",value:k,onChange:N,showSearch:!1,disabled:!0,label:"",placeholder:(0,o.__)("https://example.com","wpbc"),help:(0,o.__)("URLを変更するにはブロックを削除して再作成してください","wpbc")})),(0,a.createElement)(_,{error:R,errorCode:O}),!T&&!R&&(0,a.createElement)("div",{className:"blogcard-preview"},(0,a.createElement)(w,{attributes:{url:n,title:l,description:i,thumbnailUrl:b,showThumbnail:v,favicon:x,isManual:C,isSelected:D}}),D&&(0,a.createElement)(g,{url:n,cached:L,onOpenLink:e=>{window.open(e,"_blank")}}))):(0,a.createElement)(a.Fragment,null,(0,a.createElement)(a.Fragment,null,(0,a.createElement)(h,{key:"placeholder-search-input",value:k,onChange:N,onKeyDown:A,onSelectResult:e=>{N(e.url),U(""),I(""),B(!1);const n=y(),l=m(e.url),a=l?n.internal_target:n.external_target;t({url:e.url,title:e.title||e.url,description:e.description||e.excerpt||"",thumbnailUrl:d(e.url)?"":e.thumbnail_large||e.thumbnail||"",showThumbnail:!!(e.thumbnail_large||e.thumbnail||d(e.url)&&n.site_og_image),favicon:l?"":e.favicon||"",target:a,isManual:!1})},showSearch:!0,disabled:!1,placeholder:(0,o.__)("https://example.com or 検索キーワード","wpbc")}),k&&u(k)&&(0,a.createElement)(p.Flex,{gap:2,className:"wpbc-search-buttons",justify:"flex-end"},(0,a.createElement)(p.FlexItem,null,(0,a.createElement)(p.Button,{variant:"tertiary",onClick:()=>{k&&t({url:k,title:"",description:"",thumbnailUrl:"",showThumbnail:!1,favicon:"",isManual:!0})},disabled:T},(0,o.__)("手動で作成","wpbc"))),(0,a.createElement)(p.FlexItem,null,(0,a.createElement)(p.Button,{variant:"primary",onClick:j,isBusy:T,disabled:T},(0,o.__)("検索して作成","wpbc")," ",(0,a.createElement)("span",null,"Enter"))))),T&&(0,a.createElement)(E,null),(0,a.createElement)(_,{error:R,errorCode:O})))},save:function(){return null}})}},n={};function l(e){var a=n[e];if(void 0!==a)return a.exports;var r=n[e]={exports:{}};return t[e](r,r.exports,l),r.exports}l.m=t,e=[],l.O=(t,n,a,r)=>{if(!n){var c=1/0;for(p=0;p<e.length;p++){for(var[n,a,r]=e[p],o=!0,i=0;i<n.length;i++)(!1&r||c>=r)&&Object.keys(l.O).every(e=>l.O[e](n[i]))?n.splice(i--,1):(o=!1,r<c&&(c=r));if(o){e.splice(p--,1);var s=a();void 0!==s&&(t=s)}}return t}r=r||0;for(var p=e.length;p>0&&e[p-1][2]>r;p--)e[p]=e[p-1];e[p]=[n,a,r]},l.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return l.d(t,{a:t}),t},l.d=(e,t)=>{for(var n in t)l.o(t,n)&&!l.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},l.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{var e={57:0,350:0};l.O.j=t=>0===e[t];var t=(t,n)=>{var a,r,[c,o,i]=n,s=0;if(c.some(t=>0!==e[t])){for(a in o)l.o(o,a)&&(l.m[a]=o[a]);if(i)var p=i(l)}for(t&&t(n);s<c.length;s++)r=c[s],l.o(e,r)&&e[r]&&e[r][0](),e[r]=0;return l.O(p)},n=globalThis.webpackChunkblogcard_for_wp=globalThis.webpackChunkblogcard_for_wp||[];n.forEach(t.bind(null,0)),n.push=t.bind(null,n.push.bind(n))})();var a=l.O(void 0,[350],()=>l(486));a=l.O(a)})();
  • blogcard-for-wp/tags/2.3.0/build/render.php

    r3474088 r3475253  
    4949
    5050// サムネイル表示判定
    51 $display_thumbnail     = $thumbnail_url;
     51$display_thumbnail = $thumbnail_url;
     52
     53// 内部サイトの Home URL かつ thumbnailUrl が空の場合は、サイト共通の OG Image を取得
     54if ( empty( $display_thumbnail ) && function_exists( 'wpbc_is_internal_url' ) && wpbc_is_internal_url( $url ) ) {
     55    $normalized_url = rtrim( $url, '/' );
     56    $home_url       = rtrim( home_url(), '/' );
     57    $site_url       = rtrim( site_url(), '/' );
     58    if ( $normalized_url === $home_url || $normalized_url === $site_url ) {
     59        $display_thumbnail = wpbc_get_site_og_image();
     60    }
     61}
     62
    5263$should_show_thumbnail = $show_thumbnail && ! empty( $display_thumbnail );
    5364
     
    5970}
    6071
    61 // Faviconのフォールバック(空の場合は Google Favicon API を使用)
     72// Faviconのフォールバック
    6273if ( empty( $favicon ) && ! empty( $domain ) ) {
    63     $favicon = 'https://www.google.com/s2/favicons?domain=' . urlencode( $domain ) . '&sz=16';
     74    // 内部サイトの場合はサイト共通のファビコンを取得
     75    if ( function_exists( 'wpbc_is_internal_url' ) && wpbc_is_internal_url( $url ) ) {
     76        $favicon = wpbc_get_site_favicon();
     77    }
     78
     79    // それでも空の場合は Google Favicon API を使用(外部サイトなど)
     80    if ( empty( $favicon ) ) {
     81        $favicon = 'https://www.google.com/s2/favicons?domain=' . urlencode( $domain ) . '&sz=16';
     82    }
    6483}
    6584
  • blogcard-for-wp/tags/2.3.0/readme-ja.txt

    r3474088 r3475253  
    104104== Changelog ==
    105105
     106= 2.3.0 =
     107* 改善: サイト内検索時にFaviconが表示されない問題を修正。
     108* 改善: サイトのURLを入力時にエラーが表示される問題を修正。
     109* 改善: サイト内検索時にスピナーと「検索中...」メッセージを表示するように改善。
     110* 改善: エディター上でのローディング表示の視認性を向上。
     111
    106112= 2.2.1 =
    107113* バグ修正および微調整。
  • blogcard-for-wp/tags/2.3.0/readme.txt

    r3474088 r3475253  
    104104== Changelog ==
    105105
     106= 2.3.0 =
     107* Improved: Added spinner and loading message during site search.
     108* Fixed: Favicon not showing correctly during site search.
     109* Fixed: Error occurring when entering the site's Home URL.
     110* Improvement: Enhanced visibility of the loading indicator in the editor.
     111
    106112= 2.2.1 =
    107113* Bug fixes and minor adjustments.
  • blogcard-for-wp/trunk/blogcard-for-wp.php

    r3474088 r3475253  
    55 * Plugin URI: https://wordpress.org/plugins/blogcard-for-wp/
    66 * Description: URLを入力してブログカードを生成するブロックプラグイン
    7  * Version: 2.2.1
     7 * Version: 2.3.0
    88 * Author: Takashi Fujisaki
    99 * License: GPL v2 or later
     
    6666        'external_target' => isset( $options['external_target'] ) ? $options['external_target'] : '_blank',
    6767        'internal_target' => isset( $options['internal_target'] ) ? $options['internal_target'] : '_self',
     68        'home_url'        => home_url(),
     69        'site_favicon'    => wpbc_get_site_favicon(),
     70        'site_og_image'   => wpbc_get_site_og_image(),
    6871    );
    6972
     
    481484    $sorted_posts = array_merge( $posts_sorted, $pages_sorted );
    482485
     486    // サイト共通のFaviconを取得(キャッシュ対応)
     487    $favicon_url = wpbc_get_site_favicon();
     488
    483489    foreach ( $sorted_posts as $post ) {
     490        $thumbnail_id = get_post_thumbnail_id( $post->ID );
     491        $medium_src   = wp_get_attachment_image_src( $thumbnail_id, 'medium' );
     492        // is_intermediate ( $medium_src[3] ) が false の場合、指定サイズが存在せずオリジナルが返されている
     493        $thumbnail_url = ( $medium_src && $medium_src[3] ) ? $medium_src[0] : get_the_post_thumbnail_url( $post->ID, 'thumbnail' );
     494
    484495        $results[] = array(
    485             'id'          => $post->ID,
    486             'title'       => get_the_title( $post->ID ),
    487             'url'         => get_permalink( $post->ID ),
    488             'type'        => get_post_type( $post->ID ),
    489             'date'        => get_the_date( 'Y-m-d', $post->ID ),
    490             'thumbnail'   => get_the_post_thumbnail_url( $post->ID, 'large' ),
    491             'description' => get_the_excerpt( $post->ID ),
     496            'id'              => $post->ID,
     497            'title'           => get_the_title( $post->ID ),
     498            'url'             => get_permalink( $post->ID ),
     499            'type'            => get_post_type( $post->ID ),
     500            'date'            => get_the_date( 'Y-m-d', $post->ID ),
     501            'thumbnail'       => $thumbnail_url,
     502            'thumbnail_large' => get_the_post_thumbnail_url( $post->ID, 'large' ),
     503            'description'     => get_the_excerpt( $post->ID ),
     504            'favicon'         => $favicon_url,
    492505        );
    493506    }
     
    503516 */
    504517function wpbc_fetch_internal_metadata( $url ) {
     518    // URLの正規化(末尾のスラッシュを削除して比較)
     519    $normalized_url = rtrim( $url, '/' );
     520    $home_url       = rtrim( home_url(), '/' );
     521    $site_url       = rtrim( site_url(), '/' );
     522
     523    // ホームURLかどうかの判定
     524    if ( $normalized_url === $home_url || $normalized_url === $site_url ) {
     525        $title         = get_bloginfo( 'name' );
     526        $description   = get_bloginfo( 'description' );
     527        $thumbnail_url = '';
     528
     529        // フロントページが固定ページに設定されているか確認
     530        $front_page_id = get_option( 'page_on_front' );
     531        if ( $front_page_id ) {
     532            // 固定ページのメタデータを優先
     533            $front_page_title = get_the_title( $front_page_id );
     534            if ( $front_page_title ) {
     535                $title = $front_page_title;
     536            }
     537
     538            $front_page_excerpt = get_the_excerpt( $front_page_id );
     539            if ( $front_page_excerpt ) {
     540                $description = $front_page_excerpt;
     541            }
     542
     543            $thumbnail_url = get_the_post_thumbnail_url( $front_page_id, 'large' );
     544        }
     545
     546        // Faviconの取得処理
     547        $favicon_url = wpbc_get_site_favicon();
     548
     549        return array(
     550            'title'       => $title,
     551            'description' => $description,
     552            'thumbnail'   => $thumbnail_url,
     553            'favicon'     => $favicon_url,
     554            'url'         => $url,
     555            'cached'      => false,
     556        );
     557    }
     558
    505559    // URLから投稿IDを取得
    506560    $post_id = url_to_postid( $url );
     
    516570    $excerpt = get_the_excerpt( $post_id );
    517571
    518     // サムネイル画像を取得(thumbnailサイズ)
    519     $thumbnail_id  = get_post_thumbnail_id( $post_id );
    520     $thumbnail_url = '';
    521     if ( $thumbnail_id ) {
    522         $thumbnail_url = wp_get_attachment_image_url( $thumbnail_id, 'thumbnail' );
    523     }
     572    // サムネイル画像を取得(largeサイズ)
     573    $thumbnail_url = get_the_post_thumbnail_url( $post_id, 'large' );
     574
     575    // Faviconの取得処理
     576    $favicon_url = wpbc_get_site_favicon();
    524577
    525578    return array(
     
    527580        'description' => $excerpt,
    528581        'thumbnail'   => $thumbnail_url,
     582        'favicon'     => $favicon_url,
    529583        'url'         => $url,
    530584        'cached'      => false,
     
    547601        );
    548602        $cleared_count = $result;
     603
     604        // サイト内 Favicon / OG Image キャッシュも明示的に削除
     605        delete_transient( 'wpbc_site_favicon' );
     606        delete_transient( 'wpbc_site_og_image' );
    549607
    550608        // オブジェクトキャッシュもクリア
     
    647705 */
    648706function wpbc_check_favicon_exists( $url ) {
    649     $headers = get_headers( $url, 1 );
     707    // ローカル環境などにおいて `get_headers()` が失敗するケース(DNS解決やSSL周り)に対応するため、
     708    // まずは WordPress 標準の HTTP API (cURLベース) を用いて存在確認を試みる
     709    $response = wp_remote_head(
     710        $url,
     711        array(
     712            'timeout'     => 5,
     713            'redirection' => 5,
     714            'sslverify'   => false,
     715        )
     716    );
     717
     718    if ( ! is_wp_error( $response ) ) {
     719        $status_code = wp_remote_retrieve_response_code( $response );
     720        if ( 200 === $status_code ) {
     721            return true;
     722        }
     723    }
     724
     725    // wp_remote_head が想定外のヘッダーを返したり失敗した場合は、従来の get_headers にフォールバックする
     726    $headers = @get_headers( $url, 1 );
     727
     728    // ========= デバッグここから =========
     729    if ( strpos( $url, 'favicon.svg' ) !== false || strpos( $url, 'lovemacjp-2026-haku-child' ) !== false ) {
     730        error_log( 'wpbc_check_favicon_exists (' . $url . ') -> wp_remote_head status: ' . ( isset( $status_code ) ? $status_code : 'error' ) );
     731        error_log( 'wpbc_check_favicon_exists (' . $url . ') -> get_headers: ' . print_r( $headers, true ) );
     732    }
     733    // ========= デバッグここまで =========
     734
    650735    return $headers && false !== strpos( $headers[0], '200 OK' );
    651736}
     737
     738/**
     739 * サイト共通のFaviconを取得し、長期間キャッシュする
     740 */
     741function wpbc_get_site_favicon() {
     742    $cache_key   = 'wpbc_site_favicon';
     743    $favicon_url = get_transient( $cache_key );
     744
     745    if ( false !== $favicon_url ) {
     746        return $favicon_url;
     747    }
     748
     749    $home_url    = home_url();
     750    $favicon_url = '';
     751
     752    // Home URL からメタタグをパースして取得を試みる
     753    $body = _wpbc_fetch_home_page_html();
     754
     755    if ( ! empty( $body ) ) {
     756        $dom                   = new DOMDocument();
     757        $libxml_previous_state = libxml_use_internal_errors( true );
     758        $dom->loadHTML( mb_convert_encoding( $body, 'HTML-ENTITIES', 'UTF-8' ) );
     759        libxml_clear_errors();
     760        libxml_use_internal_errors( $libxml_previous_state );
     761        $xpath = new DOMXPath( $dom );
     762
     763        $parsed_favicon = wpbc_get_favicon_url( $xpath, $home_url );
     764        if ( $parsed_favicon ) {
     765            $favicon_url = $parsed_favicon;
     766        }
     767    }
     768
     769    // パースで取得できなかった場合は get_site_icon_url() を試す
     770    if ( empty( $favicon_url ) ) {
     771        $favicon_url = get_site_icon_url();
     772    }
     773
     774    // 1年間保存
     775    set_transient( $cache_key, $favicon_url, YEAR_IN_SECONDS );
     776
     777    return $favicon_url;
     778}
     779
     780/**
     781 * サイト共通の OG Image を取得し、長期間キャッシュする
     782 */
     783function wpbc_get_site_og_image() {
     784    $cache_key    = 'wpbc_site_og_image';
     785    $og_image_url = get_transient( $cache_key );
     786
     787    if ( false !== $og_image_url ) {
     788        return $og_image_url;
     789    }
     790
     791    $og_image_url = '';
     792
     793    $body = _wpbc_fetch_home_page_html();
     794
     795    if ( ! empty( $body ) ) {
     796        $dom                   = new DOMDocument();
     797        $libxml_previous_state = libxml_use_internal_errors( true );
     798        $dom->loadHTML( mb_convert_encoding( $body, 'HTML-ENTITIES', 'UTF-8' ) );
     799        libxml_clear_errors();
     800        libxml_use_internal_errors( $libxml_previous_state );
     801        $xpath = new DOMXPath( $dom );
     802
     803        $og_image = $xpath->query( '//meta[@property="og:image"]/@content' );
     804        if ( $og_image->length > 0 ) {
     805            $og_image_url = trim( $og_image->item( 0 )->textContent );
     806        }
     807    }
     808
     809    // 1年間保存
     810    set_transient( $cache_key, $og_image_url, YEAR_IN_SECONDS );
     811
     812    return $og_image_url;
     813}
     814
     815/**
     816 * サイトの Home Page の HTML を取得し、同一リクエスト内でキャッシュする
     817 */
     818function _wpbc_fetch_home_page_html() {
     819    static $html_content = null;
     820
     821    if ( null !== $html_content ) {
     822        return $html_content;
     823    }
     824
     825    $home_url = home_url();
     826    $response = wp_remote_get(
     827        $home_url,
     828        array(
     829            'timeout'     => 10,
     830            'redirection' => 5,
     831            'sslverify'   => false,
     832            'user-agent'  => 'Mozilla/5.0 (WordPress/Blogcard-For-WP)',
     833        )
     834    );
     835
     836    if ( ! is_wp_error( $response ) && 200 === wp_remote_retrieve_response_code( $response ) ) {
     837        $html_content = wp_remote_retrieve_body( $response );
     838    } else {
     839        $html_content = ''; // エラー時は空文字をキャッシュして再試行を防ぐ
     840    }
     841
     842    return $html_content;
     843}
  • blogcard-for-wp/trunk/build/block.json

    r3474088 r3475253  
    33  "apiVersion": 3,
    44  "name": "su/blogcard",
    5   "version": "2.2.1",
     5  "version": "2.3.0",
    66  "title": "ブログカード",
    77  "category": "su-blocks",
  • blogcard-for-wp/trunk/build/index.asset.php

    r3460397 r3475253  
    1 <?php return array('dependencies' => array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n'), 'version' => '5dd1ee7d806b20c47405');
     1<?php return array('dependencies' => array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n'), 'version' => '0dec3f352373e006806d');
  • blogcard-for-wp/trunk/build/index.js

    r3460397 r3475253  
    1 (()=>{"use strict";var e,t={486:(e,t,l)=>{const a=window.wp.blocks,n=window.React,r=window.wp.blockEditor,c=window.wp.element,o=window.wp.i18n,s=window.wp.apiFetch;var i=l.n(s);const p=window.wp.components;function m(e){return!(!e||e.length<10)&&URL.canParse(e)}function u(e){if(!e)return!1;try{const t=new URL(e),l=new URL(window.location.href).hostname,a=t.hostname;return l===a||!(!l.endsWith("."+a)&&!a.endsWith("."+l))}catch{return!1}}function d({results:e,isLoading:t,onSelect:l,onClose:a,error:r}){return(0,n.createElement)("div",{className:"wpbc-search-results"},(0,n.createElement)("div",{className:"wpbc-search-results-header"},(0,n.createElement)("span",null,(0,o.__)("検索結果","wpbc")),(0,n.createElement)("button",{type:"button",className:"wpbc-search-close",onClick:a},"×")),t?(0,n.createElement)("div",{className:"wpbc-search-loading"},(0,n.createElement)(p.Spinner,null),(0,o.__)("検索中...","wpbc")):r?(0,n.createElement)("div",{className:"wpbc-search-error",style:{color:"#cc0000",padding:"10px",textAlign:"center"}},r):e&&e.length>0?(0,n.createElement)("ul",{className:"wpbc-search-results-list"},e.map(e=>(0,n.createElement)("li",{key:e.id,className:"wpbc-search-result-item",onClick:()=>l(e)},e.thumbnail&&(0,n.createElement)("div",{className:"wpbc-search-result-thumbnail"},(0,n.createElement)("img",{src:e.thumbnail,alt:e.title,width:"60",height:"60"})),(0,n.createElement)("div",{className:"wpbc-search-result-content"},(0,n.createElement)("div",{className:"wpbc-search-result-title"},e.title),(0,n.createElement)("div",{className:"wpbc-search-result-meta"},(0,n.createElement)("span",{className:"wpbc-search-result-type"},"post"===e.type?(0,o.__)("投稿","wpbc"):(0,o.__)("固定ページ","wpbc")),(0,n.createElement)("span",{className:"wpbc-search-result-date"},e.date)),e.excerpt&&(0,n.createElement)("div",{className:"wpbc-search-result-excerpt"},e.excerpt))))):(0,n.createElement)("div",{className:"wpbc-search-no-results"},(0,o.__)("検索結果が見つかりませんでした","wpbc")))}function b({value:e,onChange:t,onKeyDown:l,onSelectResult:a,placeholder:r=(0,o.__)("https://example.com or キーワード","wpbc"),label:s=(0,o.__)("URLまたはサイト内検索","wpbc"),showSearch:u=!1,disabled:b=!1}){const h=m(e),[w,_]=(0,c.useState)([]),[g,E]=(0,c.useState)(!1),[f,v]=(0,c.useState)(!1),[y,x]=(0,c.useState)(""),C=(0,c.useRef)(null),k=(0,c.useCallback)(async e=>{if(!e||e.length<2)return _([]),v(!1),void x("");C.current&&C.current.abort(),C.current=new AbortController,E(!0),x("");try{const t=await i()({path:`/wpbc/v1/search?q=${encodeURIComponent(e)}`,method:"GET",signal:C.current.signal});t&&t.success?(_(t.data||[]),v(!0),x("")):(_([]),v(!1),x((0,o.__)("検索に失敗しました。","wpbc")))}catch(e){if("AbortError"===e.name)return;_([]),v(!1),x((0,o.__)("検索中にエラーが発生しました。","wpbc"))}finally{E(!1)}},[]);return(0,c.useEffect)(()=>{if(u&&!b){if(!e||""===e.trim())return _([]),v(!1),void x("");if(!h){const t=setTimeout(()=>{k(e)},300);return()=>{clearTimeout(t),C.current&&C.current.abort()}}_([]),v(!1),x("")}},[e,u,b,h,k]),(0,c.useEffect)(()=>{h&&(_([]),v(!1),E(!1),x(""))},[h]),(0,c.useEffect)(()=>()=>{C.current&&C.current.abort()},[]),(0,n.createElement)("div",{className:"wpbc-search-input"},(0,n.createElement)(p.TextControl,{label:s,value:e,onChange:t,onKeyDown:t=>{"Enter"===t.key&&(t.preventDefault(),m(e)&&l&&l(t))},placeholder:r,disabled:b,__next40pxDefaultSize:!0,__nextHasNoMarginBottom:!0}),u&&!b&&e&&""!==e.trim()&&!m(e)&&(f||y)&&(0,n.createElement)(d,{results:w,isLoading:g,onSelect:e=>{t(e.url),a&&a(e),v(!1),_([])},onClose:()=>{v(!1),_([])},error:y}))}function h({attributes:e}){const{url:t,title:l,description:a,thumbnailUrl:r,thumbnailId:c,showThumbnail:o,favicon:s,target:i="_blank",noopener:p=!0,nofollow:m=!1,noreferrer:u=!1,sponsored:d=!1,ugc:b=!1,isSelected:h=!1,isManual:w=!1}=e,_=[];p&&_.push("noopener"),u&&_.push("noreferrer"),m&&_.push("nofollow"),d&&_.push("sponsored"),b&&_.push("ugc");const g=_.length>0?_.join(" "):"",E=r,f=o&&E,v=w&&h&&!l,y=w&&h&&!a;return(0,n.createElement)("article",{className:"wp-blogcard",cite:t},(0,n.createElement)("a",{href:t,target:i||void 0,rel:g||void 0,className:"wp-blogcard-item"},f&&(0,n.createElement)("figure",{className:"wp-blogcard-figure"},(0,n.createElement)("img",{src:E,alt:"","aria-hidden":"true"})),(0,n.createElement)("div",{className:"wp-blogcard-content"},(0,n.createElement)("div",{className:"wp-blogcard-title"},l||(v?(0,n.createElement)("span",{className:"wp-blogcard-placeholder"},"Title Placeholder"):"")),(0,n.createElement)("div",{className:"wp-blogcard-description"},a||(y?(0,n.createElement)("span",{className:"wp-blogcard-placeholder"},"Description Placeholder"):"")),(0,n.createElement)("div",{className:"wp-blogcard-cite"},s&&(0,n.createElement)("img",{className:"wp-blogcard-favicon",src:s||"",alt:"","aria-hidden":"true"}),(0,n.createElement)("div",{className:"wp-blogcard-domain"},function(e){try{return new URL(e).hostname}catch{return""}}(t))))))}function w({url:e,cached:t,onOpenLink:l}){return(0,n.createElement)(p.Flex,{className:"blogcard-preview-footer",justify:"space-between",align:"center",style:{marginTop:"0.25rem"}},(0,n.createElement)(p.FlexItem,null,t?(0,n.createElement)("div",{className:"wpbc-cached-label"},"Cached"):null),(0,n.createElement)(p.FlexItem,null,(0,n.createElement)(p.Button,{type:"button",className:"wpbc-show-link-button",onClick:()=>l(e),disabled:!e,variant:"tertiary",size:"medium"},(0,o.__)("リンク先を確認","wpbc"))))}function _({error:e,errorCode:t}){return e?(0,n.createElement)("div",{style:{color:"#cc0000",fontSize:"14px",margin:"8px 0",padding:"8px 0"}},e,t&&(0,n.createElement)("span",{style:{marginLeft:"8px",color:"#666",fontSize:"12px"}},"(",t,")")):null}function g({message:e=(0,o.__)("メタデータを取得中...","wpbc")}){return(0,n.createElement)("div",{style:{textAlign:"center",padding:"1.25rem"}},(0,n.createElement)(p.Spinner,null),(0,n.createElement)("p",{style:{fontSize:"0.875rem"}},e))}function E({attributes:e,setAttributes:t,inputUrl:l,setInputUrl:a,handleKeyDown:c}){const{target:s,noopener:i,nofollow:m,noreferrer:u,sponsored:d,ugc:b,showThumbnail:h,title:w,description:_,thumbnailUrl:g,thumbnailId:E,favicon:v}=e,y=()=>E&&g?(0,n.createElement)("div",{style:{width:"100%",aspectRatio:"16/9",overflow:"hidden",borderRadius:"4px",backgroundColor:"#f0f0f0",display:"flex",alignItems:"center",justifyContent:"center"}},(0,n.createElement)("img",{src:g,alt:"",style:{width:"100%",height:"100%",objectFit:"cover"}})):(0,n.createElement)("div",{style:{backgroundColor:"#f0f0f0",borderRadius:"4px",display:"flex",alignItems:"center",justifyContent:"center",color:"#666",fontSize:"14px"}},(0,o.__)("サムネイルを設定","wpbc"));return(0,n.createElement)(r.InspectorControls,null,(0,n.createElement)(p.PanelBody,{title:(0,o.__)("ブロック設定","wpbc"),initialOpen:!0},(0,n.createElement)(p.TextControl,{label:(0,o.__)("URL","wpbc"),value:l,onChange:e=>a(e),onKeyDown:c,placeholder:(0,o.__)("https://example.com or キーワード","wpbc")}),(0,n.createElement)("hr",{style:{margin:"20px 0"}}),(0,n.createElement)("h4",null,(0,o.__)("TARGET属性","wpbc")),(0,n.createElement)(p.SelectControl,{label:(0,o.__)("TARGET属性","wpbc"),value:s,onChange:e=>{t("_blank"===e?{target:e,noopener:!0}:{target:e})},options:[{label:(0,o.__)("なし","wpbc"),value:""},{label:(0,o.__)("_blank(別タブ)","wpbc"),value:"_blank"},{label:(0,o.__)("_self (同じタブ)","wpbc"),value:"_self"}]}),(0,n.createElement)("hr",{style:{margin:"20px 0"}}),(0,n.createElement)("h4",null,(0,o.__)("Rel属性","wpbc")),(0,n.createElement)(p.ToggleControl,{label:(0,o.__)("noopener を追加","wpbc"),checked:i,disabled:"_blank"===s,onChange:e=>t({noopener:e})}),"_blank"===s&&(0,n.createElement)("p",{style:{fontSize:"12px",color:"#666",margin:"8px 0"}},(0,o.__)("_blankの場合はセキュリティ上noopenerが必須です","wpbc")),(0,n.createElement)(p.ToggleControl,{label:(0,o.__)("rel=nofollow を追加","wpbc"),checked:m,onChange:e=>t({nofollow:e})}),(0,n.createElement)(p.ToggleControl,{label:(0,o.__)("rel=noreferrer を追加","wpbc"),checked:u,onChange:e=>t({noreferrer:e})}),(0,n.createElement)(p.ToggleControl,{label:(0,o.__)("rel=sponsored を追加","wpbc"),checked:d,onChange:e=>t({sponsored:e})}),(0,n.createElement)(p.ToggleControl,{label:(0,o.__)("rel=ugc を追加","wpbc"),checked:b,onChange:e=>t({ugc:e})}),(0,n.createElement)("hr",{style:{margin:"20px 0"}}),(0,n.createElement)("h4",null,(0,o.__)("サムネイル","wpbc")),(0,n.createElement)(p.ToggleControl,{label:(0,o.__)("サムネイルを表示しない","wpbc"),checked:!h,onChange:e=>t({showThumbnail:!e})}),(0,n.createElement)("hr",{style:{margin:"20px 0"}}),(0,n.createElement)("h4",null,(0,o.__)("タイトルを手動で入力","wpbc")),(0,n.createElement)(p.TextControl,{label:(0,o.__)("タイトル","wpbc"),value:w,onChange:e=>t({title:e}),placeholder:(0,o.__)("タイトルを入力","wpbc")}),(0,n.createElement)("hr",{style:{margin:"20px 0"}}),(0,n.createElement)("h4",null,(0,o.__)("説明文を手動で入力","wpbc")),(0,n.createElement)(p.TextControl,{label:(0,o.__)("説明文","wpbc"),value:_,onChange:e=>t({description:e}),placeholder:(0,o.__)("説明文を入力","wpbc")}),(0,n.createElement)("hr",{style:{margin:"20px 0"}}),(0,n.createElement)("h4",null,(0,o.__)("Faviconを手動で入力","wpbc")),(0,n.createElement)(p.TextControl,{label:(0,o.__)("Favicon URL","wpbc"),value:v,onChange:e=>t({favicon:e}),placeholder:(0,o.__)("https://example.com/favicon.ico","wpbc")}),(0,n.createElement)("hr",{style:{margin:"20px 0"}}),(0,n.createElement)(p.BaseControl,{label:(0,o.__)("サムネイルを手動で設定","wpbc")},(0,n.createElement)(r.MediaUploadCheck,null,(0,n.createElement)(r.MediaUpload,{onSelect:e=>{t({thumbnailId:e.id,thumbnailUrl:e.url,showThumbnail:!0})},allowedTypes:["image"],value:E,render:({open:e})=>(0,n.createElement)(p.Button,{onClick:e,className:"editor-post-featured-image__toggle"},(0,n.createElement)(y,null))})),(0,n.createElement)(p.Button,{style:{marginTop:"0.5rem"},className:"is-tertiary",onClick:()=>{t({thumbnailId:0,thumbnailUrl:"",showThumbnail:!1})}},(0,o.__)("クリア","wpbc"))),(0,n.createElement)("hr",{style:{margin:"20px 0"}}),(0,n.createElement)("h4",null,(0,o.__)("キャッシュ管理","wpbc")),(0,n.createElement)("div",{style:{display:"flex",gap:"10px",flexWrap:"wrap"}},(0,n.createElement)(p.Button,{secondary:!0,onClick:f("plugin"),style:{fontSize:"12px"}},(0,o.__)("このブログカードのキャッシュをクリア","wpbc")),(0,n.createElement)(p.Button,{isDestructive:!0,onClick:()=>{f("all")()}},(0,o.__)("すべてのブログカードのキャッシュをクリア","wpbc")))))}function f(e="plugin"){return async()=>{try{const t=await i()({path:"/wpbc/v1/clear-cache",method:"POST",data:{type:e}});t.success?alert(t.message):alert((0,o.__)("キャッシュのクリアに失敗しました。","wpbc"))}catch(e){console.error("Cache clear error:",e),alert((0,o.__)("キャッシュのクリア中にエラーが発生しました。","wpbc"))}}}const v=()=>window.wpbcSettings||{external_target:"_blank",internal_target:"_self"};(0,a.registerBlockType)("su/blogcard",{edit:function({attributes:e,setAttributes:t}){const{url:l,title:a,description:s,thumbnailUrl:d,showThumbnail:f,favicon:y,isManual:x}=e,[C,k]=(0,c.useState)(l||""),[N,T]=(0,c.useState)(!1),[S,R]=(0,c.useState)(""),[U,O]=(0,c.useState)(""),[I,B]=(0,c.useState)(!1),F=(0,r.useBlockProps)(),L=F.className?.includes("is-selected")||!1,D=async()=>{if(!C||C.trim().length<10||!m(C))return R(""),void O("");T(!0),R(""),O("");try{const e=u(C)?`/wpbc/v1/internal-metadata?url=${encodeURIComponent(C)}`:"/wpbc/v1/metadata",l=await i()({path:e,method:u(C)?"GET":"POST",data:u(C)?void 0:{url:C}});if(l.success){const e=l.data,a=v(),n=u(C)?a.internal_target:a.external_target;t({url:C,title:e.title||C,description:e.description||"",thumbnailUrl:e.thumbnail||"",showThumbnail:!!e.thumbnail,favicon:e.favicon||"",target:n,isManual:!1}),B(!0===e.cached),R(""),O("")}else{const e=l.message||l.data?.message||(0,o.__)("メタデータの取得に失敗しました。","wpbc"),t=l.code||l.data?.code||"UNKNOWN_ERROR";R(e),O(t)}}catch(e){const t=e.status||e.code||"NETWORK_ERROR";let l=e.message||(0,o.__)("メタデータの取得中にエラーが発生しました。","wpbc");e.data&&e.data.message&&(l=e.data.message),R(l),O(t)}finally{T(!1)}},j=e=>{if("Enter"===e.key){if(e.preventDefault(),l)return;m(C)&&D()}};return(0,n.createElement)("div",{...F},(0,n.createElement)(E,{attributes:e,setAttributes:t,inputUrl:C,setInputUrl:k,handleKeyDown:j}),l?(0,n.createElement)(n.Fragment,null,N&&(0,n.createElement)(g,null),L&&(0,n.createElement)("div",{className:"wpbc-input-wrapper"},(0,n.createElement)(b,{key:"locked-search-input",value:C,onChange:k,showSearch:!1,disabled:!0,label:"",placeholder:(0,o.__)("https://example.com","wpbc"),help:(0,o.__)("URLを変更するにはブロックを削除して再作成してください","wpbc")})),(0,n.createElement)(_,{error:S,errorCode:U}),!N&&!S&&(0,n.createElement)("div",{className:"blogcard-preview"},(0,n.createElement)(h,{attributes:{url:l,title:a,description:s,thumbnailUrl:d,showThumbnail:f,favicon:y,isManual:x,isSelected:L}}),L&&(0,n.createElement)(w,{url:l,cached:I,onOpenLink:e=>{window.open(e,"_blank")}}))):(0,n.createElement)(n.Fragment,null,(0,n.createElement)(n.Fragment,null,(0,n.createElement)(b,{key:"placeholder-search-input",value:C,onChange:k,onKeyDown:j,onSelectResult:e=>{k(e.url),R(""),O(""),B(!1);const l=v(),a=u(e.url)?l.internal_target:l.external_target;t({url:e.url,title:e.title||e.url,description:e.description||e.excerpt||"",thumbnailUrl:e.thumbnail||"",showThumbnail:!!e.thumbnail,favicon:e.favicon||"",target:a,isManual:!1})},showSearch:!0,disabled:!1,placeholder:(0,o.__)("https://example.com or 検索キーワード","wpbc")}),C&&m(C)&&(0,n.createElement)(p.Flex,{gap:2,className:"wpbc-search-buttons",justify:"flex-end"},(0,n.createElement)(p.FlexItem,null,(0,n.createElement)(p.Button,{variant:"tertiary",onClick:()=>{C&&t({url:C,title:"",description:"",thumbnailUrl:"",showThumbnail:!1,favicon:"",isManual:!0})},disabled:N},(0,o.__)("手動で作成","wpbc"))),(0,n.createElement)(p.FlexItem,null,(0,n.createElement)(p.Button,{variant:"primary",onClick:D,isBusy:N,disabled:N},(0,o.__)("検索して作成","wpbc")," ",(0,n.createElement)("span",null,"Enter"))))),N&&(0,n.createElement)(g,null),(0,n.createElement)(_,{error:S,errorCode:U})))},save:function(){return null}})}},l={};function a(e){var n=l[e];if(void 0!==n)return n.exports;var r=l[e]={exports:{}};return t[e](r,r.exports,a),r.exports}a.m=t,e=[],a.O=(t,l,n,r)=>{if(!l){var c=1/0;for(p=0;p<e.length;p++){for(var[l,n,r]=e[p],o=!0,s=0;s<l.length;s++)(!1&r||c>=r)&&Object.keys(a.O).every(e=>a.O[e](l[s]))?l.splice(s--,1):(o=!1,r<c&&(c=r));if(o){e.splice(p--,1);var i=n();void 0!==i&&(t=i)}}return t}r=r||0;for(var p=e.length;p>0&&e[p-1][2]>r;p--)e[p]=e[p-1];e[p]=[l,n,r]},a.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return a.d(t,{a:t}),t},a.d=(e,t)=>{for(var l in t)a.o(t,l)&&!a.o(e,l)&&Object.defineProperty(e,l,{enumerable:!0,get:t[l]})},a.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{var e={57:0,350:0};a.O.j=t=>0===e[t];var t=(t,l)=>{var n,r,[c,o,s]=l,i=0;if(c.some(t=>0!==e[t])){for(n in o)a.o(o,n)&&(a.m[n]=o[n]);if(s)var p=s(a)}for(t&&t(l);i<c.length;i++)r=c[i],a.o(e,r)&&e[r]&&e[r][0](),e[r]=0;return a.O(p)},l=globalThis.webpackChunkblogcard_for_wp=globalThis.webpackChunkblogcard_for_wp||[];l.forEach(t.bind(null,0)),l.push=t.bind(null,l.push.bind(l))})();var n=a.O(void 0,[350],()=>a(486));n=a.O(n)})();
     1(()=>{"use strict";var e,t={486:(e,t,n)=>{const l=window.wp.blocks,a=window.React,r=window.wp.blockEditor,c=window.wp.element,o=window.wp.i18n,i=window.wp.apiFetch;var s=n.n(i);const p=window.wp.components;function u(e){return!(!e||e.length<10)&&URL.canParse(e)}function m(e){if(!e)return!1;try{const t=new URL(e),n=new URL(window.location.href).hostname,l=t.hostname;return n===l||!(!n.endsWith("."+l)&&!l.endsWith("."+n))}catch{return!1}}function d(e){if(!e)return!1;try{const t=new URL(e);let n="undefined"!=typeof window&&window.wpbcSettings?.home_url;n||(n=window.location.origin);const l=new URL(n);return t.href.replace(/\/$/,"")===l.href.replace(/\/$/,"")}catch{return!1}}function b({results:e,isLoading:t,onSelect:n,onClose:l,error:r}){return(0,a.createElement)("div",{className:"wpbc-search-results"},(0,a.createElement)("div",{className:"wpbc-search-results-header"},(0,a.createElement)("span",null,(0,o.__)("検索結果","wpbc")),(0,a.createElement)("button",{type:"button",className:"wpbc-search-close",onClick:l},"×")),t?(0,a.createElement)("div",{className:"wpbc-search-loading",style:{textAlign:"center",padding:"1.25rem"}},(0,a.createElement)(p.Spinner,null),(0,a.createElement)("p",{style:{fontSize:"0.875rem",margin:"10px 0 0"}},(0,o.__)("検索中...","wpbc"))):r?(0,a.createElement)("div",{className:"wpbc-search-error",style:{color:"#cc0000",padding:"10px",textAlign:"center"}},r):e&&e.length>0?(0,a.createElement)("ul",{className:"wpbc-search-results-list"},e.map(e=>(0,a.createElement)("li",{key:e.id,className:"wpbc-search-result-item",onClick:()=>n(e)},e.thumbnail&&(0,a.createElement)("div",{className:"wpbc-search-result-thumbnail"},(0,a.createElement)("img",{src:e.thumbnail,alt:e.title,width:"60",height:"60"})),(0,a.createElement)("div",{className:"wpbc-search-result-content"},(0,a.createElement)("div",{className:"wpbc-search-result-title"},e.title),(0,a.createElement)("div",{className:"wpbc-search-result-meta"},(0,a.createElement)("span",{className:"wpbc-search-result-type"},"post"===e.type?(0,o.__)("投稿","wpbc"):(0,o.__)("固定ページ","wpbc")),(0,a.createElement)("span",{className:"wpbc-search-result-date"},e.date)),e.excerpt&&(0,a.createElement)("div",{className:"wpbc-search-result-excerpt"},e.excerpt))))):(0,a.createElement)("div",{className:"wpbc-search-no-results"},(0,o.__)("検索結果が見つかりませんでした","wpbc")))}function h({value:e,onChange:t,onKeyDown:n,onSelectResult:l,placeholder:r=(0,o.__)("https://example.com or キーワード","wpbc"),label:i=(0,o.__)("URLまたはサイト内検索","wpbc"),showSearch:m=!1,disabled:d=!1}){const h=u(e),[w,g]=(0,c.useState)([]),[_,E]=(0,c.useState)(!1),[f,v]=(0,c.useState)(!1),[y,x]=(0,c.useState)(""),C=(0,c.useRef)(null),k=(0,c.useCallback)(async e=>{if(!e||e.length<2)return g([]),v(!1),void x("");C.current&&C.current.abort(),C.current=new AbortController,E(!0),x("");try{const t=await s()({path:`/wpbc/v1/search?q=${encodeURIComponent(e)}`,method:"GET",signal:C.current.signal});t&&t.success?(g(t.data||[]),v(!0),x("")):(g([]),v(!1),x((0,o.__)("検索に失敗しました。","wpbc")))}catch(e){if("AbortError"===e.name)return;g([]),v(!1),x((0,o.__)("検索中にエラーが発生しました。","wpbc"))}finally{E(!1)}},[]);return(0,c.useEffect)(()=>{if(m&&!d){if(!e||""===e.trim())return g([]),v(!1),void x("");if(!h){const t=setTimeout(()=>{k(e)},300);return()=>{clearTimeout(t),C.current&&C.current.abort()}}g([]),v(!1),x("")}},[e,m,d,h,k]),(0,c.useEffect)(()=>{h&&(g([]),v(!1),E(!1),x(""))},[h]),(0,c.useEffect)(()=>()=>{C.current&&C.current.abort()},[]),(0,a.createElement)("div",{className:"wpbc-search-input"},(0,a.createElement)(p.TextControl,{label:i,value:e,onChange:t,onKeyDown:t=>{"Enter"===t.key&&(t.preventDefault(),u(e)&&n&&n(t))},placeholder:r,disabled:d,__next40pxDefaultSize:!0,__nextHasNoMarginBottom:!0}),m&&!d&&e&&""!==e.trim()&&!u(e)&&(_||f||y)&&(0,a.createElement)(b,{results:w,isLoading:_,onSelect:e=>{t(e.url),l&&l(e),v(!1),g([])},onClose:()=>{v(!1),g([])},error:y}))}function w({attributes:e}){const{url:t,title:n,description:l,thumbnailUrl:r,thumbnailId:c,showThumbnail:o,favicon:i,target:s="_blank",noopener:p=!0,nofollow:u=!1,noreferrer:b=!1,sponsored:h=!1,ugc:w=!1,isSelected:g=!1,isManual:_=!1}=e,E=[];p&&E.push("noopener"),b&&E.push("noreferrer"),u&&E.push("nofollow"),h&&E.push("sponsored"),w&&E.push("ugc");const f=E.length>0?E.join(" "):"",v=!r&&d(t)&&"undefined"!=typeof window&&window.wpbcSettings?.site_og_image?window.wpbcSettings.site_og_image:r,y=o&&v,x=_&&g&&!n,C=_&&g&&!l;return(0,a.createElement)("article",{className:"wp-blogcard",cite:t},(0,a.createElement)("a",{href:t,target:s||void 0,rel:f||void 0,className:"wp-blogcard-item"},y&&(0,a.createElement)("figure",{className:"wp-blogcard-figure"},(0,a.createElement)("img",{src:v,alt:"","aria-hidden":"true"})),(0,a.createElement)("div",{className:"wp-blogcard-content"},(0,a.createElement)("div",{className:"wp-blogcard-title"},n||(x?(0,a.createElement)("span",{className:"wp-blogcard-placeholder"},"Title Placeholder"):"")),(0,a.createElement)("div",{className:"wp-blogcard-description"},l||(C?(0,a.createElement)("span",{className:"wp-blogcard-placeholder"},"Description Placeholder"):"")),(0,a.createElement)("div",{className:"wp-blogcard-cite"},(i||"undefined"!=typeof window&&window.wpbcSettings?.site_favicon&&m(t))&&(0,a.createElement)("img",{className:"wp-blogcard-favicon",src:i||("undefined"!=typeof window?window.wpbcSettings?.site_favicon:""),alt:"","aria-hidden":"true"}),(0,a.createElement)("div",{className:"wp-blogcard-domain"},function(e){try{return new URL(e).hostname}catch{return""}}(t))))))}function g({url:e,cached:t,onOpenLink:n}){return(0,a.createElement)(p.Flex,{className:"blogcard-preview-footer",justify:"space-between",align:"center",style:{marginTop:"0.25rem"}},(0,a.createElement)(p.FlexItem,null,t?(0,a.createElement)("div",{className:"wpbc-cached-label"},"Cached"):null),(0,a.createElement)(p.FlexItem,null,(0,a.createElement)(p.Button,{type:"button",className:"wpbc-show-link-button",onClick:()=>n(e),disabled:!e,variant:"tertiary",size:"medium"},(0,o.__)("リンク先を確認","wpbc"))))}function _({error:e,errorCode:t}){return e?(0,a.createElement)("div",{style:{color:"#cc0000",fontSize:"14px",margin:"8px 0",padding:"8px 0"}},e,t&&(0,a.createElement)("span",{style:{marginLeft:"8px",color:"#666",fontSize:"12px"}},"(",t,")")):null}function E({message:e=(0,o.__)("メタデータを取得中...","wpbc")}){return(0,a.createElement)("div",{style:{textAlign:"center",padding:"1.25rem"}},(0,a.createElement)(p.Spinner,null),(0,a.createElement)("p",{style:{fontSize:"0.875rem"}},e))}function f({attributes:e,setAttributes:t,inputUrl:n,setInputUrl:l,handleKeyDown:c}){const{target:i,noopener:s,nofollow:u,noreferrer:m,sponsored:d,ugc:b,showThumbnail:h,title:w,description:g,thumbnailUrl:_,thumbnailId:E,favicon:f}=e,y=()=>E&&_?(0,a.createElement)("div",{style:{width:"100%",aspectRatio:"16/9",overflow:"hidden",borderRadius:"4px",backgroundColor:"#f0f0f0",display:"flex",alignItems:"center",justifyContent:"center"}},(0,a.createElement)("img",{src:_,alt:"",style:{width:"100%",height:"100%",objectFit:"cover"}})):(0,a.createElement)("div",{style:{backgroundColor:"#f0f0f0",borderRadius:"4px",display:"flex",alignItems:"center",justifyContent:"center",color:"#666",fontSize:"14px"}},(0,o.__)("サムネイルを設定","wpbc"));return(0,a.createElement)(r.InspectorControls,null,(0,a.createElement)(p.PanelBody,{title:(0,o.__)("ブロック設定","wpbc"),initialOpen:!0},(0,a.createElement)(p.TextControl,{label:(0,o.__)("URL","wpbc"),value:n,onChange:e=>l(e),onKeyDown:c,placeholder:(0,o.__)("https://example.com or キーワード","wpbc")}),(0,a.createElement)("hr",{style:{margin:"20px 0"}}),(0,a.createElement)("h4",null,(0,o.__)("TARGET属性","wpbc")),(0,a.createElement)(p.SelectControl,{label:(0,o.__)("TARGET属性","wpbc"),value:i,onChange:e=>{t("_blank"===e?{target:e,noopener:!0}:{target:e})},options:[{label:(0,o.__)("なし","wpbc"),value:""},{label:(0,o.__)("_blank(別タブ)","wpbc"),value:"_blank"},{label:(0,o.__)("_self (同じタブ)","wpbc"),value:"_self"}]}),(0,a.createElement)("hr",{style:{margin:"20px 0"}}),(0,a.createElement)("h4",null,(0,o.__)("Rel属性","wpbc")),(0,a.createElement)(p.ToggleControl,{label:(0,o.__)("noopener を追加","wpbc"),checked:s,disabled:"_blank"===i,onChange:e=>t({noopener:e})}),"_blank"===i&&(0,a.createElement)("p",{style:{fontSize:"12px",color:"#666",margin:"8px 0"}},(0,o.__)("_blankの場合はセキュリティ上noopenerが必須です","wpbc")),(0,a.createElement)(p.ToggleControl,{label:(0,o.__)("rel=nofollow を追加","wpbc"),checked:u,onChange:e=>t({nofollow:e})}),(0,a.createElement)(p.ToggleControl,{label:(0,o.__)("rel=noreferrer を追加","wpbc"),checked:m,onChange:e=>t({noreferrer:e})}),(0,a.createElement)(p.ToggleControl,{label:(0,o.__)("rel=sponsored を追加","wpbc"),checked:d,onChange:e=>t({sponsored:e})}),(0,a.createElement)(p.ToggleControl,{label:(0,o.__)("rel=ugc を追加","wpbc"),checked:b,onChange:e=>t({ugc:e})}),(0,a.createElement)("hr",{style:{margin:"20px 0"}}),(0,a.createElement)("h4",null,(0,o.__)("サムネイル","wpbc")),(0,a.createElement)(p.ToggleControl,{label:(0,o.__)("サムネイルを表示しない","wpbc"),checked:!h,onChange:e=>t({showThumbnail:!e})}),(0,a.createElement)("hr",{style:{margin:"20px 0"}}),(0,a.createElement)("h4",null,(0,o.__)("タイトルを手動で入力","wpbc")),(0,a.createElement)(p.TextControl,{label:(0,o.__)("タイトル","wpbc"),value:w,onChange:e=>t({title:e}),placeholder:(0,o.__)("タイトルを入力","wpbc")}),(0,a.createElement)("hr",{style:{margin:"20px 0"}}),(0,a.createElement)("h4",null,(0,o.__)("説明文を手動で入力","wpbc")),(0,a.createElement)(p.TextControl,{label:(0,o.__)("説明文","wpbc"),value:g,onChange:e=>t({description:e}),placeholder:(0,o.__)("説明文を入力","wpbc")}),(0,a.createElement)("hr",{style:{margin:"20px 0"}}),(0,a.createElement)("h4",null,(0,o.__)("Faviconを手動で入力","wpbc")),(0,a.createElement)(p.TextControl,{label:(0,o.__)("Favicon URL","wpbc"),value:f,onChange:e=>t({favicon:e}),placeholder:(0,o.__)("https://example.com/favicon.ico","wpbc")}),(0,a.createElement)("hr",{style:{margin:"20px 0"}}),(0,a.createElement)(p.BaseControl,{label:(0,o.__)("サムネイルを手動で設定","wpbc")},(0,a.createElement)(r.MediaUploadCheck,null,(0,a.createElement)(r.MediaUpload,{onSelect:e=>{t({thumbnailId:e.id,thumbnailUrl:e.url,showThumbnail:!0})},allowedTypes:["image"],value:E,render:({open:e})=>(0,a.createElement)(p.Button,{onClick:e,className:"editor-post-featured-image__toggle"},(0,a.createElement)(y,null))})),(0,a.createElement)(p.Button,{style:{marginTop:"0.5rem"},className:"is-tertiary",onClick:()=>{t({thumbnailId:0,thumbnailUrl:"",showThumbnail:!1})}},(0,o.__)("クリア","wpbc"))),(0,a.createElement)("hr",{style:{margin:"20px 0"}}),(0,a.createElement)("h4",null,(0,o.__)("キャッシュ管理","wpbc")),(0,a.createElement)("div",{style:{display:"flex",gap:"10px",flexWrap:"wrap"}},(0,a.createElement)(p.Button,{secondary:!0,onClick:v("plugin"),style:{fontSize:"12px"}},(0,o.__)("このブログカードのキャッシュをクリア","wpbc")),(0,a.createElement)(p.Button,{isDestructive:!0,onClick:()=>{v("all")()}},(0,o.__)("すべてのブログカードのキャッシュをクリア","wpbc")))))}function v(e="plugin"){return async()=>{try{const t=await s()({path:"/wpbc/v1/clear-cache",method:"POST",data:{type:e}});t.success?alert(t.message):alert((0,o.__)("キャッシュのクリアに失敗しました。","wpbc"))}catch(e){console.error("Cache clear error:",e),alert((0,o.__)("キャッシュのクリア中にエラーが発生しました。","wpbc"))}}}const y=()=>window.wpbcSettings||{external_target:"_blank",internal_target:"_self"};(0,l.registerBlockType)("su/blogcard",{edit:function({attributes:e,setAttributes:t}){const{url:n,title:l,description:i,thumbnailUrl:b,showThumbnail:v,favicon:x,isManual:C}=e,[k,N]=(0,c.useState)(n||""),[T,S]=(0,c.useState)(!1),[R,U]=(0,c.useState)(""),[O,I]=(0,c.useState)(""),[L,B]=(0,c.useState)(!1),F=(0,r.useBlockProps)(),D=F.className?.includes("is-selected")||!1,j=async()=>{if(!k||k.trim().length<10||!u(k))return U(""),void I("");S(!0),U(""),I("");try{const e=m(k)?`/wpbc/v1/internal-metadata?url=${encodeURIComponent(k)}`:"/wpbc/v1/metadata",n=await s()({path:e,method:m(k)?"GET":"POST",data:m(k)?void 0:{url:k}});if(n.success){const e=n.data,l=y(),a=m(k),r=a?l.internal_target:l.external_target;t({url:k,title:e.title||k,description:e.description||"",thumbnailUrl:d(k)?"":e.thumbnail||"",showThumbnail:!!(e.thumbnail||d(k)&&y().site_og_image),favicon:a?"":e.favicon||"",target:r,isManual:!1}),B(!0===e.cached),U(""),I("")}else{const e=n.message||n.data?.message||(0,o.__)("メタデータの取得に失敗しました。","wpbc"),t=n.code||n.data?.code||"UNKNOWN_ERROR";U(e),I(t)}}catch(e){const t=e.status||e.code||"NETWORK_ERROR";let n=e.message||(0,o.__)("メタデータの取得中にエラーが発生しました。","wpbc");e.data&&e.data.message&&(n=e.data.message),U(n),I(t)}finally{S(!1)}},A=e=>{if("Enter"===e.key){if(e.preventDefault(),n)return;u(k)&&j()}};return(0,a.createElement)("div",{...F},(0,a.createElement)(f,{attributes:e,setAttributes:t,inputUrl:k,setInputUrl:N,handleKeyDown:A}),n?(0,a.createElement)(a.Fragment,null,T&&(0,a.createElement)(E,null),D&&(0,a.createElement)("div",{className:"wpbc-input-wrapper"},(0,a.createElement)(h,{key:"locked-search-input",value:k,onChange:N,showSearch:!1,disabled:!0,label:"",placeholder:(0,o.__)("https://example.com","wpbc"),help:(0,o.__)("URLを変更するにはブロックを削除して再作成してください","wpbc")})),(0,a.createElement)(_,{error:R,errorCode:O}),!T&&!R&&(0,a.createElement)("div",{className:"blogcard-preview"},(0,a.createElement)(w,{attributes:{url:n,title:l,description:i,thumbnailUrl:b,showThumbnail:v,favicon:x,isManual:C,isSelected:D}}),D&&(0,a.createElement)(g,{url:n,cached:L,onOpenLink:e=>{window.open(e,"_blank")}}))):(0,a.createElement)(a.Fragment,null,(0,a.createElement)(a.Fragment,null,(0,a.createElement)(h,{key:"placeholder-search-input",value:k,onChange:N,onKeyDown:A,onSelectResult:e=>{N(e.url),U(""),I(""),B(!1);const n=y(),l=m(e.url),a=l?n.internal_target:n.external_target;t({url:e.url,title:e.title||e.url,description:e.description||e.excerpt||"",thumbnailUrl:d(e.url)?"":e.thumbnail_large||e.thumbnail||"",showThumbnail:!!(e.thumbnail_large||e.thumbnail||d(e.url)&&n.site_og_image),favicon:l?"":e.favicon||"",target:a,isManual:!1})},showSearch:!0,disabled:!1,placeholder:(0,o.__)("https://example.com or 検索キーワード","wpbc")}),k&&u(k)&&(0,a.createElement)(p.Flex,{gap:2,className:"wpbc-search-buttons",justify:"flex-end"},(0,a.createElement)(p.FlexItem,null,(0,a.createElement)(p.Button,{variant:"tertiary",onClick:()=>{k&&t({url:k,title:"",description:"",thumbnailUrl:"",showThumbnail:!1,favicon:"",isManual:!0})},disabled:T},(0,o.__)("手動で作成","wpbc"))),(0,a.createElement)(p.FlexItem,null,(0,a.createElement)(p.Button,{variant:"primary",onClick:j,isBusy:T,disabled:T},(0,o.__)("検索して作成","wpbc")," ",(0,a.createElement)("span",null,"Enter"))))),T&&(0,a.createElement)(E,null),(0,a.createElement)(_,{error:R,errorCode:O})))},save:function(){return null}})}},n={};function l(e){var a=n[e];if(void 0!==a)return a.exports;var r=n[e]={exports:{}};return t[e](r,r.exports,l),r.exports}l.m=t,e=[],l.O=(t,n,a,r)=>{if(!n){var c=1/0;for(p=0;p<e.length;p++){for(var[n,a,r]=e[p],o=!0,i=0;i<n.length;i++)(!1&r||c>=r)&&Object.keys(l.O).every(e=>l.O[e](n[i]))?n.splice(i--,1):(o=!1,r<c&&(c=r));if(o){e.splice(p--,1);var s=a();void 0!==s&&(t=s)}}return t}r=r||0;for(var p=e.length;p>0&&e[p-1][2]>r;p--)e[p]=e[p-1];e[p]=[n,a,r]},l.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return l.d(t,{a:t}),t},l.d=(e,t)=>{for(var n in t)l.o(t,n)&&!l.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},l.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{var e={57:0,350:0};l.O.j=t=>0===e[t];var t=(t,n)=>{var a,r,[c,o,i]=n,s=0;if(c.some(t=>0!==e[t])){for(a in o)l.o(o,a)&&(l.m[a]=o[a]);if(i)var p=i(l)}for(t&&t(n);s<c.length;s++)r=c[s],l.o(e,r)&&e[r]&&e[r][0](),e[r]=0;return l.O(p)},n=globalThis.webpackChunkblogcard_for_wp=globalThis.webpackChunkblogcard_for_wp||[];n.forEach(t.bind(null,0)),n.push=t.bind(null,n.push.bind(n))})();var a=l.O(void 0,[350],()=>l(486));a=l.O(a)})();
  • blogcard-for-wp/trunk/build/render.php

    r3474088 r3475253  
    4949
    5050// サムネイル表示判定
    51 $display_thumbnail     = $thumbnail_url;
     51$display_thumbnail = $thumbnail_url;
     52
     53// 内部サイトの Home URL かつ thumbnailUrl が空の場合は、サイト共通の OG Image を取得
     54if ( empty( $display_thumbnail ) && function_exists( 'wpbc_is_internal_url' ) && wpbc_is_internal_url( $url ) ) {
     55    $normalized_url = rtrim( $url, '/' );
     56    $home_url       = rtrim( home_url(), '/' );
     57    $site_url       = rtrim( site_url(), '/' );
     58    if ( $normalized_url === $home_url || $normalized_url === $site_url ) {
     59        $display_thumbnail = wpbc_get_site_og_image();
     60    }
     61}
     62
    5263$should_show_thumbnail = $show_thumbnail && ! empty( $display_thumbnail );
    5364
     
    5970}
    6071
    61 // Faviconのフォールバック(空の場合は Google Favicon API を使用)
     72// Faviconのフォールバック
    6273if ( empty( $favicon ) && ! empty( $domain ) ) {
    63     $favicon = 'https://www.google.com/s2/favicons?domain=' . urlencode( $domain ) . '&sz=16';
     74    // 内部サイトの場合はサイト共通のファビコンを取得
     75    if ( function_exists( 'wpbc_is_internal_url' ) && wpbc_is_internal_url( $url ) ) {
     76        $favicon = wpbc_get_site_favicon();
     77    }
     78
     79    // それでも空の場合は Google Favicon API を使用(外部サイトなど)
     80    if ( empty( $favicon ) ) {
     81        $favicon = 'https://www.google.com/s2/favicons?domain=' . urlencode( $domain ) . '&sz=16';
     82    }
    6483}
    6584
  • blogcard-for-wp/trunk/readme-ja.txt

    r3474088 r3475253  
    104104== Changelog ==
    105105
     106= 2.3.0 =
     107* 改善: サイト内検索時にFaviconが表示されない問題を修正。
     108* 改善: サイトのURLを入力時にエラーが表示される問題を修正。
     109* 改善: サイト内検索時にスピナーと「検索中...」メッセージを表示するように改善。
     110* 改善: エディター上でのローディング表示の視認性を向上。
     111
    106112= 2.2.1 =
    107113* バグ修正および微調整。
  • blogcard-for-wp/trunk/readme.txt

    r3474088 r3475253  
    104104== Changelog ==
    105105
     106= 2.3.0 =
     107* Improved: Added spinner and loading message during site search.
     108* Fixed: Favicon not showing correctly during site search.
     109* Fixed: Error occurring when entering the site's Home URL.
     110* Improvement: Enhanced visibility of the loading indicator in the editor.
     111
    106112= 2.2.1 =
    107113* Bug fixes and minor adjustments.
Note: See TracChangeset for help on using the changeset viewer.