From 96c64cd42d321841826261ff32fd0928bc35caef Mon Sep 17 00:00:00 2001 From: Felix Arntz Date: Fri, 7 Jul 2023 18:06:49 +0000 Subject: [PATCH] Media: Avoid programmatically created images within post content from incorrectly receiving `fetchpriority="high"`. Follow-up to [56037], as that changeset accidentally did not consider the changes made in [55825]: Images that are programmatically injected into post content (e.g. through a block, or shortcode, or any hook calling a function like `wp_get_attachment_image()`) must be treated as part of the whole post content blob since otherwise the heuristics for applying `fetchpriority="high"` and `loading="lazy"` are skewed by parsing certain images before others rather than sequentially parsing the entire post content. [55825] addressed that for lazy-loading, but when [56037] introduced `fetchpriority` support, the related refactor missed making the same consideration for that attribute. Props flixos90, spacedmonkey, thekt12, mukesh27. Fixes #58235. See #58089. git-svn-id: https://develop.svn.wordpress.org/trunk@56164 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/media.php | 7 +++--- tests/phpunit/tests/media.php | 45 ++++++++++++++++++----------------- 2 files changed, 27 insertions(+), 25 deletions(-) diff --git a/src/wp-includes/media.php b/src/wp-includes/media.php index f8b0f9c1b1..234a826447 100644 --- a/src/wp-includes/media.php +++ b/src/wp-includes/media.php @@ -5666,11 +5666,12 @@ function wp_get_loading_optimization_attributes( $tag_name, $attr, $context ) { /* * Skip programmatically created images within post content as they need to be handled together with the other * images within the post content. - * Without this clause, they would already be counted below which skews the number and can result in the first - * post content image being lazy-loaded only because there are images elsewhere in the post content. + * Without this clause, they would already be considered below which skews the image count and can result in + * the first post content image being lazy-loaded or an image further down the page being marked as a high + * priority. */ if ( doing_filter( 'the_content' ) ) { - return $postprocess( $loading_attrs, true ); + return $loading_attrs; } // Conditionally skip lazy-loading on images before the loop. diff --git a/tests/phpunit/tests/media.php b/tests/phpunit/tests/media.php index b0cd913275..30d8a5f343 100644 --- a/tests/phpunit/tests/media.php +++ b/tests/phpunit/tests/media.php @@ -4134,31 +4134,32 @@ EOF; * @covers ::wp_filter_content_tags * @covers ::wp_get_loading_optimization_attributes */ - public function test_wp_filter_content_tags_does_not_lazy_load_special_images_within_the_content() { + public function test_wp_filter_content_tags_does_not_apply_loading_optimization_to_special_images_within_the_content() { global $wp_query, $wp_the_query; - // Force no lazy-loading on the image tag expected in the content. - $expected_content = wpautop( - wp_get_attachment_image( - self::$large_id, - 'large', - false, - array( - 'loading' => false, - 'fetchpriority' => 'high', - ) + // Force no lazy-loading or fetchpriority on the image tag expected in the content. + $expected_image = wp_get_attachment_image( + self::$large_id, + 'large', + false, + array( + 'loading' => false, + 'fetchpriority' => false, ) ); // Reset high priority flag as the forced `fetchpriority="high"` above already modified it. $this->reset_high_priority_element_flag(); + $image_within_content = ''; + // Overwrite post content with an image. add_filter( 'the_content', - static function() { + static function() use ( &$image_within_content ) { // Replace content with an image tag, i.e. the 'wp_get_attachment_image' context is used while running 'the_content' filter. - return wp_get_attachment_image( self::$large_id, 'large', false ); + $image_within_content = wp_get_attachment_image( self::$large_id, 'large', false ); + return $image_within_content; }, 9 // Run before wp_filter_content_tags(). ); @@ -4178,8 +4179,12 @@ EOF; $content = get_echo( 'the_content' ); } - // Ensure that parsed content has the image without lazy-loading. - $this->assertSame( $expected_content, $content ); + // Ensure that parsed image within content does not receive any loading optimization attributes. + $this->assertSame( $expected_image, $image_within_content, 'Image with wp_get_attachment_image context within post content should not receive loading optimization attributes' ); + + // Ensure that parsed content has the image with fetchpriority as it is the first large image. + $expected_content = wpautop( str_replace( 'assertSame( $expected_content, $content, 'Post content with programmatically injected image is missing loading optimization attributes' ); } /** @@ -4503,7 +4508,7 @@ EOF; } /** - * Tests that wp_get_loading_optimization_attributes() returns false for special contexts when they're used within 'the_content' filter. + * Tests that wp_get_loading_optimization_attributes() does not modify any attributes for special contexts when they're used within 'the_content' filter. * * @ticket 58089 * @ticket 58235 @@ -4514,7 +4519,7 @@ EOF; * * @param string $context Context for the element for which the `loading` attribute value is requested. */ - public function test_wp_get_loading_optimization_attributes_should_return_false_for_special_contexts_within_the_content( $context ) { + public function test_wp_get_loading_optimization_attributes_should_not_modify_images_for_special_contexts_within_the_content( $context ) { remove_all_filters( 'the_content' ); $result = null; @@ -4528,11 +4533,7 @@ EOF; ); apply_filters( 'the_content', '' ); - $this->assertSame( - array( 'fetchpriority' => 'high' ), - $result, - 'First large image is loaded with high fetchpriority.' - ); + $this->assertSame( array(), $result ); } /**