diff --git a/src/wp-includes/block-supports/typography.php b/src/wp-includes/block-supports/typography.php index e7d081c937ee4..6e7e093931623 100644 --- a/src/wp-includes/block-supports/typography.php +++ b/src/wp-includes/block-supports/typography.php @@ -498,19 +498,22 @@ function wp_get_computed_fluid_typography_value( $args = array() ) { * @since 6.2.0 Added 'settings.typography.fluid.minFontSize' support. * @since 6.3.0 Using layout.wideSize as max viewport width, and logarithmic scale factor to calculate minimum font scale. * @since 6.4.0 Added configurable min and max viewport width values to the typography.fluid theme.json schema. + * @since 6.6.0 Deprecated bool argument $should_use_fluid_typography. * - * @param array $preset { + * @param array $preset { * Required. fontSizes preset value as seen in theme.json. * * @type string $name Name of the font size preset. * @type string $slug Kebab-case, unique identifier for the font size preset. * @type string|int|float $size CSS font-size value, including units if applicable. * } - * @param bool $should_use_fluid_typography An override to switch fluid typography "on". Can be used for unit testing. - * Default is false. + * @param bool|array $settings Optional Theme JSON settings array that overrides any global theme settings. + * Default is false. * @return string|null Font-size value or null if a size is not passed in $preset. */ -function wp_get_typography_font_size_value( $preset, $should_use_fluid_typography = false ) { + + +function wp_get_typography_font_size_value( $preset, $settings = array() ) { if ( ! isset( $preset['size'] ) ) { return null; } @@ -523,25 +526,35 @@ function wp_get_typography_font_size_value( $preset, $should_use_fluid_typograph return $preset['size']; } - // Checks if fluid font sizes are activated. - $global_settings = wp_get_global_settings(); - $typography_settings = isset( $global_settings['typography'] ) ? $global_settings['typography'] : array(); - $layout_settings = isset( $global_settings['layout'] ) ? $global_settings['layout'] : array(); - - if ( - isset( $typography_settings['fluid'] ) && - ( true === $typography_settings['fluid'] || is_array( $typography_settings['fluid'] ) ) - ) { - $should_use_fluid_typography = true; + /* + * As a boolean (deprecated since 6.6), $settings acts as an override to switch fluid typography "on" (`true`) or "off" (`false`). + */ + if ( is_bool( $settings ) ) { + _deprecated_argument( __FUNCTION__, '6.6.0', __( '`boolean` type for second argument `$settings` is deprecated. Use `array()` instead.' ) ); + $settings = array( + 'typography' => array( + 'fluid' => $settings, + ), + ); } + // Fallback to global settings as default. + $global_settings = wp_get_global_settings(); + $settings = wp_parse_args( + $settings, + $global_settings + ); + + $typography_settings = isset( $settings['typography'] ) ? $settings['typography'] : array(); + $should_use_fluid_typography = ! empty( $typography_settings['fluid'] ); + if ( ! $should_use_fluid_typography ) { return $preset['size']; } - $fluid_settings = isset( $typography_settings['fluid'] ) && is_array( $typography_settings['fluid'] ) - ? $typography_settings['fluid'] - : array(); + // $typography_settings['fluid'] can be a bool or an array. Normalize to array. + $fluid_settings = is_array( $typography_settings['fluid'] ) ? $typography_settings['fluid'] : array(); + $layout_settings = isset( $settings['layout'] ) ? $settings['layout'] : array(); // Defaults. $default_maximum_viewport_width = '1600px'; diff --git a/src/wp-includes/class-wp-theme-json.php b/src/wp-includes/class-wp-theme-json.php index 39e3581c18765..d178fb4ff6c10 100644 --- a/src/wp-includes/class-wp-theme-json.php +++ b/src/wp-includes/class-wp-theme-json.php @@ -1822,6 +1822,7 @@ public static function scope_selector( $scope, $selector ) { * * * @since 5.9.0 + * @since 6.6.0 Passing $settings to the callbacks defined in static::PRESETS_METADATA. * * @param array $settings Settings to process. * @param array $preset_metadata One of the PRESETS_METADATA values. @@ -1848,7 +1849,7 @@ protected static function get_settings_values_by_slug( $settings, $preset_metada is_callable( $preset_metadata['value_func'] ) ) { $value_func = $preset_metadata['value_func']; - $value = call_user_func( $value_func, $preset ); + $value = call_user_func( $value_func, $preset, $settings ); } else { // If we don't have a value, then don't add it to the result. continue; @@ -2041,6 +2042,7 @@ protected static function flatten_tree( $tree, $prefix = '', $token = '--' ) { * @since 5.9.0 Added the `$settings` and `$properties` parameters. * @since 6.1.0 Added `$theme_json`, `$selector`, and `$use_root_padding` parameters. * @since 6.5.0 Output a `min-height: unset` rule when `aspect-ratio` is set. + * @since 6.6.0 Passing current theme JSON settings to wp_get_typography_font_size_value(). * * @param array $styles Styles to process. * @param array $settings Theme settings. @@ -2108,8 +2110,9 @@ protected static function compute_style_properties( $styles, $settings = array() * whether the incoming value can be converted to a fluid value. * Values that already have a clamp() function will not pass the test, * and therefore the original $value will be returned. + * Pass the current theme_json settings to override any global settings. */ - $value = wp_get_typography_font_size_value( array( 'size' => $value ) ); + $value = wp_get_typography_font_size_value( array( 'size' => $value ), $settings ); } if ( 'aspect-ratio' === $css_property ) { diff --git a/tests/phpunit/tests/block-supports/typography.php b/tests/phpunit/tests/block-supports/typography.php index 1eb29e14937ad..f31bb1aff3436 100644 --- a/tests/phpunit/tests/block-supports/typography.php +++ b/tests/phpunit/tests/block-supports/typography.php @@ -294,23 +294,24 @@ public function test_should_generate_classname_for_font_family() { * @ticket 56467 * @ticket 57065 * @ticket 58523 + * @ticket 61118 * * @covers ::wp_get_typography_font_size_value * * @dataProvider data_generate_font_size_preset_fixtures * - * @param array $font_size_preset { + * @param array $font_size_preset { * Required. fontSizes preset value as seen in theme.json. * * @type string $name Name of the font size preset. * @type string $slug Kebab-case unique identifier for the font size preset. * @type string $size CSS font-size value, including units where applicable. * } - * @param bool $should_use_fluid_typography An override to switch fluid typography "on". Can be used for unit testing. - * @param string $expected_output Expected output. + * @param bool $settings Theme JSON settings array that overrides any global theme settings. + * @param string $expected_output Expected output. */ - public function test_wp_get_typography_font_size_value( $font_size_preset, $should_use_fluid_typography, $expected_output ) { - $actual = wp_get_typography_font_size_value( $font_size_preset, $should_use_fluid_typography ); + public function test_wp_get_typography_font_size_value( $font_size_preset, $settings, $expected_output ) { + $actual = wp_get_typography_font_size_value( $font_size_preset, $settings ); $this->assertSame( $expected_output, $actual ); } @@ -323,291 +324,603 @@ public function test_wp_get_typography_font_size_value( $font_size_preset, $shou public function data_generate_font_size_preset_fixtures() { return array( 'returns value when fluid typography is deactivated' => array( - 'font_size_preset' => array( + 'font_size_preset' => array( 'size' => '28px', ), - 'should_use_fluid_typography' => false, - 'expected_output' => '28px', + 'settings' => null, + 'expected_output' => '28px', ), 'returns value where font size is 0' => array( - 'font_size_preset' => array( + 'font_size_preset' => array( 'size' => 0, ), - 'should_use_fluid_typography' => true, - 'expected_output' => 0, + 'settings' => array( + 'typography' => array( + 'fluid' => true, + ), + ), + 'expected_output' => 0, ), "returns value where font size is '0'" => array( - 'font_size_preset' => array( + 'font_size_preset' => array( 'size' => '0', ), - 'should_use_fluid_typography' => true, - 'expected_output' => '0', + 'settings' => array( + 'typography' => array( + 'fluid' => true, + ), + ), + 'expected_output' => '0', ), 'returns value where `size` is `null`' => array( - 'font_size_preset' => array( + 'font_size_preset' => array( 'size' => null, ), - 'should_use_fluid_typography' => false, - 'expected_output' => null, + 'settings' => null, + 'expected_output' => null, ), 'returns value when fluid is `false`' => array( - 'font_size_preset' => array( + 'font_size_preset' => array( 'size' => '28px', 'fluid' => false, ), - 'should_use_fluid_typography' => true, - 'expected_output' => '28px', + 'settings' => array( + 'typography' => array( + 'fluid' => false, + ), + ), + 'expected_output' => '28px', + ), + 'returns value when fluid is empty array' => array( + 'font_size' => array( + 'size' => '28px', + ), + 'settings' => array( + 'typography' => array( + 'fluid' => array(), + ), + ), + 'expected_output' => '28px', + ), + 'returns clamp value with minViewportWidth override' => array( + 'font_size' => array( + 'size' => '28px', + ), + 'settings' => array( + 'typography' => array( + 'fluid' => array( + 'minViewportWidth' => '500px', + ), + ), + ), + 'expected_output' => 'clamp(17.905px, 1.119rem + ((1vw - 5px) * 0.918), 28px)', + ), + 'returns clamp value with maxViewportWidth override' => array( + 'font_size' => array( + 'size' => '28px', + ), + 'settings' => array( + 'typography' => array( + 'fluid' => array( + 'maxViewportWidth' => '500px', + ), + ), + ), + 'expected_output' => 'clamp(17.905px, 1.119rem + ((1vw - 3.2px) * 5.608), 28px)', ), + 'returns clamp value with layout.wideSize override' => array( + 'font_size' => array( + 'size' => '28px', + ), + 'settings' => array( + 'typography' => array( + 'fluid' => true, + ), + 'layout' => array( + 'wideSize' => '500px', + ), + ), + 'expected_output' => 'clamp(17.905px, 1.119rem + ((1vw - 3.2px) * 5.608), 28px)', + ), 'returns already clamped value' => array( - 'font_size_preset' => array( + 'font_size_preset' => array( 'size' => 'clamp(21px, 1.313rem + ((1vw - 7.68px) * 2.524), 42px)', 'fluid' => false, ), - 'should_use_fluid_typography' => true, - 'expected_output' => 'clamp(21px, 1.313rem + ((1vw - 7.68px) * 2.524), 42px)', + 'settings' => array( + 'typography' => array( + 'fluid' => true, + ), + ), + 'expected_output' => 'clamp(21px, 1.313rem + ((1vw - 7.68px) * 2.524), 42px)', ), 'returns value with unsupported unit' => array( - 'font_size_preset' => array( + 'font_size_preset' => array( 'size' => '1000%', 'fluid' => false, ), - 'should_use_fluid_typography' => true, - 'expected_output' => '1000%', + 'settings' => array( + 'typography' => array( + 'fluid' => true, + ), + ), + 'expected_output' => '1000%', ), 'returns clamp value with rem min and max units' => array( - 'font_size_preset' => array( + 'font_size_preset' => array( 'size' => '1.75rem', ), - 'should_use_fluid_typography' => true, - 'expected_output' => 'clamp(1.119rem, 1.119rem + ((1vw - 0.2rem) * 0.789), 1.75rem)', + 'settings' => array( + 'typography' => array( + 'fluid' => true, + ), + ), + 'expected_output' => 'clamp(1.119rem, 1.119rem + ((1vw - 0.2rem) * 0.789), 1.75rem)', ), 'returns clamp value with em min and max units' => array( - 'font_size' => array( + 'font_size' => array( 'size' => '1.75em', ), - 'should_use_fluid_typography' => true, - 'expected_output' => 'clamp(1.119em, 1.119rem + ((1vw - 0.2em) * 0.789), 1.75em)', + 'settings' => array( + 'typography' => array( + 'fluid' => true, + ), + ), + 'expected_output' => 'clamp(1.119em, 1.119rem + ((1vw - 0.2em) * 0.789), 1.75em)', ), 'returns clamp value for floats' => array( - 'font_size' => array( + 'font_size' => array( 'size' => '70.175px', ), - 'should_use_fluid_typography' => true, - 'expected_output' => 'clamp(37.897px, 2.369rem + ((1vw - 3.2px) * 2.522), 70.175px)', + 'settings' => array( + 'typography' => array( + 'fluid' => true, + ), + ), + 'expected_output' => 'clamp(37.897px, 2.369rem + ((1vw - 3.2px) * 2.522), 70.175px)', ), 'coerces integer to `px` and returns clamp value' => array( - 'font_size_preset' => array( + 'font_size_preset' => array( 'size' => 33, ), - 'should_use_fluid_typography' => true, - 'expected_output' => 'clamp(20.515px, 1.282rem + ((1vw - 3.2px) * 0.975), 33px)', + 'settings' => array( + 'typography' => array( + 'fluid' => true, + ), + ), + 'expected_output' => 'clamp(20.515px, 1.282rem + ((1vw - 3.2px) * 0.975), 33px)', ), 'coerces float to `px` and returns clamp value' => array( - 'font_size_preset' => array( + 'font_size_preset' => array( 'size' => 70.175, ), - 'should_use_fluid_typography' => true, - 'expected_output' => 'clamp(37.897px, 2.369rem + ((1vw - 3.2px) * 2.522), 70.175px)', + 'settings' => array( + 'typography' => array( + 'fluid' => true, + ), + ), + 'expected_output' => 'clamp(37.897px, 2.369rem + ((1vw - 3.2px) * 2.522), 70.175px)', ), 'returns clamp value when `fluid` is empty array' => array( - 'font_size_preset' => array( + 'font_size_preset' => array( 'size' => '28px', 'fluid' => array(), ), - 'should_use_fluid_typography' => true, - 'expected_output' => 'clamp(17.905px, 1.119rem + ((1vw - 3.2px) * 0.789), 28px)', + 'settings' => array( + 'typography' => array( + 'fluid' => true, + ), + ), + 'expected_output' => 'clamp(17.905px, 1.119rem + ((1vw - 3.2px) * 0.789), 28px)', ), 'returns clamp value when `fluid` is `null`' => array( - 'font_size_preset' => array( + 'font_size_preset' => array( 'size' => '28px', 'fluid' => null, ), - 'should_use_fluid_typography' => true, - 'expected_output' => 'clamp(17.905px, 1.119rem + ((1vw - 3.2px) * 0.789), 28px)', + 'settings' => array( + 'typography' => array( + 'fluid' => true, + ), + ), + 'expected_output' => 'clamp(17.905px, 1.119rem + ((1vw - 3.2px) * 0.789), 28px)', ), 'returns clamp value where min and max fluid values defined' => array( - 'font_size' => array( + 'font_size' => array( 'size' => '80px', 'fluid' => array( 'min' => '70px', 'max' => '125px', ), ), - 'should_use_fluid_typography' => true, - 'expected_output' => 'clamp(70px, 4.375rem + ((1vw - 3.2px) * 4.297), 125px)', + 'settings' => array( + 'typography' => array( + 'fluid' => true, + ), + ), + 'expected_output' => 'clamp(70px, 4.375rem + ((1vw - 3.2px) * 4.297), 125px)', ), 'returns clamp value where max is equal to size' => array( - 'font_size' => array( + 'font_size' => array( 'size' => '7.8125rem', 'fluid' => array( 'min' => '4.375rem', 'max' => '7.8125rem', ), ), - 'should_use_fluid_typography' => true, - 'expected_output' => 'clamp(4.375rem, 4.375rem + ((1vw - 0.2rem) * 4.298), 7.8125rem)', + 'settings' => array( + 'typography' => array( + 'fluid' => true, + ), + ), + 'expected_output' => 'clamp(4.375rem, 4.375rem + ((1vw - 0.2rem) * 4.298), 7.8125rem)', ), 'returns clamp value if min font size is greater than max' => array( - 'font_size_preset' => array( + 'font_size_preset' => array( 'size' => '3rem', 'fluid' => array( 'min' => '5rem', 'max' => '32px', ), ), - 'should_use_fluid_typography' => true, - 'expected_output' => 'clamp(5rem, 5rem + ((1vw - 0.2rem) * -3.75), 32px)', + 'settings' => array( + 'typography' => array( + 'fluid' => true, + ), + ), + 'expected_output' => 'clamp(5rem, 5rem + ((1vw - 0.2rem) * -3.75), 32px)', ), 'returns value with invalid min/max fluid units' => array( - 'font_size_preset' => array( + 'font_size_preset' => array( 'size' => '10em', 'fluid' => array( 'min' => '20vw', 'max' => '50%', ), ), - 'should_use_fluid_typography' => true, - 'expected_output' => '10em', + 'settings' => array( + 'typography' => array( + 'fluid' => true, + ), + ), + 'expected_output' => '10em', ), 'returns value when size is < lower bounds and no fluid min/max set' => array( - 'font_size_preset' => array( + 'font_size_preset' => array( 'size' => '3px', ), - 'should_use_fluid_typography' => true, - 'expected_output' => '3px', + 'settings' => array( + 'typography' => array( + 'fluid' => true, + ), + ), + 'expected_output' => '3px', ), 'returns value when size is equal to lower bounds and no fluid min/max set' => array( - 'font_size' => array( + 'font_size' => array( 'size' => '14px', ), - 'should_use_fluid_typography' => true, - 'expected_output' => '14px', + 'settings' => array( + 'typography' => array( + 'fluid' => true, + ), + ), + 'expected_output' => '14px', ), 'returns clamp value with different min max units' => array( - 'font_size_preset' => array( + 'font_size_preset' => array( 'size' => '28px', 'fluid' => array( 'min' => '20px', 'max' => '50rem', ), ), - 'should_use_fluid_typography' => true, - 'expected_output' => 'clamp(20px, 1.25rem + ((1vw - 3.2px) * 60.938), 50rem)', + 'settings' => array( + 'typography' => array( + 'fluid' => true, + ), + ), + 'expected_output' => 'clamp(20px, 1.25rem + ((1vw - 3.2px) * 60.938), 50rem)', ), 'returns clamp value where no fluid max size is set' => array( - 'font_size_preset' => array( + 'font_size_preset' => array( 'size' => '50px', 'fluid' => array( 'min' => '2.6rem', ), ), - 'should_use_fluid_typography' => true, - 'expected_output' => 'clamp(2.6rem, 2.6rem + ((1vw - 0.2rem) * 0.656), 50px)', + 'settings' => array( + 'typography' => array( + 'fluid' => true, + ), + ), + 'expected_output' => 'clamp(2.6rem, 2.6rem + ((1vw - 0.2rem) * 0.656), 50px)', ), 'returns clamp value where no fluid min size is set' => array( - 'font_size_preset' => array( + 'font_size_preset' => array( 'size' => '28px', 'fluid' => array( 'max' => '80px', ), ), - 'should_use_fluid_typography' => true, - 'expected_output' => 'clamp(17.905px, 1.119rem + ((1vw - 3.2px) * 4.851), 80px)', + 'settings' => array( + 'typography' => array( + 'fluid' => true, + ), + ), + 'expected_output' => 'clamp(17.905px, 1.119rem + ((1vw - 3.2px) * 4.851), 80px)', ), 'should not apply lower bound test when fluid values are set' => array( - 'font_size_preset' => array( + 'font_size_preset' => array( 'size' => '1.5rem', 'fluid' => array( 'min' => '0.5rem', 'max' => '5rem', ), ), - 'should_use_fluid_typography' => true, - 'expected_output' => 'clamp(0.5rem, 0.5rem + ((1vw - 0.2rem) * 5.625), 5rem)', + 'settings' => array( + 'typography' => array( + 'fluid' => true, + ), + ), + 'expected_output' => 'clamp(0.5rem, 0.5rem + ((1vw - 0.2rem) * 5.625), 5rem)', ), 'should not apply lower bound test when only fluid min is set' => array( - 'font_size' => array( + 'font_size' => array( 'size' => '20px', 'fluid' => array( 'min' => '12px', ), ), - 'should_use_fluid_typography' => true, - 'expected_output' => 'clamp(12px, 0.75rem + ((1vw - 3.2px) * 0.625), 20px)', + 'settings' => array( + 'typography' => array( + 'fluid' => true, + ), + ), + 'expected_output' => 'clamp(12px, 0.75rem + ((1vw - 3.2px) * 0.625), 20px)', ), 'should not apply lower bound test when only fluid max is set' => array( - 'font_size' => array( + 'font_size' => array( 'size' => '0.875rem', 'fluid' => array( 'max' => '20rem', ), ), - 'should_use_fluid_typography' => true, - 'expected_output' => 'clamp(0.875rem, 0.875rem + ((1vw - 0.2rem) * 23.906), 20rem)', + 'settings' => array( + 'typography' => array( + 'fluid' => true, + ), + ), + 'expected_output' => 'clamp(0.875rem, 0.875rem + ((1vw - 0.2rem) * 23.906), 20rem)', ), 'returns clamp value when min and max font sizes are equal' => array( - 'font_size_preset' => array( + 'font_size_preset' => array( 'size' => '4rem', 'fluid' => array( 'min' => '30px', 'max' => '30px', ), ), - 'should_use_fluid_typography' => true, - 'expected_output' => 'clamp(30px, 1.875rem + ((1vw - 3.2px) * 1), 30px)', + 'settings' => array( + 'typography' => array( + 'fluid' => true, + ), + ), + 'expected_output' => 'clamp(30px, 1.875rem + ((1vw - 3.2px) * 1), 30px)', ), 'should apply scaled min font size for em values when custom min font size is not set' => array( - 'font_size' => array( + 'font_size' => array( 'size' => '12rem', ), - 'should_use_fluid_typography' => true, - 'expected_output' => 'clamp(5.174rem, 5.174rem + ((1vw - 0.2rem) * 8.533), 12rem)', + 'settings' => array( + 'typography' => array( + 'fluid' => true, + ), + ), + 'expected_output' => 'clamp(5.174rem, 5.174rem + ((1vw - 0.2rem) * 8.533), 12rem)', ), 'should apply scaled min font size for px values when custom min font size is not set' => array( - 'font_size' => array( + 'font_size' => array( 'size' => '200px', ), - 'should_use_fluid_typography' => true, - 'expected_output' => 'clamp(85.342px, 5.334rem + ((1vw - 3.2px) * 8.958), 200px)', + 'settings' => array( + 'typography' => array( + 'fluid' => true, + ), + ), + 'expected_output' => 'clamp(85.342px, 5.334rem + ((1vw - 3.2px) * 8.958), 200px)', ), 'should not apply scaled min font size for minimum font size when custom min font size is set' => array( - 'font_size' => array( + 'font_size' => array( 'size' => '200px', 'fluid' => array( 'min' => '100px', ), ), + 'settings' => array( + 'typography' => array( + 'fluid' => true, + ), + ), + 'expected_output' => 'clamp(100px, 6.25rem + ((1vw - 3.2px) * 7.813), 200px)', + ), + ); + } + + /** + * Tests backwards compatibility for deprecated second argument $should_use_fluid_typography. + * + * @ticket 61118 + * + * @covers ::wp_get_typography_font_size_value + * + * @expectedDeprecated wp_get_typography_font_size_value + * + * @dataProvider data_generate_font_size_preset_should_use_fluid_typography_deprecated_fixtures + * + * @param array $font_size { + * Required. A font size as represented in the fontSizes preset format as seen in theme.json. + * + * @type string $name Name of the font size preset. + * @type string $slug Kebab-case unique identifier for the font size preset. + * @type string $size CSS font-size value, including units where applicable. + * } + * @param bool $should_use_fluid_typography An override to switch fluid typography "on". Can be used for unit testing. + * @param string $expected_output Expected output of wp_get_typography_font_size_value(). + */ + public function test_wp_get_typography_font_size_value_should_use_fluid_typography_deprecated( $font_size, $should_use_fluid_typography, $expected_output ) { + $actual = wp_get_typography_font_size_value( $font_size, $should_use_fluid_typography ); + + $this->assertSame( $expected_output, $actual ); + } + + /** + * Data provider for test_wp_get_typography_font_size_value_should_use_fluid_typography_deprecated. + * + * @return array + */ + public function data_generate_font_size_preset_should_use_fluid_typography_deprecated_fixtures() { + return array( + 'returns value when fluid typography is deactivated' => array( + 'font_size' => array( + 'size' => '28px', + ), + 'should_use_fluid_typography' => false, + 'expected_output' => '28px', + ), + 'returns clamp value when fluid typography is activated' => array( + 'font_size' => array( + 'size' => '28px', + ), 'should_use_fluid_typography' => true, - 'expected_output' => 'clamp(100px, 6.25rem + ((1vw - 3.2px) * 7.813), 200px)', + 'expected_output' => 'clamp(17.905px, 1.119rem + ((1vw - 3.2px) * 0.789), 28px)', + ), + ); + } + + /** + * Tests that theme json settings passed to wp_get_typography_font_size_value + * override global theme settings. + * + * @ticket 61118 + * + * @covers ::wp_get_typography_font_size_value + * + * @dataProvider data_generate_should_override_theme_settings_fixtures + * + * @param array $font_size { + * Required. A font size as represented in the fontSizes preset format as seen in theme.json. + * + * @type string $name Name of the font size preset. + * @type string $slug Kebab-case unique identifier for the font size preset. + * @type string $size CSS font-size value, including units where applicable. + * } + * @param bool $settings Theme JSON settings array that overrides any global theme settings. + * @param string $expected_output Expected output of wp_get_typography_font_size_value(). + */ + public function test_should_override_theme_settings( $font_size, $settings, $expected_output ) { + switch_theme( 'block-theme-child-with-fluid-typography' ); + $actual = wp_get_typography_font_size_value( $font_size, $settings ); + + $this->assertSame( $expected_output, $actual ); + } + + /** + * Data provider for test_wp_get_typography_font_size_value_should_use_fluid_typography_deprecated. + * + * @return array + */ + public function data_generate_should_override_theme_settings_fixtures() { + return array( + 'returns clamp value when theme activates fluid typography' => array( + 'font_size' => array( + 'size' => '28px', + ), + 'settings' => null, + 'expected_output' => 'clamp(17.905px, 1.119rem + ((1vw - 3.2px) * 0.789), 28px)', + ), + 'returns value when settings argument deactivates fluid typography' => array( + 'font_size' => array( + 'size' => '28px', + ), + 'settings' => array( + 'typography' => array( + 'fluid' => false, + ), + ), + 'expected_output' => '28px', + ), + + 'returns clamp value when settings argument sets a fluid.minViewportWidth value' => array( + 'font_size' => array( + 'size' => '28px', + ), + 'settings' => array( + 'typography' => array( + 'fluid' => array( + 'minViewportWidth' => '500px', + ), + ), + ), + 'expected_output' => 'clamp(17.905px, 1.119rem + ((1vw - 5px) * 0.918), 28px)', + ), + + 'returns clamp value when settings argument sets a layout.wideSize value' => array( + 'font_size' => array( + 'size' => '28px', + ), + 'settings' => array( + 'layout' => array( + 'wideSize' => '500px', + ), + ), + 'expected_output' => 'clamp(17.905px, 1.119rem + ((1vw - 3.2px) * 5.608), 28px)', + ), + + 'returns clamp value with maxViewportWidth preferred over fallback layout.wideSize value' => array( + 'font_size' => array( + 'size' => '28px', + ), + 'settings' => array( + 'typography' => array( + 'fluid' => array( + 'maxViewportWidth' => '1000px', + ), + ), + 'layout' => array( + 'wideSize' => '500px', + ), + ), + 'expected_output' => 'clamp(17.905px, 1.119rem + ((1vw - 3.2px) * 1.485), 28px)', ), ); } diff --git a/tests/phpunit/tests/theme/wpThemeJson.php b/tests/phpunit/tests/theme/wpThemeJson.php index 8a64925cdcd7e..572c74cb1b403 100644 --- a/tests/phpunit/tests/theme/wpThemeJson.php +++ b/tests/phpunit/tests/theme/wpThemeJson.php @@ -1417,6 +1417,70 @@ public function test_get_stylesheet_custom_root_selector() { ); } + /* + * Tests that settings passed to WP_Theme_JSON override merged theme data. + * + * @ticket 61118 + */ + public function test_get_stylesheet_generates_fluid_typography_values() { + register_block_type( + 'test/clamp-me', + array( + 'api_version' => 3, + ) + ); + $theme_json = new WP_Theme_JSON( + array( + 'version' => WP_Theme_JSON::LATEST_SCHEMA, + 'settings' => array( + 'typography' => array( + 'fluid' => true, + 'fontSizes' => array( + array( + 'size' => '16px', + 'slug' => 'pickles', + 'name' => 'Pickles', + ), + array( + 'size' => '22px', + 'slug' => 'toast', + 'name' => 'Toast', + ), + ), + ), + ), + 'styles' => array( + 'typography' => array( + 'fontSize' => '1em', + ), + 'elements' => array( + 'h1' => array( + 'typography' => array( + 'fontSize' => '100px', + ), + ), + ), + 'blocks' => array( + 'test/clamp-me' => array( + 'typography' => array( + 'fontSize' => '48px', + ), + ), + ), + ), + ), + 'default' + ); + + unregister_block_type( 'test/clamp-me' ); + + // Results also include root site blocks styles. + $this->assertSame( + 'body{--wp--preset--font-size--pickles: clamp(14px, 0.875rem + ((1vw - 3.2px) * 0.156), 16px);--wp--preset--font-size--toast: clamp(14.642px, 0.915rem + ((1vw - 3.2px) * 0.575), 22px);}body { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }:where(.is-layout-flex){gap: 0.5em;}:where(.is-layout-grid){gap: 0.5em;}body .is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-constrained > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-constrained > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)){margin-left: auto !important;margin-right: auto !important;}body .is-layout-flex{display: flex;}body .is-layout-flex{flex-wrap: wrap;align-items: center;}body .is-layout-flex > *{margin: 0;}body .is-layout-grid{display: grid;}body .is-layout-grid > *{margin: 0;}body{font-size: clamp(0.875em, 0.875rem + ((1vw - 0.2em) * 0.156), 1em);}h1{font-size: clamp(50.171px, 3.136rem + ((1vw - 3.2px) * 3.893), 100px);}.wp-block-test-clamp-me{font-size: clamp(27.894px, 1.743rem + ((1vw - 3.2px) * 1.571), 48px);}.has-pickles-font-size{font-size: var(--wp--preset--font-size--pickles) !important;}.has-toast-font-size{font-size: var(--wp--preset--font-size--toast) !important;}', + $theme_json->get_stylesheet() + ); + } + public function test_allow_indirect_properties() { $actual = WP_Theme_JSON::remove_insecure_properties( array(