Skip to content

Commit 2ffca40

Browse files
committed
Media: Switch to enqueueing contain-intrinsic-size CSS fix for IMG tags having sizes=auto.
This deprecates the `wp_print_auto_sizes_contain_css_fix()` function running at `wp_head` priority 1, in favor of a `wp_enqueue_img_auto_sizes_contain_css_fix()` function which runs just before at `wp_head` priority 0. The latter function unhooks the former while also enqueueing an inline style to be printed with all other styles but up front to preserve the cascade. This eliminates directly printing the `STYLE` tag, which was a change done similarly before for the emoji styles. See #58775. For backwards compatibility, the CSS can still be prevented from being enqueued/printed via: remove_action( 'wp_head', 'wp_print_auto_sizes_contain_css_fix', 1 ); This change ensures that all styles are printed together using the correct API for emitting styles. Developed in #8954. Follow-up to [59435]. Props westonruter, sabernhardt, SirLouen, flixos90, joemcgill, SergeyBiryukov, superpoincare. See #62413. Fixes #62731. git-svn-id: https://develop.svn.wordpress.org/trunk@60910 602fd350-edb4-49c9-b593-d223f7449a82
1 parent 8c2ec29 commit 2ffca40

File tree

4 files changed

+159
-9
lines changed

4 files changed

+159
-9
lines changed

src/wp-includes/default-filters.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -628,7 +628,8 @@
628628
add_action( 'wp_default_styles', 'wp_default_styles' );
629629
add_filter( 'style_loader_src', 'wp_style_loader_src', 10, 2 );
630630

631-
add_action( 'wp_head', 'wp_print_auto_sizes_contain_css_fix', 1 );
631+
add_action( 'wp_head', 'wp_enqueue_img_auto_sizes_contain_css_fix', 0 ); // Must run before wp_print_auto_sizes_contain_css_fix().
632+
add_action( 'wp_head', 'wp_print_auto_sizes_contain_css_fix', 1 ); // Retained for backwards-compatibility. Unhooked by wp_enqueue_img_auto_sizes_contain_css_fix().
632633
add_action( 'wp_head', 'wp_maybe_inline_styles', 1 ); // Run for styles enqueued in <head>.
633634
add_action( 'wp_footer', 'wp_maybe_inline_styles', 1 ); // Run for late-loaded styles in the footer.
634635

src/wp-includes/deprecated.php

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6460,4 +6460,32 @@ function wp_add_editor_classic_theme_styles( $editor_settings ) {
64606460
array_unshift( $editor_settings['styles'], $classic_theme_styles_settings );
64616461

64626462
return $editor_settings;
6463-
}
6463+
}
6464+
6465+
/**
6466+
* Prints a CSS rule to fix potential visual issues with images using `sizes=auto`.
6467+
*
6468+
* This rule overrides the similar rule in the default user agent stylesheet, to avoid images that use e.g.
6469+
* `width: auto` or `width: fit-content` to appear smaller.
6470+
*
6471+
* @since 6.7.1
6472+
* @deprecated 6.9.0 Use wp_enqueue_img_auto_sizes_contain_css_fix() instead.
6473+
* @see wp_enqueue_img_auto_sizes_contain_css_fix()
6474+
*
6475+
* @see https://html.spec.whatwg.org/multipage/rendering.html#img-contain-size
6476+
* @see https://core.trac.wordpress.org/ticket/62413
6477+
* @see https://core.trac.wordpress.org/ticket/62731
6478+
*/
6479+
function wp_print_auto_sizes_contain_css_fix() {
6480+
_deprecated_function( __FUNCTION__, '6.9.0', 'wp_enqueue_img_auto_sizes_contain_css_fix' );
6481+
6482+
/** This filter is documented in wp-includes/media.php */
6483+
$add_auto_sizes = apply_filters( 'wp_img_tag_add_auto_sizes', true );
6484+
if ( ! $add_auto_sizes ) {
6485+
return;
6486+
}
6487+
6488+
?>
6489+
<style>img:is([sizes="auto" i], [sizes^="auto," i]) { contain-intrinsic-size: 3000px 1500px }</style>
6490+
<?php
6491+
}

src/wp-includes/media.php

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2081,25 +2081,37 @@ function wp_sizes_attribute_includes_valid_auto( string $sizes_attr ): bool {
20812081
}
20822082

20832083
/**
2084-
* Prints a CSS rule to fix potential visual issues with images using `sizes=auto`.
2084+
* Enqueues a CSS rule to fix potential visual issues with images using `sizes=auto`.
20852085
*
20862086
* This rule overrides the similar rule in the default user agent stylesheet, to avoid images that use e.g.
20872087
* `width: auto` or `width: fit-content` to appear smaller.
20882088
*
2089-
* @since 6.7.1
2089+
* @since 6.9.0
2090+
*
20902091
* @see https://html.spec.whatwg.org/multipage/rendering.html#img-contain-size
20912092
* @see https://core.trac.wordpress.org/ticket/62413
2093+
* @see https://core.trac.wordpress.org/ticket/62731
20922094
*/
2093-
function wp_print_auto_sizes_contain_css_fix() {
2095+
function wp_enqueue_img_auto_sizes_contain_css_fix(): void {
2096+
// Back-compat for plugins that disable functionality by unhooking this action.
2097+
$priority = has_action( 'wp_head', 'wp_print_auto_sizes_contain_css_fix' );
2098+
if ( false === $priority ) {
2099+
return;
2100+
}
2101+
remove_action( 'wp_head', 'wp_print_auto_sizes_contain_css_fix', $priority );
2102+
20942103
/** This filter is documented in wp-includes/media.php */
20952104
$add_auto_sizes = apply_filters( 'wp_img_tag_add_auto_sizes', true );
20962105
if ( ! $add_auto_sizes ) {
20972106
return;
20982107
}
20992108

2100-
?>
2101-
<style>img:is([sizes="auto" i], [sizes^="auto," i]) { contain-intrinsic-size: 3000px 1500px }</style>
2102-
<?php
2109+
$handle = 'wp-img-auto-sizes-contain';
2110+
wp_register_style( $handle, false );
2111+
wp_add_inline_style( $handle, 'img:is([sizes=auto i],[sizes^="auto," i]){contain-intrinsic-size:3000px 1500px}' );
2112+
2113+
// Make sure inline style is printed first since it was previously printed at wp_head priority 1 and this preserves the CSS cascade.
2114+
array_unshift( wp_styles()->queue, $handle );
21032115
}
21042116

21052117
/**

tests/phpunit/tests/media.php

Lines changed: 110 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ class Tests_Media extends WP_UnitTestCase {
2929
protected static $large_filename = 'test-image-large.jpg';
3030
protected static $post_ids;
3131

32+
/**
33+
* @var WP_Styles|null
34+
*/
35+
protected static $original_wp_styles;
36+
3237
public static function wpSetUpBeforeClass( WP_UnitTest_Factory $factory ) {
3338
self::$_sizes = wp_get_additional_image_sizes();
3439
$GLOBALS['_wp_additional_image_sizes'] = array();
@@ -66,6 +71,13 @@ public static function wpSetUpBeforeClass( WP_UnitTest_Factory $factory ) {
6671
wp_trash_post( self::$post_ids['trash'] );
6772
}
6873

74+
public function set_up(): void {
75+
global $wp_styles;
76+
self::$original_wp_styles = $wp_styles;
77+
$wp_styles = null;
78+
parent::set_up();
79+
}
80+
6981
public static function wpTearDownAfterClass() {
7082
$GLOBALS['_wp_additional_image_sizes'] = self::$_sizes;
7183
}
@@ -79,9 +91,11 @@ public static function tear_down_after_class() {
7991
* Ensures that the static content media count, fetchpriority element flag and related filter are reset between tests.
8092
*/
8193
public function tear_down() {
82-
global $_wp_current_template_id, $_wp_current_template_content;
94+
global $_wp_current_template_id, $_wp_current_template_content, $wp_styles;
8395
unset( $_wp_current_template_id, $_wp_current_template_content );
8496

97+
$wp_styles = self::$original_wp_styles;
98+
8599
parent::tear_down();
86100

87101
$this->reset_content_media_count();
@@ -6576,6 +6590,101 @@ public function data_image_with_existing_auto_sizes() {
65766590
);
65776591
}
65786592

6593+
/**
6594+
* Provides data to test wp_enqueue_img_auto_sizes_contain_css_fix().
6595+
*
6596+
* @return array<string, array>
6597+
*/
6598+
public function data_provider_data_provider_to_test_wp_enqueue_img_auto_sizes_contain_css_fix(): array {
6599+
return array(
6600+
'default' => array(
6601+
'set_up' => null,
6602+
'expected' => true,
6603+
),
6604+
'filtered_off' => array(
6605+
'set_up' => static function (): void {
6606+
add_filter( 'wp_img_tag_add_auto_sizes', '__return_false' );
6607+
},
6608+
'expected' => false,
6609+
),
6610+
'filtered_on' => array(
6611+
'set_up' => static function (): void {
6612+
add_filter( 'wp_img_tag_add_auto_sizes', '__return_false' );
6613+
add_filter( 'wp_img_tag_add_auto_sizes', '__return_true', 100 );
6614+
},
6615+
'expected' => true,
6616+
),
6617+
'deprecated_function_removed' => array(
6618+
'set_up' => static function (): void {
6619+
remove_action( 'wp_head', 'wp_print_auto_sizes_contain_css_fix', 1 );
6620+
},
6621+
'expected' => false,
6622+
),
6623+
'new_function_removed' => array(
6624+
'set_up' => static function (): void {
6625+
remove_action( 'wp_head', 'wp_enqueue_img_auto_sizes_contain_css_fix', 0 );
6626+
},
6627+
'expected' => false,
6628+
'expected_deprecated' => 'wp_print_auto_sizes_contain_css_fix',
6629+
),
6630+
'both_functions_removed' => array(
6631+
'set_up' => static function (): void {
6632+
remove_action( 'wp_head', 'wp_enqueue_img_auto_sizes_contain_css_fix', 0 );
6633+
remove_action( 'wp_head', 'wp_print_auto_sizes_contain_css_fix', 1 );
6634+
},
6635+
'expected' => false,
6636+
),
6637+
);
6638+
}
6639+
6640+
/**
6641+
* Tests that IMG auto-sizes CSS fix is enqueued (and printed) when expected.
6642+
*
6643+
* @covers ::wp_enqueue_img_auto_sizes_contain_css_fix
6644+
* @ticket 62731
6645+
*
6646+
* @dataProvider data_provider_data_provider_to_test_wp_enqueue_img_auto_sizes_contain_css_fix
6647+
*/
6648+
public function test_wp_enqueue_img_auto_sizes_contain_css_fix( ?Closure $set_up, bool $expected, ?string $expected_deprecated = null ): void {
6649+
if ( $set_up ) {
6650+
$set_up();
6651+
}
6652+
if ( isset( $expected_deprecated ) ) {
6653+
$this->setExpectedDeprecated( $expected_deprecated );
6654+
}
6655+
6656+
$this->assertCount( 0, wp_styles()->queue );
6657+
wp_enqueue_style( 'very-early-enqueued', home_url( '/very-early-enqueued.css' ) );
6658+
add_action(
6659+
'wp_enqueue_scripts',
6660+
static function () {
6661+
wp_enqueue_style( 'wp-block-library' );
6662+
}
6663+
);
6664+
6665+
$wp_head_output = get_echo( 'wp_head' );
6666+
$html_processor = new WP_HTML_Tag_Processor( $wp_head_output );
6667+
$found_style_text_content = null;
6668+
while ( $html_processor->next_tag( array( 'tag_name' => 'STYLE' ) ) ) {
6669+
if ( $html_processor->get_attribute( 'id' ) === 'wp-img-auto-sizes-contain-inline-css' ) {
6670+
$found_style_text_content = $html_processor->get_modifiable_text();
6671+
break;
6672+
}
6673+
}
6674+
6675+
$enqueued = wp_styles()->queue;
6676+
if ( $expected ) {
6677+
$this->assertSame( 'wp-img-auto-sizes-contain', array_shift( $enqueued ) );
6678+
$this->assertIsString( $found_style_text_content );
6679+
$this->assertStringContainsString( 'contain-intrinsic-size', $found_style_text_content );
6680+
} else {
6681+
$this->assertNull( $found_style_text_content );
6682+
}
6683+
$this->assertSame( 'very-early-enqueued', array_shift( $enqueued ) );
6684+
$this->assertContains( 'wp-emoji-styles', $enqueued );
6685+
$this->assertContains( 'wp-block-library', $enqueued );
6686+
}
6687+
65796688
/**
65806689
* Data provider for test_wp_img_tag_add_auto_sizes().
65816690
*

0 commit comments

Comments
 (0)