diff --git a/lib/compat/wordpress-6.1/class-wp-theme-json-6-1.php b/lib/compat/wordpress-6.1/class-wp-theme-json-6-1.php index 5abf3b5a8dd91..71fc264217cfc 100644 --- a/lib/compat/wordpress-6.1/class-wp-theme-json-6-1.php +++ b/lib/compat/wordpress-6.1/class-wp-theme-json-6-1.php @@ -17,7 +17,7 @@ class WP_Theme_JSON_6_1 extends WP_Theme_JSON_6_0 { /** - * Whitelist which defines which pseudo selectors are enabled for + * Define which defines which pseudo selectors are enabled for * which elements. * Note: this will effect both top level and block level elements. */ @@ -31,7 +31,7 @@ class WP_Theme_JSON_6_1 extends WP_Theme_JSON_6_0 { * @var string[] */ const ELEMENTS = array( - 'link' => 'a', + 'link' => 'a:not(.wp-element-button)', 'h1' => 'h1', 'h2' => 'h2', 'h3' => 'h3', @@ -431,7 +431,7 @@ private static function get_block_nodes( $theme_json, $selectors = array() ) { 'selector' => $selectors[ $name ]['elements'][ $element ], ); - // Handle any psuedo selectors for the element. + // Handle any pseudo selectors for the element. if ( isset( static::VALID_ELEMENT_PSEUDO_SELECTORS[ $element ] ) ) { foreach ( static::VALID_ELEMENT_PSEUDO_SELECTORS[ $element ] as $pseudo_selector ) { if ( isset( $theme_json['styles']['blocks'][ $name ]['elements'][ $element ][ $pseudo_selector ] ) ) { @@ -462,11 +462,6 @@ public function get_styles_for_block( $block_metadata ) { $selector = $block_metadata['selector']; $settings = _wp_array_get( $this->theme_json, array( 'settings' ) ); - // Attempt to parse a pseudo selector (e.g. ":hover") from the $selector ("a:hover"). - $pseudo_matches = array(); - preg_match( '/:[a-z]+/', $selector, $pseudo_matches ); - $pseudo_selector = isset( $pseudo_matches[0] ) ? $pseudo_matches[0] : null; - // Get a reference to element name from path. // $block_metadata['path'] = array('styles','elements','link'); // Make sure that $block_metadata['path'] describes an element node, like ['styles', 'element', 'link']. @@ -475,6 +470,21 @@ public function get_styles_for_block( $block_metadata ) { $current_element = $is_processing_element ? $block_metadata['path'][ count( $block_metadata['path'] ) - 1 ] : null; + $element_pseudo_allowed = isset( static::VALID_ELEMENT_PSEUDO_SELECTORS[ $current_element ] ) ? static::VALID_ELEMENT_PSEUDO_SELECTORS[ $current_element ] : array(); + + // Check for allowed pseudo classes (e.g. ":hover") from the $selector ("a:hover"). + // This also resets the array keys. + $pseudo_matches = array_values( + array_filter( + $element_pseudo_allowed, + function( $pseudo_selector ) use ( $selector ) { + return str_contains( $selector, $pseudo_selector ); + } + ) + ); + + $pseudo_selector = isset( $pseudo_matches[0] ) ? $pseudo_matches[0] : null; + // If the current selector is a pseudo selector that's defined in the allow list for the current // element then compute the style properties for it. // Otherwise just compute the styles for the default selector as normal. diff --git a/phpunit/class-wp-theme-json-test.php b/phpunit/class-wp-theme-json-test.php index 4ba9b65aa4f5b..a662b8efb1d9e 100644 --- a/phpunit/class-wp-theme-json-test.php +++ b/phpunit/class-wp-theme-json-test.php @@ -43,7 +43,7 @@ function test_get_stylesheet_handles_whitelisted_element_pseudo_selectors() { $base_styles = 'body { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }'; - $element_styles = 'a{background-color: red;color: green;}a:hover{background-color: green;color: red;font-size: 10em;text-transform: uppercase;}a:focus{background-color: black;color: yellow;}'; + $element_styles = 'a:not(.wp-element-button){background-color: red;color: green;}a:not(.wp-element-button):hover{background-color: green;color: red;font-size: 10em;text-transform: uppercase;}a:not(.wp-element-button):focus{background-color: black;color: yellow;}'; $expected = $base_styles . $element_styles; @@ -82,7 +82,7 @@ function test_get_stylesheet_handles_only_psuedo_selector_rules_for_given_proper $base_styles = 'body { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }'; - $element_styles = 'a:hover{background-color: green;color: red;font-size: 10em;text-transform: uppercase;}a:focus{background-color: black;color: yellow;}'; + $element_styles = 'a:not(.wp-element-button):hover{background-color: green;color: red;font-size: 10em;text-transform: uppercase;}a:not(.wp-element-button):focus{background-color: black;color: yellow;}'; $expected = $base_styles . $element_styles; @@ -160,7 +160,7 @@ function test_get_stylesheet_ignores_non_whitelisted_pseudo_selectors() { $base_styles = 'body { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }'; - $element_styles = 'a{background-color: red;color: green;}a:hover{background-color: green;color: red;}'; + $element_styles = 'a:not(.wp-element-button){background-color: red;color: green;}a:not(.wp-element-button):hover{background-color: green;color: red;}'; $expected = $base_styles . $element_styles; @@ -208,7 +208,7 @@ function test_get_stylesheet_handles_priority_of_elements_vs_block_elements_pseu $base_styles = 'body { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }'; - $element_styles = '.wp-block-group a{background-color: red;color: green;}.wp-block-group a:hover{background-color: green;color: red;font-size: 10em;text-transform: uppercase;}.wp-block-group a:focus{background-color: black;color: yellow;}'; + $element_styles = '.wp-block-group a:not(.wp-element-button){background-color: red;color: green;}.wp-block-group a:not(.wp-element-button):hover{background-color: green;color: red;font-size: 10em;text-transform: uppercase;}.wp-block-group a:not(.wp-element-button):focus{background-color: black;color: yellow;}'; $expected = $base_styles . $element_styles; @@ -255,7 +255,7 @@ function test_get_stylesheet_handles_whitelisted_block_level_element_pseudo_sele $base_styles = 'body { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }'; - $element_styles = 'a{background-color: red;color: green;}a:hover{background-color: green;color: red;}.wp-block-group a:hover{background-color: black;color: yellow;}'; + $element_styles = 'a:not(.wp-element-button){background-color: red;color: green;}a:not(.wp-element-button):hover{background-color: green;color: red;}.wp-block-group a:not(.wp-element-button):hover{background-color: black;color: yellow;}'; $expected = $base_styles . $element_styles;