wp/wp-includes/js/wp-embed.js
changeset 21 48c4eec2b7e6
parent 19 3d72ae0968f4
equal deleted inserted replaced
20:7b1b88e27a20 21:48c4eec2b7e6
     2  * WordPress inline HTML embed
     2  * WordPress inline HTML embed
     3  *
     3  *
     4  * @since 4.4.0
     4  * @since 4.4.0
     5  * @output wp-includes/js/wp-embed.js
     5  * @output wp-includes/js/wp-embed.js
     6  *
     6  *
     7  * This file cannot have ampersands in it. This is to ensure
     7  * Single line comments should not be used since they will break
     8  * it can be embedded in older versions of WordPress.
     8  * the script when inlined in get_post_embed_html(), specifically
     9  * See https://core.trac.wordpress.org/changeset/35708.
     9  * when the comments are not stripped out due to SCRIPT_DEBUG
       
    10  * being turned on.
    10  */
    11  */
    11 (function ( window, document ) {
    12 (function ( window, document ) {
    12 	'use strict';
    13 	'use strict';
    13 
    14 
    14 	var supportedBrowser = false,
    15 	/* Abort for ancient browsers. */
    15 		loaded = false;
    16 	if ( ! document.querySelector || ! window.addEventListener || typeof URL === 'undefined' ) {
    16 
    17 		return;
    17 		if ( document.querySelector ) {
    18 	}
    18 			if ( window.addEventListener ) {
       
    19 				supportedBrowser = true;
       
    20 			}
       
    21 		}
       
    22 
    19 
    23 	/** @namespace wp */
    20 	/** @namespace wp */
    24 	window.wp = window.wp || {};
    21 	window.wp = window.wp || {};
    25 
    22 
       
    23 	/* Abort if script was already executed. */
    26 	if ( !! window.wp.receiveEmbedMessage ) {
    24 	if ( !! window.wp.receiveEmbedMessage ) {
    27 		return;
    25 		return;
    28 	}
    26 	}
    29 
    27 
    30 	/**
    28 	/**
    33 	 * @param {MessageEvent} e
    31 	 * @param {MessageEvent} e
    34 	 */
    32 	 */
    35 	window.wp.receiveEmbedMessage = function( e ) {
    33 	window.wp.receiveEmbedMessage = function( e ) {
    36 		var data = e.data;
    34 		var data = e.data;
    37 
    35 
    38 		if ( ! data ) {
    36 		/* Verify shape of message. */
    39 			return;
    37 		if (
    40 		}
    38 			! ( data || data.secret || data.message || data.value ) ||
    41 
    39 			/[^a-zA-Z0-9]/.test( data.secret )
    42 		if ( ! ( data.secret || data.message || data.value ) ) {
    40 		) {
    43 			return;
       
    44 		}
       
    45 
       
    46 		if ( /[^a-zA-Z0-9]/.test( data.secret ) ) {
       
    47 			return;
    41 			return;
    48 		}
    42 		}
    49 
    43 
    50 		var iframes = document.querySelectorAll( 'iframe[data-secret="' + data.secret + '"]' ),
    44 		var iframes = document.querySelectorAll( 'iframe[data-secret="' + data.secret + '"]' ),
    51 			blockquotes = document.querySelectorAll( 'blockquote[data-secret="' + data.secret + '"]' ),
    45 			blockquotes = document.querySelectorAll( 'blockquote[data-secret="' + data.secret + '"]' ),
       
    46 			allowedProtocols = new RegExp( '^https?:$', 'i' ),
    52 			i, source, height, sourceURL, targetURL;
    47 			i, source, height, sourceURL, targetURL;
    53 
    48 
    54 		for ( i = 0; i < blockquotes.length; i++ ) {
    49 		for ( i = 0; i < blockquotes.length; i++ ) {
    55 			blockquotes[ i ].style.display = 'none';
    50 			blockquotes[ i ].style.display = 'none';
    56 		}
    51 		}
    62 				continue;
    57 				continue;
    63 			}
    58 			}
    64 
    59 
    65 			source.removeAttribute( 'style' );
    60 			source.removeAttribute( 'style' );
    66 
    61 
    67 			/* Resize the iframe on request. */
       
    68 			if ( 'height' === data.message ) {
    62 			if ( 'height' === data.message ) {
       
    63 				/* Resize the iframe on request. */
    69 				height = parseInt( data.value, 10 );
    64 				height = parseInt( data.value, 10 );
    70 				if ( height > 1000 ) {
    65 				if ( height > 1000 ) {
    71 					height = 1000;
    66 					height = 1000;
    72 				} else if ( ~~height < 200 ) {
    67 				} else if ( ~~height < 200 ) {
    73 					height = 200;
    68 					height = 200;
    74 				}
    69 				}
    75 
    70 
    76 				source.height = height;
    71 				source.height = height;
    77 			}
    72 			} else if ( 'link' === data.message ) {
       
    73 				/* Link to a specific URL on request. */
       
    74 				sourceURL = new URL( source.getAttribute( 'src' ) );
       
    75 				targetURL = new URL( data.value );
    78 
    76 
    79 			/* Link to a specific URL on request. */
    77 				if (
    80 			if ( 'link' === data.message ) {
    78 					allowedProtocols.test( targetURL.protocol ) &&
    81 				sourceURL = document.createElement( 'a' );
    79 					targetURL.host === sourceURL.host &&
    82 				targetURL = document.createElement( 'a' );
    80 					document.activeElement === source
    83 
    81 				) {
    84 				sourceURL.href = source.getAttribute( 'src' );
    82 					window.top.location.href = data.value;
    85 				targetURL.href = data.value;
       
    86 
       
    87 				/* Only continue if link hostname matches iframe's hostname. */
       
    88 				if ( targetURL.host === sourceURL.host ) {
       
    89 					if ( document.activeElement === source ) {
       
    90 						window.top.location.href = data.value;
       
    91 					}
       
    92 				}
    83 				}
    93 			}
    84 			}
    94 		}
    85 		}
    95 	};
    86 	};
    96 
    87 
    97 	function onLoad() {
    88 	function onLoad() {
    98 		if ( loaded ) {
    89 		var iframes = document.querySelectorAll( 'iframe.wp-embedded-content' ),
    99 			return;
    90 			i, source, secret;
   100 		}
       
   101 
       
   102 		loaded = true;
       
   103 
       
   104 		var isIE10 = -1 !== navigator.appVersion.indexOf( 'MSIE 10' ),
       
   105 			isIE11 = !!navigator.userAgent.match( /Trident.*rv:11\./ ),
       
   106 			iframes = document.querySelectorAll( 'iframe.wp-embedded-content' ),
       
   107 			iframeClone, i, source, secret;
       
   108 
    91 
   109 		for ( i = 0; i < iframes.length; i++ ) {
    92 		for ( i = 0; i < iframes.length; i++ ) {
   110 			/** @var {IframeElement} */
    93 			/** @var {IframeElement} */
   111 			source = iframes[ i ];
    94 			source = iframes[ i ];
   112 
    95 
   113 			secret = source.getAttribute( 'data-secret' );
    96 			secret = source.getAttribute( 'data-secret' );
   114 			if ( ! secret ) {
    97 			if ( ! secret ) {
   115 				/* Add secret to iframe */
    98 				/* Add secret to iframe */
   116 				secret = Math.random().toString( 36 ).substr( 2, 10 );
    99 				secret = Math.random().toString( 36 ).substring( 2, 12 );
   117 				source.src += '#?secret=' + secret;
   100 				source.src += '#?secret=' + secret;
   118 				source.setAttribute( 'data-secret', secret );
   101 				source.setAttribute( 'data-secret', secret );
   119 			}
       
   120 
       
   121 			/* Remove security attribute from iframes in IE10 and IE11. */
       
   122 			if ( ( isIE10 || isIE11 ) ) {
       
   123 				iframeClone = source.cloneNode( true );
       
   124 				iframeClone.removeAttribute( 'security' );
       
   125 				source.parentNode.replaceChild( iframeClone, source );
       
   126 			}
   102 			}
   127 
   103 
   128 			/*
   104 			/*
   129 			 * Let post embed window know that the parent is ready for receiving the height message, in case the iframe
   105 			 * Let post embed window know that the parent is ready for receiving the height message, in case the iframe
   130 			 * loaded before wp-embed.js was loaded. When the ready message is received by the post embed window, the
   106 			 * loaded before wp-embed.js was loaded. When the ready message is received by the post embed window, the
   135 				secret: secret
   111 				secret: secret
   136 			}, '*' );
   112 			}, '*' );
   137 		}
   113 		}
   138 	}
   114 	}
   139 
   115 
   140 	if ( supportedBrowser ) {
   116 	window.addEventListener( 'message', window.wp.receiveEmbedMessage, false );
   141 		window.addEventListener( 'message', window.wp.receiveEmbedMessage, false );
   117 	document.addEventListener( 'DOMContentLoaded', onLoad, false );
   142 		document.addEventListener( 'DOMContentLoaded', onLoad, false );
       
   143 		window.addEventListener( 'load', onLoad, false );
       
   144 	}
       
   145 })( window, document );
   118 })( window, document );