diff --git a/packages/core-data/src/utils/set-nested-value.js b/packages/core-data/src/utils/set-nested-value.js index cb7db8a04b4b0..e90bf23e4dad8 100644 --- a/packages/core-data/src/utils/set-nested-value.js +++ b/packages/core-data/src/utils/set-nested-value.js @@ -10,6 +10,8 @@ * * @see https://lodash.com/docs/4.17.15#set * + * @todo Needs to be deduplicated with its copy in `@wordpress/edit-site`. + * * @param {Object} object Object to modify * @param {Array} path Path of the property to set. * @param {*} value Value to set. diff --git a/packages/edit-site/src/hooks/push-changes-to-global-styles/index.js b/packages/edit-site/src/hooks/push-changes-to-global-styles/index.js index d82f3a86847da..ab2487e76f191 100644 --- a/packages/edit-site/src/hooks/push-changes-to-global-styles/index.js +++ b/packages/edit-site/src/hooks/push-changes-to-global-styles/index.js @@ -1,7 +1,7 @@ /** * External dependencies */ -import { get, set } from 'lodash'; +import { get } from 'lodash'; /** * WordPress dependencies @@ -119,6 +119,46 @@ function useChangesToPush( name, attributes ) { ); } +/** + * Sets the value at path of object. + * If a portion of path doesn’t exist, it’s created. + * Arrays are created for missing index properties while objects are created + * for all other missing properties. + * + * This function intentionally mutates the input object. + * + * Inspired by _.set(). + * + * @see https://lodash.com/docs/4.17.15#set + * + * @todo Needs to be deduplicated with its copy in `@wordpress/core-data`. + * + * @param {Object} object Object to modify + * @param {Array} path Path of the property to set. + * @param {*} value Value to set. + */ +function setNestedValue( object, path, value ) { + if ( ! object || typeof object !== 'object' ) { + return object; + } + + path.reduce( ( acc, key, idx ) => { + if ( acc[ key ] === undefined ) { + if ( Number.isInteger( path[ idx + 1 ] ) ) { + acc[ key ] = []; + } else { + acc[ key ] = {}; + } + } + if ( idx === path.length - 1 ) { + acc[ key ] = value; + } + return acc[ key ]; + }, object ); + + return object; +} + function cloneDeep( object ) { return ! object ? {} : JSON.parse( JSON.stringify( object ) ); } @@ -148,8 +188,12 @@ function PushChangesToGlobalStylesControl( { const newUserConfig = cloneDeep( userConfig ); for ( const { path, value } of changes ) { - set( newBlockStyles, path, undefined ); - set( newUserConfig, [ 'styles', 'blocks', name, ...path ], value ); + setNestedValue( newBlockStyles, path, undefined ); + setNestedValue( + newUserConfig, + [ 'styles', 'blocks', name, ...path ], + value + ); } // @wordpress/core-data doesn't support editing multiple entity types in