diff --git a/plugins/auto-sizes/hooks.php b/plugins/auto-sizes/hooks.php index a3508c6d78..41b653e457 100644 --- a/plugins/auto-sizes/hooks.php +++ b/plugins/auto-sizes/hooks.php @@ -57,24 +57,33 @@ function auto_sizes_update_content_img_tag( $html ): string { $html = ''; } + $processor = new WP_HTML_Tag_Processor( $html ); + + // Bail if there is no IMG tag. + if ( ! $processor->next_tag( array( 'tag_name' => 'IMG' ) ) ) { + return $html; + } + // Bail early if the image is not lazy-loaded. - if ( false === strpos( $html, 'loading="lazy"' ) ) { + $value = $processor->get_attribute( 'loading' ); + if ( ! is_string( $value ) || 'lazy' !== strtolower( trim( $value, " \t\f\r\n" ) ) ) { return $html; } + $sizes = $processor->get_attribute( 'sizes' ); + // Bail early if the image is not responsive. - if ( 1 !== preg_match( '/sizes="([^"]+)"/', $html, $match ) ) { + if ( ! is_string( $sizes ) ) { return $html; } // Don't add 'auto' to the sizes attribute if it already exists. - if ( auto_sizes_attribute_includes_valid_auto( $match[1] ) ) { + if ( auto_sizes_attribute_includes_valid_auto( $sizes ) ) { return $html; } - $html = str_replace( 'sizes="', 'sizes="auto, ', $html ); - - return $html; + $processor->set_attribute( 'sizes', "auto, $sizes" ); + return $processor->get_updated_html(); } add_filter( 'wp_content_img_tag', 'auto_sizes_update_content_img_tag' ); diff --git a/plugins/auto-sizes/tests/test-auto-sizes.php b/plugins/auto-sizes/tests/test-auto-sizes.php index 037820331f..13898a4ae9 100644 --- a/plugins/auto-sizes/tests/test-auto-sizes.php +++ b/plugins/auto-sizes/tests/test-auto-sizes.php @@ -71,8 +71,6 @@ public function test_content_image_with_lazy_loading_has_auto_sizes(): void { // Force lazy loading attribute. add_filter( 'wp_img_tag_add_loading_attr', '__return_true' ); - $image_tag = $this->get_image_tag( self::$image_id ); - $this->assertStringContainsString( 'sizes="auto, (max-width: 1024px) 100vw, 1024px"', wp_filter_content_tags( $this->get_image_tag( self::$image_id ) ) @@ -218,4 +216,63 @@ public function test_auto_sizes_render_generator(): void { $this->assertStringContainsString( 'generator', $tag ); $this->assertStringContainsString( 'auto-sizes ' . IMAGE_AUTO_SIZES_VERSION, $tag ); } + + /** + * @return array + */ + public function data_provider_to_test_auto_sizes_update_content_img_tag(): array { + return array( + 'expected_with_single_quoted_attributes' => array( + 'input' => "", + 'expected' => "", + ), + 'expected_with_data_sizes_attribute' => array( + 'input' => '', + 'expected' => '', + ), + 'expected_with_data_sizes_attribute_already_present' => array( + 'input' => '', + 'expected' => '', + ), + 'not_expected_with_loading_lazy_in_attr_value' => array( + 'input' => '\'This', + 'expected' => '\'This', + ), + 'not_expected_with_data_loading_attribute_present' => array( + 'input' => '', + 'expected' => '', + ), + 'expected_when_attributes_have_spaces_after_them' => array( + 'input' => '', + 'expected' => '', + ), + 'expected_when_attributes_are_upper_case' => array( + 'input' => '', + 'expected' => '', + ), + 'expected_when_loading_lazy_lacks_quotes' => array( + 'input' => '', + 'expected' => '', + ), + 'expected_when_loading_lazy_has_whitespace' => array( + 'input' => '', + 'expected' => '', + ), + 'not_expected_when_sizes_auto_lacks_quotes' => array( + 'input' => '', + 'expected' => '', + ), + ); + } + + /** + * @covers ::auto_sizes_update_content_img_tag + * @dataProvider data_provider_to_test_auto_sizes_update_content_img_tag + */ + public function test_auto_sizes_update_content_img_tag( string $input, string $expected ): void { + $this->assertSame( + $expected, + auto_sizes_update_content_img_tag( $input ) + ); + } }