-
Notifications
You must be signed in to change notification settings - Fork 4.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Typography: replace non-dot decimal separator for float to string conversions #57634
Typography: replace non-dot decimal separator for float to string conversions #57634
Conversation
Where coercing a float to a string, replace the non-dots with dots. This is so we can output valid CSS values. Moving all this work to gutenberg_get_typography_value_and_unit() Updating tests
This pull request has changed or added PHP files. Please confirm whether these changes need to be synced to WordPress Core, and therefore featured in the next release of WordPress. If so, it is recommended to create a new Trac ticket and submit a pull request to the WordPress Core Github repository soon after this pull request is merged. If you're unsure, you can always ask for help in the #core-editor channel in WordPress Slack. Thank you! ❤️ View changed files❔ lib/block-supports/typography.php ❔ phpunit/block-supports/typography-test.php |
Updated tests - removed setlocale tests as they don't run on Gutenberg I think (no locales in the Docker container)
lib/block-supports/typography.php
Outdated
|
||
$acceptable_units_group = implode( '|', $options['acceptable_units'] ); | ||
$pattern = '/^(\d*\.?\d+)(' . $acceptable_units_group . '){1,1}$/'; | ||
$pattern = '/^(-?\d*[\.,]?\d+)(' . $acceptable_units_group . '){0,1}$/'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now accepts negative numbers. This was an unrelated limitation.
-10rem
Also now accepts any pre-stringified floats from other locales:
12,232px
And unit less values:
10.333
to which a px
unit will be added by default. This matches existing behaviour only that we move it down to after the regex matching so we can do the string replace on any found values. Note that incoming $raw_value
can be anything, e.g., clamp(...)
or whatever, so I'm letting the regex do the check before we get clever.
'unit' => $unit, | ||
'value' => $value, | ||
'unit' => $unit, | ||
'combined' => str_replace( ',', '.', $value . $unit ), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This property is an addition of convenience. Any subsequent string coercion runs the risk of triggering the locale behaviour, so do it here once and return the combined value for use in our output.
lib/block-supports/typography.php
Outdated
@@ -403,11 +405,15 @@ function gutenberg_get_computed_fluid_typography_value( $args = array() ) { | |||
|
|||
// Build CSS rule. | |||
// Borrowed from https://websemantics.uk/tools/responsive-font-calculator/. | |||
$view_port_width_offset = round( $minimum_viewport_width['value'] / 100, 3 ) . $font_size_unit; | |||
$view_port_width_offset = gutenberg_get_typography_value_and_unit( ( $minimum_viewport_width['value'] / 100 ) . $font_size_unit )['combined']; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just double-check my reading here: it's safe to access ['combined']
here without checking it's set, because it's guaranteed to be as $minimum_viewport_width
is sure to be an actual / valid value because if it wasn't this function would have returned early?
Or to put it differently: at first I saw the call to gutenberg_get_typography_value_and_unit
and thought it might be dangerous because the function can technically return null
, but in practice here it looks like it never will / it'll always return a value with combined
available 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
because it's guaranteed to be as $minimum_viewport_width is sure to be an actual / valid value because if it wasn't this function would have returned early?
Exactly! But I've replaced this with a regular string replace for another reason 😆
Basically a micro optimization: don't run the viewport offset value through gutenberg_get_typography_value_and_unit()
as the values have already been previously checked via gutenberg_get_typography_value_and_unit()
.
It avoids another regex parsing, and as you say, the function will return early if those values are bunk.
…berg_get_typography_value_and_unit unnecessarily. The values have already been checked.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for testing this one @andrewserong I know it was a bit fiddly 😄 |
I have a more universal approach with a new function here: This PR remains relevant however, since any float->string coercion will be run through the new function in pretty much the same places. |
Converting to draft while #57607 plays out |
Closing for now. I'll come back later if this feature is required and time permits. |
Resolves:
What?
When coercing a float to a string, replace commas with dots.
This is so we can output valid CSS values where locales use commas as decimal separators.
Why?
In PHP version < 8, PHP uses the current locale for float to string conversions.
That means
1.333 + "px"
, for example, will be converted to1,333px
.PHP 8 does not do this.
See: https://php.watch/versions/8.0/float-to-string-locale-independent
How?
String replace before turning floats to strings or trying to use stringified floats for any other business.
E.g.,
str_replace( ',', '.', '$some_number )
Testing Instructions
To test, we need to be running a PHP version of < 8, e.g., 7.4.
If you're not and you're using
wp-env
, you can update the.wp-env.json
file and set thephpVersion
value.Another dependency is
locale
, which needs to be installed on the server.Here's a diff that does all that:
wp-env override and locale
If you don't mind losing your docker containers, once that patch is applied, run the following commands:
npm run wp-env destroy # Hit `y` to destroy your local docker containers npm run wp-env start
Then, somewhere at the top of the typography.php file (not inside a function), add the following line:
setlocale( LC_ALL, 'de_DE.UTF-8' );
This sets the locale to German, which uses commas as decimal separators, e.g.,
1,33
.Finally, ensure that tests pass and that fluid typography works on the frontend as expected.