diff --git a/src/wp-includes/media.php b/src/wp-includes/media.php index ec70f5b2f6..720f91db2b 100644 --- a/src/wp-includes/media.php +++ b/src/wp-includes/media.php @@ -1495,6 +1495,7 @@ function wp_calculate_image_sizes( $size, $image_src = null, $image_meta = null, * Adds 'srcset' and 'sizes' attributes to an existing 'img' element. * * @since 4.4.0 + * @since 5.5.0 `width` and `height` are now added if not already present. * * @see wp_calculate_image_srcset() * @see wp_calculate_image_sizes() @@ -1525,6 +1526,8 @@ function wp_image_add_srcset_and_sizes( $image, $image_meta, $attachment_id ) { return $image; } + $attr = ''; + $width = preg_match( '/ width="([0-9]+)"/', $image, $match_width ) ? (int) $match_width[1] : 0; $height = preg_match( '/ height="([0-9]+)"/', $image, $match_height ) ? (int) $match_height[1] : 0; @@ -1547,10 +1550,13 @@ function wp_image_add_srcset_and_sizes( $image, $image_meta, $attachment_id ) { } } } - } - if ( ! $width || ! $height ) { - return $image; + if ( ! $width || ! $height ) { + return $image; + } + + // Add width and height if not present. + $attr .= ' ' . trim( image_hwstring( $width, $height ) ); } $size_array = array( $width, $height ); @@ -1567,17 +1573,19 @@ function wp_image_add_srcset_and_sizes( $image, $image_meta, $attachment_id ) { if ( $srcset && $sizes ) { // Format the 'srcset' and 'sizes' string and escape attributes. - $attr = sprintf( ' srcset="%s"', esc_attr( $srcset ) ); + $attr .= sprintf( ' srcset="%s"', esc_attr( $srcset ) ); if ( is_string( $sizes ) ) { $attr .= sprintf( ' sizes="%s"', esc_attr( $sizes ) ); } - - // Add 'srcset' and 'sizes' attributes to the image markup. - $image = preg_replace( '/]+?)[\/ ]*>/', '', $image ); } - return $image; + if ( empty( $attr ) ) { + return $image; + } + + // Add extra attributes to the image markup. + return preg_replace( '/]+?)[\/ ]*>/', '', $image ); } /** @@ -1714,6 +1722,12 @@ function wp_img_tag_add_loading_attr( $image, $context ) { $value = 'lazy'; } + // Images should have dimension attributes for the `loading` attribute + // to be added. + if ( false === strpos( $image, ' width=' ) || false === strpos( $image, ' height=' ) ) { + return $image; + } + $quote = null; // Check if the img tag is valid (has `src` attribute) and get the quote character. diff --git a/tests/phpunit/tests/media.php b/tests/phpunit/tests/media.php index 2b040d93ad..c21b5b115d 100644 --- a/tests/phpunit/tests/media.php +++ b/tests/phpunit/tests/media.php @@ -1963,6 +1963,7 @@ EOF; /** * @ticket 33641 + * @ticket 50367 */ function test_wp_filter_content_tags() { $image_meta = wp_get_attachment_metadata( self::$large_id ); @@ -1982,10 +1983,12 @@ EOF; $img_xhtml = str_replace( ' />', '/>', $img ); $img_html5 = str_replace( ' />', '>', $img ); + $hwstring = image_hwstring( $size_array[0], $size_array[1] ); + // Manually add srcset and sizes to the markup from get_image_tag(). $respimg = preg_replace( '|]+) />|', '', $img ); $respimg_no_size_in_class = preg_replace( '|]+) />|', '', $img_no_size_in_class ); - $respimg_no_width_height = preg_replace( '|]+) />|', '', $img_no_width_height ); + $respimg_no_width_height = preg_replace( '|]+) />|', '', $img_no_width_height ); $respimg_with_sizes_attr = preg_replace( '|]+) />|', '', $img_with_sizes_attr ); $respimg_xhtml = preg_replace( '|]+)/>|', '', $img_xhtml ); $respimg_html5 = preg_replace( '|]+)>|', '', $img_html5 ); @@ -1997,7 +2000,7 @@ EOF;

Image, no size class. Should have srcset and sizes.

%2$s -

Image, no width and height attributes. Should have srcset and sizes (from matching the file name).

+

Image, no width and height attributes. Should have width, height, srcset and sizes (from matching the file name).

%3$s

Image, no attachment ID class. Should NOT have srcset and sizes.

@@ -2530,12 +2533,18 @@ EOF; /** * @ticket 44427 + * @ticket 50367 */ function test_wp_lazy_load_content_media() { - $img = get_image_tag( self::$large_id, '', '', '', 'medium' ); - $img_xhtml = str_replace( ' />', '/>', $img ); - $img_html5 = str_replace( ' />', '>', $img ); - $iframe = ''; + $image_meta = wp_get_attachment_metadata( self::$large_id ); + $size_array = $this->_get_image_size_array_from_meta( $image_meta, 'medium' ); + + $img = get_image_tag( self::$large_id, '', '', '', 'medium' ); + $img_xhtml = str_replace( ' />', '/>', $img ); + $img_html5 = str_replace( ' />', '>', $img ); + $img_no_width_height = str_replace( ' width="' . $size_array[0] . '"', '', $img ); + $img_no_width_height = str_replace( ' height="' . $size_array[1] . '"', '', $img_no_width_height ); + $iframe = ''; $lazy_img = wp_img_tag_add_loading_attr( $img, 'test' ); $lazy_img_xhtml = wp_img_tag_add_loading_attr( $img_xhtml, 'test' ); @@ -2551,13 +2560,15 @@ EOF; %2$s

Image, HTML 5.0 style.

%3$s -

Image, with pre-existing "loading" attribute.

+

Image, with pre-existing "loading" attribute. Should not be modified.

+ %4$s +

Image, without dimension attributes. Should not be modified.

%5$s

Iframe, standard. Should not be modified.

- %4$s'; + %6$s'; - $content_unfiltered = sprintf( $content, $img, $img_xhtml, $img_html5, $iframe, $img_eager ); - $content_filtered = sprintf( $content, $lazy_img, $lazy_img_xhtml, $lazy_img_html5, $iframe, $img_eager ); + $content_unfiltered = sprintf( $content, $img, $img_xhtml, $img_html5, $img_eager, $img_no_width_height, $iframe ); + $content_filtered = sprintf( $content, $lazy_img, $lazy_img_xhtml, $lazy_img_html5, $img_eager, $img_no_width_height, $iframe ); // Do not add srcset and sizes. add_filter( 'wp_img_tag_add_srcset_and_sizes_attr', '__return_false' );