Skip to content

Commit

Permalink
Fluid typography: convert font size inline style attributes to fluid …
Browse files Browse the repository at this point in the history
…values (#44764)

* This commit ensures that custom font size values that appear in the style attribute of block content are converted to fluid typography (if activated)

* Adding comments

* Bail early if we don't find a custom font size

* Adding tests yo

* Updating PHP doc to describe incoming type of $raw_value (string|number)
  • Loading branch information
ramonjd authored Oct 10, 2022
1 parent 029d296 commit b1d4ffd
Show file tree
Hide file tree
Showing 3 changed files with 188 additions and 3 deletions.
43 changes: 40 additions & 3 deletions lib/block-supports/typography.php
Original file line number Diff line number Diff line change
Expand Up @@ -228,14 +228,42 @@ 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 ) {
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 ) );

/*
* 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 );
}

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'`.
*
* @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'`.
Expand Down Expand Up @@ -380,9 +408,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;
Expand Down Expand Up @@ -452,3 +484,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 );
139 changes: 139 additions & 0 deletions phpunit/block-supports/typography-test.php
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}

Expand Down Expand Up @@ -301,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',
Expand Down Expand Up @@ -382,4 +439,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' => '<h2 class="has-vivid-red-background-color has-background has-link-color" style="margin-top:var(--wp--preset--spacing--60);font-size:4rem;font-style:normal;font-weight:600;letter-spacing:29px;text-decoration:underline;text-transform:capitalize">This is a heading</h2>',
'font_size_value' => '4rem',
'should_use_fluid_typography' => false,
'expected_output' => '<h2 class="has-vivid-red-background-color has-background has-link-color" style="margin-top:var(--wp--preset--spacing--60);font-size:4rem;font-style:normal;font-weight:600;letter-spacing:29px;text-decoration:underline;text-transform:capitalize">This is a heading</h2>',
),
'return_content_with_replaced_fluid_font_size_inline_style' => array(
'block_content' => '<h2 class="has-vivid-red-background-color has-background has-link-color" style="margin-top:var(--wp--preset--spacing--60);font-size:4rem;font-style:normal;font-weight:600;letter-spacing:29px;text-decoration:underline;text-transform:capitalize">This is a heading</h2>',
'font_size_value' => '4rem',
'should_use_fluid_typography' => true,
'expected_output' => '<h2 class="has-vivid-red-background-color has-background has-link-color" style="margin-top:var(--wp--preset--spacing--60);font-size:clamp(3rem, 3rem + ((1vw - 0.48rem) * 5.769), 6rem);font-style:normal;font-weight:600;letter-spacing:29px;text-decoration:underline;text-transform:capitalize">This is a heading</h2>',
),
'return_content_if_no_inline_font_size_found' => array(
'block_content' => '<p class="has-medium-font-size" style="font-style:normal;font-weight:600;letter-spacing:29px;">A paragraph inside a group</p>',
'font_size_value' => '20px',
'should_use_fluid_typography' => true,
'expected_output' => '<p class="has-medium-font-size" style="font-style:normal;font-weight:600;letter-spacing:29px;">A paragraph inside a group</p>',
),
'return_content_css_var' => array(
'block_content' => '<p class="has-medium-font-size" style="font-size:var(--wp--preset--font-size--x-large);">A paragraph inside a group</p>',
'font_size_value' => 'var:preset|font-size|x-large',
'should_use_fluid_typography' => true,
'expected_output' => '<p class="has-medium-font-size" style="font-size:var(--wp--preset--font-size--x-large);">A paragraph inside a group</p>',
),
'return_content_with_spaces' => array(
'block_content' => '<p class="has-medium-font-size" style=" font-size: 20px ; ">A paragraph inside a group</p>',
'font_size_value' => '20px',
'should_use_fluid_typography' => true,
'expected_output' => '<p class="has-medium-font-size" style=" font-size:clamp(15px, 0.9375rem + ((1vw - 7.68px) * 1.803), 30px); ">A paragraph inside a group</p>',
),
'return_content_with_first_match_replace_only' => array(
'block_content' => "<div class=\"wp-block-group\" style=\"font-size:1em\"> \n \n<p style=\"font-size:1em\">A paragraph inside a group</p></div>",
'font_size_value' => '1em',
'should_use_fluid_typography' => true,
'expected_output' => "<div class=\"wp-block-group\" style=\"font-size:clamp(0.75em, 0.75em + ((1vw - 0.48em) * 1.442), 1.5em);\"> \n \n<p style=\"font-size:1em\">A paragraph inside a group</p></div>",
),
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"version": 2,
"settings": {
"appearanceTools": true,
"typography": {
"fluid": true
}
}
}

0 comments on commit b1d4ffd

Please sign in to comment.