Skip to content

Commit

Permalink
Style engine: rename at_rule to rules_groups and update test/docs (#5…
Browse files Browse the repository at this point in the history
…8922)

* Add missing tests
Update var name and documentation

* linty

* Update test to reflect merge functionality

* Return type
fix unit test comment

* Return type again
fix unit test comment again


Co-authored-by: ramonjd <ramonopoly@git.wordpress.org>
Co-authored-by: andrewserong <andrewserong@git.wordpress.org>
Co-authored-by: tellthemachines <isabel_brison@git.wordpress.org>
  • Loading branch information
4 people committed Feb 13, 2024
1 parent 1a2a1d3 commit f790549
Show file tree
Hide file tree
Showing 10 changed files with 164 additions and 56 deletions.
25 changes: 23 additions & 2 deletions packages/style-engine/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,10 +126,31 @@ $styles = array(
'selector' => '.wp-tomato',
'declarations' => array( 'padding' => '100px' )
),
);

$stylesheet = wp_style_engine_get_stylesheet_from_css_rules(
$styles,
array(
'selector' => '.wp-kumquat',
'context' => 'block-supports', // Indicates that these styles should be stored with block supports CSS.
)
);
print_r( $stylesheet ); // .wp-pumpkin{color:orange}.wp-tomato{color:red;padding:100px}
```

It's also possible to build simple, nested CSS rules using the `rules_group` key.

```php
$styles = array(
array(
'rules_group' => '@media (min-width: 80rem)',
'selector' => '.wp-carrot',
'declarations' => array( 'color' => 'orange' )
),
array(
'rules_group' => '@media (min-width: 80rem)',
'selector' => '.wp-tomato',
'declarations' => array( 'color' => 'red' )
),
);

$stylesheet = wp_style_engine_get_stylesheet_from_css_rules(
Expand All @@ -138,7 +159,7 @@ $stylesheet = wp_style_engine_get_stylesheet_from_css_rules(
'context' => 'block-supports', // Indicates that these styles should be stored with block supports CSS.
)
);
print_r( $stylesheet ); // .wp-pumpkin,.wp-kumquat{color:orange}.wp-tomato{color:red;padding:100px}
print_r( $stylesheet ); // @media (min-width: 80rem){.wp-carrot{color:orange}}@media (min-width: 80rem){.wp-tomato{color:red;}}
```

### wp_style_engine_get_stylesheet_from_context()
Expand Down
47 changes: 23 additions & 24 deletions packages/style-engine/class-wp-style-engine-css-rule.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,26 +33,25 @@ class WP_Style_Engine_CSS_Rule {
protected $declarations;

/**
* The CSS nested @rule, such as `@media (min-width: 80rem)` or `@layer module`.
* A parent CSS selector in the case of nested CSS, or a CSS nested @rule, such as `@media (min-width: 80rem)` or `@layer module`..
*
* @var string
*/
protected $at_rule;

protected $rules_group;

/**
* Constructor
*
* @param string $selector The CSS selector.
* @param string[]|WP_Style_Engine_CSS_Declarations $declarations An associative array of CSS definitions, e.g., array( "$property" => "$value", "$property" => "$value" ),
* or a WP_Style_Engine_CSS_Declarations object.
* @param string $at_rule A CSS nested @rule, such as `@media (min-width: 80rem)` or `@layer module`.
* @param string $rules_group A parent CSS selector in the case of nested CSS, or a CSS nested @rule, such as `@media (min-width: 80rem)` or `@layer module`.
*
*/
public function __construct( $selector = '', $declarations = array(), $at_rule = '' ) {
public function __construct( $selector = '', $declarations = array(), $rules_group = '' ) {
$this->set_selector( $selector );
$this->add_declarations( $declarations );
$this->set_at_rule( $at_rule );
$this->set_rules_group( $rules_group );
}

/**
Expand Down Expand Up @@ -92,17 +91,26 @@ public function add_declarations( $declarations ) {
}

/**
* Sets the at_rule.
* Sets the rules group.
*
* @param string $at_rule A CSS nested @rule, such as `@media (min-width: 80rem)` or `@layer module`.
* @param string $rules_group A parent CSS selector in the case of nested CSS, or a CSS nested @rule, such as `@media (min-width: 80rem)` or `@layer module`.
*
* @return WP_Style_Engine_CSS_Rule Returns the object to allow chaining of methods.
*/
public function set_at_rule( $at_rule ) {
$this->at_rule = $at_rule;
public function set_rules_group( $rules_group ) {
$this->rules_group = $rules_group;
return $this;
}

/**
* Gets the rules group.
*
* @return string
*/
public function get_rules_group() {
return $this->rules_group;
}

/**
* Gets the declarations object.
*
Expand All @@ -121,15 +129,6 @@ public function get_selector() {
return $this->selector;
}

/**
* Gets the at_rule.
*
* @return string
*/
public function get_at_rule() {
return $this->at_rule;
}

/**
* Gets the CSS.
*
Expand All @@ -148,16 +147,16 @@ public function get_css( $should_prettify = false, $indent_count = 0 ) {
// Trims any multiple selectors strings.
$selector = $should_prettify ? implode( ',', array_map( 'trim', explode( ',', $this->get_selector() ) ) ) : $this->get_selector();
$selector = $should_prettify ? str_replace( array( ',' ), ",\n", $selector ) : $selector;
$at_rule = $this->get_at_rule();
$has_at_rule = ! empty( $at_rule );
$css_declarations = $this->declarations->get_declarations_string( $should_prettify, $has_at_rule ? $nested_declarations_indent : $declarations_indent );
$rules_group = $this->get_rules_group();
$has_rules_group = ! empty( $rules_group );
$css_declarations = $this->declarations->get_declarations_string( $should_prettify, $has_rules_group ? $nested_declarations_indent : $declarations_indent );

if ( empty( $css_declarations ) ) {
return '';
}

if ( $has_at_rule ) {
$selector = "{$rule_indent}{$at_rule}{$spacer}{{$suffix}{$nested_rule_indent}{$selector}{$spacer}{{$suffix}{$css_declarations}{$suffix}{$nested_rule_indent}}{$suffix}{$rule_indent}}";
if ( $has_rules_group ) {
$selector = "{$rule_indent}{$rules_group}{$spacer}{{$suffix}{$nested_rule_indent}{$selector}{$spacer}{{$suffix}{$css_declarations}{$suffix}{$nested_rule_indent}}{$suffix}{$rule_indent}}";
return $selector;
}

Expand Down
18 changes: 9 additions & 9 deletions packages/style-engine/class-wp-style-engine-css-rules-store.php
Original file line number Diff line number Diff line change
Expand Up @@ -109,25 +109,25 @@ public function get_all_rules() {
* Gets a WP_Style_Engine_CSS_Rule object by its selector.
* If the rule does not exist, it will be created.
*
* @param string $selector The CSS selector.
* @param string $at_rule The CSS nested @rule, such as `@media (min-width: 80rem)` or `@layer module`.
* @param string $selector The CSS selector.
* @param string $rules_group A parent CSS selector in the case of nested CSS, or a CSS nested @rule, such as `@media (min-width: 80rem)` or `@layer module`..
*
* @return WP_Style_Engine_CSS_Rule|void Returns a WP_Style_Engine_CSS_Rule object, or null if the selector is empty.
*/
public function add_rule( $selector, $at_rule = '' ) {
$selector = trim( $selector );
$at_rule = trim( $at_rule );
public function add_rule( $selector, $rules_group = '' ) {
$selector = $selector ? trim( $selector ) : '';
$rules_group = $rules_group ? trim( $rules_group ) : '';

// Bail early if there is no selector.
if ( empty( $selector ) ) {
return;
}

if ( ! empty( $at_rule ) ) {
if ( empty( $this->rules[ "$at_rule $selector" ] ) ) {
$this->rules[ "$at_rule $selector" ] = new WP_Style_Engine_CSS_Rule( $selector, array(), $at_rule );
if ( ! empty( $rules_group ) ) {
if ( empty( $this->rules[ "$rules_group $selector" ] ) ) {
$this->rules[ "$rules_group $selector" ] = new WP_Style_Engine_CSS_Rule( $selector, array(), $rules_group );
}
return $this->rules[ "$at_rule $selector" ];
return $this->rules[ "$rules_group $selector" ];
}

// Create the rule if it doesn't exist.
Expand Down
12 changes: 6 additions & 6 deletions packages/style-engine/class-wp-style-engine-processor.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,20 +65,20 @@ public function add_rules( $css_rules ) {
}

foreach ( $css_rules as $rule ) {
$selector = $rule->get_selector();
$at_rule = $rule->get_at_rule();
$selector = $rule->get_selector();
$rules_group = $rule->get_rules_group();

/**
* If there is an at_rule and it already exists in the css_rules array,
* add the rule to it.
* Otherwise, create a new entry for the at_rule
*/
if ( ! empty( $at_rule ) ) {
if ( isset( $this->css_rules[ "$at_rule $selector" ] ) ) {
$this->css_rules[ "$at_rule $selector" ]->add_declarations( $rule->get_declarations() );
if ( ! empty( $rules_group ) ) {
if ( isset( $this->css_rules[ "$rules_group $selector" ] ) ) {
$this->css_rules[ "$rules_group $selector" ]->add_declarations( $rule->get_declarations() );
continue;
}
$this->css_rules[ "$at_rule $selector" ] = $rule;
$this->css_rules[ "$rules_group $selector" ] = $rule;
continue;
}

Expand Down
5 changes: 3 additions & 2 deletions packages/style-engine/class-wp-style-engine.php
Original file line number Diff line number Diff line change
Expand Up @@ -355,14 +355,15 @@ protected static function is_valid_style_value( $style_value ) {
* @param string $store_name A valid store key.
* @param string $css_selector When a selector is passed, the function will return a full CSS rule `$selector { ...rules }`, otherwise a concatenated string of properties and values.
* @param string[] $css_declarations An associative array of CSS definitions, e.g., array( "$property" => "$value", "$property" => "$value" ).
* @param string $rules_group Optional. A parent CSS selector in the case of nested CSS, or a CSS nested @rule, such as `@media (min-width: 80rem)` or `@layer module`.
*
* @return void.
*/
public static function store_css_rule( $store_name, $css_selector, $css_declarations, $css_at_rule = '' ) {
public static function store_css_rule( $store_name, $css_selector, $css_declarations, $rules_group = '' ) {
if ( empty( $store_name ) || empty( $css_selector ) || empty( $css_declarations ) ) {
return;
}
static::get_store( $store_name )->add_rule( $css_selector, $css_at_rule )->add_declarations( $css_declarations );
static::get_store( $store_name )->add_rule( $css_selector, $rules_group )->add_declarations( $css_declarations );
}

/**
Expand Down
9 changes: 4 additions & 5 deletions packages/style-engine/style-engine.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ function wp_style_engine_get_styles( $block_styles, $options = array() ) {
* Required. A collection of CSS rules.
*
* @type array ...$0 {
* @type string $at_rule A CSS nested @rule, such as `@media (min-width: 80rem)` or `@layer module`.
* @type string $rules_group A parent CSS selector in the case of nested CSS, or a CSS nested @rule, such as `@media (min-width: 80rem)` or `@layer module`.
* @type string $selector A CSS selector.
* @type string[] $declarations An associative array of CSS definitions, e.g., array( "$property" => "$value", "$property" => "$value" ).
* }
Expand Down Expand Up @@ -117,13 +117,12 @@ function wp_style_engine_get_stylesheet_from_css_rules( $css_rules, $options = a
continue;
}

$at_rule = ! empty( $css_rule['at_rule'] ) ? $css_rule['at_rule'] : '';

$rules_group = $css_rule['rules_group'] ?? null;
if ( ! empty( $options['context'] ) ) {
WP_Style_Engine::store_css_rule( $options['context'], $css_rule['selector'], $css_rule['declarations'], $at_rule );
WP_Style_Engine::store_css_rule( $options['context'], $css_rule['selector'], $css_rule['declarations'], $rules_group );
}

$css_rule_objects[] = new WP_Style_Engine_CSS_Rule( $css_rule['selector'], $css_rule['declarations'], $at_rule );
$css_rule_objects[] = new WP_Style_Engine_CSS_Rule( $css_rule['selector'], $css_rule['declarations'], $rules_group );
}

if ( empty( $css_rule_objects ) ) {
Expand Down
16 changes: 16 additions & 0 deletions phpunit/style-engine/class-wp-style-engine-css-rule-test.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,22 @@ public function test_should_instantiate_with_selector_and_rules() {
$this->assertSame( $expected, $css_rule->get_css(), 'Value returned by get_css() does not match expected declarations string.' );
}

/**
* Tests setting and getting a rules group.
*
* @covers ::set_rules_group
* @covers ::get_rules_group
*/
public function test_should_set_rules_group() {
$rule = new WP_Style_Engine_CSS_Rule_Gutenberg( '.heres-johnny', array(), '@layer state' );

$this->assertSame( '@layer state', $rule->get_rules_group(), 'Return value of get_rules_group() does not match value passed to constructor.' );

$rule->set_rules_group( '@layer pony' );

$this->assertSame( '@layer pony', $rule->get_rules_group(), 'Return value of get_rules_group() does not match value passed to set_rules_group().' );
}

/**
* Tests that declaration properties are deduplicated.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,4 +170,20 @@ public function test_should_get_all_rule_objects_for_a_store() {

$this->assertSame( $expected, $new_pizza_store->get_all_rules(), 'Return value for get_all_rules() does not match expectations after adding new rules to store.' );
}

/**
* Tests adding rules group keys to store.
*
* @covers ::add_rule
*/
public function test_should_store_as_concatenated_rules_groups_and_selector() {
$store_one = WP_Style_Engine_CSS_Rules_Store_Gutenberg::get_store( 'one' );
$store_one_rule = $store_one->add_rule( '.tony', '.one' );

$this->assertSame(
'.one .tony',
"{$store_one_rule->get_rules_group()} {$store_one_rule->get_selector()}",
'add_rule() does not concatenate rules group and selector.'
);
}
}
8 changes: 4 additions & 4 deletions phpunit/style-engine/class-wp-style-engine-processor-test.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public function test_should_return_nested_rules_as_compiled_css() {
'background-color' => 'purple',
)
);
$a_nice_css_rule->set_at_rule( '@media (min-width: 80rem)' );
$a_nice_css_rule->set_rules_group( '@media (min-width: 80rem)' );

$a_nicer_css_rule = new WP_Style_Engine_CSS_Rule_Gutenberg( '.a-nicer-rule' );
$a_nicer_css_rule->add_declarations(
Expand All @@ -68,7 +68,7 @@ public function test_should_return_nested_rules_as_compiled_css() {
'background-color' => 'purple',
)
);
$a_nicer_css_rule->set_at_rule( '@layer nicety' );
$a_nicer_css_rule->set_rules_group( '@layer nicety' );

$a_nice_processor = new WP_Style_Engine_Processor_Gutenberg();
$a_nice_processor->add_rules( array( $a_nice_css_rule, $a_nicer_css_rule ) );
Expand Down Expand Up @@ -143,7 +143,7 @@ public function test_should_return_prettified_nested_css_rules() {
'background-color' => 'orange',
)
);
$a_wonderful_css_rule->set_at_rule( '@media (min-width: 80rem)' );
$a_wonderful_css_rule->set_rules_group( '@media (min-width: 80rem)' );

$a_very_wonderful_css_rule = new WP_Style_Engine_CSS_Rule_Gutenberg( '.a-very_wonderful-rule' );
$a_very_wonderful_css_rule->add_declarations(
Expand All @@ -152,7 +152,7 @@ public function test_should_return_prettified_nested_css_rules() {
'background-color' => 'orange',
)
);
$a_very_wonderful_css_rule->set_at_rule( '@layer wonderfulness' );
$a_very_wonderful_css_rule->set_rules_group( '@layer wonderfulness' );

$a_wonderful_processor = new WP_Style_Engine_Processor_Gutenberg();
$a_wonderful_processor->add_rules( array( $a_wonderful_css_rule, $a_very_wonderful_css_rule ) );
Expand Down
Loading

1 comment on commit f790549

@github-actions
Copy link

Choose a reason for hiding this comment

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

Flaky tests detected in f790549.
Some tests passed with failed attempts. The failures may not be related to this commit but are still reported for visibility. See the documentation for more information.

🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/7892848149
📝 Reported issues:

Please sign in to comment.