Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Apply ! important to user preset styles for theme.json themes only #39660

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions lib/compat/wordpress-6.0/class-wp-theme-json-gutenberg.php
Original file line number Diff line number Diff line change
Expand Up @@ -161,4 +161,44 @@ public function get_data() {
return $flattened_theme_json;
}

/**
* Given a settings array, it returns the generated rulesets
* for the preset classes.
*
* @param array $settings Settings to process.
* @param string $selector Selector wrapping the classes.
* @param array $origins List of origins to process.
* @return string The result of processing the presets.
*/
protected static function compute_preset_classes( $settings, $selector, $origins ) {
if ( static::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 ( static::PRESETS_METADATA as $preset_metadata ) {
$slugs = static::get_settings_slugs( $settings, $preset_metadata, $origins );
foreach ( $preset_metadata['classes'] as $class => $property ) {
foreach ( $slugs as $slug ) {
$css_var = static::replace_slug_in_string( $preset_metadata['css_vars'], $slug );
$class_name = static::replace_slug_in_string( $class, $slug );
$prioritize_user_presets = ( WP_Theme_JSON_Resolver_Gutenberg::theme_has_support() ) ? ' !important' : '';
Copy link
Member

@oandregal oandregal Apr 4, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So far the WP_Theme_JSON class has stayed theme-agnostic and it was pure (it only used the input data passed to it to compute the output, nothing from the surrounding environment). The WP_Theme_JSON_Resolver was the one that picked up environment data. I think we should keep these concerns separated.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 Good point


$stylesheet .= static::to_ruleset(
static::append_to_selector( $selector, $class_name ),
array(
array(
'name' => $property,
'value' => 'var(' . $css_var . ')' . $prioritize_user_presets,
),
)
);
}
}
}

return $stylesheet;
}
}
73 changes: 72 additions & 1 deletion phpunit/class-wp-theme-json-test.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,33 @@
*/

class WP_Theme_JSON_Gutenberg_Test extends WP_UnitTestCase {
function setUp() {
parent::setUp();
$this->theme_root = realpath( __DIR__ . '/data/themedir1' );
$this->orig_theme_dir = $GLOBALS['wp_theme_directories'];

// /themes is necessary as theme.php functions assume /themes is the root if there is only one root.
$GLOBALS['wp_theme_directories'] = array( WP_CONTENT_DIR . '/themes', $this->theme_root );

add_filter( 'theme_root', array( $this, 'filter_set_theme_root' ) );
add_filter( 'stylesheet_root', array( $this, 'filter_set_theme_root' ) );
add_filter( 'template_root', array( $this, 'filter_set_theme_root' ) );
$this->queries = array();
// Clear caches.
wp_clean_themes_cache();
unset( $GLOBALS['wp_themes'] );
}

function tearDown() {
$GLOBALS['wp_theme_directories'] = $this->orig_theme_dir;
wp_clean_themes_cache();
unset( $GLOBALS['wp_themes'] );
parent::tearDown();
}

function filter_set_theme_root() {
return $this->theme_root;
}

function test_get_settings() {
$theme_json = new WP_Theme_JSON_Gutenberg(
Expand Down Expand Up @@ -408,6 +435,7 @@ function test_get_stylesheet_renders_enabled_protected_properties() {
}

function test_get_stylesheet() {
switch_theme( 'block-theme' );
$theme_json = new WP_Theme_JSON_Gutenberg(
array(
'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA,
Expand Down Expand Up @@ -538,6 +566,7 @@ function test_get_stylesheet() {
}

function test_get_stylesheet_preset_classes_work_with_compounded_selectors() {
switch_theme( 'block-theme' );
$theme_json = new WP_Theme_JSON_Gutenberg(
array(
'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA,
Expand Down Expand Up @@ -565,6 +594,7 @@ function test_get_stylesheet_preset_classes_work_with_compounded_selectors() {
}

function test_get_stylesheet_preset_rules_come_after_block_rules() {
switch_theme( 'block-theme' );
$theme_json = new WP_Theme_JSON_Gutenberg(
array(
'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA,
Expand Down Expand Up @@ -605,6 +635,7 @@ function test_get_stylesheet_preset_rules_come_after_block_rules() {
}

function test_get_stylesheet_generates_proper_classes_and_css_vars_from_slugs() {
switch_theme( 'block-theme' );
$theme_json = new WP_Theme_JSON_Gutenberg(
array(
'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA,
Expand Down Expand Up @@ -647,7 +678,8 @@ function test_get_stylesheet_generates_proper_classes_and_css_vars_from_slugs()

}

public function test_get_stylesheet_preset_values_are_marked_as_important() {
public function test_get_stylesheet_preset_values_are_marked_as_important_for_themejson_theme() {
switch_theme( 'block-theme' );
$theme_json = new WP_Theme_JSON_Gutenberg(
array(
'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA,
Expand Down Expand Up @@ -685,6 +717,44 @@ public function test_get_stylesheet_preset_values_are_marked_as_important() {
);
}

public function test_get_stylesheet_preset_values_not_marked_as_important_for_non_themejson_theme() {
switch_theme( 'default-theme' );
$theme_json = new WP_Theme_JSON_Gutenberg(
array(
'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA,
'settings' => array(
'color' => array(
'palette' => array(
array(
'slug' => 'grey',
'color' => 'grey',
),
),
),
),
'styles' => array(
'blocks' => array(
'core/paragraph' => array(
'color' => array(
'text' => 'red',
'background' => 'blue',
),
'typography' => array(
'fontSize' => '12px',
'lineHeight' => '1.3',
),
),
),
),
),
'default'
);

$this->assertEquals(
'body{--wp--preset--color--grey: grey;}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; }p{background-color: blue;color: red;font-size: 12px;line-height: 1.3;}.has-grey-color{color: var(--wp--preset--color--grey);}.has-grey-background-color{background-color: var(--wp--preset--color--grey);}.has-grey-border-color{border-color: var(--wp--preset--color--grey);}',
$theme_json->get_stylesheet()
);
}
public function test_merge_incoming_data() {
$theme_json = new WP_Theme_JSON_Gutenberg(
array(
Expand Down Expand Up @@ -931,6 +1001,7 @@ public function test_merge_incoming_data() {
}

public function test_merge_incoming_data_empty_presets() {
switch_theme( 'block-theme' );
$theme_json = new WP_Theme_JSON_Gutenberg(
array(
'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA,
Expand Down