diff --git a/src/wp-includes/block-supports/dimensions.php b/src/wp-includes/block-supports/dimensions.php index aad482f31ff2f..381f7bc3fb8be 100644 --- a/src/wp-includes/block-supports/dimensions.php +++ b/src/wp-includes/block-supports/dimensions.php @@ -86,6 +86,25 @@ function wp_apply_dimensions_support( $block_type, $block_attributes ) { return $attributes; } +/** + * Checks whether an aspectRatio block-support value is explicitly set. + * + * @since 7.1.0 + * @access private + * + * @param mixed $aspect_ratio Aspect-ratio value. + * @return bool Whether the value is an explicit aspect ratio. + */ +function wp_is_explicit_aspect_ratio_value( $aspect_ratio ) { + if ( ! is_string( $aspect_ratio ) && ! is_numeric( $aspect_ratio ) ) { + return false; + } + + $aspect_ratio = strtolower( trim( (string) $aspect_ratio ) ); + + return '' !== $aspect_ratio && 'auto' !== $aspect_ratio; +} + /** * Renders server-side dimensions styles to the block wrapper. * This block support uses the `render_block` hook to ensure that @@ -113,11 +132,12 @@ function wp_render_dimensions_support( $block_content, $block ) { $dimensions_block_styles = array(); $dimensions_block_styles['aspectRatio'] = $block_attributes['style']['dimensions']['aspectRatio'] ?? null; - // To ensure the aspect ratio does not get overridden by `minHeight` unset any existing rule. + // To ensure the aspect ratio does not get overridden by `minHeight` or `height` unset any existing rule. if ( - isset( $dimensions_block_styles['aspectRatio'] ) + wp_is_explicit_aspect_ratio_value( $dimensions_block_styles['aspectRatio'] ) ) { $dimensions_block_styles['minHeight'] = 'unset'; + $dimensions_block_styles['height'] = 'unset'; } elseif ( isset( $block_attributes['style']['dimensions']['minHeight'] ) || isset( $block_attributes['minHeight'] ) @@ -149,7 +169,7 @@ function wp_render_dimensions_support( $block_content, $block ) { foreach ( explode( ' ', $styles['classnames'] ) as $class_name ) { if ( str_contains( $class_name, 'aspect-ratio' ) && - ! isset( $block_attributes['style']['dimensions']['aspectRatio'] ) + ! wp_is_explicit_aspect_ratio_value( $block_attributes['style']['dimensions']['aspectRatio'] ?? null ) ) { continue; } diff --git a/src/wp-includes/block-supports/states.php b/src/wp-includes/block-supports/states.php index 787a55b659814..d283dc2b4acf3 100644 --- a/src/wp-includes/block-supports/states.php +++ b/src/wp-includes/block-supports/states.php @@ -133,6 +133,56 @@ function wp_get_state_declarations_with_background_resets( $declarations ) { return $declarations; } +/** + * Adds fallback dimension styles for aspectRatio and height block-support values. + * + * @since 7.1.0 + * + * @param array $state_style State style object. + * @return array State style object with fallback dimension styles applied where needed. + */ +function wp_get_state_style_with_fallback_dimension_styles( $state_style ) { + if ( ! is_array( $state_style ) ) { + return $state_style; + } + + $dimensions = isset( $state_style['dimensions'] ) && is_array( $state_style['dimensions'] ) + ? $state_style['dimensions'] + : array(); + + if ( empty( $dimensions ) ) { + return $state_style; + } + + if ( wp_is_explicit_aspect_ratio_value( $dimensions['aspectRatio'] ?? null ) ) { + return array_replace_recursive( + $state_style, + array( + 'dimensions' => array( + 'minHeight' => 'unset', + 'height' => 'unset', + ), + ) + ); + } + + $has_min_height = isset( $dimensions['minHeight'] ) && ( is_string( $dimensions['minHeight'] ) || is_numeric( $dimensions['minHeight'] ) ) && '' !== trim( (string) $dimensions['minHeight'] ); + $has_height = isset( $dimensions['height'] ) && ( is_string( $dimensions['height'] ) || is_numeric( $dimensions['height'] ) ) && '' !== trim( (string) $dimensions['height'] ); + + if ( $has_min_height || $has_height ) { + return array_replace_recursive( + $state_style, + array( + 'dimensions' => array( + 'aspectRatio' => 'unset', + ), + ) + ); + } + + return $state_style; +} + /** * Adds a style fragment to a selector-keyed state style group. * @@ -267,8 +317,9 @@ function wp_get_block_state_style_rules( $state_styles, $block_type, $rules_grou } foreach ( wp_get_state_style_groups( $state_style, $block_selectors ) as $group ) { + $style = wp_get_state_style_with_fallback_dimension_styles( $group['style'] ); $compiled = wp_style_engine_get_styles( - wp_normalize_state_style_for_css_output( $group['style'] ) + wp_normalize_state_style_for_css_output( $style ) ); if ( ! empty( $compiled['declarations'] ) ) { @@ -490,8 +541,8 @@ function wp_render_block_states_support( $block_content, $block ) { */ $style_rules = array(); foreach ( $css_rules as $rule ) { - $declarations = array(); - foreach ( $rule['declarations'] as $property => $value ) { + $declarations = $rule['declarations']; + foreach ( $declarations as $property => $value ) { $declarations[ $property ] = is_string( $value ) && str_contains( $value, '!important' ) ? $value : $value . ' !important'; diff --git a/src/wp-includes/style-engine/class-wp-style-engine.php b/src/wp-includes/style-engine/class-wp-style-engine.php index be52699c642eb..ab29294576735 100644 --- a/src/wp-includes/style-engine/class-wp-style-engine.php +++ b/src/wp-includes/style-engine/class-wp-style-engine.php @@ -229,6 +229,12 @@ final class WP_Style_Engine { 'dimension' => '--wp--preset--dimension--$slug', ), ), + 'objectFit' => array( + 'property_keys' => array( + 'default' => 'object-fit', + ), + 'path' => array( 'dimensions', 'objectFit' ), + ), 'width' => array( 'property_keys' => array( 'default' => 'width', diff --git a/tests/phpunit/tests/block-supports/states.php b/tests/phpunit/tests/block-supports/states.php index 1d1e6da33408d..3c8fa6951d20d 100644 --- a/tests/phpunit/tests/block-supports/states.php +++ b/tests/phpunit/tests/block-supports/states.php @@ -223,6 +223,87 @@ public function test_no_background_reset_when_no_background_color() { $this->assertSame( $input, $actual ); } + /** + * Tests that fallback dimension styles are added for aspect ratio. + * + * @covers ::wp_get_state_style_with_fallback_dimension_styles + * + * @ticket 65239 + */ + public function test_adds_fallback_dimension_styles_for_aspect_ratio() { + $actual = wp_get_state_style_with_fallback_dimension_styles( + array( + 'dimensions' => array( + 'aspectRatio' => '16/9', + ), + ) + ); + + $this->assertSame( + array( + 'dimensions' => array( + 'aspectRatio' => '16/9', + 'minHeight' => 'unset', + 'height' => 'unset', + ), + ), + $actual + ); + } + + /** + * Tests that fallback dimension styles are not added for the default aspect ratio. + * + * @covers ::wp_get_state_style_with_fallback_dimension_styles + * + * @ticket 65239 + */ + public function test_does_not_add_fallback_dimension_styles_for_default_aspect_ratio() { + $actual = wp_get_state_style_with_fallback_dimension_styles( + array( + 'dimensions' => array( + 'aspectRatio' => 'auto', + ), + ) + ); + + $this->assertSame( + array( + 'dimensions' => array( + 'aspectRatio' => 'auto', + ), + ), + $actual + ); + } + + /** + * Tests that fallback aspectRatio styles are added for height. + * + * @covers ::wp_get_state_style_with_fallback_dimension_styles + * + * @ticket 65239 + */ + public function test_adds_fallback_aspect_ratio_style_for_height() { + $actual = wp_get_state_style_with_fallback_dimension_styles( + array( + 'dimensions' => array( + 'height' => '20rem', + ), + ) + ); + + $this->assertSame( + array( + 'dimensions' => array( + 'height' => '20rem', + 'aspectRatio' => 'unset', + ), + ), + $actual + ); + } + /** * Tests that modifier classes on the first compound selector are preserved * when state selectors are scoped to the block wrapper. diff --git a/tests/phpunit/tests/block-supports/wpRenderDimensionsSupport.php b/tests/phpunit/tests/block-supports/wpRenderDimensionsSupport.php index 3e2894c5538bf..7296ea4668b7b 100644 --- a/tests/phpunit/tests/block-supports/wpRenderDimensionsSupport.php +++ b/tests/phpunit/tests/block-supports/wpRenderDimensionsSupport.php @@ -121,7 +121,7 @@ public function test_dimensions_block_support( $theme_name, $block_name, $dimens */ public function data_dimensions_block_support() { return array( - 'aspect ratio style is applied, with min-height unset' => array( + 'aspect ratio style is applied, with min-height and height unset' => array( 'theme_name' => 'block-theme-child-with-fluid-typography', 'block_name' => 'test/dimensions-rules-are-output', 'dimensions_settings' => array( @@ -130,7 +130,7 @@ public function data_dimensions_block_support() { 'dimensions_style' => array( 'aspectRatio' => '16/9', ), - 'expected_wrapper' => '