Skip to content

Commit

Permalink
Global Styles: fix specificity conflict of blocks with single classes…
Browse files Browse the repository at this point in the history
… as selectors (#29378)

We want the source order specificity for presets
to be higher than for block styles, to fix cases in which the
block selector has the same specificity as the class.

Ex:

- an user attaches the .has-white-color class to a block
  of type "my block", whose selector is .wp-block-my-block.

- the themes targets the color of "my block" as well,
  generating a rule with the .wp-block-my-block selector.

The color applied to the block that was tweaked by the user
will be the last in the source.
  • Loading branch information
nosolosw authored Mar 2, 2021
1 parent 5a98254 commit e18750d
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 12 deletions.
21 changes: 11 additions & 10 deletions lib/class-wp-theme-json.php
Original file line number Diff line number Diff line change
Expand Up @@ -785,22 +785,22 @@ private static function compute_style_properties( $declarations, $styles, $suppo
}

/**
* Given a settings array, it extracts its presets
* and adds them to the given input $stylesheet.
* Given a settings array, it returns the generated rulesets
* for the preset classes.
*
* @param string $stylesheet Input stylesheet to add the presets to.
* @param array $settings Settings to process.
* @param string $selector Selector wrapping the classes.
*
* @return the modified $stylesheet.
* @return string The result of processing the presets.
*/
private static function compute_preset_classes( $stylesheet, $settings, $selector ) {
private static function compute_preset_classes( $settings, $selector ) {
if ( self::ROOT_BLOCK_SELECTOR === $selector ) {
// Classes at the global level do not need any CSS prefixed,
// and we don't want to increase its specificity.
$selector = '';
}

$stylesheet = '';
foreach ( self::PRESETS_METADATA as $preset ) {
$values = gutenberg_experimental_get( $settings, $preset['path'], array() );
foreach ( $values as $value ) {
Expand Down Expand Up @@ -1002,7 +1002,9 @@ private function get_block_styles() {
return $stylesheet;
}

$metadata = self::get_blocks_metadata();
$metadata = self::get_blocks_metadata();
$block_rules = '';
$preset_rules = '';
foreach ( $metadata as $block_selector => $metadata ) {
if ( empty( $metadata['selector'] ) ) {
continue;
Expand All @@ -1020,19 +1022,18 @@ private function get_block_styles() {
);
}

$stylesheet .= self::to_ruleset( $selector, $declarations );
$block_rules .= self::to_ruleset( $selector, $declarations );

// Attach the rulesets for the classes.
if ( isset( $this->theme_json['settings'][ $block_selector ] ) ) {
$stylesheet = self::compute_preset_classes(
$stylesheet,
$preset_rules .= self::compute_preset_classes(
$this->theme_json['settings'][ $block_selector ],
$selector
);
}
}

return $stylesheet;
return $block_rules . $preset_rules;
}

/**
Expand Down
39 changes: 37 additions & 2 deletions phpunit/class-wp-theme-json-test.php
Original file line number Diff line number Diff line change
Expand Up @@ -280,11 +280,11 @@ function test_get_stylesheet() {
);

$this->assertEquals(
':root{--wp--preset--color--grey: grey;--wp--preset--font-family--small: 14px;--wp--preset--font-family--big: 41px;}.wp-block-group{--wp--custom--base-font: 16;--wp--custom--line-height--small: 1.2;--wp--custom--line-height--medium: 1.4;--wp--custom--line-height--large: 1.8;}:root{--wp--style--color--link: #111;color: var(--wp--preset--color--grey);}.has-grey-color{color: grey;}.has-grey-background-color{background-color: grey;}.wp-block-group{padding-top: 12px;padding-bottom: 24px;}',
':root{--wp--preset--color--grey: grey;--wp--preset--font-family--small: 14px;--wp--preset--font-family--big: 41px;}.wp-block-group{--wp--custom--base-font: 16;--wp--custom--line-height--small: 1.2;--wp--custom--line-height--medium: 1.4;--wp--custom--line-height--large: 1.8;}:root{--wp--style--color--link: #111;color: var(--wp--preset--color--grey);}.wp-block-group{padding-top: 12px;padding-bottom: 24px;}.has-grey-color{color: grey;}.has-grey-background-color{background-color: grey;}',
$theme_json->get_stylesheet()
);
$this->assertEquals(
':root{--wp--style--color--link: #111;color: var(--wp--preset--color--grey);}.has-grey-color{color: grey;}.has-grey-background-color{background-color: grey;}.wp-block-group{padding-top: 12px;padding-bottom: 24px;}',
':root{--wp--style--color--link: #111;color: var(--wp--preset--color--grey);}.wp-block-group{padding-top: 12px;padding-bottom: 24px;}.has-grey-color{color: grey;}.has-grey-background-color{background-color: grey;}',
$theme_json->get_stylesheet( 'block_styles' )
);
$this->assertEquals(
Expand All @@ -293,6 +293,41 @@ function test_get_stylesheet() {
);
}

function test_get_stylesheet_preset_rules_come_after_block_rules() {
$theme_json = new WP_Theme_JSON(
array(
'settings' => array(
'core/group' => array(
'color' => array(
'palette' => array(
array(
'slug' => 'grey',
'color' => 'grey',
),
),
),
),
),
'styles' => array(
'core/group' => array(
'color' => array(
'text' => 'red',
),
),
),
)
);

$this->assertEquals(
'.wp-block-group{--wp--preset--color--grey: grey;}.wp-block-group{color: red;}.wp-block-group.has-grey-color{color: grey;}.wp-block-group.has-grey-background-color{background-color: grey;}',
$theme_json->get_stylesheet()
);
$this->assertEquals(
'.wp-block-group{color: red;}.wp-block-group.has-grey-color{color: grey;}.wp-block-group.has-grey-background-color{background-color: grey;}',
$theme_json->get_stylesheet( 'block_styles' )
);
}

public function test_merge_incoming_data() {
$root_name = WP_Theme_JSON::ROOT_BLOCK_NAME;
$initial = array(
Expand Down

0 comments on commit e18750d

Please sign in to comment.