diff --git a/projects/plugins/jetpack/changelog/update-add-csstidy-config-setting-to-preserve-leading-decimal-zero b/projects/plugins/jetpack/changelog/update-add-csstidy-config-setting-to-preserve-leading-decimal-zero
new file mode 100644
index 000000000000..64a215160d7e
--- /dev/null
+++ b/projects/plugins/jetpack/changelog/update-add-csstidy-config-setting-to-preserve-leading-decimal-zero
@@ -0,0 +1,4 @@
+Significance: minor
+Type: bugfix
+
+Adds a setting to csstidy to tell the optimizer to preserve leading decimal zeros.
diff --git a/projects/plugins/jetpack/modules/custom-css/csstidy/class.csstidy.php b/projects/plugins/jetpack/modules/custom-css/csstidy/class.csstidy.php
index ecb5f72931c5..106a770b8bb7 100644
--- a/projects/plugins/jetpack/modules/custom-css/csstidy/class.csstidy.php
+++ b/projects/plugins/jetpack/modules/custom-css/csstidy/class.csstidy.php
@@ -280,6 +280,8 @@ function __construct() {
$this->settings['timestamp'] = false;
$this->settings['template'] = ''; // say that propertie exist
$this->set_cfg('template','default'); // call load_template
+ /* Tells csstidy_optimise to keep leading zeros on decimal numbers, e.g., 0.7 */
+ $this->settings['preserve_leading_zeros'] = false;
$this->optimise = new csstidy_optimise($this);
$this->tokens_list = & $GLOBALS['csstidy']['tokens'];
diff --git a/projects/plugins/jetpack/modules/custom-css/csstidy/class.csstidy_optimise.php b/projects/plugins/jetpack/modules/custom-css/csstidy/class.csstidy_optimise.php
index a5318a499996..5f4a3843a005 100644
--- a/projects/plugins/jetpack/modules/custom-css/csstidy/class.csstidy_optimise.php
+++ b/projects/plugins/jetpack/modules/custom-css/csstidy/class.csstidy_optimise.php
@@ -401,10 +401,13 @@ function AnalyseCssNumber($string) {
$return[0] = (float) $string;
if (abs($return[0]) > 0 && abs($return[0]) < 1) {
- if ($return[0] < 0) {
- $return[0] = '-' . ltrim(substr($return[0], 1), '0');
- } else {
- $return[0] = ltrim($return[0], '0');
+ // Removes the initial `0` from a decimal number, e.g., `0.7 => .7` or `-0.666 => -.666`.
+ if ( ! $this->parser->get_cfg( 'preserve_leading_zeros' ) ) {
+ if ( $return[0] < 0 ) {
+ $return[0] = '-' . ltrim( substr( $return[0], 1 ), '0' );
+ } else {
+ $return[0] = ltrim( $return[0], '0' );
+ }
}
}
diff --git a/projects/plugins/jetpack/modules/custom-css/custom-css.php b/projects/plugins/jetpack/modules/custom-css/custom-css.php
index d821c77fef3d..a62e2fe703f8 100644
--- a/projects/plugins/jetpack/modules/custom-css/custom-css.php
+++ b/projects/plugins/jetpack/modules/custom-css/custom-css.php
@@ -1623,9 +1623,10 @@ static function filter_attr( $css, $element = 'div' ) {
$csstidy->set_cfg( 'remove_last_;', false );
$csstidy->set_cfg( 'css_level', 'CSS3.0' );
- // Turn off css shorthands when in block editor context as it breaks block validation.
+ // Turn off css shorthands and leading zero removal when in block editor context as it breaks block validation.
if ( true === isset( $_REQUEST['_gutenberg_nonce'] ) && wp_verify_nonce( $_REQUEST['_gutenberg_nonce'], 'gutenberg_request' ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
$csstidy->set_cfg( 'optimise_shorthands', 0 );
+ $csstidy->set_cfg( 'preserve_leading_zeros', true );
}
$css = preg_replace( '/\\\\([0-9a-fA-F]{4})/', '\\\\\\\\$1', $css );
diff --git a/projects/plugins/jetpack/phpunit.xml.dist b/projects/plugins/jetpack/phpunit.xml.dist
index 10aa1e98f164..3cd084bd3b63 100644
--- a/projects/plugins/jetpack/phpunit.xml.dist
+++ b/projects/plugins/jetpack/phpunit.xml.dist
@@ -128,6 +128,9 @@
tests/php/modules/seo-tools
+
+ tests/php/modules/csstidy
+
diff --git a/projects/plugins/jetpack/tests/php/modules/csstidy/test-class.jetpack-csstidy.php b/projects/plugins/jetpack/tests/php/modules/csstidy/test-class.jetpack-csstidy.php
new file mode 100644
index 000000000000..a30b3bcc4d52
--- /dev/null
+++ b/projects/plugins/jetpack/tests/php/modules/csstidy/test-class.jetpack-csstidy.php
@@ -0,0 +1,64 @@
+instance = new csstidy();
+ $this->instance->set_cfg( 'optimise_shorthands', 0 );
+ }
+
+ /** Provides values for CSS preserve leading zeros patterns */
+ public function custom_preserve_leading_zeros_provider() {
+ // phpcs:ignore Squiz.PHP.CommentedOutCode.Found -- false positive
+ // 'test case description' => [ 'input', 'expected output', 'preserve_leading_zeros' ].
+ return array(
+ 'test_removes_leading_zeros_by_default' => array( 'marquee {line-height:0.7;opacity:0.05;background-color:rgba(255, 255, 255, 0.25);}', "marquee {\nline-height:.7;\nopacity:.05;\nbackground-color:rgba(255,255,255,0.25)\n}", false ),
+ 'test_decimals_greater_than_one_unchanged_default' => array( 'blink {line-height:1.7;top:-100.55em;}', "blink {\nline-height:1.7;\ntop:-100.55em\n}", false ),
+ 'test_removes_leading_zeros_by_default_units' => array( 'dfn {margin-left:-0.7px;top:0.55rem;line-height:0.3333;text-indent:-9999%}', "dfn {\nmargin-left:-.7px;\ntop:.55rem;\nline-height:.3333;\ntext-indent:-9999%\n}", false ),
+ 'test_preserves_leading_zeros' => array( 'aside {line-height:0.7;background-color:rgba(255, 255, 255, 0.25);opacity:0.05;}', "aside {\nline-height:0.7;\nbackground-color:rgba(255,255,255,0.25);\nopacity:0.05\n}", true ),
+ 'test_preserves_leading_zeros_units' => array( 'code {line-height:.70;margin-left:-00.70px;top:0.55rem;padding:0.3333%;}', "code {\nline-height:0.7;\nmargin-left:-0.7px;\ntop:0.55rem;\npadding:0.3333%\n}", true ),
+ 'test_decimals_greater_than_one_unchanged_preserve_zeros' => array( 'blink {line-height:1.70;top:100.55em;margin-left:900px;}', "blink {\nline-height:1.7;\ntop:100.55em;\nmargin-left:900px\n}", false ),
+ );
+ }
+
+ /**
+ * Test that leading zeros for decimals values are preserved/discarded as expected.
+ *
+ * @dataProvider custom_preserve_leading_zeros_provider
+ *
+ * @param string $input potential CSS values.
+ * @param string $expected_output what we expect csstidy to output.
+ * @param bool $preserve_leading_zeros the value of `preserve_leading_zeros` in csstidy's config.
+ */
+ public function test_preserve_leading_zeros( $input, $expected_output, $preserve_leading_zeros ) {
+ $this->instance->set_cfg( 'preserve_leading_zeros', $preserve_leading_zeros );
+ $this->instance->parse( $input );
+ $this->assertEquals(
+ $expected_output,
+ $this->instance->print->plain()
+ );
+ }
+}