diff -r 48c4eec2b7e6 -r 8c2e4d02f4ef wp/wp-includes/media.php
--- a/wp/wp-includes/media.php Fri Sep 05 18:40:08 2025 +0200
+++ b/wp/wp-includes/media.php Fri Sep 05 18:52:52 2025 +0200
@@ -6,6 +6,11 @@
* @subpackage Media
*/
+// Don't load directly.
+if ( ! defined( 'ABSPATH' ) ) {
+ die( '-1' );
+}
+
/**
* Retrieves additional image sizes.
*
@@ -288,7 +293,7 @@
* If true, image will be cropped to the specified dimensions using center positions.
* If an array, the image will be cropped using the array to specify the crop location:
*
- * @type string $0 The x crop position. Accepts 'left' 'center', or 'right'.
+ * @type string $0 The x crop position. Accepts 'left', 'center', or 'right'.
* @type string $1 The y crop position. Accepts 'top', 'center', or 'bottom'.
* }
*/
@@ -350,7 +355,7 @@
* If true, image will be cropped to the specified dimensions using center positions.
* If an array, the image will be cropped using the array to specify the crop location:
*
- * @type string $0 The x crop position. Accepts 'left' 'center', or 'right'.
+ * @type string $0 The x crop position. Accepts 'left', 'center', or 'right'.
* @type string $1 The y crop position. Accepts 'top', 'center', or 'bottom'.
* }
*/
@@ -530,7 +535,7 @@
* If true, image will be cropped to the specified dimensions using center positions.
* If an array, the image will be cropped using the array to specify the crop location:
*
- * @type string $0 The x crop position. Accepts 'left' 'center', or 'right'.
+ * @type string $0 The x crop position. Accepts 'left', 'center', or 'right'.
* @type string $1 The y crop position. Accepts 'top', 'center', or 'bottom'.
* }
* @return array|false Returned array matches parameters for `imagecopyresampled()`. False on failure.
@@ -684,7 +689,7 @@
* If true, image will be cropped to the specified dimensions using center positions.
* If an array, the image will be cropped using the array to specify the crop location:
*
- * @type string $0 The x crop position. Accepts 'left' 'center', or 'right'.
+ * @type string $0 The x crop position. Accepts 'left', 'center', or 'right'.
* @type string $1 The y crop position. Accepts 'top', 'center', or 'bottom'.
* }
* @return array|false Metadata array on success. False if no image was created.
@@ -1065,7 +1070,6 @@
list( $src, $width, $height ) = $image;
$attachment = get_post( $attachment_id );
- $hwstring = image_hwstring( $width, $height );
$size_class = $size;
if ( is_array( $size_class ) ) {
@@ -1085,15 +1089,14 @@
*
* @param string $context The context. Default 'wp_get_attachment_image'.
*/
- $context = apply_filters( 'wp_get_attachment_image_context', 'wp_get_attachment_image' );
- $attr = wp_parse_args( $attr, $default_attr );
-
- $loading_attr = $attr;
- $loading_attr['width'] = $width;
- $loading_attr['height'] = $height;
+ $context = apply_filters( 'wp_get_attachment_image_context', 'wp_get_attachment_image' );
+ $attr = wp_parse_args( $attr, $default_attr );
+ $attr['width'] = $width;
+ $attr['height'] = $height;
+
$loading_optimization_attr = wp_get_loading_optimization_attributes(
'img',
- $loading_attr,
+ $attr,
$context
);
@@ -1137,6 +1140,20 @@
}
}
+ /** This filter is documented in wp-includes/media.php */
+ $add_auto_sizes = apply_filters( 'wp_img_tag_add_auto_sizes', true );
+
+ // Adds 'auto' to the sizes attribute if applicable.
+ if (
+ $add_auto_sizes &&
+ 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.
*
@@ -1150,8 +1167,16 @@
*/
$attr = apply_filters( 'wp_get_attachment_image_attributes', $attr, $attachment, $size );
- $attr = array_map( 'esc_attr', $attr );
- $html = rtrim( " $value ) {
$html .= " $name=" . '"' . $value . '"';
@@ -1917,6 +1942,9 @@
// 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.
*
@@ -1964,6 +1992,103 @@
}
/**
+ * 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 {
+ /**
+ * Filters whether auto-sizes for lazy loaded images is enabled.
+ *
+ * @since 6.7.1
+ *
+ * @param boolean $enabled Whether auto-sizes for lazy loaded images is enabled.
+ */
+ if ( ! apply_filters( 'wp_img_tag_add_auto_sizes', true ) ) {
+ return $image;
+ }
+
+ $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.
+ $loading = $processor->get_attribute( 'loading' );
+ if ( ! is_string( $loading ) || 'lazy' !== strtolower( trim( $loading, " \t\f\r\n" ) ) ) {
+ return $image;
+ }
+
+ /*
+ * Bail early if the image doesn't have a width attribute.
+ * Per WordPress Core itself, lazy-loaded images should always have a width attribute.
+ * However, it is possible that lazy-loading could be added by a plugin, where we don't have that guarantee.
+ * As such, it still makes sense to ensure presence of a width attribute here in order to use `sizes=auto`.
+ */
+ $width = $processor->get_attribute( 'width' );
+ if ( ! is_string( $width ) || '' === $width ) {
+ 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" ) );
+}
+
+/**
+ * Prints a CSS rule to fix potential visual issues with images using `sizes=auto`.
+ *
+ * This rule overrides the similar rule in the default user agent stylesheet, to avoid images that use e.g.
+ * `width: auto` or `width: fit-content` to appear smaller.
+ *
+ * @since 6.7.1
+ * @see https://html.spec.whatwg.org/multipage/rendering.html#img-contain-size
+ * @see https://core.trac.wordpress.org/ticket/62413
+ */
+function wp_print_auto_sizes_contain_css_fix() {
+ /** This filter is documented in wp-includes/media.php */
+ $add_auto_sizes = apply_filters( 'wp_img_tag_add_auto_sizes', true );
+ if ( ! $add_auto_sizes ) {
+ return;
+ }
+
+ ?>
+
+ $src,
'width' => $width,
'height' => $height,
'loading' => $loading_val,
@@ -3224,6 +3351,7 @@
* WordPress mp3s in a post.
*
* @since 3.6.0
+ * @since 6.8.0 Added the 'muted' attribute.
*
* @param array $attr {
* Attributes of the audio shortcode.
@@ -3231,6 +3359,7 @@
* @type string $src URL to the source of the audio file. Default empty.
* @type string $loop The 'loop' attribute for the `