Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
aristath committed Feb 1, 2023
1 parent 540e118 commit d9be94e
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 0 deletions.
33 changes: 33 additions & 0 deletions src/wp-includes/class-wp-theme-json.php
Original file line number Diff line number Diff line change
Expand Up @@ -883,6 +883,27 @@ public function get_settings() {
}
}

/**
* Processes the CSS, to apply nesting.
*
* @param string $css The CSS to process.
* @param string $selector The selector to nest.
*
* @return string The processed CSS.
*/
public function process_blocks_custom_css( $css, $selector ) {
$processed_css = '';

// Split CSS nested rules.
$parts = explode( '&', $css );
foreach ( $parts as $part ) {
$processed_css .= ( ! str_contains( $part, '{' ) )
? trim( $selector ) . '{' . trim( $part ) . '}' // If the part doesn't contain braces, it applies to the root level.
: trim( $selector . $part ); // Prepend the selector, which effectively replaces the "&" character.
}
return $processed_css;
}

/**
* Returns the stylesheet that results of processing
* the theme.json structure this object represents.
Expand Down Expand Up @@ -957,7 +978,19 @@ public function get_stylesheet( $types = array( 'variables', 'styles', 'presets'

// Load the custom CSS last so it has the highest specificity.
if ( in_array( 'custom-css', $types, true ) ) {
// Add the global styles root CSS.
$stylesheet .= _wp_array_get( $this->theme_json, array( 'styles', 'css' ) );

// Add the global styles block CSS.
if ( isset( $this->theme_json['styles']['blocks'] ) ) {
foreach ( $this->theme_json['styles']['blocks'] as $name => $node ) {
$custom_block_css = _wp_array_get( $this->theme_json, array( 'styles', 'blocks', $name, 'css' ) );
if ( $custom_block_css ) {
$selector = static::$blocks_metadata[ $name ]['selector'];
$stylesheet .= $this->process_blocks_custom_css( $custom_block_css, $selector );
}
}
}
}

return $stylesheet;
Expand Down
51 changes: 51 additions & 0 deletions tests/phpunit/tests/theme/wpThemeJson.php
Original file line number Diff line number Diff line change
Expand Up @@ -4249,4 +4249,55 @@ public function data_custom_css_for_user_caps() {
),
);
}

/**
* @dataProvider data_process_blocks_custom_css
*
* @param array $input An array containing the selector and css to test.
* @param string $expected Expected results.
*/
public function test_process_blocks_custom_css( $input, $expected ) {
$theme_json = new WP_Theme_JSON(
array(
'version' => WP_Theme_JSON::LATEST_SCHEMA,
'styles' => array(),
)
);

$this->assertEquals( $expected, $theme_json->process_blocks_custom_css( $input['css'], $input['selector'] ) );
}

/**
* Data provider.
*
* @return array[]
*/
public function data_process_blocks_custom_css() {
return array(
// Simple CSS without any child selectors.
'no child selectors' => array(
'input' => array(
'selector' => '.foo',
'css' => 'color: red; margin: auto;',
),
'expected' => '.foo{color: red; margin: auto;}',
),
// CSS with child selectors.
'with children' => array(
'input' => array(
'selector' => '.foo',
'css' => 'color: red; margin: auto; & .bar{color: blue;}',
),
'expected' => '.foo{color: red; margin: auto;}.foo .bar{color: blue;}',
),
// CSS with child selectors and pseudo elements.
'with children and pseudo elements' => array(
'input' => array(
'selector' => '.foo',
'css' => 'color: red; margin: auto; & .bar{color: blue;} &::before{color: green;}',
),
'expected' => '.foo{color: red; margin: auto;}.foo .bar{color: blue;}.foo::before{color: green;}',
),
);
}
}

0 comments on commit d9be94e

Please sign in to comment.