From b8b9cbf98e33863cda9340c00697d5b40daa37e0 Mon Sep 17 00:00:00 2001 From: ramonjd Date: Fri, 7 Oct 2022 16:01:21 +1100 Subject: [PATCH 1/5] This commit ensures that custom font size values that appear in the style attribute of block content are converted to fluid typography (if activated) --- lib/block-supports/typography.php | 30 ++++- phpunit/block-supports/typography-test.php | 121 ++++++++++++++++++ .../theme.json | 9 ++ 3 files changed, 159 insertions(+), 1 deletion(-) create mode 100644 phpunit/data/themedir1/block-theme-child-with-fluid-typography/theme.json diff --git a/lib/block-supports/typography.php b/lib/block-supports/typography.php index f84bfd2a74b8f..2baaa979124c4 100644 --- a/lib/block-supports/typography.php +++ b/lib/block-supports/typography.php @@ -228,6 +228,25 @@ function gutenberg_typography_get_css_variable_inline_style( $attributes, $featu return sprintf( '%s:var(--wp--preset--%s--%s);', $css_property, $css_property, $slug ); } +/** + * Renders typography styles/content to the block wrapper. + * + * @param string $block_content Rendered block content. + * @param array $block Block object. + * @return string Filtered block content. + */ +function gutenberg_render_typography_support( $block_content, $block ) { + $custom_font_size = isset( $block['attrs']['style']['typography']['fontSize'] ) ? $block['attrs']['style']['typography']['fontSize'] : null; + $fluid_font_size = gutenberg_get_typography_font_size_value( array( 'size' => $custom_font_size ) ); + + if ( ! empty( $fluid_font_size ) && $fluid_font_size !== $custom_font_size ) { + return preg_replace( '/font-size\s*:\s*' . preg_quote( $custom_font_size, '/' ) . '\s*;?/', 'font-size:' . esc_attr( $fluid_font_size ) . ';', $block_content, 1 ); + } + + return $block_content; + +} + /** * Internal method that checks a string for a unit and value and returns an array consisting of `'value'` and `'unit'`, e.g., [ '42', 'rem' ]. * A raw font size of `value + unit` is expected. If the value is a number, it will convert to `value + 'px'`. @@ -380,9 +399,13 @@ function gutenberg_get_computed_fluid_typography_value( $args = array() ) { * } * @param bool $should_use_fluid_typography An override to switch fluid typography "on". Can be used for unit testing. Default is `false`. * - * @return string Font-size value. + * @return string|null Font-size value or `null` if a size is not passed in $preset. */ function gutenberg_get_typography_font_size_value( $preset, $should_use_fluid_typography = false ) { + if ( ! isset( $preset['size'] ) || empty( $preset['size'] ) ) { + return null; + } + // Check if fluid font sizes are activated. $typography_settings = gutenberg_get_global_settings( array( 'typography' ) ); $should_use_fluid_typography = isset( $typography_settings['fluid'] ) && true === $typography_settings['fluid'] ? true : $should_use_fluid_typography; @@ -452,3 +475,8 @@ function gutenberg_get_typography_font_size_value( $preset, $should_use_fluid_ty 'apply' => 'gutenberg_apply_typography_support', ) ); + +if ( function_exists( 'wp_render_typography_support' ) ) { + remove_filter( 'render_block', 'wp_render_typography_support' ); +} +add_filter( 'render_block', 'gutenberg_render_typography_support', 10, 2 ); diff --git a/phpunit/block-supports/typography-test.php b/phpunit/block-supports/typography-test.php index 0b1cba6c83c80..e72d1f431e531 100644 --- a/phpunit/block-supports/typography-test.php +++ b/phpunit/block-supports/typography-test.php @@ -12,20 +12,59 @@ class WP_Block_Supports_Typography_Test extends WP_UnitTestCase { */ private $test_block_name; + /** + * Stores the current test theme root. + * + * @var string|null + */ + private $theme_root; + + /** + * Caches the original theme directory global value in order + * to restore it in tear down. + * + * @var string|null + */ + private $orig_theme_dir; + /** * Sets up tests. */ public function set_up() { parent::set_up(); + $this->test_block_name = null; + + // Sets up the `wp-content/themes/` directory to ensure consistency when running tests. + $this->theme_root = realpath( __DIR__ . '/../data/themedir1' ); + $this->orig_theme_dir = $GLOBALS['wp_theme_directories']; + $GLOBALS['wp_theme_directories'] = array( WP_CONTENT_DIR . '/themes', $this->theme_root ); + + $theme_root_callback = function () { + return $this->theme_root; + }; + add_filter( 'theme_root', $theme_root_callback ); + add_filter( 'stylesheet_root', $theme_root_callback ); + add_filter( 'template_root', $theme_root_callback ); + + // Clear caches. + wp_clean_themes_cache(); + unset( $GLOBALS['wp_themes'] ); } /** * Tears down tests. */ public function tear_down() { + // Restores the original theme directory setup. + $GLOBALS['wp_theme_directories'] = $this->orig_theme_dir; + wp_clean_themes_cache(); + unset( $GLOBALS['wp_themes'] ); + + // Resets test block name. unregister_block_type( $this->test_block_name ); $this->test_block_name = null; + parent::tear_down(); } @@ -382,4 +421,86 @@ public function data_generate_font_size_preset_fixtures() { ), ); } + + /** + * Tests that custom font sizes are converted to fluid values + * in inline block supports styles, + * when "settings.typography.fluid" is set to `true`. + * + * @covers ::gutenberg_render_typography_support + * + * @dataProvider data_generate_replace_inline_font_styles_with_fluid_values_fixtures + * + * @param string $block_content HTML block content. + * @param string $font_size_value The block supports custom font size value. + * @param bool $should_use_fluid_typography An override to switch fluid typography "on". Can be used for unit testing. + * @param string $expected_output Expected value of style property from gutenberg_apply_typography_support(). + */ + public function test_should_replace_inline_font_styles_with_fluid_values( $block_content, $font_size_value, $should_use_fluid_typography, $expected_output ) { + if ( $should_use_fluid_typography ) { + switch_theme( 'block-theme-child-with-fluid-typography' ); + } else { + switch_theme( 'default' ); + } + + $block = array( + 'blockName' => 'core/image', + 'attrs' => array( + 'style' => array( + 'typography' => array( + 'fontSize' => $font_size_value, + ), + ), + ), + ); + $actual = gutenberg_render_typography_support( $block_content, $block ); + + $this->assertSame( $expected_output, $actual ); + } + + /** + * Data provider for test_should_replace_inline_font_styles_with_fluid_values. + * + * @return array + */ + public function data_generate_replace_inline_font_styles_with_fluid_values_fixtures() { + return array( + 'default_return_content' => array( + 'block_content' => '', + 'font_size_value' => '4rem', + 'should_use_fluid_typography' => false, + 'expected_output' => '', + ), + 'return_content_with_replaced_fluid_font_size_inline_style' => array( + 'block_content' => '', + 'font_size_value' => '4rem', + 'should_use_fluid_typography' => true, + 'expected_output' => '', + ), + 'return_content_if_no_inline_font_size_found' => array( + 'block_content' => '

A paragraph inside a group

', + 'font_size_value' => '20px', + 'should_use_fluid_typography' => true, + 'expected_output' => '

A paragraph inside a group

', + ), + 'return_content_css_var' => array( + 'block_content' => '

A paragraph inside a group

', + 'font_size_value' => 'var:preset|font-size|x-large', + 'should_use_fluid_typography' => true, + 'expected_output' => '

A paragraph inside a group

', + ), + 'return_content_with_spaces' => array( + 'block_content' => '

A paragraph inside a group

', + 'font_size_value' => '20px', + 'should_use_fluid_typography' => true, + 'expected_output' => '

A paragraph inside a group

', + ), + 'return_content_with_first_match_replace_only' => array( + 'block_content' => "
\n \n

A paragraph inside a group

", + 'font_size_value' => '1em', + 'should_use_fluid_typography' => true, + 'expected_output' => "
\n \n

A paragraph inside a group

", + ), + ); + } } diff --git a/phpunit/data/themedir1/block-theme-child-with-fluid-typography/theme.json b/phpunit/data/themedir1/block-theme-child-with-fluid-typography/theme.json new file mode 100644 index 0000000000000..93234766eddd2 --- /dev/null +++ b/phpunit/data/themedir1/block-theme-child-with-fluid-typography/theme.json @@ -0,0 +1,9 @@ +{ + "version": 2, + "settings": { + "appearanceTools": true, + "typography": { + "fluid": true + } + } +} From e3ebfd83cd793a0cb7cc94873bd4e413e4c880a6 Mon Sep 17 00:00:00 2001 From: ramonjd Date: Fri, 7 Oct 2022 16:19:20 +1100 Subject: [PATCH 2/5] Adding comments --- lib/block-supports/typography.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/block-supports/typography.php b/lib/block-supports/typography.php index 2baaa979124c4..4e94a9dd740b2 100644 --- a/lib/block-supports/typography.php +++ b/lib/block-supports/typography.php @@ -239,7 +239,12 @@ function gutenberg_render_typography_support( $block_content, $block ) { $custom_font_size = isset( $block['attrs']['style']['typography']['fontSize'] ) ? $block['attrs']['style']['typography']['fontSize'] : null; $fluid_font_size = gutenberg_get_typography_font_size_value( array( 'size' => $custom_font_size ) ); + /* + * Checks that $fluid_font_size does not match $custom_font_size, + * which means it's been mutated by the fluid font size functions. + */ if ( ! empty( $fluid_font_size ) && $fluid_font_size !== $custom_font_size ) { + // Replaces the first instance of `font-size:$custom_font_size` with `font-size:$fluid_font_size`. return preg_replace( '/font-size\s*:\s*' . preg_quote( $custom_font_size, '/' ) . '\s*;?/', 'font-size:' . esc_attr( $fluid_font_size ) . ';', $block_content, 1 ); } From 7767d4cd7577b56b9c60d23740ef1a08f3948819 Mon Sep 17 00:00:00 2001 From: ramonjd Date: Mon, 10 Oct 2022 10:39:48 +1100 Subject: [PATCH 3/5] Bail early if we don't find a custom font size --- lib/block-supports/typography.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/block-supports/typography.php b/lib/block-supports/typography.php index 4e94a9dd740b2..eeb7a2f3dda4d 100644 --- a/lib/block-supports/typography.php +++ b/lib/block-supports/typography.php @@ -236,7 +236,11 @@ function gutenberg_typography_get_css_variable_inline_style( $attributes, $featu * @return string Filtered block content. */ function gutenberg_render_typography_support( $block_content, $block ) { - $custom_font_size = isset( $block['attrs']['style']['typography']['fontSize'] ) ? $block['attrs']['style']['typography']['fontSize'] : null; + if ( ! isset( $block['attrs']['style']['typography']['fontSize'] ) ) { + return $block_content; + } + + $custom_font_size = $block['attrs']['style']['typography']['fontSize']; $fluid_font_size = gutenberg_get_typography_font_size_value( array( 'size' => $custom_font_size ) ); /* From dbc2adc8f219d8e666be1285c701c361911ac014 Mon Sep 17 00:00:00 2001 From: ramonjd Date: Mon, 10 Oct 2022 10:51:23 +1100 Subject: [PATCH 4/5] Adding tests yo --- phpunit/block-supports/typography-test.php | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/phpunit/block-supports/typography-test.php b/phpunit/block-supports/typography-test.php index e72d1f431e531..d21619a3a5286 100644 --- a/phpunit/block-supports/typography-test.php +++ b/phpunit/block-supports/typography-test.php @@ -340,6 +340,24 @@ public function data_generate_font_size_preset_fixtures() { 'expected_output' => '28px', ), + 'default_return_value_when_value_is_already_clamped' => array( + 'font_size_preset' => array( + 'size' => 'clamp(21px, 1.3125rem + ((1vw - 7.68px) * 2.524), 42px)', + 'fluid' => false, + ), + 'should_use_fluid_typography' => true, + 'expected_output' => 'clamp(21px, 1.3125rem + ((1vw - 7.68px) * 2.524), 42px)', + ), + + 'default_return_value_with_unsupported_unit' => array( + 'font_size_preset' => array( + 'size' => '1000%', + 'fluid' => false, + ), + 'should_use_fluid_typography' => true, + 'expected_output' => '1000%', + ), + 'return_fluid_value' => array( 'font_size_preset' => array( 'size' => '1.75rem', From d1dfb5f2bedd8288de8539da88f032381a84ba99 Mon Sep 17 00:00:00 2001 From: ramonjd Date: Mon, 10 Oct 2022 21:04:58 +1100 Subject: [PATCH 5/5] Updating PHP doc to describe incoming type of $raw_value (string|number) --- lib/block-supports/typography.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/block-supports/typography.php b/lib/block-supports/typography.php index eeb7a2f3dda4d..22dfdba97fbb8 100644 --- a/lib/block-supports/typography.php +++ b/lib/block-supports/typography.php @@ -262,8 +262,8 @@ function gutenberg_render_typography_support( $block_content, $block ) { * * @access private * - * @param string $raw_value Raw size value from theme.json. - * @param array $options { + * @param string|number $raw_value Raw size value from theme.json. + * @param array $options { * Optional. An associative array of options. Default is empty array. * * @type string $coerce_to Coerce the value to rem or px. Default `'rem'`.