<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[52132] trunk: Embeds: Conditionally enqueue `wp-embed` only if needed and send `ready` message in case script loads after post embed windows.</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { white-space: pre-line; overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta" style="font-size: 105%">
<dt style="float: left; width: 6em; font-weight: bold">Revision</dt> <dd><a style="font-weight: bold" href="https://core.trac.wordpress.org/changeset/52132">52132</a><script type="application/ld+json">{"@context":"http://schema.org","@type":"EmailMessage","description":"Review this Commit","action":{"@type":"ViewAction","url":"https://core.trac.wordpress.org/changeset/52132","name":"Review Commit"}}</script></dd>
<dt style="float: left; width: 6em; font-weight: bold">Author</dt> <dd>westonruter</dd>
<dt style="float: left; width: 6em; font-weight: bold">Date</dt> <dd>2021-11-11 02:47:10 +0000 (Thu, 11 Nov 2021)</dd>
</dl>

<pre style='padding-left: 1em; margin: 2em 0; border-left: 2px solid #ccc; line-height: 1.25; font-size: 105%; font-family: sans-serif'>Embeds: Conditionally enqueue `wp-embed` only if needed and send `ready` message in case script loads after post embed windows.

* Prevent loading `wp-embed` script unconditionally on every page in favor of conditionally enqueueing when a post embed is detected. The `wp-embed` script is also explicitly marked as being in the footer group. Sites which currently disable post embed scripts from being enqueued via `remove_action( 'wp_head', 'wp_oembed_add_host_js' )` will continue to do so.
* Send a `ready` message from the host page to each post embed window in case the `iframe` loads before the `wp-embed` script does. When the `ready` message is received by the post embed window, it sends the same `height` message as it sends when it loads.
* Eliminate use of `grunt-include` to inject emoji script and the post embed script. Instead obtain the script contents via `file_get_contents()` (as is done elsewhere in core) and utilize `wp_print_inline_script_tag()`/`wp_get_inline_script_tag()` to construct out the script. This simplifies the logic and allows the running of src without `SCRIPT_DEBUG` enabled.
* For the embed code that users are provided to copy for embedding outside of WP, add the `secret` on the `blockquote` and `iframe`. This ensures the `blockquote` will be hidden when the `iframe` loads. The embed code in question is accessed here via `get_post_embed_html()`.

Props westonruter, swissspidy, pento, flixos90, ocean90.
Fixes <a href="https://core.trac.wordpress.org/ticket/44632">#44632</a>, <a href="https://core.trac.wordpress.org/ticket/44306">#44306</a>.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkGruntfilejs">trunk/Gruntfile.js</a></li>
<li><a href="#trunkpackagelockjson">trunk/package-lock.json</a></li>
<li><a href="#trunkpackagejson">trunk/package.json</a></li>
<li><a href="#trunksrcjs_enqueueslibembedtemplatejs">trunk/src/js/_enqueues/lib/embed-template.js</a></li>
<li><a href="#trunksrcjs_enqueueswpembedjs">trunk/src/js/_enqueues/wp/embed.js</a></li>
<li><a href="#trunksrcwpincludesembedphp">trunk/src/wp-includes/embed.php</a></li>
<li><a href="#trunksrcwpincludesformattingphp">trunk/src/wp-includes/formatting.php</a></li>
<li><a href="#trunksrcwpincludesscriptloaderphp">trunk/src/wp-includes/script-loader.php</a></li>
<li><a href="#trunktestsphpunittestsoembedgetResponseDataphp">trunk/tests/phpunit/tests/oembed/getResponseData.php</a></li>
<li><a href="#trunktestsphpunittestsoembedtemplatephp">trunk/tests/phpunit/tests/oembed/template.php</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkGruntfilejs"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/Gruntfile.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/Gruntfile.js        2021-11-10 21:09:30 UTC (rev 52131)
+++ trunk/Gruntfile.js  2021-11-11 02:47:10 UTC (rev 52132)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1020,16 +1020,6 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                dest: SOURCE_DIR
</span><span class="cx" style="display: block; padding: 0 10px">                        }
</span><span class="cx" style="display: block; padding: 0 10px">                },
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                includes: {
-                       emoji: {
-                               src: BUILD_DIR + 'wp-includes/formatting.php',
-                               dest: '.'
-                       },
-                       embed: {
-                               src: BUILD_DIR + 'wp-includes/embed.php',
-                               dest: '.'
-                       }
-               },
</del><span class="cx" style="display: block; padding: 0 10px">                 replace: {
</span><span class="cx" style="display: block; padding: 0 10px">                        'emoji-regex': {
</span><span class="cx" style="display: block; padding: 0 10px">                                options: {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1593,8 +1583,6 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                'build:files',
</span><span class="cx" style="display: block; padding: 0 10px">                                'build:js',
</span><span class="cx" style="display: block; padding: 0 10px">                                'build:css',
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                'includes:emoji',
-                               'includes:embed',
</del><span class="cx" style="display: block; padding: 0 10px">                                 'replace:emoji-banner-text',
</span><span class="cx" style="display: block; padding: 0 10px">                                'replace:source-maps',
</span><span class="cx" style="display: block; padding: 0 10px">                                'verify:build'
</span></span></pre></div>
<a id="trunkpackagelockjson"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/package-lock.json</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/package-lock.json   2021-11-10 21:09:30 UTC (rev 52131)
+++ trunk/package-lock.json     2021-11-11 02:47:10 UTC (rev 52132)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -13422,12 +13422,6 @@
</span><span class="cx" style="display: block; padding: 0 10px">                        "integrity": "sha1-P376M2lvoFdwsoCU9EUIyvxdLto=",
</span><span class="cx" style="display: block; padding: 0 10px">                        "dev": true
</span><span class="cx" style="display: block; padding: 0 10px">                },
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                "grunt-includes": {
-                       "version": "1.1.0",
-                       "resolved": "https://registry.npmjs.org/grunt-includes/-/grunt-includes-1.1.0.tgz",
-                       "integrity": "sha512-aZQfL+fiAonPI173QUjGyuCkaUTJci7+a5SkmSAbezUikwLban7Jp6W+vbA/Mnacmy+EPipnuK5kAF6O0SvrDw==",
-                       "dev": true
-               },
</del><span class="cx" style="display: block; padding: 0 10px">                 "grunt-jsdoc": {
</span><span class="cx" style="display: block; padding: 0 10px">                        "version": "2.4.1",
</span><span class="cx" style="display: block; padding: 0 10px">                        "resolved": "https://registry.npmjs.org/grunt-jsdoc/-/grunt-jsdoc-2.4.1.tgz",
</span></span></pre></div>
<a id="trunkpackagejson"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/package.json</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/package.json        2021-11-10 21:09:30 UTC (rev 52131)
+++ trunk/package.json  2021-11-11 02:47:10 UTC (rev 52132)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -49,7 +49,6 @@
</span><span class="cx" style="display: block; padding: 0 10px">                "grunt-contrib-uglify": "~5.0.1",
</span><span class="cx" style="display: block; padding: 0 10px">                "grunt-contrib-watch": "~1.1.0",
</span><span class="cx" style="display: block; padding: 0 10px">                "grunt-file-append": "0.0.7",
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                "grunt-includes": "~1.1.0",
</del><span class="cx" style="display: block; padding: 0 10px">                 "grunt-jsdoc": "2.4.1",
</span><span class="cx" style="display: block; padding: 0 10px">                "grunt-jsvalidate": "~0.2.2",
</span><span class="cx" style="display: block; padding: 0 10px">                "grunt-legacy-util": "^2.0.1",
</span></span></pre></div>
<a id="trunksrcjs_enqueueslibembedtemplatejs"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/js/_enqueues/lib/embed-template.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/js/_enqueues/lib/embed-template.js      2021-11-10 21:09:30 UTC (rev 52131)
+++ trunk/src/js/_enqueues/lib/embed-template.js        2021-11-11 02:47:10 UTC (rev 52132)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -18,6 +18,13 @@
</span><span class="cx" style="display: block; padding: 0 10px">                }, '*' );
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+        /**
+        * Send the height message to the parent window.
+        */
+       function sendHeightMessage() {
+               sendEmbedMessage( 'height', Math.ceil( document.body.getBoundingClientRect().height ) );
+       }
+
</ins><span class="cx" style="display: block; padding: 0 10px">         function onLoad() {
</span><span class="cx" style="display: block; padding: 0 10px">                if ( loaded ) {
</span><span class="cx" style="display: block; padding: 0 10px">                        return;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -138,13 +145,11 @@
</span><span class="cx" style="display: block; padding: 0 10px">                }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                // Send this document's height to the parent (embedding) site.
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                sendEmbedMessage( 'height', Math.ceil( document.body.getBoundingClientRect().height ) );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         sendHeightMessage();
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                // Send the document's height again after the featured image has been loaded.
</span><span class="cx" style="display: block; padding: 0 10px">                if ( featured_image ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        featured_image.addEventListener( 'load', function() {
-                               sendEmbedMessage( 'height', Math.ceil( document.body.getBoundingClientRect().height ) );
-                       } );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 featured_image.addEventListener( 'load', sendHeightMessage );
</ins><span class="cx" style="display: block; padding: 0 10px">                 }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                /**
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -184,12 +189,39 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                clearTimeout( resizing );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                resizing = setTimeout( function () {
-                       sendEmbedMessage( 'height', Math.ceil( document.body.getBoundingClientRect().height ) );
-               }, 100 );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         resizing = setTimeout( sendHeightMessage, 100 );
</ins><span class="cx" style="display: block; padding: 0 10px">         }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        /**
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         * Message handler.
+        *
+        * @param {MessageEvent} event
+        */
+       function onMessage( event ) {
+               var data = event.data;
+
+               if ( ! data ) {
+                       return;
+               }
+
+               if ( event.source !== window.parent ) {
+                       return;
+               }
+
+               if ( ! ( data.secret || data.message ) ) {
+                       return;
+               }
+
+               if ( data.secret !== secret ) {
+                       return;
+               }
+
+               if ( 'ready' === data.message ) {
+                       sendHeightMessage();
+               }
+       }
+
+       /**
</ins><span class="cx" style="display: block; padding: 0 10px">          * Re-get the secret when it was added later on.
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><span class="cx" style="display: block; padding: 0 10px">        function getSecret() {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -212,5 +244,6 @@
</span><span class="cx" style="display: block; padding: 0 10px">                document.addEventListener( 'DOMContentLoaded', onLoad, false );
</span><span class="cx" style="display: block; padding: 0 10px">                window.addEventListener( 'load', onLoad, false );
</span><span class="cx" style="display: block; padding: 0 10px">                window.addEventListener( 'resize', onResize, false );
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                window.addEventListener( 'message', onMessage, false );
</ins><span class="cx" style="display: block; padding: 0 10px">         }
</span><span class="cx" style="display: block; padding: 0 10px"> })( window, document );
</span></span></pre></div>
<a id="trunksrcjs_enqueueswpembedjs"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/js/_enqueues/wp/embed.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/js/_enqueues/wp/embed.js        2021-11-10 21:09:30 UTC (rev 52131)
+++ trunk/src/js/_enqueues/wp/embed.js  2021-11-11 02:47:10 UTC (rev 52132)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -27,6 +27,11 @@
</span><span class="cx" style="display: block; padding: 0 10px">                return;
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+        /**
+        * Receive embed message.
+        *
+        * @param {MessageEvent} e
+        */
</ins><span class="cx" style="display: block; padding: 0 10px">         window.wp.receiveEmbedMessage = function( e ) {
</span><span class="cx" style="display: block; padding: 0 10px">                var data = e.data;
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -102,9 +107,11 @@
</span><span class="cx" style="display: block; padding: 0 10px">                        iframeClone, i, source, secret;
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                for ( i = 0; i < iframes.length; i++ ) {
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                        /** @var {IframeElement} */
</ins><span class="cx" style="display: block; padding: 0 10px">                         source = iframes[ i ];
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        if ( ! source.getAttribute( 'data-secret' ) ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 secret = source.getAttribute( 'data-secret' );
+                       if ( ! secret ) {
</ins><span class="cx" style="display: block; padding: 0 10px">                                 /* Add secret to iframe */
</span><span class="cx" style="display: block; padding: 0 10px">                                secret = Math.random().toString( 36 ).substr( 2, 10 );
</span><span class="cx" style="display: block; padding: 0 10px">                                source.src += '#?secret=' + secret;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -117,6 +124,16 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                iframeClone.removeAttribute( 'security' );
</span><span class="cx" style="display: block; padding: 0 10px">                                source.parentNode.replaceChild( iframeClone, source );
</span><span class="cx" style="display: block; padding: 0 10px">                        }
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+                       /*
+                        * Let post embed window know that the parent is ready for receiving the height message, in case the iframe
+                        * loaded before wp-embed.js was loaded. When the ready message is received by the post embed window, the
+                        * window will then (re-)send the height message right away.
+                        */
+                       source.contentWindow.postMessage( {
+                               message: 'ready',
+                               secret: secret
+                       }, '*' );
</ins><span class="cx" style="display: block; padding: 0 10px">                 }
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span></span></pre></div>
<a id="trunksrcwpincludesembedphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/embed.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/embed.php   2021-11-10 21:09:30 UTC (rev 52131)
+++ trunk/src/wp-includes/embed.php     2021-11-11 02:47:10 UTC (rev 52132)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -359,10 +359,28 @@
</span><span class="cx" style="display: block; padding: 0 10px">  * @since 4.4.0
</span><span class="cx" style="display: block; padding: 0 10px">  */
</span><span class="cx" style="display: block; padding: 0 10px"> function wp_oembed_add_host_js() {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        wp_enqueue_script( 'wp-embed' );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ add_filter( 'embed_oembed_html', 'wp_maybe_enqueue_oembed_host_js' );
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * Enqueue the wp-embed script if the provided oEmbed HTML contains a post embed.
+ *
+ * In order to only enqueue the wp-embed script on pages that actually contain post embeds, this function checks if the
+ * provided HTML contains post embed markup and if so enqueues the script so that it will get printed in the footer.
+ *
+ * @since 5.9.0
+ *
+ * @param string $html Embed markup.
+ * @return string Embed markup (without modifications).
+ */
+function wp_maybe_enqueue_oembed_host_js( $html ) {
+       if ( preg_match( '/<blockquote\s[^>]*wp-embedded-content/', $html ) ) {
+               wp_enqueue_script( 'wp-embed' );
+       }
+       return $html;
+}
+
+/**
</ins><span class="cx" style="display: block; padding: 0 10px">  * Retrieves the URL to embed a specific post in an iframe.
</span><span class="cx" style="display: block; padding: 0 10px">  *
</span><span class="cx" style="display: block; padding: 0 10px">  * @since 4.4.0
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -450,32 +468,22 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        $embed_url = get_post_embed_url( $post );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        $output = '<blockquote class="wp-embedded-content"><a href="' . esc_url( get_permalink( $post ) ) . '">' . get_the_title( $post ) . "</a></blockquote>\n";
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $secret     = wp_generate_password( 10, false );
+       $embed_url .= "#?secret={$secret}";
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        $output .= "<script type='text/javascript'>\n";
-       $output .= "<!--//--><![CDATA[//><!--\n";
-       if ( SCRIPT_DEBUG ) {
-               $output .= file_get_contents( ABSPATH . WPINC . '/js/wp-embed.js' );
-       } else {
-               /*
-                * If you're looking at a src version of this file, you'll see an "include"
-                * statement below. This is used by the `npm run build` process to directly
-                * include a minified version of wp-embed.js, instead of using the
-                * file_get_contents() method from above.
-                *
-                * If you're looking at a build version of this file, you'll see a string of
-                * minified JavaScript. If you need to debug it, please turn on SCRIPT_DEBUG
-                * and edit wp-embed.js directly.
-                */
-               $output .= <<<JS
-               include "js/wp-embed.min.js"
-JS;
-       }
-       $output .= "\n//--><!]]>";
-       $output .= "\n</script>";
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $output = wp_get_inline_script_tag(
+               file_get_contents( sprintf( ABSPATH . WPINC . '/js/wp-embed' . wp_scripts_get_suffix() . '.js' ) )
+       );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        $output .= sprintf(
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                '<iframe sandbox="allow-scripts" security="restricted" src="%1$s" width="%2$d" height="%3$d" title="%4$s" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" class="wp-embedded-content"></iframe>',
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         '<blockquote class="wp-embedded-content" data-secret="%1$s"><a href="%2$s">%3$s</a></blockquote>',
+               esc_attr( $secret ),
+               esc_url( get_permalink( $post ) ),
+               get_the_title( $post )
+       );
+
+       $output .= sprintf(
+               '<iframe sandbox="allow-scripts" security="restricted" src="%1$s" width="%2$d" height="%3$d" title="%4$s" data-secret="%5$s" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" class="wp-embedded-content"></iframe>',
</ins><span class="cx" style="display: block; padding: 0 10px">                 esc_url( $embed_url ),
</span><span class="cx" style="display: block; padding: 0 10px">                absint( $width ),
</span><span class="cx" style="display: block; padding: 0 10px">                absint( $height ),
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -486,7 +494,8 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                get_the_title( $post ),
</span><span class="cx" style="display: block; padding: 0 10px">                                get_bloginfo( 'name' )
</span><span class="cx" style="display: block; padding: 0 10px">                        )
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                )
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         ),
+               esc_attr( $secret )
</ins><span class="cx" style="display: block; padding: 0 10px">         );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        /**
</span></span></pre></div>
<a id="trunksrcwpincludesformattingphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/formatting.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/formatting.php      2021-11-10 21:09:30 UTC (rev 52131)
+++ trunk/src/wp-includes/formatting.php        2021-11-11 02:47:10 UTC (rev 52132)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -5756,8 +5756,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                'svgExt'  => apply_filters( 'emoji_svg_ext', '.svg' ),
</span><span class="cx" style="display: block; padding: 0 10px">        );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        $version   = 'ver=' . get_bloginfo( 'version' );
-       $type_attr = current_theme_supports( 'html5', 'style' ) ? '' : ' type="text/javascript"';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $version = 'ver=' . get_bloginfo( 'version' );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        if ( SCRIPT_DEBUG ) {
</span><span class="cx" style="display: block; padding: 0 10px">                $settings['source'] = array(
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -5766,36 +5765,17 @@
</span><span class="cx" style="display: block; padding: 0 10px">                        /** This filter is documented in wp-includes/class.wp-scripts.php */
</span><span class="cx" style="display: block; padding: 0 10px">                        'twemoji' => apply_filters( 'script_loader_src', includes_url( "js/twemoji.js?$version" ), 'twemoji' ),
</span><span class="cx" style="display: block; padding: 0 10px">                );
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-
-               ?>
-               <script<?php echo $type_attr; ?>>
-                       window._wpemojiSettings = <?php echo wp_json_encode( $settings ); ?>;
-                       <?php readfile( ABSPATH . WPINC . '/js/wp-emoji-loader.js' ); ?>
-               </script>
-               <?php
</del><span class="cx" style="display: block; padding: 0 10px">         } else {
</span><span class="cx" style="display: block; padding: 0 10px">                $settings['source'] = array(
</span><span class="cx" style="display: block; padding: 0 10px">                        /** This filter is documented in wp-includes/class.wp-scripts.php */
</span><span class="cx" style="display: block; padding: 0 10px">                        'concatemoji' => apply_filters( 'script_loader_src', includes_url( "js/wp-emoji-release.min.js?$version" ), 'concatemoji' ),
</span><span class="cx" style="display: block; padding: 0 10px">                );
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+        }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                /*
-                * If you're looking at a src version of this file, you'll see an "include"
-                * statement below. This is used by the `npm run build` process to directly
-                * include a minified version of wp-emoji-loader.js, instead of using the
-                * readfile() method from above.
-                *
-                * If you're looking at a build version of this file, you'll see a string of
-                * minified JavaScript. If you need to debug it, please turn on SCRIPT_DEBUG
-                * and edit wp-emoji-loader.js directly.
-                */
-               ?>
-               <script<?php echo $type_attr; ?>>
-                       window._wpemojiSettings = <?php echo wp_json_encode( $settings ); ?>;
-                       include "js/wp-emoji-loader.min.js"
-               </script>
-               <?php
-       }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ wp_print_inline_script_tag(
+               sprintf( 'window._wpemojiSettings = %s;', wp_json_encode( $settings ) ) .
+                       file_get_contents( sprintf( ABSPATH . WPINC . '/js/wp-emoji-loader' . wp_scripts_get_suffix() . '.js' ) )
+       );
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span></span></pre></div>
<a id="trunksrcwpincludesscriptloaderphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/script-loader.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/script-loader.php   2021-11-10 21:09:30 UTC (rev 52131)
+++ trunk/src/wp-includes/script-loader.php     2021-11-11 02:47:10 UTC (rev 52132)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1247,7 +1247,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                )
</span><span class="cx" style="display: block; padding: 0 10px">        );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        $scripts->add( 'wp-embed', "/wp-includes/js/wp-embed$suffix.js" );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $scripts->add( 'wp-embed', "/wp-includes/js/wp-embed$suffix.js", array(), false, 1 );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        // To enqueue media-views or media-editor, call wp_enqueue_media().
</span><span class="cx" style="display: block; padding: 0 10px">        // Both rely on numerous settings, styles, and templates to operate correctly.
</span></span></pre></div>
<a id="trunktestsphpunittestsoembedgetResponseDataphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/tests/phpunit/tests/oembed/getResponseData.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tests/phpunit/tests/oembed/getResponseData.php      2021-11-10 21:09:30 UTC (rev 52131)
+++ trunk/tests/phpunit/tests/oembed/getResponseData.php        2021-11-11 02:47:10 UTC (rev 52132)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -12,6 +12,24 @@
</span><span class="cx" style="display: block; padding: 0 10px">                self::touch( ABSPATH . WPINC . '/js/wp-embed.js' );
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+        private function normalize_secret_attribute( $data ) {
+               if ( is_array( $data ) ) {
+                       $html = $data['html'];
+               } else {
+                       $html = $data;
+               }
+
+               $html = preg_replace( '/secret=("?)\w+\1/', 'secret=__SECRET__', $html );
+
+               if ( is_array( $data ) ) {
+                       $data['html'] = $html;
+               } else {
+                       $data = $html;
+               }
+
+               return $data;
+       }
+
</ins><span class="cx" style="display: block; padding: 0 10px">         public function test_get_oembed_response_data_non_existent_post() {
</span><span class="cx" style="display: block; padding: 0 10px">                $this->assertFalse( get_oembed_response_data( 0, 100 ) );
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -36,9 +54,9 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                'type'          => 'rich',
</span><span class="cx" style="display: block; padding: 0 10px">                                'width'         => 400,
</span><span class="cx" style="display: block; padding: 0 10px">                                'height'        => 225,
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                'html'          => get_post_embed_html( 400, 225, $post ),
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         'html'          => $this->normalize_secret_attribute( get_post_embed_html( 400, 225, $post ) ),
</ins><span class="cx" style="display: block; padding: 0 10px">                         ),
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        $data
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 $this->normalize_secret_attribute( $data )
</ins><span class="cx" style="display: block; padding: 0 10px">                 );
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -72,9 +90,9 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                'type'          => 'rich',
</span><span class="cx" style="display: block; padding: 0 10px">                                'width'         => 400,
</span><span class="cx" style="display: block; padding: 0 10px">                                'height'        => 225,
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                'html'          => get_post_embed_html( 400, 225, $post ),
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         'html'          => $this->normalize_secret_attribute( get_post_embed_html( 400, 225, $post ) ),
</ins><span class="cx" style="display: block; padding: 0 10px">                         ),
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        $data
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 $this->normalize_secret_attribute( $data )
</ins><span class="cx" style="display: block; padding: 0 10px">                 );
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span></span></pre></div>
<a id="trunktestsphpunittestsoembedtemplatephp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/tests/phpunit/tests/oembed/template.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tests/phpunit/tests/oembed/template.php     2021-11-10 21:09:30 UTC (rev 52131)
+++ trunk/tests/phpunit/tests/oembed/template.php       2021-11-11 02:47:10 UTC (rev 52132)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -4,6 +4,21 @@
</span><span class="cx" style="display: block; padding: 0 10px">  * @group oembed
</span><span class="cx" style="display: block; padding: 0 10px">  */
</span><span class="cx" style="display: block; padding: 0 10px"> class Tests_Embed_Template extends WP_UnitTestCase {
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+       public function set_up() {
+               parent::set_up();
+
+               global $wp_scripts;
+               $wp_scripts = null;
+       }
+
+       public function tear_down() {
+               parent::tear_down();
+
+               global $wp_scripts;
+               $wp_scripts = null;
+       }
+
</ins><span class="cx" style="display: block; padding: 0 10px">         public function test_oembed_output_post() {
</span><span class="cx" style="display: block; padding: 0 10px">                $user = self::factory()->user->create_and_get(
</span><span class="cx" style="display: block; padding: 0 10px">                        array(
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -281,17 +296,38 @@
</span><span class="cx" style="display: block; padding: 0 10px">                        )
</span><span class="cx" style="display: block; padding: 0 10px">                );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $expected = '<iframe sandbox="allow-scripts" security="restricted" src="' . esc_url( get_post_embed_url( $post_id ) ) . '" width="200" height="200" title="' . $title . '" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" class="wp-embedded-content"></iframe>';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $expected = '<iframe sandbox="allow-scripts" security="restricted" src="' . esc_url( get_post_embed_url( $post_id ) ) . '#?secret=__SECRET__" width="200" height="200" title="' . $title . '" data-secret=__SECRET__ frameborder="0" marginwidth="0" marginheight="0" scrolling="no" class="wp-embedded-content"></iframe>';
+               $actual   = get_post_embed_html( 200, 200, $post_id );
+               $actual   = preg_replace( '/secret=("?)\w+\1/', 'secret=__SECRET__', $actual );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $this->assertStringEndsWith( $expected, get_post_embed_html( 200, 200, $post_id ) );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $this->assertStringEndsWith( $expected, $actual );
</ins><span class="cx" style="display: block; padding: 0 10px">         }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+        /** @covers ::wp_oembed_add_host_js() */
</ins><span class="cx" style="display: block; padding: 0 10px">         public function test_add_host_js() {
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                remove_all_filters( 'embed_oembed_html' );
+
</ins><span class="cx" style="display: block; padding: 0 10px">                 wp_oembed_add_host_js();
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $this->assertTrue( wp_script_is( 'wp-embed' ) );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $this->assertEquals( 10, has_filter( 'embed_oembed_html', 'wp_maybe_enqueue_oembed_host_js' ) );
</ins><span class="cx" style="display: block; padding: 0 10px">         }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+        /** @covers ::wp_maybe_enqueue_oembed_host_js() */
+       function test_wp_maybe_enqueue_oembed_host_js() {
+               $scripts = wp_scripts();
+
+               $this->assertFalse( $scripts->query( 'wp-embed', 'enqueued' ) );
+
+               $post_embed     = '<blockquote class="wp-embedded-content" data-secret="S24AQCJW9i"><a href="https://make.wordpress.org/core/2016/03/11/embeds-changes-in-wordpress-4-5/">Embeds Changes in WordPress 4.5</a></blockquote><iframe class="wp-embedded-content" sandbox="allow-scripts" security="restricted" style="position: absolute; clip: rect(1px, 1px, 1px, 1px);" title="&#8220;Embeds Changes in WordPress 4.5&#8221; &#8212; Make WordPress Core" src="https://make.wordpress.org/core/2016/03/11/embeds-changes-in-wordpress-4-5/embed/#?secret=S24AQCJW9i" data-secret="S24AQCJW9i" width="600" height="338" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"></iframe>';
+               $non_post_embed = '<iframe title="Zoo Cares For 23 Tiny Pond Turtles" width="750" height="422" src="https://www.youtube.com/embed/6ZXHqUjL6f8?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>';
+
+               wp_maybe_enqueue_oembed_host_js( $non_post_embed );
+               $this->assertFalse( $scripts->query( 'wp-embed', 'enqueued' ) );
+
+               wp_maybe_enqueue_oembed_host_js( $post_embed );
+               $this->assertTrue( $scripts->query( 'wp-embed', 'enqueued' ) );
+       }
+
</ins><span class="cx" style="display: block; padding: 0 10px">         /**
</span><span class="cx" style="display: block; padding: 0 10px">         * Confirms that no ampersands exist in src/wp-includes/js/wp-embed.js.
</span><span class="cx" style="display: block; padding: 0 10px">         *
</span></span></pre>
</div>
</div>

</body>
</html>