Make WordPress Core

Ticket #53232: 53232.6.diff

File 53232.6.diff, 16.3 KB (added by adamsilverstein, 3 years ago)
  • src/wp-includes/media.php

    diff --git src/wp-includes/media.php src/wp-includes/media.php
    index 2b46167afc..1ad96454c2 100644
    function wp_get_attachment_image( $attachment_id, $size = 'thumbnail', $icon = f 
    10771077                        }
    10781078                }
    10791079
     1080                $attr['decoding'] = 'async';
     1081
    10801082                /**
    10811083                 * Filters the list of attachment image attributes.
    10821084                 *
    function wp_filter_content_tags( $content, $context = null ) { 
    18541856                         */
    18551857                        $filtered_image = apply_filters( 'wp_content_img_tag', $filtered_image, $context, $attachment_id );
    18561858
     1859                        // Add 'decoding=async' attribute unless a 'decoding' attribute is already present.
     1860                        if ( false === strpos( $filtered_image, ' decoding=' ) ) {
     1861                                $filtered_image = wp_img_tag_add_decoding_async_attr( $filtered_image, $context );
     1862                        }
     1863
    18571864                        if ( $filtered_image !== $match[0] ) {
    18581865                                $content = str_replace( $match[0], $filtered_image, $content );
    18591866                        }
    function wp_img_tag_add_loading_attr( $image, $context ) { 
    19341941        return $image;
    19351942}
    19361943
     1944/**
     1945 * Add `decoding` attribute to an `img` HTML tag.
     1946 *
     1947 * The `decoding` attribute allows developers to indicate whether the
     1948 * browser can decode the image off the main thread (`async`), on the
     1949 * main thread (`sync`) or as determined by the browser (`auto`).
     1950 *
     1951 * By default WordPress adds `decoding="async"` to images but developers
     1952 * can use the {@see 'wp_img_tag_add_decoding_attr'} filter to modify this
     1953 * to remove the attribute or set it to another accepted value.
     1954 *
     1955 * @since 6.0.0
     1956 *
     1957 * @param string $image   The HTML `img` tag where the attribute should be added.
     1958 * @param string $context Additional context to pass to the filters.
     1959 * @return string Converted `img` tag with `decoding` attribute added.
     1960 */
     1961function wp_img_tag_add_decoding_async_attr( $image, $context ) {
     1962        /**
     1963         * Filters the `decoding` attribute value to add to an image. Default `async`.
     1964         *
     1965         * Returning `false` or an empty string will not add the attribute.
     1966         *
     1967         * @since 6.0.0
     1968         *
     1969         * @param string|bool $value The `decoding` attribute value. Returning a falsey value will result in
     1970         *                           the attribute being omitted for the image. Otherwise, it may be:
     1971         *                           'async' (default), 'sync', or 'auto'.
     1972         * @param string      $image The HTML `img` tag to be filtered.
     1973         * @param string      $context Additional context about how the function was called or where the img tag is.
     1974         */
     1975        $value = apply_filters( 'wp_img_tag_add_decoding_attr', 'async', $image, $context );
     1976        if ( in_array( $value, array( 'async', 'sync', 'auto' ), true ) ) {
     1977                $image = str_replace( '<img ', '<img decoding="' . esc_attr( $value ) . '" ', $image );
     1978        }
     1979
     1980        return $image;
     1981}
     1982
    19371983/**
    19381984 * Adds `width` and `height` attributes to an `img` HTML tag.
    19391985 *
  • src/wp-includes/pluggable.php

    diff --git src/wp-includes/pluggable.php src/wp-includes/pluggable.php
    index fdbfdea250..e13f05c2e5 100644
    if ( ! function_exists( 'get_avatar' ) ) : 
    26942694                        'force_display' => false,
    26952695                        'loading'       => null,
    26962696                        'extra_attr'    => '',
     2697                        'decoding'      => 'async'
    26972698                );
    26982699
    26992700                if ( wp_lazy_loading_enabled( 'img', 'get_avatar' ) ) {
    27002701                        $defaults['loading'] = wp_get_loading_attr_default( 'get_avatar' );
    27012702                }
    27022703
     2704                if ( isset( $args['decoding'] ) && in_array( $args['decoding'], array( 'async', 'sync', 'auto' ) ) && ! preg_match( '/\bdecoding\s*=/', $extra_attr ) ) {
     2705                        if ( ! empty( $extra_attr ) ) {
     2706                                $extra_attr .= ' ';
     2707                        }
     2708                        $extra_attr .= "decoding='{$args['decoding']}'";
     2709                }
     2710
    27032711                if ( empty( $args ) ) {
    27042712                        $args = array();
    27052713                }
    if ( ! function_exists( 'get_avatar' ) ) : 
    27812789                        $extra_attr .= "loading='{$loading}'";
    27822790                }
    27832791
     2792                if ( isset( $args['decoding'] ) && in_array( $args['decoding'], array( 'async', 'sync', 'auto' ) ) && ! preg_match( '/\bdecoding\s*=/', $extra_attr ) ) {
     2793                        if ( ! empty( $extra_attr ) ) {
     2794                                $extra_attr .= ' ';
     2795                        }
     2796                        $extra_attr .= "decoding='{$args['decoding']}'";
     2797                }
     2798
    27842799                $avatar = sprintf(
    27852800                        "<img alt='%s' src='%s' srcset='%s' class='%s' height='%d' width='%d' %s/>",
    27862801                        esc_attr( $args['alt'] ),
  • tests/phpunit/tests/avatar.php

    diff --git tests/phpunit/tests/avatar.php tests/phpunit/tests/avatar.php
    index 336ab611e2..026809b4a1 100644
    class Tests_Avatar extends WP_UnitTestCase { 
    169169
    170170        public function test_get_avatar() {
    171171                $img = get_avatar( 1 );
    172                 $this->assertSame( preg_match( "|^<img alt='[^']*' src='[^']*' srcset='[^']*' class='[^']*' height='[^']*' width='[^']*' loading='lazy'/>$|", $img ), 1 );
     172                $this->assertSame( preg_match( "|^<img alt='[^']*' src='[^']*' srcset='[^']*' class='[^']*' height='[^']*' width='[^']*' loading='lazy' decoding='async'/>$|", $img ), 1 );
    173173        }
    174174
    175175        public function test_get_avatar_size() {
  • tests/phpunit/tests/media.php

    diff --git tests/phpunit/tests/media.php tests/phpunit/tests/media.php
    index 8f3340aaf7..999858206d 100644
    EOF; 
    14741474        public function test_wp_get_attachment_image_defaults() {
    14751475                $image    = image_downsize( self::$large_id, 'thumbnail' );
    14761476                $expected = sprintf(
    1477                         '<img width="%1$d" height="%2$d" src="%3$s" class="attachment-thumbnail size-thumbnail" alt="" loading="lazy" />',
     1477                        '<img width="%1$d" height="%2$d" src="%3$s" class="attachment-thumbnail size-thumbnail" alt="" loading="lazy" decoding="async" />',
    14781478                        $image[1],
    14791479                        $image[2],
    14801480                        $image[0]
    EOF; 
    15121512
    15131513                $image    = image_downsize( self::$large_id, 'thumbnail' );
    15141514                $expected = sprintf(
    1515                         '<img width="%1$d" height="%2$d" src="%3$s" class="attachment-thumbnail size-thumbnail" alt="Some very clever alt text" loading="lazy" />',
     1515                        '<img width="%1$d" height="%2$d" src="%3$s" class="attachment-thumbnail size-thumbnail" alt="Some very clever alt text" loading="lazy" decoding="async" />',
    15161516                        $image[1],
    15171517                        $image[2],
    15181518                        $image[0]
    EOF; 
    22482248                        $respimg_xhtml,
    22492249                        $respimg_html5
    22502250                );
     2251                $content_filtered = wp_img_tag_add_decoding_async_attr( $content_filtered, 'the_content' );
    22512252
    22522253                // Do not add width, height, and loading.
    22532254                add_filter( 'wp_img_tag_add_width_and_height_attr', '__return_false' );
    EOF; 
    22732274        public function test_wp_filter_content_tags_srcset_sizes_wrong() {
    22742275                $img = get_image_tag( self::$large_id, '', '', '', 'medium' );
    22752276                $img = wp_img_tag_add_loading_attr( $img, 'test' );
     2277                $img = wp_img_tag_add_decoding_async_attr( $img, 'the_content' );
    22762278
    22772279                // Replace the src URL.
    22782280                $image_wrong_src = preg_replace( '|src="[^"]+"|', 'src="http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/foo.jpg"', $img );
    EOF; 
    22872289                // Generate HTML and add a dummy srcset attribute.
    22882290                $img = get_image_tag( self::$large_id, '', '', '', 'medium' );
    22892291                $img = wp_img_tag_add_loading_attr( $img, 'test' );
     2292                $img = wp_img_tag_add_decoding_async_attr( $img, 'the_content' );
    22902293                $img = preg_replace( '|<img ([^>]+) />|', '<img $1 ' . 'srcset="image2x.jpg 2x" />', $img );
    22912294
    22922295                // The content filter should return the image unchanged.
    EOF; 
    24612464                        $respimg_https,
    24622465                        $respimg_relative
    24632466                );
     2467                $expected = wp_img_tag_add_decoding_async_attr( $expected, 'the_content' );
    24642468
    24652469                $actual = wp_filter_content_tags( $unfiltered );
    24662470
    EOF; 
    26052609                        'src="' . $uploads_url . 'test-image-testsize-999x999.jpg" ' .
    26062610                        'class="attachment-testsize size-testsize" alt="" loading="lazy" ' .
    26072611                        'srcset="' . $uploads_url . 'test-image-testsize-999x999.jpg 999w, ' . $uploads_url . $basename . '-150x150.jpg 150w" ' .
    2608                         'sizes="(max-width: 999px) 100vw, 999px" />';
     2612                        'sizes="(max-width: 999px) 100vw, 999px" decoding="async" />';
    26092613
    26102614                $actual = wp_get_attachment_image( self::$large_id, 'testsize' );
    26112615
    EOF; 
    29102914                        %4$s';
    29112915
    29122916                $content_unfiltered = sprintf( $content, $img, $img_no_width_height, $img_no_width, $img_no_height );
    2913                 $content_filtered   = sprintf( $content, $img, $respimg_no_width_height, $img_no_width, $img_no_height );
     2917                $content_filtered   = wp_img_tag_add_decoding_async_attr( sprintf( $content, $img, $respimg_no_width_height, $img_no_width, $img_no_height ), 'the_content' );
    29142918
    29152919                // Do not add loading, srcset, and sizes.
    29162920                add_filter( 'wp_img_tag_add_loading_attr', '__return_false' );
    EOF; 
    29682972                        %8$s';
    29692973
    29702974                $content_unfiltered = sprintf( $content, $img, $img_xhtml, $img_html5, $img_eager, $img_no_width_height, $iframe, $iframe_eager, $iframe_no_width_height );
    2971                 $content_filtered   = sprintf( $content, $lazy_img, $lazy_img_xhtml, $lazy_img_html5, $img_eager, $img_no_width_height, $lazy_iframe, $iframe_eager, $iframe_no_width_height );
     2975                $content_filtered   = wp_img_tag_add_decoding_async_attr( sprintf( $content, $lazy_img, $lazy_img_xhtml, $lazy_img_html5, $img_eager, $img_no_width_height, $lazy_iframe, $iframe_eager, $iframe_no_width_height ), 'the_content' );
    29722976
    29732977                // Do not add width, height, srcset, and sizes.
    29742978                add_filter( 'wp_img_tag_add_width_and_height_attr', '__return_false' );
    EOF; 
    29973001                        %2$s';
    29983002
    29993003                $content_unfiltered = sprintf( $content, $img, $iframe );
    3000                 $content_filtered   = sprintf( $content, $lazy_img, $lazy_iframe );
     3004                $content_filtered   = sprintf( $content, wp_img_tag_add_decoding_async_attr( $lazy_img ), $lazy_iframe, 'the_content' );
    30013005
    30023006                // Do not add srcset and sizes while testing.
    30033007                add_filter( 'wp_img_tag_add_srcset_and_sizes_attr', '__return_false' );
    EOF; 
    30153019         * @ticket 50756
    30163020         */
    30173021        public function test_wp_filter_content_tags_loading_lazy_opted_out() {
    3018                 $img    = get_image_tag( self::$large_id, '', '', '', 'medium' );
     3022                $img    = wp_img_tag_add_decoding_async_attr( get_image_tag( self::$large_id, '', '', '', 'medium' ), 'the_content' );
    30193023                $iframe = '<iframe src="https://www.example.com" width="640" height="360"></iframe>';
    30203024
    30213025                $content = '
    EOF; 
    34793483
    34803484                // Following the threshold of 2, the first two content media elements should not be lazy-loaded.
    34813485                $content_unfiltered = $img1 . $iframe1 . $img2 . $img3 . $iframe2;
    3482                 $content_expected   = $img1 . $iframe1 . $lazy_img2 . $lazy_img3 . $lazy_iframe2;
     3486                $content_expected   = wp_img_tag_add_decoding_async_attr( $img1 . $iframe1 . $lazy_img2 . $lazy_img3 . $lazy_iframe2, 'the_content' );
    34833487
    34843488                $wp_query     = new WP_Query( array( 'post__in' => array( self::$post_ids['publish'] ) ) );
    34853489                $wp_the_query = $wp_query;
  • tests/phpunit/tests/media/getAdjacentImageLink.php

    diff --git tests/phpunit/tests/media/getAdjacentImageLink.php tests/phpunit/tests/media/getAdjacentImageLink.php
    index 735c0ff15c..1c4133d6e7 100644
    class Tests_Media_GetAdjacentImageLink extends WP_Test_Adjacent_Image_Link_TestC 
    3232                        'when has previous link'           => array(
    3333                                'current_attachment_index'  => 3,
    3434                                'expected_attachment_index' => 2,
    35                                 'expected'                  => '<a href=\'http://example.org/?attachment_id=%%ID%%\'><img width="1" height="1" src="http://example.org/wp-content/uploads/image2.jpg" class="attachment-thumbnail size-thumbnail" alt="" loading="lazy" /></a>',
     35                                'expected'                  => '<a href=\'http://example.org/?attachment_id=%%ID%%\'><img width="1" height="1" src="' . WP_CONTENT_URL . '/uploads/image2.jpg" class="attachment-thumbnail size-thumbnail" alt="" loading="lazy" decoding="async" /></a>',
    3636                        ),
    3737                        'with text when has previous link' => array(
    3838                                'current_attachment_index'  => 3,
    class Tests_Media_GetAdjacentImageLink extends WP_Test_Adjacent_Image_Link_TestC 
    4343                        'when has next link'               => array(
    4444                                'current_attachment_index'  => 4,
    4545                                'expected_attachment_index' => 5,
    46                                 'expected'                  => '<a href=\'http://example.org/?attachment_id=%%ID%%\'><img width="1" height="1" src="http://example.org/wp-content/uploads/image5.jpg" class="attachment-thumbnail size-thumbnail" alt="" loading="lazy" /></a>',
     46                                'expected'                  => '<a href=\'http://example.org/?attachment_id=%%ID%%\'><img width="1" height="1" src="' . WP_CONTENT_URL . '/uploads/image5.jpg" class="attachment-thumbnail size-thumbnail" alt="" loading="lazy" decoding="async" /></a>',
    4747                                'args'                      => array( 'prev' => false ),
    4848                        ),
    4949                        'with text when has next link'     => array(
  • tests/phpunit/tests/media/getNextImageLink.php

    diff --git tests/phpunit/tests/media/getNextImageLink.php tests/phpunit/tests/media/getNextImageLink.php
    index 86a843cbfc..88ee51a434 100644
    class Tests_Media_GetNextImageLink extends WP_Test_Adjacent_Image_Link_TestCase 
    3131                        'when has next link'           => array(
    3232                                'current_attachment_index'  => 4,
    3333                                'expected_attachment_index' => 5,
    34                                 'expected'                  => '<a href=\'http://example.org/?attachment_id=%%ID%%\'><img width="1" height="1" src="http://example.org/wp-content/uploads/image5.jpg" class="attachment-thumbnail size-thumbnail" alt="" loading="lazy" /></a>',
     34                                'expected'                  => '<a href=\'http://example.org/?attachment_id=%%ID%%\'><img width="1" height="1" src="' . WP_CONTENT_URL . '/uploads/image5.jpg" class="attachment-thumbnail size-thumbnail" alt="" loading="lazy" decoding="async" /></a>',
    3535                        ),
    3636                        'with text when has next link' => array(
    3737                                'current_attachment_index'  => 4,
  • tests/phpunit/tests/media/getPreviousImageLink.php

    diff --git tests/phpunit/tests/media/getPreviousImageLink.php tests/phpunit/tests/media/getPreviousImageLink.php
    index 2d2d511e4f..d0eba54295 100644
    class Tests_Media_GetPreviousImageLink extends WP_Test_Adjacent_Image_Link_TestC 
    3131                        'when has previous link'           => array(
    3232                                'current_attachment_index'  => 3,
    3333                                'expected_attachment_index' => 2,
    34                                 'expected'                  => '<a href=\'http://example.org/?attachment_id=%%ID%%\'><img width="1" height="1" src="http://example.org/wp-content/uploads/image2.jpg" class="attachment-thumbnail size-thumbnail" alt="" loading="lazy" /></a>',
     34                                'expected'                  => '<a href=\'http://example.org/?attachment_id=%%ID%%\'><img width="1" height="1" src="' . WP_CONTENT_URL . '/uploads/image2.jpg" class="attachment-thumbnail size-thumbnail" alt="" loading="lazy" decoding="async" /></a>',
    3535                        ),
    3636                        'with text when has previous link' => array(
    3737                                'current_attachment_index'  => 3,
  • tests/phpunit/tests/media/nextImageLink.php

    diff --git tests/phpunit/tests/media/nextImageLink.php tests/phpunit/tests/media/nextImageLink.php
    index 7799779fa8..f6da4605ca 100644
    class Tests_Media_NextImageLink extends WP_Test_Adjacent_Image_Link_TestCase { 
    3030                        'when has next link'           => array(
    3131                                'current_attachment_index'  => 4,
    3232                                'expected_attachment_index' => 5,
    33                                 'expected'                  => '<a href=\'http://example.org/?attachment_id=%%ID%%\'><img width="1" height="1" src="http://example.org/wp-content/uploads/image5.jpg" class="attachment-thumbnail size-thumbnail" alt="" loading="lazy" /></a>',
     33                                'expected'                  => '<a href=\'http://example.org/?attachment_id=%%ID%%\'><img width="1" height="1" src="' . WP_CONTENT_URL . '/uploads/image5.jpg" class="attachment-thumbnail size-thumbnail" alt="" loading="lazy" decoding="async" /></a>',
    3434                        ),
    3535                        'with text when has next link' => array(
    3636                                'current_attachment_index'  => 4,
  • tests/phpunit/tests/media/previousImageLink.php

    diff --git tests/phpunit/tests/media/previousImageLink.php tests/phpunit/tests/media/previousImageLink.php
    index 11d6583d6a..de422e0379 100644
    class Tests_Media_PreviousImageLink extends WP_Test_Adjacent_Image_Link_TestCase 
    3030                        'when has previous link'           => array(
    3131                                'current_attachment_index'  => 3,
    3232                                'expected_attachment_index' => 2,
    33                                 'expected'                  => '<a href=\'http://example.org/?attachment_id=%%ID%%\'><img width="1" height="1" src="http://example.org/wp-content/uploads/image2.jpg" class="attachment-thumbnail size-thumbnail" alt="" loading="lazy" /></a>',
     33                                'expected'                  => '<a href=\'http://example.org/?attachment_id=%%ID%%\'><img width="1" height="1" src="' . WP_CONTENT_URL . '/uploads/image2.jpg" class="attachment-thumbnail size-thumbnail" alt="" loading="lazy" decoding="async" /></a>',
    3434                        ),
    3535                        'with text when has previous link' => array(
    3636                                'current_attachment_index'  => 3,