diff --git a/src/wp-includes/media.php b/src/wp-includes/media.php index 11815e65fa..f8b0f9c1b1 100644 --- a/src/wp-includes/media.php +++ b/src/wp-includes/media.php @@ -5662,7 +5662,7 @@ function wp_get_loading_optimization_attributes( $tag_name, $attr, $context ) { } // Special handling for programmatically created image tags. - if ( 'the_post_thumbnail' === $context || 'wp_get_attachment_image' === $context ) { + if ( 'the_post_thumbnail' === $context || 'wp_get_attachment_image' === $context || 'widget_media_image' === $context ) { /* * Skip programmatically created images within post content as they need to be handled together with the other * images within the post content. diff --git a/src/wp-includes/widgets/class-wp-widget-media-image.php b/src/wp-includes/widgets/class-wp-widget-media-image.php index 77df8050d8..31a8bef16f 100644 --- a/src/wp-includes/widgets/class-wp-widget-media-image.php +++ b/src/wp-includes/widgets/class-wp-widget-media-image.php @@ -239,14 +239,31 @@ class WP_Widget_Media_Image extends WP_Widget_Media { $instance['height'] = ''; } - $image = sprintf( - '%3$s', - esc_attr( $classes ), - esc_url( $instance['url'] ), - esc_attr( $instance['alt'] ), - esc_attr( $instance['width'] ), - esc_attr( $instance['height'] ) + $attr = array( + 'class' => $classes, + 'src' => $instance['url'], + 'alt' => $instance['alt'], + 'width' => $instance['width'], + 'height' => $instance['height'], + 'decoding' => 'async', ); + + $loading_optimization_attr = wp_get_loading_optimization_attributes( + 'img', + $attr, + 'widget_media_image' + ); + + $attr = array_merge( $attr, $loading_optimization_attr ); + + $attr = array_map( 'esc_attr', $attr ); + $image = ' $value ) { + $image .= ' ' . $name . '="' . $value . '"'; + } + + $image .= ' />'; } // End if(). $url = ''; diff --git a/tests/phpunit/tests/media.php b/tests/phpunit/tests/media.php index 41c1598a0e..b0cd913275 100644 --- a/tests/phpunit/tests/media.php +++ b/tests/phpunit/tests/media.php @@ -4191,7 +4191,7 @@ EOF; * * @expectedDeprecated wp_get_loading_attr_default * - * @dataProvider data_special_contexts_for_the_content + * @dataProvider data_special_contexts_for_the_content_wp_get_loading_attr_default * * @param string $context Context for the element for which the `loading` attribute value is requested. */ @@ -4208,7 +4208,7 @@ EOF; * * @expectedDeprecated wp_get_loading_attr_default * - * @dataProvider data_special_contexts_for_the_content + * @dataProvider data_special_contexts_for_the_content_wp_get_loading_attr_default * * @param string $context Context for the element for which the `loading` attribute value is requested. */ @@ -4233,6 +4233,19 @@ EOF; * @return array[] */ public function data_special_contexts_for_the_content() { + return array( + 'widget_media_image' => array( 'context' => 'widget_media_image' ), + 'the_post_thumbnail' => array( 'context' => 'the_post_thumbnail' ), + 'wp_get_attachment_image' => array( 'context' => 'wp_get_attachment_image' ), + ); + } + + /** + * Data provider. + * + * @return array[] + */ + public function data_special_contexts_for_the_content_wp_get_loading_attr_default() { return array( 'the_post_thumbnail' => array( 'context' => 'the_post_thumbnail' ), 'wp_get_attachment_image' => array( 'context' => 'wp_get_attachment_image' ), diff --git a/tests/phpunit/tests/widgets/wpWidgetMediaImage.php b/tests/phpunit/tests/widgets/wpWidgetMediaImage.php index 57ffc9a6aa..3f96cf34eb 100644 --- a/tests/phpunit/tests/widgets/wpWidgetMediaImage.php +++ b/tests/phpunit/tests/widgets/wpWidgetMediaImage.php @@ -494,6 +494,8 @@ class Tests_Widgets_wpWidgetMediaImage extends WP_UnitTestCase { // Custom image class. $this->assertStringContainsString( 'src="http://example.org/url/to/image.jpg"', $output ); + $this->assertStringContainsString( 'decoding="async"', $output ); + $this->assertStringContainsString( 'loading="lazy"', $output ); // Link settings. ob_start();