From 108f91952dfc7abfb9c4e3b890602db6d5e4557d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <andres.maneiro@automattic.com> Date: Mon, 10 May 2021 18:30:05 +0200 Subject: [PATCH 01/10] Modify the merge algorithm so all the colors are kept --- lib/class-wp-theme-json.php | 43 ++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/lib/class-wp-theme-json.php b/lib/class-wp-theme-json.php index 6734d439b10f9b..18af192f9a4846 100644 --- a/lib/class-wp-theme-json.php +++ b/lib/class-wp-theme-json.php @@ -1079,30 +1079,47 @@ public function get_stylesheet( $type = 'all' ) { */ public function merge( $incoming ) { $incoming_data = $incoming->get_raw_data(); - $this->theme_json = array_replace_recursive( $this->theme_json, $incoming_data ); + $existing_data = $this->theme_json; // The array_replace_recursive algorithm merges at the leaf level. // For leaf values that are arrays it will use the numeric indexes for replacement. - // In those cases, what we want is to use the incoming value, if it exists. - // - // These are the cases that have array values at the leaf levels. - $properties = array(); - $properties[] = array( 'color', 'palette' ); - $properties[] = array( 'color', 'gradients' ); - $properties[] = array( 'custom' ); - $properties[] = array( 'spacing', 'units' ); - $properties[] = array( 'typography', 'fontSizes' ); - $properties[] = array( 'typography', 'fontFamilies' ); + $this->theme_json = array_replace_recursive( $this->theme_json, $incoming_data ); + + // There are a few cases in which we want to merge things differently + // from what array_replace_recursive does. + + // Some incoming properties should replace the existing. + $to_replace = array(); + $to_replace[] = array( 'custom' ); + $to_replace[] = array( 'spacing', 'units' ); + $to_replace[] = array( 'typography', 'fontSizes' ); + $to_replace[] = array( 'typography', 'fontFamilies' ); + + // Some others should be appended to the existing. + $to_append = array(); + $to_append[] = array( 'color', 'palette' ); + $to_append[] = array( 'color', 'gradients' ); $nodes = self::get_setting_nodes( $this->theme_json ); foreach ( $nodes as $metadata ) { - foreach ( $properties as $property_path ) { - $path = array_merge( $metadata['path'], $property_path ); + foreach ( $to_replace as $path_to_replace ) { + $path = array_merge( $metadata['path'], $path_to_replace ); $node = _wp_array_get( $incoming_data, $path, array() ); if ( ! empty( $node ) ) { gutenberg_experimental_set( $this->theme_json, $path, $node ); } } + foreach ( $to_append as $path_to_append ) { + $path = array_merge( $metadata['path'], $path_to_append ); + $incoming_node = _wp_array_get( $incoming_data, $path, array() ); + $existing_node = _wp_array_get( $existing_data, $path, array() ); + + if ( empty( $incoming_node ) && empty( $existing_data ) ) { + continue; + } + + gutenberg_experimental_set( $this->theme_json, $path, array_merge( $existing_node, $incoming_node ) ); + } } } From e0b6d6ce73209a3467eb4ea2c03fbc1f7d3be175 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <andres.maneiro@automattic.com> Date: Fri, 14 May 2021 17:34:02 +0200 Subject: [PATCH 02/10] Do not show core colors in the UI controls --- lib/experimental-default-theme.json | 72 ++++++++++++------- .../src/components/use-setting/index.js | 22 +++++- .../edit-site/src/components/editor/utils.js | 15 +++- 3 files changed, 82 insertions(+), 27 deletions(-) diff --git a/lib/experimental-default-theme.json b/lib/experimental-default-theme.json index d92547a1468952..dc4dbbaf058529 100644 --- a/lib/experimental-default-theme.json +++ b/lib/experimental-default-theme.json @@ -6,124 +6,148 @@ { "name": "Black", "slug": "black", - "color": "#000000" + "color": "#000000", + "origin": "core" }, { "name": "Cyan bluish gray", "slug": "cyan-bluish-gray", - "color": "#abb8c3" + "color": "#abb8c3", + "origin": "core" }, { "name": "White", "slug": "white", - "color": "#ffffff" + "color": "#ffffff", + "origin": "core" }, { "name": "Pale pink", "slug": "pale-pink", - "color": "#f78da7" + "color": "#f78da7", + "origin": "core" }, { "name": "Vivid red", "slug": "vivid-red", - "color": "#cf2e2e" + "color": "#cf2e2e", + "origin": "core" }, { "name": "Luminous vivid orange", "slug": "luminous-vivid-orange", - "color": "#ff6900" + "color": "#ff6900", + "origin": "core" }, { "name": "Luminous vivid amber", "slug": "luminous-vivid-amber", - "color": "#fcb900" + "color": "#fcb900", + "origin": "core" }, { "name": "Light green cyan", "slug": "light-green-cyan", - "color": "#7bdcb5" + "color": "#7bdcb5", + "origin": "core" }, { "name": "Vivid green cyan", "slug": "vivid-green-cyan", - "color": "#00d084" + "color": "#00d084", + "origin": "core" }, { "name": "Pale cyan blue", "slug": "pale-cyan-blue", - "color": "#8ed1fc" + "color": "#8ed1fc", + "origin": "core" }, { "name": "Vivid cyan blue", "slug": "vivid-cyan-blue", - "color": "#0693e3" + "color": "#0693e3", + "origin": "core" }, { "name": "Vivid purple", "slug": "vivid-purple", - "color": "#9b51e0" + "color": "#9b51e0", + "origin": "core" } ], "gradients": [ { "name": "Vivid cyan blue to vivid purple", "gradient": "linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%)", - "slug": "vivid-cyan-blue-to-vivid-purple" + "slug": "vivid-cyan-blue-to-vivid-purple", + "origin": "core" }, { "name": "Light green cyan to vivid green cyan", "gradient": "linear-gradient(135deg,rgb(122,220,180) 0%,rgb(0,208,130) 100%)", - "slug": "light-green-cyan-to-vivid-green-cyan" + "slug": "light-green-cyan-to-vivid-green-cyan", + "origin": "core" }, { "name": "Luminous vivid amber to luminous vivid orange", "gradient": "linear-gradient(135deg,rgba(252,185,0,1) 0%,rgba(255,105,0,1) 100%)", - "slug": "luminous-vivid-amber-to-luminous-vivid-orange" + "slug": "luminous-vivid-amber-to-luminous-vivid-orange", + "origin": "core" }, { "name": "Luminous vivid orange to vivid red", "gradient": "linear-gradient(135deg,rgba(255,105,0,1) 0%,rgb(207,46,46) 100%)", - "slug": "luminous-vivid-orange-to-vivid-red" + "slug": "luminous-vivid-orange-to-vivid-red", + "origin": "core" }, { "name": "Very light gray to cyan bluish gray", "gradient": "linear-gradient(135deg,rgb(238,238,238) 0%,rgb(169,184,195) 100%)", - "slug": "very-light-gray-to-cyan-bluish-gray" + "slug": "very-light-gray-to-cyan-bluish-gray", + "origin": "core" }, { "name": "Cool to warm spectrum", "gradient": "linear-gradient(135deg,rgb(74,234,220) 0%,rgb(151,120,209) 20%,rgb(207,42,186) 40%,rgb(238,44,130) 60%,rgb(251,105,98) 80%,rgb(254,248,76) 100%)", - "slug": "cool-to-warm-spectrum" + "slug": "cool-to-warm-spectrum", + "origin": "core" }, { "name": "Blush light purple", "gradient": "linear-gradient(135deg,rgb(255,206,236) 0%,rgb(152,150,240) 100%)", - "slug": "blush-light-purple" + "slug": "blush-light-purple", + "origin": "core" }, { "name": "Blush bordeaux", "gradient": "linear-gradient(135deg,rgb(254,205,165) 0%,rgb(254,45,45) 50%,rgb(107,0,62) 100%)", - "slug": "blush-bordeaux" + "slug": "blush-bordeaux", + "origin": "core" }, { "name": "Luminous dusk", "gradient": "linear-gradient(135deg,rgb(255,203,112) 0%,rgb(199,81,192) 50%,rgb(65,88,208) 100%)", - "slug": "luminous-dusk" + "slug": "luminous-dusk", + "origin": "core" }, { "name": "Pale ocean", "gradient": "linear-gradient(135deg,rgb(255,245,203) 0%,rgb(182,227,212) 50%,rgb(51,167,181) 100%)", - "slug": "pale-ocean" + "slug": "pale-ocean", + "origin": "core" }, { "name": "Electric grass", "gradient": "linear-gradient(135deg,rgb(202,248,128) 0%,rgb(113,206,126) 100%)", - "slug": "electric-grass" + "slug": "electric-grass", + "origin": "core" }, { "name": "Midnight", "gradient": "linear-gradient(135deg,rgb(2,3,129) 0%,rgb(40,116,252) 100%)", - "slug": "midnight" + "slug": "midnight", + "origin": "core" } ], "duotone": [ diff --git a/packages/block-editor/src/components/use-setting/index.js b/packages/block-editor/src/components/use-setting/index.js index ec0e813eb8eace..ce8c6d0da519d8 100644 --- a/packages/block-editor/src/components/use-setting/index.js +++ b/packages/block-editor/src/components/use-setting/index.js @@ -49,6 +49,18 @@ const deprecatedFlags = { 'spacing.customPadding': ( settings ) => settings.enableCustomSpacing, }; +const filterColorsFromCoreOrigin = ( path, colors ) => { + if ( path !== 'color.palette' && path !== 'color.gradients' ) { + return colors; + } + + if ( ! Array.isArray( colors ) ) { + return colors; + } + + return colors.filter( ( color ) => color?.origin !== 'core' ); +}; + /** * Hook that retrieves the editor setting. * It works with nested objects using by finding the value at path. @@ -76,7 +88,10 @@ export default function useSetting( path ) { const experimentalFeaturesResult = get( settings, blockPath ) ?? get( settings, defaultsPath ); if ( experimentalFeaturesResult !== undefined ) { - return experimentalFeaturesResult; + return filterColorsFromCoreOrigin( + path, + experimentalFeaturesResult + ); } // 2 - Use deprecated settings, otherwise. @@ -84,7 +99,10 @@ export default function useSetting( path ) { ? deprecatedFlags[ path ]( settings ) : undefined; if ( deprecatedSettingsValue !== undefined ) { - return deprecatedSettingsValue; + return filterColorsFromCoreOrigin( + path, + deprecatedSettingsValue + ); } // 3 - Fall back for typography.dropCap: diff --git a/packages/edit-site/src/components/editor/utils.js b/packages/edit-site/src/components/editor/utils.js index 865279b4625ba4..9fa9c7274628ca 100644 --- a/packages/edit-site/src/components/editor/utils.js +++ b/packages/edit-site/src/components/editor/utils.js @@ -90,13 +90,26 @@ function getPresetMetadataFromStyleProperty( styleProperty ) { return getPresetMetadataFromStyleProperty.MAP[ styleProperty ]; } +const filterColorsFromCoreOrigin = ( path, colors ) => { + if ( path !== 'color.palette' && path !== 'color.gradients' ) { + return colors; + } + + if ( ! Array.isArray( colors ) ) { + return colors; + } + + return colors.filter( ( color ) => color?.origin !== 'core' ); +}; + export function useSetting( path, blockName = '' ) { const settings = useSelect( ( select ) => { return select( editSiteStore ).getSettings(); } ); const topLevelPath = `__experimentalFeatures.${ path }`; const blockPath = `__experimentalFeatures.blocks.${ blockName }.${ path }`; - return get( settings, blockPath ) ?? get( settings, topLevelPath ); + const setting = get( settings, blockPath ) ?? get( settings, topLevelPath ); + return filterColorsFromCoreOrigin( path, setting ); } export function getPresetVariable( styles, context, propertyName, value ) { From 4ddd1defeee4f46ccc23f4a48d0907c491b8169a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <andres.maneiro@automattic.com> Date: Tue, 18 May 2021 11:33:45 +0200 Subject: [PATCH 03/10] Color palette and gradients are merged --- phpunit/class-wp-theme-json-test.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/phpunit/class-wp-theme-json-test.php b/phpunit/class-wp-theme-json-test.php index 5b6d02059829f2..14851a00f4dbf8 100644 --- a/phpunit/class-wp-theme-json-test.php +++ b/phpunit/class-wp-theme-json-test.php @@ -410,6 +410,14 @@ public function test_merge_incoming_data() { 'custom' => true, 'customGradient' => true, 'palette' => array( + array( + 'slug' => 'red', + 'color' => 'red', + ), + array( + 'slug' => 'green', + 'color' => 'green', + ), array( 'slug' => 'blue', 'color' => 'blue', From b7fbedf500791d2d44eec9d93892dd86b2d22642 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <andres.maneiro@automattic.com> Date: Tue, 18 May 2021 11:35:41 +0200 Subject: [PATCH 04/10] Do not add palette and gradients if empty --- lib/class-wp-theme-json.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/class-wp-theme-json.php b/lib/class-wp-theme-json.php index 18af192f9a4846..0160fada5810d2 100644 --- a/lib/class-wp-theme-json.php +++ b/lib/class-wp-theme-json.php @@ -1114,7 +1114,7 @@ public function merge( $incoming ) { $incoming_node = _wp_array_get( $incoming_data, $path, array() ); $existing_node = _wp_array_get( $existing_data, $path, array() ); - if ( empty( $incoming_node ) && empty( $existing_data ) ) { + if ( empty( $incoming_node ) && empty( $existing_node ) ) { continue; } From 3aa6568bc247ed1a3240937c52959e2aa95ffb03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <andres.maneiro@automattic.com> Date: Tue, 18 May 2021 16:42:46 +0200 Subject: [PATCH 05/10] Fix linting issues --- lib/class-wp-theme-json.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/class-wp-theme-json.php b/lib/class-wp-theme-json.php index 0160fada5810d2..f42efec8fb727f 100644 --- a/lib/class-wp-theme-json.php +++ b/lib/class-wp-theme-json.php @@ -1078,8 +1078,8 @@ public function get_stylesheet( $type = 'all' ) { * @param WP_Theme_JSON $incoming Data to merge. */ public function merge( $incoming ) { - $incoming_data = $incoming->get_raw_data(); - $existing_data = $this->theme_json; + $incoming_data = $incoming->get_raw_data(); + $existing_data = $this->theme_json; // The array_replace_recursive algorithm merges at the leaf level. // For leaf values that are arrays it will use the numeric indexes for replacement. From ee4ffe7da735edcd92a983febccb9ae01716ee6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <andres.maneiro@automattic.com> Date: Wed, 19 May 2021 10:18:41 +0200 Subject: [PATCH 06/10] Cover the case in which the theme does not provide any color --- .../block-editor/src/components/use-setting/index.js | 12 +++++++----- packages/edit-site/src/components/editor/utils.js | 12 +++++++----- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/packages/block-editor/src/components/use-setting/index.js b/packages/block-editor/src/components/use-setting/index.js index ce8c6d0da519d8..43ee185c396617 100644 --- a/packages/block-editor/src/components/use-setting/index.js +++ b/packages/block-editor/src/components/use-setting/index.js @@ -49,16 +49,18 @@ const deprecatedFlags = { 'spacing.customPadding': ( settings ) => settings.enableCustomSpacing, }; -const filterColorsFromCoreOrigin = ( path, colors ) => { +const filterColorsFromCoreOrigin = ( path, setting ) => { if ( path !== 'color.palette' && path !== 'color.gradients' ) { - return colors; + return setting; } - if ( ! Array.isArray( colors ) ) { - return colors; + if ( ! Array.isArray( setting ) ) { + return setting; } - return colors.filter( ( color ) => color?.origin !== 'core' ); + const colors = setting.filter( ( color ) => color?.origin !== 'core' ); + + return colors.length > 0 ? colors : setting; }; /** diff --git a/packages/edit-site/src/components/editor/utils.js b/packages/edit-site/src/components/editor/utils.js index 9fa9c7274628ca..7d5d55884feeeb 100644 --- a/packages/edit-site/src/components/editor/utils.js +++ b/packages/edit-site/src/components/editor/utils.js @@ -90,16 +90,18 @@ function getPresetMetadataFromStyleProperty( styleProperty ) { return getPresetMetadataFromStyleProperty.MAP[ styleProperty ]; } -const filterColorsFromCoreOrigin = ( path, colors ) => { +const filterColorsFromCoreOrigin = ( path, setting ) => { if ( path !== 'color.palette' && path !== 'color.gradients' ) { - return colors; + return setting; } - if ( ! Array.isArray( colors ) ) { - return colors; + if ( ! Array.isArray( setting ) ) { + return setting; } - return colors.filter( ( color ) => color?.origin !== 'core' ); + const colors = setting.filter( ( color ) => color?.origin !== 'core' ); + + return colors.length > 0 ? colors : setting; }; export function useSetting( path, blockName = '' ) { From 9faec4d42edcb6e739dc8a95679212b4b02384ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <andres.maneiro@automattic.com> Date: Wed, 19 May 2021 20:07:10 +0200 Subject: [PATCH 07/10] Update merge algorithm for user colors --- .../editor/global-styles-provider.js | 26 ++++++++++++++++++- .../components/sidebar/color-palette-panel.js | 18 +++++++++++-- 2 files changed, 41 insertions(+), 3 deletions(-) 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 7fdf78b060a829..6d173773a18499 100644 --- a/packages/edit-site/src/components/editor/global-styles-provider.js +++ b/packages/edit-site/src/components/editor/global-styles-provider.js @@ -47,7 +47,31 @@ const GlobalStylesContext = createContext( { /* eslint-enable no-unused-vars */ } ); -const mergeTreesCustomizer = ( objValue, srcValue ) => { +const mergeTreesCustomizer = ( objValue, srcValue, key ) => { + // Users can add their own colors. + // We want to append them when they don't + // have the same slug as an existing color, + // otherwise we want to update the existing color instead. + if ( 'palette' === key ) { + const indexTable = {}; + const existingSlugs = []; + const result = [ ...( objValue ?? [] ) ]; + result.forEach( ( { slug }, index ) => { + indexTable[ slug ] = index; + existingSlugs.push( slug ); + } ); + + ( srcValue ?? [] ).forEach( ( element ) => { + if ( existingSlugs.includes( element?.slug ) ) { + result[ indexTable[ element?.slug ] ] = element; + } else { + result.push( element ); + } + } ); + + return result; + } + // We only pass as arrays the presets, // in which case we want the new array of values // to override the old array (no merging). diff --git a/packages/edit-site/src/components/sidebar/color-palette-panel.js b/packages/edit-site/src/components/sidebar/color-palette-panel.js index e3fbda55711974..49e7c964fc29c8 100644 --- a/packages/edit-site/src/components/sidebar/color-palette-panel.js +++ b/packages/edit-site/src/components/sidebar/color-palette-panel.js @@ -1,7 +1,7 @@ /** * External dependencies */ -import { get } from 'lodash'; +import { difference, get } from 'lodash'; /** * WordPress dependencies @@ -58,7 +58,21 @@ export default function ColorPalettePanel( { immutableColorSlugs={ immutableColorSlugs } colors={ colors } onChange={ ( newColors ) => { - setSetting( contextName, 'color.palette', newColors ); + const existingUserColors = ( newColors ?? [] ).filter( + ( color ) => color.origin === 'user' + ); + const differentUserColors = difference( newColors, colors ); + if ( differentUserColors.length === 1 ) { + differentUserColors[ 0 ] = { + ...differentUserColors[ 0 ], + origin: 'user', + }; + } + + setSetting( contextName, 'color.palette', [ + ...existingUserColors, + ...differentUserColors, + ] ); } } emptyUI={ __( 'Colors are empty! Add some colors to create your own color palette.' From 0c4653fc8ae1342a3846afcbaf714da4a357beb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <andres.maneiro@automattic.com> Date: Wed, 19 May 2021 20:45:56 +0200 Subject: [PATCH 08/10] Update merge algorithm for colors in the server --- lib/class-wp-theme-json.php | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/lib/class-wp-theme-json.php b/lib/class-wp-theme-json.php index f42efec8fb727f..eb723a7f0cf60b 100644 --- a/lib/class-wp-theme-json.php +++ b/lib/class-wp-theme-json.php @@ -1095,7 +1095,8 @@ public function merge( $incoming ) { $to_replace[] = array( 'typography', 'fontSizes' ); $to_replace[] = array( 'typography', 'fontFamilies' ); - // Some others should be appended to the existing. + // Some others should be either appended to the existing + // or update the existing if the slug is the same. $to_append = array(); $to_append[] = array( 'color', 'palette' ); $to_append[] = array( 'color', 'gradients' ); @@ -1118,7 +1119,24 @@ public function merge( $incoming ) { continue; } - gutenberg_experimental_set( $this->theme_json, $path, array_merge( $existing_node, $incoming_node ) ); + $index_table = array(); + $existing_slugs = array(); + $merged = array(); + foreach( $existing_node as $key => $value ) { + $index_table[ $value['slug'] ] = $key; + $existing_slugs[] = $value['slug']; + $merged[ $key ] = $value; + } + + foreach( $incoming_node as $value ) { + if ( in_array( $value['slug'], $existing_slugs ) ) { + $merged[ $index_table[ $value['slug'] ] ] = $value; + } else { + $merged[] = $value; + } + } + + gutenberg_experimental_set( $this->theme_json, $path, $merged ); } } From c9fc39f4b01bd072828888224b1351db056125c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <andres.maneiro@automattic.com> Date: Thu, 20 May 2021 09:35:30 +0200 Subject: [PATCH 09/10] Fix color ordering --- lib/class-wp-theme-json-resolver.php | 2 +- lib/class-wp-theme-json.php | 29 ++++++++++++++++++++++------ 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/lib/class-wp-theme-json-resolver.php b/lib/class-wp-theme-json-resolver.php index 4df3881a72c565..96e04f43c80216 100644 --- a/lib/class-wp-theme-json-resolver.php +++ b/lib/class-wp-theme-json-resolver.php @@ -419,7 +419,7 @@ public static function get_merged_data( $settings = array(), $origin = 'user' ) $result->merge( self::get_theme_data( $theme_support_data ) ); if ( 'user' === $origin ) { - $result->merge( self::get_user_data() ); + $result->merge( self::get_user_data(), 'update' ); } return $result; diff --git a/lib/class-wp-theme-json.php b/lib/class-wp-theme-json.php index eb723a7f0cf60b..994f2e413ddb50 100644 --- a/lib/class-wp-theme-json.php +++ b/lib/class-wp-theme-json.php @@ -1076,8 +1076,10 @@ public function get_stylesheet( $type = 'all' ) { * Merge new incoming data. * * @param WP_Theme_JSON $incoming Data to merge. + * @param string $update_or_remove Whether update or remove existing colors + * for which the incoming data has a duplicated slug. */ - public function merge( $incoming ) { + public function merge( $incoming, $update_or_remove = 'remove' ) { $incoming_data = $incoming->get_raw_data(); $existing_data = $this->theme_json; @@ -1095,11 +1097,16 @@ public function merge( $incoming ) { $to_replace[] = array( 'typography', 'fontSizes' ); $to_replace[] = array( 'typography', 'fontFamilies' ); - // Some others should be either appended to the existing - // or update the existing if the slug is the same. + // Some others should be appended to the existing. + // If the slug is the same than an existing element, + // the $update_or_remove param is used to decide + // what to do with the existing element: + // either remove it and append the incoming, + // or update it with the incoming. $to_append = array(); - $to_append[] = array( 'color', 'palette' ); + $to_append[] = array( 'color', 'duotone' ); $to_append[] = array( 'color', 'gradients' ); + $to_append[] = array( 'color', 'palette' ); $nodes = self::get_setting_nodes( $this->theme_json ); foreach ( $nodes as $metadata ) { @@ -1128,14 +1135,24 @@ public function merge( $incoming ) { $merged[ $key ] = $value; } + $to_remove = []; foreach( $incoming_node as $value ) { - if ( in_array( $value['slug'], $existing_slugs ) ) { + if ( ! in_array( $value['slug'], $existing_slugs ) ) { + $merged[] = $value; + } elseif ( 'update' === $update_or_remove ) { $merged[ $index_table[ $value['slug'] ] ] = $value; } else { - $merged[] = $value; + $merged[] = $value; + $to_remove[] = $index_table[ $value['slug'] ]; } } + // Remove the duplicated values and pack the sparsed array. + foreach( $to_remove as $index ) { + unset( $merged[ $index ] ); + } + $merged = array_values( $merged ); + gutenberg_experimental_set( $this->theme_json, $path, $merged ); } } From d45d090c99588ffa5c999e00eec2377e79a70b0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <andres.maneiro@automattic.com> Date: Thu, 20 May 2021 09:40:56 +0200 Subject: [PATCH 10/10] Fix linting issues --- lib/class-wp-theme-json.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/class-wp-theme-json.php b/lib/class-wp-theme-json.php index 994f2e413ddb50..ba18c6a9e69247 100644 --- a/lib/class-wp-theme-json.php +++ b/lib/class-wp-theme-json.php @@ -1076,7 +1076,7 @@ public function get_stylesheet( $type = 'all' ) { * Merge new incoming data. * * @param WP_Theme_JSON $incoming Data to merge. - * @param string $update_or_remove Whether update or remove existing colors + * @param string $update_or_remove Whether update or remove existing colors * for which the incoming data has a duplicated slug. */ public function merge( $incoming, $update_or_remove = 'remove' ) { @@ -1129,15 +1129,15 @@ public function merge( $incoming, $update_or_remove = 'remove' ) { $index_table = array(); $existing_slugs = array(); $merged = array(); - foreach( $existing_node as $key => $value ) { + foreach ( $existing_node as $key => $value ) { $index_table[ $value['slug'] ] = $key; $existing_slugs[] = $value['slug']; $merged[ $key ] = $value; } - $to_remove = []; - foreach( $incoming_node as $value ) { - if ( ! in_array( $value['slug'], $existing_slugs ) ) { + $to_remove = array(); + foreach ( $incoming_node as $value ) { + if ( ! in_array( $value['slug'], $existing_slugs, true ) ) { $merged[] = $value; } elseif ( 'update' === $update_or_remove ) { $merged[ $index_table[ $value['slug'] ] ] = $value; @@ -1148,7 +1148,7 @@ public function merge( $incoming, $update_or_remove = 'remove' ) { } // Remove the duplicated values and pack the sparsed array. - foreach( $to_remove as $index ) { + foreach ( $to_remove as $index ) { unset( $merged[ $index ] ); } $merged = array_values( $merged );