Make WordPress Core

Changeset 58143


Ignore:
Timestamp:
05/13/2024 10:37:38 PM (2 weeks ago)
Author:
westonruter
Message:

Embeds: Enable lazy-loading of post embeds and fix keyboard a11y for hidden iframes.

Chrome unreliably loads a lazy-loaded iframe when it is hidden using clip: rect(1px, 1px, 1px, 1px). Instead of using clip, a lazy-loaded iframe can also be hidden with visibility:hidden which results in it loading not only in Chrome but all other browsers. With this change applied, the hard-coded check to prevent lazy-loading post embeds is now removed. An added benefit to using visibility:hidden is that the entire iframe in this case is not interactable, meaning that users navigating the document with the keyboard will not unexpectedly encounter tab stops inside of the hidden iframe, as can happen now with clip when the JS fails to reveal the loaded iframe. Note also that the clip property is deprecated.

Lastly, when such a post embed iframe is rendered in an RSS feed, the style attribute is now removed using the HTML Tag Processor as opposed to using string replacement.

Fixes #58773.
Props westonruter, joemcgill, swissspidy, joedolson, adamsilverstein.

Location:
trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/embed.php

    r58097 r58143  
    967967    if ( ! empty( $content[1] ) ) {
    968968        // We have a blockquote to fall back on. Hide the iframe by default.
    969         $html = str_replace( '<iframe', '<iframe style="position: absolute; clip: rect(1px, 1px, 1px, 1px);"', $html );
     969        $html = str_replace( '<iframe', '<iframe style="position: absolute; visibility: hidden;"', $html );
    970970        $html = str_replace( '<blockquote', '<blockquote class="wp-embedded-content"', $html );
    971971    }
     
    11001100 */
    11011101function _oembed_filter_feed_content( $content ) {
    1102     return str_replace( '<iframe class="wp-embedded-content" sandbox="allow-scripts" security="restricted" style="position: absolute; clip: rect(1px, 1px, 1px, 1px);"', '<iframe class="wp-embedded-content" sandbox="allow-scripts" security="restricted"', $content );
     1102    $p = new WP_HTML_Tag_Processor( $content );
     1103    while ( $p->next_tag( array( 'tag_name' => 'iframe' ) ) ) {
     1104        if ( $p->has_class( 'wp-embedded-content' ) ) {
     1105            $p->remove_attribute( 'style' );
     1106        }
     1107    }
     1108    return $p->get_updated_html();
    11031109}
    11041110
  • trunk/src/wp-includes/media.php

    r58110 r58143  
    21982198 */
    21992199function wp_iframe_tag_add_loading_attr( $iframe, $context ) {
    2200     /*
    2201      * Iframes with fallback content (see `wp_filter_oembed_result()`) should not be lazy-loaded because they are
    2202      * visually hidden initially.
    2203      */
    2204     if ( str_contains( $iframe, ' data-secret="' ) ) {
    2205         return $iframe;
    2206     }
    2207 
    22082200    /*
    22092201     * Get loading attribute value to use. This must occur before the conditional check below so that even iframes that
  • trunk/tests/phpunit/tests/media.php

    r57987 r58143  
    32583258    /**
    32593259     * @ticket 52768
    3260      */
    3261     public function test_wp_iframe_tag_add_loading_attr_skip_wp_embed() {
     3260     * @ticket 58773
     3261     */
     3262    public function test_wp_iframe_tag_add_loading_attr_include_wp_embed() {
    32623263        $iframe   = '<iframe src="https://www.example.com" width="640" height="360"></iframe>';
    32633264        $fallback = '<blockquote>Fallback content.</blockquote>';
     
    32653266        $iframe   = wp_iframe_tag_add_loading_attr( $iframe, 'test' );
    32663267
    3267         $this->assertStringNotContainsString( ' loading=', $iframe );
     3268        $this->assertStringContainsString( ' loading="lazy"', $iframe );
    32683269    }
    32693270
  • trunk/tests/phpunit/tests/oembed/filterResult.php

    r57987 r58143  
    8484        $actual = wp_filter_oembed_result( $html, (object) array( 'type' => 'rich' ), '' );
    8585
    86         $this->assertSame( '<blockquote class="wp-embedded-content"></blockquote><iframe class="wp-embedded-content" sandbox="allow-scripts" security="restricted" style="position: absolute; clip: rect(1px, 1px, 1px, 1px);"></iframe>', $actual );
     86        $this->assertSame( '<blockquote class="wp-embedded-content"></blockquote><iframe class="wp-embedded-content" sandbox="allow-scripts" security="restricted" style="position: absolute; visibility: hidden;"></iframe>', $actual );
    8787    }
    8888
     
    9191        $actual = wp_filter_oembed_result( $html, (object) array( 'type' => 'rich' ), '' );
    9292
    93         $this->assertSame( '<blockquote class="wp-embedded-content"><a href=""></a></blockquote><iframe class="wp-embedded-content" sandbox="allow-scripts" security="restricted" style="position: absolute; clip: rect(1px, 1px, 1px, 1px);"></iframe>', $actual );
     93        $this->assertSame( '<blockquote class="wp-embedded-content"><a href=""></a></blockquote><iframe class="wp-embedded-content" sandbox="allow-scripts" security="restricted" style="position: absolute; visibility: hidden;"></iframe>', $actual );
    9494    }
    9595
     
    9898            array(
    9999                '<blockquote></blockquote><iframe title=""></iframe>',
    100                 '<blockquote class="wp-embedded-content"></blockquote><iframe class="wp-embedded-content" sandbox="allow-scripts" security="restricted" style="position: absolute; clip: rect(1px, 1px, 1px, 1px);" title="Hola"></iframe>',
     100                '<blockquote class="wp-embedded-content"></blockquote><iframe class="wp-embedded-content" sandbox="allow-scripts" security="restricted" style="position: absolute; visibility: hidden;" title="Hola"></iframe>',
    101101            ),
    102102            array(
    103103                '<blockquote class="foo" id="bar"><strong><a href="" target=""></a></strong></blockquote><iframe width=123></iframe>',
    104                 '<blockquote class="wp-embedded-content"><a href=""></a></blockquote><iframe class="wp-embedded-content" sandbox="allow-scripts" security="restricted" style="position: absolute; clip: rect(1px, 1px, 1px, 1px);" title="Hola" width="123"></iframe>',
     104                '<blockquote class="wp-embedded-content"><a href=""></a></blockquote><iframe class="wp-embedded-content" sandbox="allow-scripts" security="restricted" style="position: absolute; visibility: hidden;" title="Hola" width="123"></iframe>',
    105105            ),
    106106            array(
    107107                '<blockquote><iframe width="100"></iframe></blockquote><iframe stitle="aaaa"></iframe>',
    108                 '<blockquote class="wp-embedded-content"><iframe class="wp-embedded-content" sandbox="allow-scripts" security="restricted" style="position: absolute; clip: rect(1px, 1px, 1px, 1px);" title="Hola" width="100"></iframe></blockquote><iframe class="wp-embedded-content" sandbox="allow-scripts" security="restricted" style="position: absolute; clip: rect(1px, 1px, 1px, 1px);" title="Hola"></iframe>',
     108                '<blockquote class="wp-embedded-content"><iframe class="wp-embedded-content" sandbox="allow-scripts" security="restricted" style="position: absolute; visibility: hidden;" title="Hola" width="100"></iframe></blockquote><iframe class="wp-embedded-content" sandbox="allow-scripts" security="restricted" style="position: absolute; visibility: hidden;" title="Hola"></iframe>',
    109109            ),
    110110            array(
    111111                "<blockquote><iframe title=' width=\"'></iframe></blockquote><iframe title='' height=' title=' width=\"'' height='123'\"></iframe>",
    112                 '<blockquote class="wp-embedded-content"><iframe class="wp-embedded-content" sandbox="allow-scripts" security="restricted" style="position: absolute; clip: rect(1px, 1px, 1px, 1px);" title=" width=&quot;"></iframe></blockquote><iframe class="wp-embedded-content" sandbox="allow-scripts" security="restricted" style="position: absolute; clip: rect(1px, 1px, 1px, 1px);" title=" width=&quot;" height=\' title=\' width="\'\' height=\'123\'"></iframe>',
     112                '<blockquote class="wp-embedded-content"><iframe class="wp-embedded-content" sandbox="allow-scripts" security="restricted" style="position: absolute; visibility: hidden;" title=" width=&quot;"></iframe></blockquote><iframe class="wp-embedded-content" sandbox="allow-scripts" security="restricted" style="position: absolute; visibility: hidden;" title=" width=&quot;" height=\' title=\' width="\'\' height=\'123\'"></iframe>',
    113113            ),
    114114        );
     
    135135        $actual = _oembed_filter_feed_content( wp_filter_oembed_result( $html, (object) array( 'type' => 'rich' ), '' ) );
    136136
    137         $this->assertSame( '<blockquote class="wp-embedded-content"></blockquote><iframe class="wp-embedded-content" sandbox="allow-scripts" security="restricted"></iframe>', $actual );
     137        $this->assertSame( '<blockquote class="wp-embedded-content"></blockquote><iframe class="wp-embedded-content" sandbox="allow-scripts" security="restricted" ></iframe>', $actual );
    138138    }
    139139}
  • trunk/tests/phpunit/tests/oembed/template.php

    r57306 r58143  
    322322        $this->assertFalse( $scripts->query( 'wp-embed', 'enqueued' ) );
    323323
    324         $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>';
     324        $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; visibility: hidden;" 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>';
    325325        $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>';
    326326
     
    339339        $this->assertFalse( $scripts->query( 'wp-embed', 'enqueued' ) );
    340340
    341         $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>';
     341        $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; visibility: hidden;" 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>';
    342342
    343343        wp_maybe_enqueue_oembed_host_js( $post_embed );
Note: See TracChangeset for help on using the changeset viewer.