From cafd7544c2153e71923eda2b6b495dec6dca266a Mon Sep 17 00:00:00 2001 From: hellofromTonya Date: Wed, 1 Feb 2023 13:43:18 +0000 Subject: [PATCH] Editor: Add support for editing block style variations in global styles. To allow editing of block style variations in global styles, this changeset adds the following for server side support: * building of block style schema into `WP_Theme_JSON::sanitize()`. * appending of style variation selectors to block metadata in `WP_Theme_JSON::get_blocks_metadata()`. * building of selectors and variations for nodes in `WP_Theme_JSON::get_block_nodes()`. Tests for happy and unhappy paths are included. Reference: * [https://github.com/WordPress/gutenberg/pull/46343 Gutenberg PR 46343] Follow-up to [54118], [50973], [50959]. Props isabel_brison, Fixes #57583. Built from https://develop.svn.wordpress.org/trunk@55172 git-svn-id: http://core.svn.wordpress.org/trunk@54705 1a063a9b-81f0-0310-95a4-ce76da25c4cd --- wp-includes/class-wp-theme-json.php | 104 +++++++++++++++++++++++++--- wp-includes/version.php | 2 +- 2 files changed, 97 insertions(+), 9 deletions(-) diff --git a/wp-includes/class-wp-theme-json.php b/wp-includes/class-wp-theme-json.php index 2e39b3c353..1f03a675c5 100644 --- a/wp-includes/class-wp-theme-json.php +++ b/wp-includes/class-wp-theme-json.php @@ -665,9 +665,24 @@ class WP_Theme_JSON { $schema_styles_blocks = array(); $schema_settings_blocks = array(); foreach ( $valid_block_names as $block ) { - $schema_settings_blocks[ $block ] = static::VALID_SETTINGS; - $schema_styles_blocks[ $block ] = $styles_non_top_level; - $schema_styles_blocks[ $block ]['elements'] = $schema_styles_elements; + // Build the schema for each block style variation. + $style_variation_names = array(); + if ( + ! empty( $input['styles']['blocks'][ $block ]['variations'] ) && + is_array( $input['styles']['blocks'][ $block ]['variations'] ) + ) { + $style_variation_names = array_keys( $input['styles']['blocks'][ $block ]['variations'] ); + } + + $schema_styles_variations = array(); + if ( ! empty( $style_variation_names ) ) { + $schema_styles_variations = array_fill_keys( $style_variation_names, $styles_non_top_level ); + } + + $schema_settings_blocks[ $block ] = static::VALID_SETTINGS; + $schema_styles_blocks[ $block ] = $styles_non_top_level; + $schema_styles_blocks[ $block ]['elements'] = $schema_styles_elements; + $schema_styles_blocks[ $block ]['variations'] = $schema_styles_variations; } $schema['styles'] = static::VALID_STYLES; @@ -814,6 +829,15 @@ class WP_Theme_JSON { } static::$blocks_metadata[ $block_name ]['elements'][ $el_name ] = implode( ',', $element_selector ); } + // If the block has style variations, append their selectors to the block metadata. + if ( ! empty( $block_type->styles ) ) { + $style_selectors = array(); + foreach ( $block_type->styles as $style ) { + // The style variation classname is duplicated in the selector to ensure that it overrides core block styles. + $style_selectors[ $style['name'] ] = static::append_to_selector( '.is-style-' . $style['name'] . '.is-style-' . $style['name'], static::$blocks_metadata[ $block_name ]['selector'] ); + } + static::$blocks_metadata[ $block_name ]['styleVariations'] = $style_selectors; + } } return static::$blocks_metadata; @@ -2039,12 +2063,23 @@ class WP_Theme_JSON { $feature_selectors = $selectors[ $name ]['features']; } + $variation_selectors = array(); + if ( isset( $node['variations'] ) ) { + foreach ( $node['variations'] as $variation => $node ) { + $variation_selectors[] = array( + 'path' => array( 'styles', 'blocks', $name, 'variations', $variation ), + 'selector' => $selectors[ $name ]['styleVariations'][ $variation ], + ); + } + } + $nodes[] = array( - 'name' => $name, - 'path' => array( 'styles', 'blocks', $name ), - 'selector' => $selector, - 'duotone' => $duotone_selector, - 'features' => $feature_selectors, + 'name' => $name, + 'path' => array( 'styles', 'blocks', $name ), + 'selector' => $selector, + 'duotone' => $duotone_selector, + 'features' => $feature_selectors, + 'variations' => $variation_selectors, ); if ( isset( $theme_json['styles']['blocks'][ $name ]['elements'] ) ) { @@ -2124,6 +2159,54 @@ class WP_Theme_JSON { } } + // If there are style variations, generate the declarations for them, including any feature selectors the block may have. + $style_variation_declarations = array(); + if ( ! empty( $block_metadata['variations'] ) ) { + foreach ( $block_metadata['variations'] as $style_variation ) { + $style_variation_node = _wp_array_get( $this->theme_json, $style_variation['path'], array() ); + $style_variation_selector = $style_variation['selector']; + + // If the block has feature selectors, generate the declarations for them within the current style variation. + if ( ! empty( $block_metadata['features'] ) ) { + $clean_style_variation_selector = trim( $style_variation_selector ); + foreach ( $block_metadata['features'] as $feature_name => $feature_selector ) { + if ( empty( $style_variation_node[ $feature_name ] ) ) { + continue; + } + // Prepend the variation selector to the feature selector. + $split_feature_selectors = explode( ',', $feature_selector ); + $feature_selectors = array_map( + static function( $split_feature_selector ) use ( $clean_style_variation_selector ) { + return $clean_style_variation_selector . trim( $split_feature_selector ); + }, + $split_feature_selectors + ); + $combined_feature_selectors = implode( ',', $feature_selectors ); + + // Compute declarations for the feature. + $new_feature_declarations = static::compute_style_properties( array( $feature_name => $style_variation_node[ $feature_name ] ), $settings, null, $this->theme_json ); + + /* + * Merge new declarations with any that already exist for + * the feature selector. This may occur when multiple block + * support features use the same custom selector. + */ + if ( isset( $style_variation_declarations[ $combined_feature_selectors ] ) ) { + $style_variation_declarations[ $combined_feature_selectors ] = array_merge( $style_variation_declarations[ $combined_feature_selectors ], $new_feature_declarations ); + } else { + $style_variation_declarations[ $combined_feature_selectors ] = $new_feature_declarations; + } + /* + * Remove the feature from the variation's node now the + * styles will be included under the feature level selector. + */ + unset( $style_variation_node[ $feature_name ] ); + } + } + // Compute declarations for remaining styles not covered by feature level selectors. + $style_variation_declarations[ $style_variation_selector ] = static::compute_style_properties( $style_variation_node, $settings, null, $this->theme_json ); + } + } /* * Get a reference to element name from path. * $block_metadata['path'] = array( 'styles','elements','link' ); @@ -2214,6 +2297,11 @@ class WP_Theme_JSON { $block_rules .= static::to_ruleset( $feature_selector, $individual_feature_declarations ); } + // 6. Generate and append the style variation rulesets. + foreach ( $style_variation_declarations as $style_variation_selector => $individual_style_variation_declarations ) { + $block_rules .= static::to_ruleset( $style_variation_selector, $individual_style_variation_declarations ); + } + return $block_rules; } diff --git a/wp-includes/version.php b/wp-includes/version.php index 3e48910395..9e9fa489b2 100644 --- a/wp-includes/version.php +++ b/wp-includes/version.php @@ -16,7 +16,7 @@ * * @global string $wp_version */ -$wp_version = '6.2-alpha-55171'; +$wp_version = '6.2-alpha-55172'; /** * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.