Skip to content

Commit

Permalink
Process CSS nesting
Browse files Browse the repository at this point in the history
  • Loading branch information
aristath committed Dec 15, 2022
1 parent 6d32468 commit c9814c8
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 10 deletions.
32 changes: 27 additions & 5 deletions lib/compat/wordpress-6.2/class-wp-theme-json-6-2.php
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,27 @@ protected static function remove_insecure_styles( $input ) {
return $output;
}

/**
* 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.
*/
private function process_nested_css( $css, $selector ) {
$processed_css = '';

// Split CSS nested rules.
$parts = explode( '&', $css );
foreach ( $parts as $part ) {
$processed_css .= ( ! str_contains( $part, '{' ) )
? $selector . '{' . $part . '}' // If the part doesn't contain braces, it applies to the root level.
: $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 @@ -383,15 +404,16 @@ 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:
// Add the global styles root CSS.
$stylesheet .= _wp_array_get( $this->theme_json, array( 'styles', 'css' ) );

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -939,18 +939,30 @@ export function useGlobalStylesOutput() {
},
];

const processCSSNesting = ( css, blockSelector ) => {
let processedCSS = '';

// Split CSS nested rules.
const parts = css.split( '&' );
parts.forEach( ( part ) => {
processedCSS += ! part.includes( '{' )
? blockSelector + '{' + part + '}' // If the part doesn't contain braces, it applies to the root level.
: blockSelector + part; // Prepend the selector, which effectively replaces the "&" character.
} );
return processedCSS;
};

// Loop through the blocks to check if there are custom CSS values.
// If there are, get the block selector and push the selector together with
// the CSS value to the 'stylesheets' array.
Object.entries( blockNames ).forEach( ( name ) => {
if ( mergedConfig.styles.blocks[ name[ 0 ] ]?.css ) {
const selector = blockSelectors[ name[ 0 ] ].selector;
stylesheets.push( {
css:
selector +
'{' +
mergedConfig.styles.blocks[ name[ 0 ] ]?.css +
'}',
css: processCSSNesting(
mergedConfig.styles.blocks[ name[ 0 ] ]?.css,
selector
),
isGlobalStyles: true,
} );
}
Expand Down

0 comments on commit c9814c8

Please sign in to comment.