From 6badc2fadfcde0b6534de38383afa191c47d144f Mon Sep 17 00:00:00 2001 From: Aaron Robertshaw <60436221+aaronrobertshaw@users.noreply.github.com> Date: Thu, 1 Feb 2024 15:36:51 +1000 Subject: [PATCH] Try allowing variation > block > element styles again --- lib/class-wp-theme-json-gutenberg.php | 38 +++++-------- .../global-styles/use-global-styles-output.js | 57 ++++++++++++++----- .../global-styles/global-styles-provider.js | 32 ++++++----- 3 files changed, 74 insertions(+), 53 deletions(-) diff --git a/lib/class-wp-theme-json-gutenberg.php b/lib/class-wp-theme-json-gutenberg.php index b323091d9896b..eae73a8c7cde2 100644 --- a/lib/class-wp-theme-json-gutenberg.php +++ b/lib/class-wp-theme-json-gutenberg.php @@ -843,44 +843,36 @@ protected static function sanitize( $input, $valid_block_names, $valid_element_n // Generate a schema for blocks. // - Block styles can contain `elements` & `variations` definitions. - // - Variations can contain styles for inner `blocks`. // - Variations definitions cannot be nested. - // - Variations inner block styles cannot contain `elements`. + // - Variations can contain styles for inner `blocks`. + // - Variation inner `blocks` styles can contain `elements`. // - // As each variation needs a `blocks` schema but without `elements` and + // As each variation needs a `blocks` schema but further nested // inner `blocks`, the overall schema will be generated in multiple // passes. foreach ( $valid_block_names as $block ) { - $schema_settings_blocks[ $block ] = static::VALID_SETTINGS; - $schema_styles_blocks[ $block ] = $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; } $block_style_variation_styles = static::VALID_STYLES; $block_style_variation_styles['blocks'] = $schema_styles_blocks; $block_style_variation_styles['elements'] = $schema_styles_elements; - // Generate schema for shared variations i.e. those that can be - // referenced with block style variations and live under - // styles.blocks.variations. These variations could be any valid block - // style variation. The schema will differ in that these variations - // cannot reference another. - // - // NOTE: The size of the schema array is already very large given - // entries for each individual block. This is compounded when multiple - // variations need to added to the schema. Would multiple passes for - // validation offer any improvements? - $unique_variations = array_unique( + // Generate schema for shared block style variations i.e. those that can + // be reused across block types and live under `styles.blocks.variations`. + $unique_variations = array_unique( call_user_func_array( 'array_merge', array_values( $valid_variations ) ) ); + + // Shared block style variations have an additional property to those + // defined under individual block types so they can specify eligible + // block types. $shared_variation_styles = $block_style_variation_styles; $shared_variation_styles['supportedBlockTypes'] = null; $schema_shared_style_variations = array_fill_keys( $unique_variations, $shared_variation_styles ); - // Allow refs only within the individual block type variations properties. - // Assigning it before `$schema_shared_style_variations` would mean - // shared variations would allow `ref` properties. - $block_style_variation_styles['ref'] = null; - foreach ( $valid_block_names as $block ) { // Build the schema for each block style variation. $style_variation_names = array(); @@ -901,10 +893,6 @@ protected static function sanitize( $input, $valid_block_names, $valid_element_n } $schema_styles_blocks[ $block ]['variations'] = $schema_styles_variations; - - // The element styles schema can now be added for this block to the - // styles.blocks.$block schema. - $schema_styles_blocks[ $block ]['elements'] = $schema_styles_elements; } $schema['styles'] = static::VALID_STYLES; diff --git a/packages/block-editor/src/components/global-styles/use-global-styles-output.js b/packages/block-editor/src/components/global-styles/use-global-styles-output.js index e9a5e8a9feb19..f2a148fd8f9bc 100644 --- a/packages/block-editor/src/components/global-styles/use-global-styles-output.js +++ b/packages/block-editor/src/components/global-styles/use-global-styles-output.js @@ -687,6 +687,24 @@ export const getNodesWithStyles = ( tree, blockSelectors, rootSelector ) => { variationName ]; + // Process the variation's inner element styles. + // This comes before the inner block styles so the + // element styles within the block type styles take + // precedence over these. + Object.entries( variation?.elements ?? {} ).forEach( + ( [ element, elementStyles ] ) => { + if ( elementStyles && ELEMENTS[ element ] ) { + nodes.push( { + styles: elementStyles, + selector: scopeSelector( + variationSelector, + ELEMENTS[ element ] + ), + } ); + } + } + ); + // Process the variations inner block type styles. Object.entries( variation?.blocks ?? {} ).forEach( ( [ @@ -724,21 +742,32 @@ export const getNodesWithStyles = ( tree, blockSelectors, rootSelector ) => { variationBlockStyles ), } ); - } - ); - // Process the variations inner element styles. - Object.entries( variation?.elements ?? {} ).forEach( - ( [ element, elementStyles ] ) => { - if ( elementStyles && ELEMENTS[ element ] ) { - nodes.push( { - styles: elementStyles, - selector: scopeSelector( - variationSelector, - ELEMENTS[ element ] - ), - } ); - } + // Process element styles for the inner blocks + // of the variation. + Object.entries( + variationBlockStyles.elements ?? {} + ).forEach( + ( [ + variationBlockElement, + variationBlockElementStyles, + ] ) => { + if ( + variationBlockElementStyles && + ELEMENTS[ variationBlockElement ] + ) { + nodes.push( { + styles: variationBlockElementStyles, + selector: scopeSelector( + variationBlockSelector, + ELEMENTS[ + variationBlockElement + ] + ), + } ); + } + } + ); } ); } diff --git a/packages/edit-site/src/components/global-styles/global-styles-provider.js b/packages/edit-site/src/components/global-styles/global-styles-provider.js index a7e71ee027f8c..2b8263cff63f5 100644 --- a/packages/edit-site/src/components/global-styles/global-styles-provider.js +++ b/packages/edit-site/src/components/global-styles/global-styles-provider.js @@ -156,32 +156,36 @@ function useGlobalStylesContext() { useGlobalStylesUserConfig(); const [ isBaseConfigReady, baseConfig ] = useGlobalStylesBaseConfig(); + // TODO: Where is the right place to resolve shared block style + // variations within the site editor when they are in a theme + // style variation's data that simply gets applied to the "user" + // origin styles? + const userConfigWithVariations = useMemo( () => { + if ( ! userConfig ) { + return userConfig; + } + return resolveBlockStyleVariations( userConfig ); + }, [ userConfig ] ); + const mergedConfig = useMemo( () => { - if ( ! baseConfig || ! userConfig ) { + if ( ! baseConfig || ! userConfigWithVariations ) { return {}; } - // TODO: Where is the right place to resolve shared block style - // variations within the site editor when they are in a theme - // style variation's data that simply gets applied to the "user" - // origin styles? - const configWithResolvedVariations = - resolveBlockStyleVariations( userConfig ); - return mergeBaseAndUserConfigs( - baseConfig, - configWithResolvedVariations - ); - }, [ userConfig, baseConfig ] ); + + return mergeBaseAndUserConfigs( baseConfig, userConfigWithVariations ); + }, [ userConfigWithVariations, baseConfig ] ); + const context = useMemo( () => { return { isReady: isUserConfigReady && isBaseConfigReady, - user: userConfig, + user: userConfigWithVariations, base: baseConfig, merged: mergedConfig, setUserConfig, }; }, [ mergedConfig, - userConfig, + userConfigWithVariations, baseConfig, setUserConfig, isUserConfigReady,