wp-embed-template.js 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. /**
  2. * @output wp-includes/js/wp-embed-template.js
  3. */
  4. (function ( window, document ) {
  5. 'use strict';
  6. var supportedBrowser = ( document.querySelector && window.addEventListener ),
  7. loaded = false,
  8. secret,
  9. secretTimeout,
  10. resizing;
  11. function sendEmbedMessage( message, value ) {
  12. window.parent.postMessage( {
  13. message: message,
  14. value: value,
  15. secret: secret
  16. }, '*' );
  17. }
  18. function onLoad() {
  19. if ( loaded ) {
  20. return;
  21. }
  22. loaded = true;
  23. var share_dialog = document.querySelector( '.wp-embed-share-dialog' ),
  24. share_dialog_open = document.querySelector( '.wp-embed-share-dialog-open' ),
  25. share_dialog_close = document.querySelector( '.wp-embed-share-dialog-close' ),
  26. share_input = document.querySelectorAll( '.wp-embed-share-input' ),
  27. share_dialog_tabs = document.querySelectorAll( '.wp-embed-share-tab-button button' ),
  28. featured_image = document.querySelector( '.wp-embed-featured-image img' ),
  29. i;
  30. if ( share_input ) {
  31. for ( i = 0; i < share_input.length; i++ ) {
  32. share_input[ i ].addEventListener( 'click', function ( e ) {
  33. e.target.select();
  34. } );
  35. }
  36. }
  37. function openSharingDialog() {
  38. share_dialog.className = share_dialog.className.replace( 'hidden', '' );
  39. // Initial focus should go on the currently selected tab in the dialog.
  40. document.querySelector( '.wp-embed-share-tab-button [aria-selected="true"]' ).focus();
  41. }
  42. function closeSharingDialog() {
  43. share_dialog.className += ' hidden';
  44. document.querySelector( '.wp-embed-share-dialog-open' ).focus();
  45. }
  46. if ( share_dialog_open ) {
  47. share_dialog_open.addEventListener( 'click', function () {
  48. openSharingDialog();
  49. } );
  50. }
  51. if ( share_dialog_close ) {
  52. share_dialog_close.addEventListener( 'click', function () {
  53. closeSharingDialog();
  54. } );
  55. }
  56. function shareClickHandler( e ) {
  57. var currentTab = document.querySelector( '.wp-embed-share-tab-button [aria-selected="true"]' );
  58. currentTab.setAttribute( 'aria-selected', 'false' );
  59. document.querySelector( '#' + currentTab.getAttribute( 'aria-controls' ) ).setAttribute( 'aria-hidden', 'true' );
  60. e.target.setAttribute( 'aria-selected', 'true' );
  61. document.querySelector( '#' + e.target.getAttribute( 'aria-controls' ) ).setAttribute( 'aria-hidden', 'false' );
  62. }
  63. function shareKeyHandler( e ) {
  64. var target = e.target,
  65. previousSibling = target.parentElement.previousElementSibling,
  66. nextSibling = target.parentElement.nextElementSibling,
  67. newTab, newTabChild;
  68. if ( 37 === e.keyCode ) {
  69. newTab = previousSibling;
  70. } else if ( 39 === e.keyCode ) {
  71. newTab = nextSibling;
  72. } else {
  73. return false;
  74. }
  75. if ( 'rtl' === document.documentElement.getAttribute( 'dir' ) ) {
  76. newTab = ( newTab === previousSibling ) ? nextSibling : previousSibling;
  77. }
  78. if ( newTab ) {
  79. newTabChild = newTab.firstElementChild;
  80. target.setAttribute( 'tabindex', '-1' );
  81. target.setAttribute( 'aria-selected', false );
  82. document.querySelector( '#' + target.getAttribute( 'aria-controls' ) ).setAttribute( 'aria-hidden', 'true' );
  83. newTabChild.setAttribute( 'tabindex', '0' );
  84. newTabChild.setAttribute( 'aria-selected', 'true' );
  85. newTabChild.focus();
  86. document.querySelector( '#' + newTabChild.getAttribute( 'aria-controls' ) ).setAttribute( 'aria-hidden', 'false' );
  87. }
  88. }
  89. if ( share_dialog_tabs ) {
  90. for ( i = 0; i < share_dialog_tabs.length; i++ ) {
  91. share_dialog_tabs[ i ].addEventListener( 'click', shareClickHandler );
  92. share_dialog_tabs[ i ].addEventListener( 'keydown', shareKeyHandler );
  93. }
  94. }
  95. document.addEventListener( 'keydown', function ( e ) {
  96. if ( 27 === e.keyCode && -1 === share_dialog.className.indexOf( 'hidden' ) ) {
  97. closeSharingDialog();
  98. } else if ( 9 === e.keyCode ) {
  99. constrainTabbing( e );
  100. }
  101. }, false );
  102. function constrainTabbing( e ) {
  103. // Need to re-get the selected tab each time.
  104. var firstFocusable = document.querySelector( '.wp-embed-share-tab-button [aria-selected="true"]' );
  105. if ( share_dialog_close === e.target && ! e.shiftKey ) {
  106. firstFocusable.focus();
  107. e.preventDefault();
  108. } else if ( firstFocusable === e.target && e.shiftKey ) {
  109. share_dialog_close.focus();
  110. e.preventDefault();
  111. }
  112. }
  113. if ( window.self === window.top ) {
  114. return;
  115. }
  116. /**
  117. * Send this document's height to the parent (embedding) site.
  118. */
  119. sendEmbedMessage( 'height', Math.ceil( document.body.getBoundingClientRect().height ) );
  120. // Send the document's height again after the featured image has been loaded.
  121. if ( featured_image ) {
  122. featured_image.addEventListener( 'load', function() {
  123. sendEmbedMessage( 'height', Math.ceil( document.body.getBoundingClientRect().height ) );
  124. } );
  125. }
  126. /**
  127. * Detect clicks to external (_top) links.
  128. */
  129. function linkClickHandler( e ) {
  130. var target = e.target,
  131. href;
  132. if ( target.hasAttribute( 'href' ) ) {
  133. href = target.getAttribute( 'href' );
  134. } else {
  135. href = target.parentElement.getAttribute( 'href' );
  136. }
  137. /**
  138. * Send link target to the parent (embedding) site.
  139. */
  140. if ( href ) {
  141. sendEmbedMessage( 'link', href );
  142. e.preventDefault();
  143. }
  144. }
  145. document.addEventListener( 'click', linkClickHandler );
  146. }
  147. /**
  148. * Iframe resize handler.
  149. */
  150. function onResize() {
  151. if ( window.self === window.top ) {
  152. return;
  153. }
  154. clearTimeout( resizing );
  155. resizing = setTimeout( function () {
  156. sendEmbedMessage( 'height', Math.ceil( document.body.getBoundingClientRect().height ) );
  157. }, 100 );
  158. }
  159. /**
  160. * Re-get the secret when it was added later on.
  161. */
  162. function getSecret() {
  163. if ( window.self === window.top || !!secret ) {
  164. return;
  165. }
  166. secret = window.location.hash.replace( /.*secret=([\d\w]{10}).*/, '$1' );
  167. clearTimeout( secretTimeout );
  168. secretTimeout = setTimeout( function () {
  169. getSecret();
  170. }, 100 );
  171. }
  172. if ( supportedBrowser ) {
  173. getSecret();
  174. document.documentElement.className = document.documentElement.className.replace( /\bno-js\b/, '' ) + ' js';
  175. document.addEventListener( 'DOMContentLoaded', onLoad, false );
  176. window.addEventListener( 'load', onLoad, false );
  177. window.addEventListener( 'resize', onResize, false );
  178. }
  179. })( window, document );