From 4867fe3aa3324d14d94c92e42d96cd50201c432b Mon Sep 17 00:00:00 2001 From: Ari Stathopoulos Date: Fri, 3 Feb 2023 08:59:29 +0200 Subject: [PATCH 1/3] backport https://github.com/WordPress/gutenberg/pull/46571 --- src/wp-includes/class-wp-theme-json.php | 21 ++++++++++ tests/phpunit/tests/theme/wpThemeJson.php | 51 +++++++++++++++++++++++ 2 files changed, 72 insertions(+) diff --git a/src/wp-includes/class-wp-theme-json.php b/src/wp-includes/class-wp-theme-json.php index 2908fb94d7e69..15633dba2932d 100644 --- a/src/wp-includes/class-wp-theme-json.php +++ b/src/wp-includes/class-wp-theme-json.php @@ -1006,6 +1006,27 @@ public function get_stylesheet( $types = array( 'variables', 'styles', 'presets' return $stylesheet; } + /** + * Processes the CSS, to apply nesting. + * + * @param string $css The CSS to process. + * @param string $selector The selector to nest. + * + * @return string The processed CSS. + */ + public function process_blocks_custom_css( $css, $selector ) { + $processed_css = ''; + + // Split CSS nested rules. + $parts = explode( '&', $css ); + foreach ( $parts as $part ) { + $processed_css .= ( ! str_contains( $part, '{' ) ) + ? trim( $selector ) . '{' . trim( $part ) . '}' // If the part doesn't contain braces, it applies to the root level. + : trim( $selector . $part ); // Prepend the selector, which effectively replaces the "&" character. + } + return $processed_css; + } + /** * Returns the global styles custom css. * diff --git a/tests/phpunit/tests/theme/wpThemeJson.php b/tests/phpunit/tests/theme/wpThemeJson.php index efa709ef756dc..1b68745244338 100644 --- a/tests/phpunit/tests/theme/wpThemeJson.php +++ b/tests/phpunit/tests/theme/wpThemeJson.php @@ -4624,4 +4624,55 @@ public function data_custom_css_for_user_caps() { ), ); } + + /** + * @dataProvider data_process_blocks_custom_css + * + * @param array $input An array containing the selector and css to test. + * @param string $expected Expected results. + */ + public function test_process_blocks_custom_css( $input, $expected ) { + $theme_json = new WP_Theme_JSON_Gutenberg( + array( + 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, + 'styles' => array(), + ) + ); + + $this->assertEquals( $expected, $theme_json->process_blocks_custom_css( $input['css'], $input['selector'] ) ); + } + + /** + * Data provider. + * + * @return array[] + */ + public function data_process_blocks_custom_css() { + return array( + // Simple CSS without any child selectors. + 'no child selectors' => array( + 'input' => array( + 'selector' => '.foo', + 'css' => 'color: red; margin: auto;', + ), + 'expected' => '.foo{color: red; margin: auto;}', + ), + // CSS with child selectors. + 'with children' => array( + 'input' => array( + 'selector' => '.foo', + 'css' => 'color: red; margin: auto; & .bar{color: blue;}', + ), + 'expected' => '.foo{color: red; margin: auto;}.foo .bar{color: blue;}', + ), + // CSS with child selectors and pseudo elements. + 'with children and pseudo elements' => array( + 'input' => array( + 'selector' => '.foo', + 'css' => 'color: red; margin: auto; & .bar{color: blue;} &::before{color: green;}', + ), + 'expected' => '.foo{color: red; margin: auto;}.foo .bar{color: blue;}.foo::before{color: green;}', + ), + ); + } } From 9ebc8b4212917bb2bfbf4c2c04207bdd27dfc3db Mon Sep 17 00:00:00 2001 From: Ari Stathopoulos Date: Fri, 3 Feb 2023 10:24:25 +0200 Subject: [PATCH 2/3] make method protected & fix tests --- src/wp-includes/class-wp-theme-json.php | 2 +- tests/phpunit/tests/theme/wpThemeJson.php | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/wp-includes/class-wp-theme-json.php b/src/wp-includes/class-wp-theme-json.php index 15633dba2932d..65b0d33e19829 100644 --- a/src/wp-includes/class-wp-theme-json.php +++ b/src/wp-includes/class-wp-theme-json.php @@ -1014,7 +1014,7 @@ public function get_stylesheet( $types = array( 'variables', 'styles', 'presets' * * @return string The processed CSS. */ - public function process_blocks_custom_css( $css, $selector ) { + protected function process_blocks_custom_css( $css, $selector ) { $processed_css = ''; // Split CSS nested rules. diff --git a/tests/phpunit/tests/theme/wpThemeJson.php b/tests/phpunit/tests/theme/wpThemeJson.php index 1b68745244338..561466cc6e517 100644 --- a/tests/phpunit/tests/theme/wpThemeJson.php +++ b/tests/phpunit/tests/theme/wpThemeJson.php @@ -4632,14 +4632,16 @@ public function data_custom_css_for_user_caps() { * @param string $expected Expected results. */ public function test_process_blocks_custom_css( $input, $expected ) { - $theme_json = new WP_Theme_JSON_Gutenberg( + $theme_json = new WP_Theme_JSON( array( - 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, + 'version' => WP_Theme_JSON::LATEST_SCHEMA, 'styles' => array(), ) ); + $reflection = new ReflectionMethod( $theme_json, 'process_blocks_custom_css' ); + $reflection->setAccessible( true ); - $this->assertEquals( $expected, $theme_json->process_blocks_custom_css( $input['css'], $input['selector'] ) ); + $this->assertEquals( $expected, $reflection->invoke( $theme_json, $input['css'], $input['selector'] ) ); } /** From 2cf1b08be2f735f508c3e44c24154fc692cf6d75 Mon Sep 17 00:00:00 2001 From: Felix Arntz Date: Fri, 3 Feb 2023 10:13:22 -0800 Subject: [PATCH 3/3] Address docs feedback. --- src/wp-includes/class-wp-theme-json.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/wp-includes/class-wp-theme-json.php b/src/wp-includes/class-wp-theme-json.php index 65b0d33e19829..7aaa6c3b66074 100644 --- a/src/wp-includes/class-wp-theme-json.php +++ b/src/wp-includes/class-wp-theme-json.php @@ -1009,9 +1009,10 @@ public function get_stylesheet( $types = array( 'variables', 'styles', 'presets' /** * Processes the CSS, to apply nesting. * + * @since 6.2.0 + * * @param string $css The CSS to process. * @param string $selector The selector to nest. - * * @return string The processed CSS. */ protected function process_blocks_custom_css( $css, $selector ) { @@ -1032,7 +1033,7 @@ protected function process_blocks_custom_css( $css, $selector ) { * * @since 6.2.0 * - * @return string + * @return string The global styles custom CSS. */ public function get_custom_css() { // Add the global styles root CSS.