diff --git a/backport-changelog/6.8/7825.md b/backport-changelog/6.8/7825.md new file mode 100644 index 00000000000000..42d09c86b7f3ba --- /dev/null +++ b/backport-changelog/6.8/7825.md @@ -0,0 +1,3 @@ +https://github.com/WordPress/wordpress-develop/pull/7825 + +* https://github.com/WordPress/gutenberg/pull/67061 diff --git a/lib/class-wp-theme-json-gutenberg.php b/lib/class-wp-theme-json-gutenberg.php index 10f80c3f3cdb7b..47301e4463e363 100644 --- a/lib/class-wp-theme-json-gutenberg.php +++ b/lib/class-wp-theme-json-gutenberg.php @@ -2874,8 +2874,14 @@ public function get_styles_for_block( $block_metadata ) { // Combine selectors with style variation's selector and add to overall style variation declarations. foreach ( $variation_declarations as $current_selector => $new_declarations ) { - // If current selector includes block classname, remove it but leave the whitespace in. - $shortened_selector = str_replace( $block_metadata['selector'] . ' ', ' ', $current_selector ); + /* + * Clean up any whitespace between comma separated selectors. + * This prevents these spaces breaking compound selectors such as: + * - `.wp-block-list:not(.wp-block-list .wp-block-list)` + * - `.wp-block-image img, .wp-block-image.my-class img` + */ + $clean_current_selector = preg_replace( '/,\s+/', ',', $current_selector ); + $shortened_selector = str_replace( $block_metadata['selector'], '', $clean_current_selector ); // Prepend the variation selector to the current selector. $split_selectors = explode( ',', $shortened_selector ); diff --git a/phpunit/class-wp-theme-json-test.php b/phpunit/class-wp-theme-json-test.php index 1aacb92759e591..c8ca89c7c1f6c7 100644 --- a/phpunit/class-wp-theme-json-test.php +++ b/phpunit/class-wp-theme-json-test.php @@ -4308,6 +4308,74 @@ public function data_get_styles_for_block_with_style_variations() { ); } + public function test_get_styles_for_block_with_style_variations_and_custom_selectors() { + register_block_type( + 'test/milk', + array( + 'api_version' => 3, + 'selectors' => array( + 'root' => '.milk', + 'color' => '.wp-block-test-milk .liquid, .wp-block-test-milk:not(.spoiled), .wp-block-test-milk.in-bottle', + ), + ) + ); + + register_block_style( + 'test/milk', + array( + 'name' => 'chocolate', + 'label' => 'Chocolate', + ) + ); + + $theme_json = new WP_Theme_JSON_Gutenberg( + array( + 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, + 'styles' => array( + 'blocks' => array( + 'test/milk' => array( + 'color' => array( + 'background' => 'white', + ), + 'variations' => array( + 'chocolate' => array( + 'color' => array( + 'background' => '#35281E', + ), + ), + ), + ), + ), + ), + ) + ); + + $metadata = array( + 'name' => 'test/milk', + 'path' => array( 'styles', 'blocks', 'test/milk' ), + 'selector' => '.wp-block-test-milk', + 'selectors' => array( + 'color' => '.wp-block-test-milk .liquid, .wp-block-test-milk:not(.spoiled), .wp-block-test-milk.in-bottle', + ), + 'variations' => array( + 'chocolate' => array( + 'path' => array( 'styles', 'blocks', 'test/milk', 'variations', 'chocolate' ), + 'selector' => '.is-style-chocolate.wp-block-test-milk', + ), + ), + ); + + $actual_styles = $theme_json->get_styles_for_block( $metadata ); + $default_styles = ':root :where(.wp-block-test-milk .liquid, .wp-block-test-milk:not(.spoiled), .wp-block-test-milk.in-bottle){background-color: white;}'; + $variation_styles = ':root :where(.is-style-chocolate.wp-block-test-milk .liquid,.is-style-chocolate.wp-block-test-milk:not(.spoiled),.is-style-chocolate.wp-block-test-milk.in-bottle){background-color: #35281E;}'; + $expected = $default_styles . $variation_styles; + + unregister_block_style( 'test/milk', 'chocolate' ); + unregister_block_type( 'test/milk' ); + + $this->assertSame( $expected, $actual_styles ); + } + public function test_block_style_variations() { wp_set_current_user( static::$administrator_id );