Skip to content

Commit 4d22998

Browse files
Merge pull request #1471 from WordPress/fix/1446-use-html-tag-processor-auto-sizes
Enhanced Responsive Images: Use more robust HTML Tag Processor for auto sizes injection
2 parents ab56ad0 + c5de91c commit 4d22998

File tree

2 files changed

+74
-8
lines changed

2 files changed

+74
-8
lines changed

plugins/auto-sizes/hooks.php

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,24 +57,33 @@ function auto_sizes_update_content_img_tag( $html ): string {
5757
$html = '';
5858
}
5959

60+
$processor = new WP_HTML_Tag_Processor( $html );
61+
62+
// Bail if there is no IMG tag.
63+
if ( ! $processor->next_tag( array( 'tag_name' => 'IMG' ) ) ) {
64+
return $html;
65+
}
66+
6067
// Bail early if the image is not lazy-loaded.
61-
if ( false === strpos( $html, 'loading="lazy"' ) ) {
68+
$value = $processor->get_attribute( 'loading' );
69+
if ( ! is_string( $value ) || 'lazy' !== strtolower( trim( $value, " \t\f\r\n" ) ) ) {
6270
return $html;
6371
}
6472

73+
$sizes = $processor->get_attribute( 'sizes' );
74+
6575
// Bail early if the image is not responsive.
66-
if ( 1 !== preg_match( '/sizes="([^"]+)"/', $html, $match ) ) {
76+
if ( ! is_string( $sizes ) ) {
6777
return $html;
6878
}
6979

7080
// Don't add 'auto' to the sizes attribute if it already exists.
71-
if ( auto_sizes_attribute_includes_valid_auto( $match[1] ) ) {
81+
if ( auto_sizes_attribute_includes_valid_auto( $sizes ) ) {
7282
return $html;
7383
}
7484

75-
$html = str_replace( 'sizes="', 'sizes="auto, ', $html );
76-
77-
return $html;
85+
$processor->set_attribute( 'sizes', "auto, $sizes" );
86+
return $processor->get_updated_html();
7887
}
7988
add_filter( 'wp_content_img_tag', 'auto_sizes_update_content_img_tag' );
8089

plugins/auto-sizes/tests/test-auto-sizes.php

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,6 @@ public function test_content_image_with_lazy_loading_has_auto_sizes(): void {
7171
// Force lazy loading attribute.
7272
add_filter( 'wp_img_tag_add_loading_attr', '__return_true' );
7373

74-
$image_tag = $this->get_image_tag( self::$image_id );
75-
7674
$this->assertStringContainsString(
7775
'sizes="auto, (max-width: 1024px) 100vw, 1024px"',
7876
wp_filter_content_tags( $this->get_image_tag( self::$image_id ) )
@@ -218,4 +216,63 @@ public function test_auto_sizes_render_generator(): void {
218216
$this->assertStringContainsString( 'generator', $tag );
219217
$this->assertStringContainsString( 'auto-sizes ' . IMAGE_AUTO_SIZES_VERSION, $tag );
220218
}
219+
220+
/**
221+
* @return array<string, mixed>
222+
*/
223+
public function data_provider_to_test_auto_sizes_update_content_img_tag(): array {
224+
return array(
225+
'expected_with_single_quoted_attributes' => array(
226+
'input' => "<img src='https://example.com/foo-300x225.jpg' srcset='https://example.com/foo-300x225.jpg 300w, https://example.com/foo-1024x768.jpg 1024w, https://example.com/foo-768x576.jpg 768w, https://example.com/foo-1536x1152.jpg 1536w, https://example.com/foo-2048x1536.jpg 2048w' sizes='(max-width: 650px) 100vw, 650px' loading='lazy'>",
227+
'expected' => "<img src='https://example.com/foo-300x225.jpg' srcset='https://example.com/foo-300x225.jpg 300w, https://example.com/foo-1024x768.jpg 1024w, https://example.com/foo-768x576.jpg 768w, https://example.com/foo-1536x1152.jpg 1536w, https://example.com/foo-2048x1536.jpg 2048w' sizes=\"auto, (max-width: 650px) 100vw, 650px\" loading='lazy'>",
228+
),
229+
'expected_with_data_sizes_attribute' => array(
230+
'input' => '<img data-tshirt-sizes="S M L" src="https://example.com/foo-300x225.jpg" srcset="https://example.com/foo-300x225.jpg 300w, https://example.com/foo-1024x768.jpg 1024w, https://example.com/foo-768x576.jpg 768w, https://example.com/foo-1536x1152.jpg 1536w, https://example.com/foo-2048x1536.jpg 2048w" sizes="(max-width: 650px) 100vw, 650px" loading="lazy">',
231+
'expected' => '<img data-tshirt-sizes="S M L" src="https://example.com/foo-300x225.jpg" srcset="https://example.com/foo-300x225.jpg 300w, https://example.com/foo-1024x768.jpg 1024w, https://example.com/foo-768x576.jpg 768w, https://example.com/foo-1536x1152.jpg 1536w, https://example.com/foo-2048x1536.jpg 2048w" sizes="auto, (max-width: 650px) 100vw, 650px" loading="lazy">',
232+
),
233+
'expected_with_data_sizes_attribute_already_present' => array(
234+
'input' => '<img data-tshirt-sizes="S M L" src="https://example.com/foo-300x225.jpg" srcset="https://example.com/foo-300x225.jpg 300w, https://example.com/foo-1024x768.jpg 1024w, https://example.com/foo-768x576.jpg 768w, https://example.com/foo-1536x1152.jpg 1536w, https://example.com/foo-2048x1536.jpg 2048w" sizes="AUTO, (max-width: 650px) 100vw, 650px" loading="lazy">',
235+
'expected' => '<img data-tshirt-sizes="S M L" src="https://example.com/foo-300x225.jpg" srcset="https://example.com/foo-300x225.jpg 300w, https://example.com/foo-1024x768.jpg 1024w, https://example.com/foo-768x576.jpg 768w, https://example.com/foo-1536x1152.jpg 1536w, https://example.com/foo-2048x1536.jpg 2048w" sizes="AUTO, (max-width: 650px) 100vw, 650px" loading="lazy">',
236+
),
237+
'not_expected_with_loading_lazy_in_attr_value' => array(
238+
'input' => '<img src="https://example.com/foo-300x225.jpg" srcset="https://example.com/foo-300x225.jpg 300w, https://example.com/foo-1024x768.jpg 1024w, https://example.com/foo-768x576.jpg 768w, https://example.com/foo-1536x1152.jpg 1536w, https://example.com/foo-2048x1536.jpg 2048w" sizes="(max-width: 650px) 100vw, 650px" alt=\'This is the LCP image and it should not get loading="lazy"!\'>',
239+
'expected' => '<img src="https://example.com/foo-300x225.jpg" srcset="https://example.com/foo-300x225.jpg 300w, https://example.com/foo-1024x768.jpg 1024w, https://example.com/foo-768x576.jpg 768w, https://example.com/foo-1536x1152.jpg 1536w, https://example.com/foo-2048x1536.jpg 2048w" sizes="(max-width: 650px) 100vw, 650px" alt=\'This is the LCP image and it should not get loading="lazy"!\'>',
240+
),
241+
'not_expected_with_data_loading_attribute_present' => array(
242+
'input' => '<img src="https://example.com/foo-300x225.jpg" srcset="https://example.com/foo-300x225.jpg 300w, https://example.com/foo-1024x768.jpg 1024w, https://example.com/foo-768x576.jpg 768w, https://example.com/foo-1536x1152.jpg 1536w, https://example.com/foo-2048x1536.jpg 2048w" sizes="(max-width: 650px) 100vw, 650px" data-removed-loading="lazy">',
243+
'expected' => '<img src="https://example.com/foo-300x225.jpg" srcset="https://example.com/foo-300x225.jpg 300w, https://example.com/foo-1024x768.jpg 1024w, https://example.com/foo-768x576.jpg 768w, https://example.com/foo-1536x1152.jpg 1536w, https://example.com/foo-2048x1536.jpg 2048w" sizes="(max-width: 650px) 100vw, 650px" data-removed-loading="lazy">',
244+
),
245+
'expected_when_attributes_have_spaces_after_them' => array(
246+
'input' => '<img src = "https://example.com/foo-300x225.jpg" srcset = "https://example.com/foo-300x225.jpg 300w, https://example.com/foo-1024x768.jpg 1024w, https://example.com/foo-768x576.jpg 768w, https://example.com/foo-1536x1152.jpg 1536w, https://example.com/foo-2048x1536.jpg 2048w" sizes = "(max-width: 650px) 100vw, 650px" loading = "lazy">',
247+
'expected' => '<img src = "https://example.com/foo-300x225.jpg" srcset = "https://example.com/foo-300x225.jpg 300w, https://example.com/foo-1024x768.jpg 1024w, https://example.com/foo-768x576.jpg 768w, https://example.com/foo-1536x1152.jpg 1536w, https://example.com/foo-2048x1536.jpg 2048w" sizes="auto, (max-width: 650px) 100vw, 650px" loading = "lazy">',
248+
),
249+
'expected_when_attributes_are_upper_case' => array(
250+
'input' => '<IMG SRC="https://example.com/foo-300x225.jpg" SRCSET="https://example.com/foo-300x225.jpg 300w, https://example.com/foo-1024x768.jpg 1024w, https://example.com/foo-768x576.jpg 768w, https://example.com/foo-1536x1152.jpg 1536w, https://example.com/foo-2048x1536.jpg 2048w" SIZES="(max-width: 650px) 100vw, 650px" LOADING="LAZY">',
251+
'expected' => '<IMG SRC="https://example.com/foo-300x225.jpg" SRCSET="https://example.com/foo-300x225.jpg 300w, https://example.com/foo-1024x768.jpg 1024w, https://example.com/foo-768x576.jpg 768w, https://example.com/foo-1536x1152.jpg 1536w, https://example.com/foo-2048x1536.jpg 2048w" sizes="auto, (max-width: 650px) 100vw, 650px" LOADING="LAZY">',
252+
),
253+
'expected_when_loading_lazy_lacks_quotes' => array(
254+
'input' => '<img src="https://example.com/foo-300x225.jpg" srcset="https://example.com/foo-300x225.jpg 300w, https://example.com/foo-1024x768.jpg 1024w, https://example.com/foo-768x576.jpg 768w, https://example.com/foo-1536x1152.jpg 1536w, https://example.com/foo-2048x1536.jpg 2048w" sizes="(max-width: 650px) 100vw, 650px" loading=lazy>',
255+
'expected' => '<img src="https://example.com/foo-300x225.jpg" srcset="https://example.com/foo-300x225.jpg 300w, https://example.com/foo-1024x768.jpg 1024w, https://example.com/foo-768x576.jpg 768w, https://example.com/foo-1536x1152.jpg 1536w, https://example.com/foo-2048x1536.jpg 2048w" sizes="auto, (max-width: 650px) 100vw, 650px" loading=lazy>',
256+
),
257+
'expected_when_loading_lazy_has_whitespace' => array(
258+
'input' => '<img src="https://example.com/foo-300x225.jpg" srcset="https://example.com/foo-300x225.jpg 300w, https://example.com/foo-1024x768.jpg 1024w, https://example.com/foo-768x576.jpg 768w, https://example.com/foo-1536x1152.jpg 1536w, https://example.com/foo-2048x1536.jpg 2048w" sizes="(max-width: 650px) 100vw, 650px" loading=" lazy ">',
259+
'expected' => '<img src="https://example.com/foo-300x225.jpg" srcset="https://example.com/foo-300x225.jpg 300w, https://example.com/foo-1024x768.jpg 1024w, https://example.com/foo-768x576.jpg 768w, https://example.com/foo-1536x1152.jpg 1536w, https://example.com/foo-2048x1536.jpg 2048w" sizes="auto, (max-width: 650px) 100vw, 650px" loading=" lazy ">',
260+
),
261+
'not_expected_when_sizes_auto_lacks_quotes' => array(
262+
'input' => '<img src="https://example.com/foo-300x225.jpg" srcset="https://example.com/foo-300x225.jpg 300w, https://example.com/foo-1024x768.jpg 1024w, https://example.com/foo-768x576.jpg 768w, https://example.com/foo-1536x1152.jpg 1536w, https://example.com/foo-2048x1536.jpg 2048w" sizes=auto loading="lazy">',
263+
'expected' => '<img src="https://example.com/foo-300x225.jpg" srcset="https://example.com/foo-300x225.jpg 300w, https://example.com/foo-1024x768.jpg 1024w, https://example.com/foo-768x576.jpg 768w, https://example.com/foo-1536x1152.jpg 1536w, https://example.com/foo-2048x1536.jpg 2048w" sizes=auto loading="lazy">',
264+
),
265+
);
266+
}
267+
268+
/**
269+
* @covers ::auto_sizes_update_content_img_tag
270+
* @dataProvider data_provider_to_test_auto_sizes_update_content_img_tag
271+
*/
272+
public function test_auto_sizes_update_content_img_tag( string $input, string $expected ): void {
273+
$this->assertSame(
274+
$expected,
275+
auto_sizes_update_content_img_tag( $input )
276+
);
277+
}
221278
}

0 commit comments

Comments
 (0)