Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
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
Next Next commit
Global Styles: Prevent duplicate CSS for block style variations
  • Loading branch information
aaronrobertshaw committed Jun 14, 2024
commit 82c3a1ab2c1da33a252572282aa55534b8e43c86
1 change: 1 addition & 0 deletions src/wp-includes/block-supports/block-style-variations.php
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ function wp_render_block_style_variation_support_styles( $parsed_block ) {
array( 'styles' ),
array( 'custom' ),
array(
'block_style_variations' => true,
'skip_root_layout_styles' => true,
'scope' => ".$class_name",
)
Expand Down
27 changes: 20 additions & 7 deletions src/wp-includes/class-wp-theme-json.php
Original file line number Diff line number Diff line change
Expand Up @@ -750,7 +750,7 @@ public static function get_element_class_name( $element ) {
* @param string $origin Optional. What source of data this object represents.
* One of 'blocks', 'default', 'theme', or 'custom'. Default 'theme'.
*/
public function __construct( $theme_json = array( 'version' => WP_Theme_JSON::LATEST_SCHEMA ), $origin = 'theme' ) {
public function __construct( $theme_json = array( 'version' => self::LATEST_SCHEMA ), $origin = 'theme' ) {
if ( ! in_array( $origin, static::VALID_ORIGINS, true ) ) {
$origin = 'theme';
}
Expand Down Expand Up @@ -1260,6 +1260,7 @@ public function get_settings() {
* @type string $scope Makes sure all style are scoped to a given selector
* @type string $root_selector Overwrites and forces a given selector to be used on the root node
* @type bool $skip_root_layout_styles Omits root layout styles from the generated stylesheet. Default false.
* @type bool $block_style_variations Includes styles for block style variations in the generated stylesheet. Default false.
* }
* @return string The resulting stylesheet.
*/
Expand All @@ -1281,7 +1282,7 @@ public function get_stylesheet( $types = array( 'variables', 'styles', 'presets'
}

$blocks_metadata = static::get_blocks_metadata();
$style_nodes = static::get_style_nodes( $this->theme_json, $blocks_metadata );
$style_nodes = static::get_style_nodes( $this->theme_json, $blocks_metadata, $options );
$setting_nodes = static::get_setting_nodes( $this->theme_json, $blocks_metadata );

$root_style_key = array_search( static::ROOT_BLOCK_SELECTOR, array_column( $style_nodes, 'selector' ), true );
Expand Down Expand Up @@ -2449,9 +2450,14 @@ protected static function get_setting_nodes( $theme_json, $selectors = array() )
*
* @param array $theme_json The tree to extract style nodes from.
* @param array $selectors List of selectors per block.
* @param array $options {
* Optional. An array of options for now used for internal purposes only (may change without notice).
*
* @type bool $block_style_variations Includes style nodes for block style variations. Default false.
* }
* @return array An array of style nodes metadata.
*/
protected static function get_style_nodes( $theme_json, $selectors = array() ) {
protected static function get_style_nodes( $theme_json, $selectors = array(), $options = array() ) {
$nodes = array();
if ( ! isset( $theme_json['styles'] ) ) {
return $nodes;
Expand Down Expand Up @@ -2493,7 +2499,7 @@ protected static function get_style_nodes( $theme_json, $selectors = array() ) {
return $nodes;
}

$block_nodes = static::get_block_nodes( $theme_json );
$block_nodes = static::get_block_nodes( $theme_json, $options );
foreach ( $block_nodes as $block_node ) {
$nodes[] = $block_node;
}
Expand Down Expand Up @@ -2566,9 +2572,14 @@ private static function update_separator_declarations( $declarations ) {
* @since 6.3.0 Refactored and stabilized selectors API.
*
* @param array $theme_json The theme.json converted to an array.
* @param array $options {
* Optional. An array of options for now used for internal purposes only (may change without notice).
*
* @type bool $block_style_variations Includes nodes for block style variations. Default false.
* }
* @return array The block nodes in theme.json.
*/
private static function get_block_nodes( $theme_json ) {
private static function get_block_nodes( $theme_json, $options = array() ) {
$selectors = static::get_blocks_metadata();
$nodes = array();
if ( ! isset( $theme_json['styles'] ) ) {
Expand Down Expand Up @@ -2597,7 +2608,8 @@ private static function get_block_nodes( $theme_json ) {
}

$variation_selectors = array();
if ( isset( $node['variations'] ) ) {
$include_variations = $options['block_style_variations'] ?? false;
if ( $include_variations && isset( $node['variations'] ) ) {
foreach ( $node['variations'] as $variation => $node ) {
$variation_selectors[] = array(
'path' => array( 'styles', 'blocks', $name, 'variations', $variation ),
Expand Down Expand Up @@ -3266,7 +3278,8 @@ public static function remove_insecure_properties( $theme_json, $origin = 'theme
$theme_json = static::sanitize( $theme_json, $valid_block_names, $valid_element_names, $valid_variations );

$blocks_metadata = static::get_blocks_metadata();
$style_nodes = static::get_style_nodes( $theme_json, $blocks_metadata );
$style_options = array( 'block_style_variations' => true ); // Allow variations data.
$style_nodes = static::get_style_nodes( $theme_json, $blocks_metadata, $style_options );

foreach ( $style_nodes as $metadata ) {
$input = _wp_array_get( $theme_json, $metadata['path'], array() );
Expand Down
79 changes: 79 additions & 0 deletions tests/phpunit/tests/theme/wpThemeJson.php
Original file line number Diff line number Diff line change
Expand Up @@ -5500,4 +5500,83 @@ public function test_scope_style_node_selectors() {

$this->assertEquals( $expected, $actual );
}

/**
* Block style variations styles aren't generated by default. This test covers
* the `get_block_nodes` does not include variations by default, preventing
* the inclusion of their styles.
*
* @ticket 61443
*/
public function test_opt_out_of_block_style_variations_by_default() {
$theme_json = new ReflectionClass( 'WP_Theme_JSON' );

$func = $theme_json->getMethod( 'get_block_nodes' );
$func->setAccessible( true );

$theme_json = array(
'version' => WP_Theme_JSON::LATEST_SCHEMA,
'styles' => array(
'blocks' => array(
'core/button' => array(
'variations' => array(
'outline' => array(
'color' => array(
'background' => 'red',
),
),
),
),
),
),
);

$block_nodes = $func->invoke( null, $theme_json );
$button_variations = $block_nodes[0]['variations'] ?? array();

$this->assertEquals( array(), $button_variations );
}

/**
* Block style variations styles aren't generated by default. This test ensures
* variations are included by `get_block_nodes` when requested.
*
* @ticket 61443
*/
public function test_opt_in_to_block_style_variations() {
$theme_json = new ReflectionClass( 'WP_Theme_JSON' );

$func = $theme_json->getMethod( 'get_block_nodes' );
$func->setAccessible( true );

$theme_json = array(
'version' => WP_Theme_JSON::LATEST_SCHEMA,
'styles' => array(
'blocks' => array(
'core/button' => array(
'variations' => array(
'outline' => array(
'color' => array(
'background' => 'red',
),
),
),
),
),
),
);
$options = array( 'block_style_variations' => true );

$block_nodes = $func->invoke( null, $theme_json, $options );
$button_variations = $block_nodes[0]['variations'] ?? array();

$expected = array(
array(
'path' => array( 'styles', 'blocks', 'core/button', 'variations', 'outline' ),
'selector' => '.wp-block-button.is-style-outline .wp-block-button__link',
),
);

$this->assertEquals( $expected, $button_variations );
}
}