From a2040a36e192fa61a024e4f5f16d85e4deb39e55 Mon Sep 17 00:00:00 2001 From: Jorge Date: Wed, 18 Nov 2020 18:54:45 +0000 Subject: [PATCH] Client side (+1 squashed commit) Squashed commits: [0ef9982104] Global Styles: Keep core and theme preset classes and variables even if they are overwritten. --- lib/class-wp-theme-json.php | 78 ++++++++++++++++--- .../editor/global-styles-provider.js | 27 ++++++- .../editor/global-styles-renderer.js | 31 ++++++-- phpunit/class-wp-theme-json-test.php | 14 ++++ 4 files changed, 133 insertions(+), 17 deletions(-) diff --git a/lib/class-wp-theme-json.php b/lib/class-wp-theme-json.php index 0452510d306c6c..0e84547b309dd4 100644 --- a/lib/class-wp-theme-json.php +++ b/lib/class-wp-theme-json.php @@ -177,7 +177,7 @@ class WP_Theme_JSON { */ const PRESETS_METADATA = array( array( - 'path' => array( 'settings', 'color', 'palette' ), + 'path' => array( 'color', 'palette' ), 'value_key' => 'color', 'css_var_infix' => 'color', 'classes' => array( @@ -192,7 +192,7 @@ class WP_Theme_JSON { ), ), array( - 'path' => array( 'settings', 'color', 'gradients' ), + 'path' => array( 'color', 'gradients' ), 'value_key' => 'gradient', 'css_var_infix' => 'gradient', 'classes' => array( @@ -203,7 +203,7 @@ class WP_Theme_JSON { ), ), array( - 'path' => array( 'settings', 'typography', 'fontSizes' ), + 'path' => array( 'typography', 'fontSizes' ), 'value_key' => 'size', 'css_var_infix' => 'font-size', 'classes' => array( @@ -214,13 +214,13 @@ class WP_Theme_JSON { ), ), array( - 'path' => array( 'settings', 'typography', 'fontFamilies' ), + 'path' => array( 'typography', 'fontFamilies' ), 'value_key' => 'fontFamily', 'css_var_infix' => 'font-family', 'classes' => array(), ), array( - 'path' => array( 'settings', 'typography', 'fontStyles' ), + 'path' => array( 'typography', 'fontStyles' ), 'value_key' => 'slug', 'css_var_infix' => 'font-style', 'classes' => array( @@ -231,7 +231,7 @@ class WP_Theme_JSON { ), ), array( - 'path' => array( 'settings', 'typography', 'fontWeights' ), + 'path' => array( 'typography', 'fontWeights' ), 'value_key' => 'slug', 'css_var_infix' => 'font-weight', 'classes' => array( @@ -242,7 +242,7 @@ class WP_Theme_JSON { ), ), array( - 'path' => array( 'settings', 'typography', 'textDecorations' ), + 'path' => array( 'typography', 'textDecorations' ), 'value_key' => 'value', 'css_var_infix' => 'text-decoration', 'classes' => array( @@ -253,7 +253,7 @@ class WP_Theme_JSON { ), ), array( - 'path' => array( 'settings', 'typography', 'textTransforms' ), + 'path' => array( 'typography', 'textTransforms' ), 'value_key' => 'slug', 'css_var_infix' => 'text-transform', 'classes' => array( @@ -701,9 +701,19 @@ private static function compute_preset_classes( &$stylesheet, $context ) { // and we don't want to increase its specificity. $selector = ''; } + if ( empty( $context['settings'] ) ) { + return; + } foreach ( self::PRESETS_METADATA as $preset ) { - $values = gutenberg_experimental_get( $context, $preset['path'], array() ); + $values = gutenberg_experimental_get( $context['settings'], $preset['path'], array() ); + if ( isset( $context['deactivatedSettings'] ) ) { + $values = array_merge( + gutenberg_experimental_get( $context['deactivatedSettings'], $preset['path'], array() ), + $values + ); + } + foreach ( $values as $value ) { foreach ( $preset['classes'] as $class ) { $stylesheet .= self::to_ruleset( @@ -738,8 +748,17 @@ private static function compute_preset_classes( &$stylesheet, $context ) { * @param array $context Input context to process. */ private static function compute_preset_vars( &$declarations, $context ) { + if ( empty( $context['settings'] ) ) { + return; + } foreach ( self::PRESETS_METADATA as $preset ) { - $values = gutenberg_experimental_get( $context, $preset['path'], array() ); + $values = gutenberg_experimental_get( $context['settings'], $preset['path'], array() ); + if ( isset( $context['deactivatedSettings'] ) ) { + $values = array_merge( + gutenberg_experimental_get( $context['deactivatedSettings'], $preset['path'], array() ), + $values + ); + } foreach ( $values as $value ) { $declarations[] = array( 'name' => '--wp--preset--' . $preset['css_var_infix'] . '--' . $value['slug'], @@ -930,6 +949,45 @@ public function merge( $theme_json ) { $this->contexts[ $context ]['selector'] = $metadata[ $context ]['selector']; $this->contexts[ $context ]['supports'] = $metadata[ $context ]['supports']; + // Add the presets to the deactivated settings if they will be overwritten. + if ( + ! empty( $incoming_data[ $context ]['settings'] ) && + ! empty( $this->contexts[ $context ]['settings'] ) + ) { + foreach ( self::PRESETS_METADATA as $preset ) { + $incoming_preset = gutenberg_experimental_get( + $incoming_data[ $context ]['settings'], + $preset['path'], + null + ); + $current_preset = gutenberg_experimental_get( + $this->contexts[ $context ]['settings'], + $preset['path'], + null + ); + // If the preset will be overwritten. + if ( + ! empty( $current_preset ) && + ! empty( $incoming_preset ) + ) { + if ( ! isset( $this->contexts[ $context ]['deactivatedSettings'] ) ) { + $this->contexts[ $context ]['deactivatedSettings'] = array(); + } + // Append the presets that will be overwritten to the set of deactivated presets that already exist. + $inactive_preset = gutenberg_experimental_get( + $this->contexts[ $context ]['deactivatedSettings'], + $preset['path'], + array() + ); + gutenberg_experimental_set( + $this->contexts[ $context ]['deactivatedSettings'], + $preset['path'], + array_merge( $inactive_preset, $current_preset ) + ); + } + } + } + foreach ( array( 'settings', 'styles' ) as $subtree ) { if ( ! isset( $incoming_data[ $context ][ $subtree ] ) ) { continue; diff --git a/packages/edit-site/src/components/editor/global-styles-provider.js b/packages/edit-site/src/components/editor/global-styles-provider.js index 544bd7f20eb2e5..9aae70d2e6a0e4 100644 --- a/packages/edit-site/src/components/editor/global-styles-provider.js +++ b/packages/edit-site/src/components/editor/global-styles-provider.js @@ -1,7 +1,7 @@ /** * External dependencies */ -import { set, get, mapValues, mergeWith } from 'lodash'; +import { set, get, mapValues, mergeWith, isEmpty } from 'lodash'; /** * WordPress dependencies @@ -22,6 +22,7 @@ import { useSelect, useDispatch } from '@wordpress/data'; */ import { default as getGlobalStyles } from './global-styles-renderer'; import { + PRESET_CATEGORIES, GLOBAL_CONTEXT, getValueFromVariable, getPresetVariable, @@ -135,6 +136,30 @@ export default function GlobalStylesProvider( { children, baseStyles } ) { mergeTreesCustomizer ); + for ( const context in newMergedStyles ) { + const userSettings = get( newUserStyles, [ context, 'settings' ] ); + const baseSettings = get( baseStyles, [ context, 'settings' ] ); + if ( ! isEmpty( userSettings ) && ! isEmpty( baseSettings ) ) { + for ( const presetCategory in PRESET_CATEGORIES ) { + const { path } = PRESET_CATEGORIES[ presetCategory ]; + const userPreset = get( userSettings, path ); + const basePreset = get( baseSettings, path ); + if ( ! isEmpty( userPreset ) && ! isEmpty( basePreset ) ) { + const inactivePreset = get( + newMergedStyles, + [ context, 'deactivatedSettings', ...path ], + [] + ); + set( + newMergedStyles, + [ context, 'deactivatedSettings', ...path ], + [ ...inactivePreset, ...basePreset ] + ); + } + } + } + } + return { userStyles: newUserStyles, mergedStyles: newMergedStyles, diff --git a/packages/edit-site/src/components/editor/global-styles-renderer.js b/packages/edit-site/src/components/editor/global-styles-renderer.js index e0dc01f4c9777a..cd3e946eb10373 100644 --- a/packages/edit-site/src/components/editor/global-styles-renderer.js +++ b/packages/edit-site/src/components/editor/global-styles-renderer.js @@ -64,13 +64,21 @@ export default ( blockData, tree, metadata ) => { * * @param {string} blockSelector * @param {Object} blockPresets + * @param {Object} deactivatedPresets * @return {string} CSS declarations for the preset classes. */ - const getBlockPresetClasses = ( blockSelector, blockPresets = {} ) => { + const getBlockPresetClasses = ( + blockSelector, + blockPresets = {}, + deactivatedPresets = {} + ) => { return reduce( PRESET_CLASSES, ( declarations, { path, key, property }, classSuffix ) => { - const presets = get( blockPresets, path, [] ); + const presets = [ + ...get( deactivatedPresets, path, [] ), + ...get( blockPresets, path, [] ), + ]; presets.forEach( ( preset ) => { const slug = preset.slug; const value = preset[ key ]; @@ -88,14 +96,21 @@ export default ( blockData, tree, metadata ) => { * Transform given preset tree into a set of style declarations. * * @param {Object} blockPresets + * @param {Object} deactivatedPresets * * @return {Array} An array of style declarations. */ - const getBlockPresetsDeclarations = ( blockPresets = {} ) => { + const getBlockPresetsDeclarations = ( + blockPresets = {}, + deactivatedPresets = {} + ) => { return reduce( PRESET_CATEGORIES, ( declarations, { path, key }, category ) => { - const preset = get( blockPresets, path, [] ); + const preset = [ + ...get( deactivatedPresets, path, [] ), + ...get( blockPresets, path, [] ), + ]; preset.forEach( ( value ) => { declarations.push( `--wp--preset--${ kebabCase( category ) }--${ @@ -144,7 +159,10 @@ export default ( blockData, tree, metadata ) => { blockData[ context ].supports, tree?.[ context ]?.styles ), - ...getBlockPresetsDeclarations( tree?.[ context ]?.settings ), + ...getBlockPresetsDeclarations( + tree?.[ context ]?.settings, + tree?.[ context ]?.deactivatedSettings + ), ...getCustomDeclarations( tree?.[ context ]?.settings?.custom ), ]; if ( blockDeclarations.length > 0 ) { @@ -155,7 +173,8 @@ export default ( blockData, tree, metadata ) => { const presetClasses = getBlockPresetClasses( blockSelector, - tree?.[ context ]?.settings + tree?.[ context ]?.settings, + tree?.[ context ]?.deactivatedSettings ); if ( presetClasses ) { styles.push( presetClasses ); diff --git a/phpunit/class-wp-theme-json-test.php b/phpunit/class-wp-theme-json-test.php index 8682d0618ae546..c8806275d038bc 100644 --- a/phpunit/class-wp-theme-json-test.php +++ b/phpunit/class-wp-theme-json-test.php @@ -458,6 +458,20 @@ public function test_merge_incoming_data() { 'fontSize' => '12', ), ), + 'deactivatedSettings' => array( + 'color' => array( + 'palette' => array( + array( + 'slug' => 'red', + 'color' => 'red', + ), + array( + 'slug' => 'blue', + 'color' => 'blue', + ), + ), + ), + ), ), 'core/paragraph' => array( 'selector' => 'p',