PageSourceSearch

https://wp-cocoon.com/wp-content/themes/cocoon-master/js/group-link.js?ver=1790170718&fver=20260923103838

js wp-cocoon.com collected 2026-09-24 18:27:51 UTC 3,444 bytes, 94 lines download raw bytes

1/**
2 * Cocoon WordPress Theme
3 * @author: yhira
4 * @link: https://wp-cocoon.com/
5 * @license: http://www.gnu.org/licenses/gpl-2.0.html GPL v2 or later
6 *
7 * グループブロックのリンク化機能
8 */
9( function () {
10  'use strict';
11
12  function initGroupLinks() {
13    // リンクグループの取得
14    var groups = document.querySelectorAll( '.is-cocoon-group-link' );
15
16    groups.forEach( function ( group ) {
17      var url = group.getAttribute( 'data-cocoon-group-link' );
18      var newTab =
19        group.getAttribute( 'data-cocoon-group-link-target' ) === '_blank';
20
21      if ( ! url ) {
22        return;
23      }
24
25      var navigate = function () {
26        // 多層防御: 危険なプロトコル(javascript:, vbscript:, data:)をブロック
27        var sanitized = url
28          .replace( /[\u0000-\u001F\u007F-\u009F\s]+/g, '' )
29          .toLowerCase();
30        if (
31          sanitized.indexOf( 'javascript:' ) === 0 ||
32          sanitized.indexOf( 'vbscript:' ) === 0 ||
33          sanitized.indexOf( 'data:' ) === 0
34        ) {
35          return;
36        }
37
38        if ( newTab ) {
39          window.open( url, '_blank', 'noopener,noreferrer' );
40        } else {
41          window.location.href = url;
42        }
43      };
44
45      // クリック時の遷移イベント
46      group.addEventListener( 'click', function ( e ) {
47        // ユーザーがテキスト選択中(ドラッグによる選択)の場合は遷移しない
48        var selection = window.getSelection();
49        if ( selection && selection.toString().length > 0 ) {
50          return;
51        }
52
53        // イベントの発生元が「自身より内側にある別のリンクターゲット(入れ子になったグループリンクなど)」なら除外
54        var clickedGroupLink = e.target.closest( '.is-cocoon-group-link' );
55        if ( clickedGroupLink && clickedGroupLink !== group ) {
56          return;
57        }
58
59        // 内部に配置されたリンクやインタラクティブ要素がクリックされた場合は親の遷移を発火させない
60        var interactiveSelectors =
61          'a, button, input, textarea, select, details, summary, video, audio, [role="button"]';
62        var clickedEl = e.target.closest( interactiveSelectors );
63        if ( clickedEl && group.contains( clickedEl ) && clickedEl !== group ) {
64          return;
65        }
66
67        // 修飾キー(Ctrl/Cmd/Shift)押下時は新しいタブで開く
68        // navigate() の安全判定(危険プロトコル除外)を共通利用するため、newTab を一時的に上書きする
69        if ( e.ctrlKey || e.metaKey || e.shiftKey ) {
70          e.preventDefault();
71          var wasNewTab = newTab;
72          newTab = true;
73          navigate();
74          newTab = wasNewTab;
75          return;
76        }
77
78        e.preventDefault();
79        navigate();
80      } );
81
82      // 【注意】キーボード操作(Enter/Space)のハンドラはこのファイルには含めない。
83      // PHP側(lib/block-editor-group-link.php)でインライン onkeydown 属性として出力し、
84      // this.click() を通じて上記の click リスナーに委譲する設計。詳細はPHP側のコメントを参照。
85    } );
86  }
87
88  // DOMContentLoaded後に実行
89  if ( document.readyState === 'loading' ) {
90    document.addEventListener( 'DOMContentLoaded', initGroupLinks );
91  } else {
92    initGroupLinks();
93  }
94} )();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.