Make WordPress Core


Ignore:
Timestamp:
09/10/2024 11:59:54 PM (2 years ago)
Author:
joemcgill
Message:

Media: Add auto sizes for lazy-loaded images.

This implements the HTML spec for applying auto sizes to lazy-loaded images by prepending auto to the sizes attribute generated by WordPress if the image has a loading attribute set to lazy. For browser that support this HTML spec, the image's size value will be set to the concrete object size of the image. For browsers that don't support the spec, the word "auto" will be ignored when parsing the sizes value.

References:

Props mukesh27, flixos90, joemcgill, westonruter, peterwilsoncc.
Fixes #61847.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/media.php

    r58974 r59008  
    11381138                }
    11391139
     1140                // Adds 'auto' to the sizes attribute if applicable.
     1141                if (
     1142                        isset( $attr['loading'] ) &&
     1143                        'lazy' === $attr['loading'] &&
     1144                        isset( $attr['sizes'] ) &&
     1145                        ! wp_sizes_attribute_includes_valid_auto( $attr['sizes'] )
     1146                ) {
     1147                        $attr['sizes'] = 'auto, ' . $attr['sizes'];
     1148                }
     1149
    11401150                /**
    11411151                 * Filters the list of attachment image attributes.
     
    19181928                        $filtered_image = wp_img_tag_add_loading_optimization_attrs( $filtered_image, $context );
    19191929
     1930                        // Adds 'auto' to the sizes attribute if applicable.
     1931                        $filtered_image = wp_img_tag_add_auto_sizes( $filtered_image );
     1932
    19201933                        /**
    19211934                         * Filters an img tag within the content for a given context.
     
    19621975
    19631976        return $content;
     1977}
     1978
     1979/**
     1980 * Adds 'auto' to the sizes attribute to the image, if the image is lazy loaded and does not already include it.
     1981 *
     1982 * @since 6.7.0
     1983 *
     1984 * @param string $image The image tag markup being filtered.
     1985 * @return string The filtered image tag markup.
     1986 */
     1987function wp_img_tag_add_auto_sizes( string $image ): string {
     1988        $processor = new WP_HTML_Tag_Processor( $image );
     1989
     1990        // Bail if there is no IMG tag.
     1991        if ( ! $processor->next_tag( array( 'tag_name' => 'IMG' ) ) ) {
     1992                return $image;
     1993        }
     1994
     1995        // Bail early if the image is not lazy-loaded.
     1996        $value = $processor->get_attribute( 'loading' );
     1997        if ( ! is_string( $value ) || 'lazy' !== strtolower( trim( $value, " \t\f\r\n" ) ) ) {
     1998                return $image;
     1999        }
     2000
     2001        $sizes = $processor->get_attribute( 'sizes' );
     2002
     2003        // Bail early if the image is not responsive.
     2004        if ( ! is_string( $sizes ) ) {
     2005                return $image;
     2006        }
     2007
     2008        // Don't add 'auto' to the sizes attribute if it already exists.
     2009        if ( wp_sizes_attribute_includes_valid_auto( $sizes ) ) {
     2010                return $image;
     2011        }
     2012
     2013        $processor->set_attribute( 'sizes', "auto, $sizes" );
     2014        return $processor->get_updated_html();
     2015}
     2016
     2017/**
     2018 * Checks whether the given 'sizes' attribute includes the 'auto' keyword as the first item in the list.
     2019 *
     2020 * Per the HTML spec, if present it must be the first entry.
     2021 *
     2022 * @since 6.7.0
     2023 *
     2024 * @param string $sizes_attr The 'sizes' attribute value.
     2025 * @return bool True if the 'auto' keyword is present, false otherwise.
     2026 */
     2027function wp_sizes_attribute_includes_valid_auto( string $sizes_attr ): bool {
     2028        list( $first_size ) = explode( ',', $sizes_attr, 2 );
     2029        return 'auto' === strtolower( trim( $first_size, " \t\f\r\n" ) );
    19642030}
    19652031
Note: See TracChangeset for help on using the changeset viewer.