Skip to content

Commit

Permalink
Media: Add auto sizes for lazy-loaded images.
Browse files Browse the repository at this point in the history
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:
- https://html.spec.whatwg.org/multipage/images.html#sizes-attributes
- whatwg/html#8008

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

Built from https://develop.svn.wordpress.org/trunk@59008


git-svn-id: https://core.svn.wordpress.org/trunk@58404 1a063a9b-81f0-0310-95a4-ce76da25c4cd
  • Loading branch information
joemcgill committed Sep 11, 2024
1 parent 34c248a commit 0ad1b79
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 1 deletion.
66 changes: 66 additions & 0 deletions wp-includes/media.php
Original file line number Diff line number Diff line change
Expand Up @@ -1137,6 +1137,16 @@ function wp_get_attachment_image( $attachment_id, $size = 'thumbnail', $icon = f
}
}

// Adds 'auto' to the sizes attribute if applicable.
if (
isset( $attr['loading'] ) &&
'lazy' === $attr['loading'] &&
isset( $attr['sizes'] ) &&
! wp_sizes_attribute_includes_valid_auto( $attr['sizes'] )
) {
$attr['sizes'] = 'auto, ' . $attr['sizes'];
}

/**
* Filters the list of attachment image attributes.
*
Expand Down Expand Up @@ -1917,6 +1927,9 @@ function wp_filter_content_tags( $content, $context = null ) {
// Add loading optimization attributes if applicable.
$filtered_image = wp_img_tag_add_loading_optimization_attrs( $filtered_image, $context );

// Adds 'auto' to the sizes attribute if applicable.
$filtered_image = wp_img_tag_add_auto_sizes( $filtered_image );

/**
* Filters an img tag within the content for a given context.
*
Expand Down Expand Up @@ -1963,6 +1976,59 @@ function wp_filter_content_tags( $content, $context = null ) {
return $content;
}

/**
* Adds 'auto' to the sizes attribute to the image, if the image is lazy loaded and does not already include it.
*
* @since 6.7.0
*
* @param string $image The image tag markup being filtered.
* @return string The filtered image tag markup.
*/
function wp_img_tag_add_auto_sizes( string $image ): string {
$processor = new WP_HTML_Tag_Processor( $image );

// Bail if there is no IMG tag.
if ( ! $processor->next_tag( array( 'tag_name' => 'IMG' ) ) ) {
return $image;
}

// Bail early if the image is not lazy-loaded.
$value = $processor->get_attribute( 'loading' );
if ( ! is_string( $value ) || 'lazy' !== strtolower( trim( $value, " \t\f\r\n" ) ) ) {
return $image;
}

$sizes = $processor->get_attribute( 'sizes' );

// Bail early if the image is not responsive.
if ( ! is_string( $sizes ) ) {
return $image;
}

// Don't add 'auto' to the sizes attribute if it already exists.
if ( wp_sizes_attribute_includes_valid_auto( $sizes ) ) {
return $image;
}

$processor->set_attribute( 'sizes', "auto, $sizes" );
return $processor->get_updated_html();
}

/**
* Checks whether the given 'sizes' attribute includes the 'auto' keyword as the first item in the list.
*
* Per the HTML spec, if present it must be the first entry.
*
* @since 6.7.0
*
* @param string $sizes_attr The 'sizes' attribute value.
* @return bool True if the 'auto' keyword is present, false otherwise.
*/
function wp_sizes_attribute_includes_valid_auto( string $sizes_attr ): bool {
list( $first_size ) = explode( ',', $sizes_attr, 2 );
return 'auto' === strtolower( trim( $first_size, " \t\f\r\n" ) );
}

/**
* Adds optimization attributes to an `img` HTML tag.
*
Expand Down
2 changes: 1 addition & 1 deletion wp-includes/version.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
*
* @global string $wp_version
*/
$wp_version = '6.7-alpha-59003';
$wp_version = '6.7-alpha-59008';

/**
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.
Expand Down

0 comments on commit 0ad1b79

Please sign in to comment.