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.

Built from https://develop.svn.wordpress.org/trunk@58143


git-svn-id: http://core.svn.wordpress.org/trunk@57608 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
Weston Ruter 2024-05-13 22:39:16 +00:00
parent 922c74ac70
commit 9702c2e265
3 changed files with 9 additions and 11 deletions

View File

@ -966,7 +966,7 @@ function wp_filter_oembed_result( $result, $data, $url ) {
if ( ! empty( $content[1] ) ) {
// We have a blockquote to fall back on. Hide the iframe by default.
$html = str_replace( '<iframe', '<iframe style="position: absolute; clip: rect(1px, 1px, 1px, 1px);"', $html );
$html = str_replace( '<iframe', '<iframe style="position: absolute; visibility: hidden;"', $html );
$html = str_replace( '<blockquote', '<blockquote class="wp-embedded-content"', $html );
}
@ -1099,7 +1099,13 @@ function print_embed_scripts() {
* @return string The filtered content.
*/
function _oembed_filter_feed_content( $content ) {
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 );
$p = new WP_HTML_Tag_Processor( $content );
while ( $p->next_tag( array( 'tag_name' => 'iframe' ) ) ) {
if ( $p->has_class( 'wp-embedded-content' ) ) {
$p->remove_attribute( 'style' );
}
}
return $p->get_updated_html();
}
/**

View File

@ -2197,14 +2197,6 @@ function wp_img_tag_add_srcset_and_sizes_attr( $image, $context, $attachment_id
* @return string Converted `iframe` tag with `loading` attribute added.
*/
function wp_iframe_tag_add_loading_attr( $iframe, $context ) {
/*
* Iframes with fallback content (see `wp_filter_oembed_result()`) should not be lazy-loaded because they are
* visually hidden initially.
*/
if ( str_contains( $iframe, ' data-secret="' ) ) {
return $iframe;
}
/*
* Get loading attribute value to use. This must occur before the conditional check below so that even iframes that
* are ineligible for being lazy-loaded are considered.

View File

@ -16,7 +16,7 @@
*
* @global string $wp_version
*/
$wp_version = '6.6-alpha-58142';
$wp_version = '6.6-alpha-58143';
/**
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.