From 60bc9ca8846bd9ef980f20758494cb710cda424a Mon Sep 17 00:00:00 2001 From: Ramon Date: Fri, 7 Aug 2026 16:00:32 +1000 Subject: [PATCH] Global styles: stop sanitize keeping breakpoints set on an element `sanitize()` added a breakpoint state to every element, so an element could carry `@mobile` or `@tablet` directly, at the top level and inside a block. Nothing reads that shape. The target structures are listed four lines above the loop, and the responsive one puts the breakpoint on the block with `elements` inside it. The data survived as far as the database and the REST API, since `remove_insecure_properties()` uses the same schema, while never producing a rule. Drop the loop. CSS output is unchanged, which the existing rendering tests cover, and the two structures that do work are assembled elsewhere from this same element schema. Two sanitization tests now assert the breakpoints are stripped rather than kept, at block and top level. --- lib/class-wp-theme-json-gutenberg.php | 10 +++-- phpunit/class-wp-theme-json-test.php | 53 +++++++++++++++++++++------ 2 files changed, 48 insertions(+), 15 deletions(-) diff --git a/lib/class-wp-theme-json-gutenberg.php b/lib/class-wp-theme-json-gutenberg.php index 0a6a924221e47b..d13e44e95cd6cd 100644 --- a/lib/class-wp-theme-json-gutenberg.php +++ b/lib/class-wp-theme-json-gutenberg.php @@ -1287,10 +1287,12 @@ protected static function sanitize( $input, $valid_block_names, $valid_element_n } } - // Add responsive breakpoint states for elements. - foreach ( array_keys( $responsive_media_queries ) as $breakpoint_state ) { - $schema_styles_elements[ $element ][ $breakpoint_state ] = $styles_non_top_level; - } + /* + * Breakpoint states are not added here. A responsive element is + * written as a block breakpoint containing elements, the third + * structure listed above, which is assembled further down from + * this same element schema. + */ } $schema_styles_blocks = array(); diff --git a/phpunit/class-wp-theme-json-test.php b/phpunit/class-wp-theme-json-test.php index 9760e5875391d0..911cbe977936bd 100644 --- a/phpunit/class-wp-theme-json-test.php +++ b/phpunit/class-wp-theme-json-test.php @@ -3613,7 +3613,7 @@ public function test_remove_insecure_properties_removes_unsafe_styles_sub_proper /** * @covers WP_Theme_JSON_Gutenberg::remove_insecure_properties */ - public function test_remove_insecure_properties_preserves_responsive_block_element_styles() { + public function test_remove_insecure_properties_strips_breakpoints_set_on_a_block_element() { $actual = WP_Theme_JSON_Gutenberg::remove_insecure_properties( array( 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, @@ -3643,6 +3643,7 @@ public function test_remove_insecure_properties_preserves_responsive_block_eleme ) ); + // The breakpoints are dropped. Only the element's own styles remain. $expected = array( 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, 'styles' => array( @@ -3650,23 +3651,53 @@ public function test_remove_insecure_properties_preserves_responsive_block_eleme 'core/group' => array( 'elements' => array( 'link' => array( - 'color' => array( + 'color' => array( 'text' => 'var(--wp--preset--color--dark-gray)', ), - '@mobile' => array( - 'color' => array( - 'text' => 'var(--wp--preset--color--dark-pink)', - ), - ), - '@tablet' => array( - 'color' => array( - 'text' => 'var(--wp--preset--color--dark-red)', - ), + ), + ), + ), + ), + ), + ); + + $this->assertEqualSetsWithIndex( $expected, $actual ); + } + + /** + * @covers WP_Theme_JSON_Gutenberg::remove_insecure_properties + */ + public function test_remove_insecure_properties_strips_breakpoints_set_on_a_top_level_element() { + $actual = WP_Theme_JSON_Gutenberg::remove_insecure_properties( + array( + 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, + 'styles' => array( + 'elements' => array( + 'link' => array( + 'color' => array( + 'text' => 'var:preset|color|dark-gray', + ), + '@mobile' => array( + 'color' => array( + 'text' => 'var:preset|color|dark-pink', ), ), ), ), ), + ) + ); + + $expected = array( + 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, + 'styles' => array( + 'elements' => array( + 'link' => array( + 'color' => array( + 'text' => 'var(--wp--preset--color--dark-gray)', + ), + ), + ), ), );