[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

title

Body

[close]

/wp-includes/js/ -> wp-embed-template.js (source)

   1  /**
   2   * @output wp-includes/js/wp-embed-template.js
   3   */
   4  
   5  /**
   6   * IIFE setup function.
   7   *
   8   * @param {Window}   window   The global window object.
   9   * @param {Document} document The global document object.
  10   */
  11  (function ( window, document ) {
  12      'use strict';
  13  
  14      var supportedBrowser = ( document.querySelector && window.addEventListener ),
  15          loaded = false,
  16          secret,
  17          secretTimeout,
  18          resizing;
  19  
  20      /**
  21       * Sends a message to the parent window.
  22       *
  23       * @param {string} message The message type (e.g., 'height', 'link').
  24       * @param {*}      value   The message value. Type depends on message (number for height, string for link).
  25       */
  26  	function sendEmbedMessage( message, value ) {
  27          window.parent.postMessage( {
  28              message: message,
  29              value: value,
  30              secret: secret
  31          }, '*' );
  32      }
  33  
  34      /**
  35       * Send the height message to the parent window.
  36       */
  37  	function sendHeightMessage() {
  38          sendEmbedMessage( 'height', Math.ceil( document.body.getBoundingClientRect().height ) );
  39      }
  40  
  41      /**
  42       * Runs on DomContentLoaded and load event.
  43       *
  44       * Exits early on the load event if the earlier event has
  45       * successfully fired.
  46       */
  47  	function onLoad() {
  48          if ( loaded ) {
  49              return;
  50          }
  51          loaded = true;
  52  
  53          var share_dialog = document.querySelector( '.wp-embed-share-dialog' ),
  54              share_dialog_open = document.querySelector( '.wp-embed-share-dialog-open' ),
  55              share_dialog_close = document.querySelector( '.wp-embed-share-dialog-close' ),
  56              share_input = document.querySelectorAll( '.wp-embed-share-input' ),
  57              share_dialog_tabs = document.querySelectorAll( '.wp-embed-share-tab-button button' ),
  58              featured_image = document.querySelector( '.wp-embed-featured-image img' ),
  59              i;
  60  
  61          if ( share_input ) {
  62              for ( i = 0; i < share_input.length; i++ ) {
  63                  share_input[ i ].addEventListener( 'click', function ( event ) {
  64                      event.target.select();
  65                  } );
  66              }
  67          }
  68  
  69          /**
  70           * Open share dialog within embed iframe.
  71           */
  72  		function openSharingDialog() {
  73              share_dialog.className = share_dialog.className.replace( 'hidden', '' );
  74              // Initial focus should go on the currently selected tab in the dialog.
  75              document.querySelector( '.wp-embed-share-tab-button [aria-selected="true"]' ).focus();
  76          }
  77  
  78          /**
  79           * Close share dialog within embed iframe.
  80           */
  81  		function closeSharingDialog() {
  82              share_dialog.className += ' hidden';
  83              document.querySelector( '.wp-embed-share-dialog-open' ).focus();
  84          }
  85  
  86          if ( share_dialog_open ) {
  87              share_dialog_open.addEventListener( 'click', function () {
  88                  openSharingDialog();
  89              } );
  90          }
  91  
  92          if ( share_dialog_close ) {
  93              share_dialog_close.addEventListener( 'click', function () {
  94                  closeSharingDialog();
  95              } );
  96          }
  97  
  98          /**
  99           * Click event handler for share button.
 100           *
 101           * @param {MouseEvent} event Event handler.
 102           */
 103  		function shareClickHandler( event ) {
 104              var currentTab = document.querySelector( '.wp-embed-share-tab-button [aria-selected="true"]' );
 105              currentTab.setAttribute( 'aria-selected', 'false' );
 106              document.querySelector( '#' + currentTab.getAttribute( 'aria-controls' ) ).setAttribute( 'aria-hidden', 'true' );
 107  
 108              event.target.setAttribute( 'aria-selected', 'true' );
 109              document.querySelector( '#' + event.target.getAttribute( 'aria-controls' ) ).setAttribute( 'aria-hidden', 'false' );
 110          }
 111  
 112          /**
 113           * Keyboard event handler for share button.
 114           *
 115           * @param {KeyboardEvent} event Event handler.
 116           * @return {boolean|void} Returns false if default action is to be prevented.
 117           */
 118  		function shareKeyHandler( event ) {
 119              var target = event.target,
 120                  previousSibling = target.parentElement.previousElementSibling,
 121                  nextSibling = target.parentElement.nextElementSibling,
 122                  newTab, newTabChild;
 123  
 124              if ( 37 === event.keyCode ) {
 125                  newTab = previousSibling;
 126              } else if ( 39 === event.keyCode ) {
 127                  newTab = nextSibling;
 128              } else {
 129                  return false;
 130              }
 131  
 132              if ( 'rtl' === document.documentElement.getAttribute( 'dir' ) ) {
 133                  newTab = ( newTab === previousSibling ) ? nextSibling : previousSibling;
 134              }
 135  
 136              if ( newTab ) {
 137                  newTabChild = newTab.firstElementChild;
 138  
 139                  target.setAttribute( 'tabindex', '-1' );
 140                  target.setAttribute( 'aria-selected', false );
 141                  document.querySelector( '#' + target.getAttribute( 'aria-controls' ) ).setAttribute( 'aria-hidden', 'true' );
 142  
 143                  newTabChild.setAttribute( 'tabindex', '0' );
 144                  newTabChild.setAttribute( 'aria-selected', 'true' );
 145                  newTabChild.focus();
 146                  document.querySelector( '#' + newTabChild.getAttribute( 'aria-controls' ) ).setAttribute( 'aria-hidden', 'false' );
 147              }
 148          }
 149  
 150          if ( share_dialog_tabs ) {
 151              for ( i = 0; i < share_dialog_tabs.length; i++ ) {
 152                  share_dialog_tabs[ i ].addEventListener( 'click', shareClickHandler );
 153  
 154                  share_dialog_tabs[ i ].addEventListener( 'keydown', shareKeyHandler );
 155              }
 156          }
 157  
 158          document.addEventListener( 'keydown', function ( event ) {
 159              if ( 27 === event.keyCode && -1 === share_dialog.className.indexOf( 'hidden' ) ) {
 160                  closeSharingDialog();
 161              } else if ( 9 === event.keyCode ) {
 162                  constrainTabbing( event );
 163              }
 164          }, false );
 165  
 166          /**
 167           * Constrain tabbing to share dialog when open.
 168           *
 169           * @param {KeyboardEvent} event Event object.
 170           */
 171  		function constrainTabbing( event ) {
 172              // Need to re-get the selected tab each time.
 173              var firstFocusable = document.querySelector( '.wp-embed-share-tab-button [aria-selected="true"]' );
 174  
 175              if ( share_dialog_close === event.target && ! event.shiftKey ) {
 176                  firstFocusable.focus();
 177                  event.preventDefault();
 178              } else if ( firstFocusable === event.target && event.shiftKey ) {
 179                  share_dialog_close.focus();
 180                  event.preventDefault();
 181              }
 182          }
 183  
 184          if ( window.self === window.top ) {
 185              return;
 186          }
 187  
 188          // Send this document's height to the parent (embedding) site.
 189          sendHeightMessage();
 190  
 191          // Send the document's height again after the featured image has been loaded.
 192          if ( featured_image ) {
 193              featured_image.addEventListener( 'load', sendHeightMessage );
 194          }
 195  
 196          /**
 197           * Detect clicks to external (_top) links.
 198           *
 199           * @param {MouseEvent} event
 200           */
 201  		function linkClickHandler( event ) {
 202              /*
 203               * The href property resolves to an absolute URL, which the parent window requires.
 204               * Elements whose href is not a string, such as SVG anchors, are skipped.
 205               */
 206              var link = event.target.closest( '[href]' ),
 207                  href = 'string' === typeof link?.href ? link.href : null;
 208  
 209              // Only catch clicks from the primary mouse button, without any modifiers.
 210              if ( event.altKey || event.ctrlKey || event.metaKey || event.shiftKey ) {
 211                  return;
 212              }
 213  
 214              // Send link target to the parent (embedding) site.
 215              if ( href ) {
 216                  sendEmbedMessage( 'link', href );
 217                  event.preventDefault();
 218              }
 219          }
 220  
 221          document.addEventListener( 'click', linkClickHandler );
 222      }
 223  
 224      /**
 225       * Iframe resize handler.
 226       */
 227  	function onResize() {
 228          if ( window.self === window.top ) {
 229              return;
 230          }
 231  
 232          clearTimeout( resizing );
 233  
 234          resizing = setTimeout( sendHeightMessage, 100 );
 235      }
 236  
 237      /**
 238       * Message handler.
 239       *
 240       * @param {MessageEvent} event
 241       */
 242  	function onMessage( event ) {
 243          var data = event.data;
 244  
 245          if ( ! data ) {
 246              return;
 247          }
 248  
 249          if ( event.source !== window.parent ) {
 250              return;
 251          }
 252  
 253          if ( ! ( data.secret || data.message ) ) {
 254              return;
 255          }
 256  
 257          if ( data.secret !== secret ) {
 258              return;
 259          }
 260  
 261          if ( 'ready' === data.message ) {
 262              sendHeightMessage();
 263          }
 264      }
 265  
 266      /**
 267       * Re-get the secret when it was added later on.
 268       */
 269  	function getSecret() {
 270          if ( window.self === window.top || !!secret ) {
 271              return;
 272          }
 273  
 274          secret = window.location.hash.replace( /.*secret=([\d\w]{10}).*/, '$1' );
 275  
 276          clearTimeout( secretTimeout );
 277  
 278          secretTimeout = setTimeout( function () {
 279              getSecret();
 280          }, 100 );
 281      }
 282  
 283      if ( supportedBrowser ) {
 284          getSecret();
 285          document.documentElement.className = document.documentElement.className.replace( /\bno-js\b/, '' ) + ' js';
 286          document.addEventListener( 'DOMContentLoaded', onLoad, false );
 287          window.addEventListener( 'load', onLoad, false );
 288          window.addEventListener( 'resize', onResize, false );
 289          window.addEventListener( 'message', onMessage, false );
 290      }
 291  })( window, document );


Generated : Fri Sep 11 08:20:31 2026 Cross-referenced by PHPXref