Skip to content

Commit 40a96ee

Browse files
committed
Editor: Shallow merge on whitelisted post property edits
1 parent 7b6bccd commit 40a96ee

4 files changed

Lines changed: 56 additions & 208 deletions

File tree

packages/editor/src/store/object.js

Lines changed: 0 additions & 88 deletions
This file was deleted.

packages/editor/src/store/reducer.js

Lines changed: 55 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,16 @@ import {
3434
INITIAL_EDITS_DEFAULTS,
3535
} from './defaults';
3636
import { insertAt, moveTo } from './array';
37-
import { getMutateSafeObject, merge, diff } from './object';
37+
38+
/**
39+
* Set of post properties for which edits should assume a merging behavior,
40+
* assuming an object value.
41+
*
42+
* @type {Set}
43+
*/
44+
const EDIT_MERGE_PROPERTIES = new Set( [
45+
'meta',
46+
] );
3847

3948
/**
4049
* Returns a post attribute value, flattening nested rendered content using its
@@ -102,6 +111,23 @@ function getFlattenedBlocks( blocks ) {
102111
return flattenedBlocks;
103112
}
104113

114+
/**
115+
* Returns an object against which it is safe to perform mutating operations,
116+
* given the original object and its current working copy.
117+
*
118+
* @param {Object} original Original object.
119+
* @param {Object} working Working object.
120+
*
121+
* @return {Object} Mutation-safe object.
122+
*/
123+
function getMutateSafeObject( original, working ) {
124+
if ( original === working ) {
125+
return { ...original };
126+
}
127+
128+
return working;
129+
}
130+
105131
/**
106132
* Returns true if the two object arguments have the same keys, or false
107133
* otherwise.
@@ -224,7 +250,22 @@ export const editor = flow( [
224250
edits( state = {}, action ) {
225251
switch ( action.type ) {
226252
case 'EDIT_POST':
227-
return merge( state, action.edits );
253+
return reduce( action.edits, ( result, value, key ) => {
254+
// Only assign into result if not already same value
255+
if ( value !== state[ key ] ) {
256+
result = getMutateSafeObject( state, result );
257+
258+
if ( EDIT_MERGE_PROPERTIES.has( key ) ) {
259+
// Merge properties should assign to current value.
260+
result[ key ] = { ...result[ key ], ...value };
261+
} else {
262+
// Otherwise override.
263+
result[ key ] = value;
264+
}
265+
}
266+
267+
return result;
268+
}, state );
228269

229270
case 'RESET_BLOCKS':
230271
if ( 'content' in state ) {
@@ -235,14 +276,19 @@ export const editor = flow( [
235276

236277
case 'UPDATE_POST':
237278
case 'RESET_POST':
238-
let updates;
239-
if ( action.type === 'UPDATE_POST' ) {
240-
updates = action.edits;
241-
} else {
242-
updates = mapValues( action.post, getPostRawValue );
243-
}
279+
const getCanonicalValue = action.type === 'UPDATE_POST' ?
280+
( key ) => action.edits[ key ] :
281+
( key ) => getPostRawValue( action.post[ key ] );
282+
283+
return reduce( state, ( result, value, key ) => {
284+
if ( ! isEqual( value, getCanonicalValue( key ) ) ) {
285+
return result;
286+
}
244287

245-
return diff( updates, state );
288+
result = getMutateSafeObject( state, result );
289+
delete result[ key ];
290+
return result;
291+
}, state );
246292
}
247293

248294
return state;

packages/editor/src/store/test/object.js

Lines changed: 0 additions & 81 deletions
This file was deleted.

packages/editor/src/store/test/reducer.js

Lines changed: 1 addition & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1078,35 +1078,6 @@ describe( 'state', () => {
10781078
expect( state.present.edits ).toBe( original.present.edits );
10791079
} );
10801080

1081-
it( 'unset updated post values which match', () => {
1082-
const original = editor( undefined, {
1083-
type: 'EDIT_POST',
1084-
edits: {
1085-
title: 'modified title',
1086-
meta: {
1087-
a: 1,
1088-
b: 2,
1089-
},
1090-
},
1091-
} );
1092-
1093-
const state = editor( original, {
1094-
type: 'UPDATE_POST',
1095-
edits: {
1096-
title: 'modified title',
1097-
meta: {
1098-
a: 1,
1099-
},
1100-
},
1101-
} );
1102-
1103-
expect( state.present.edits ).toEqual( {
1104-
meta: {
1105-
b: 2,
1106-
},
1107-
} );
1108-
} );
1109-
11101081
it( 'unset reset post values which match by canonical value', () => {
11111082
const original = editor( undefined, {
11121083
type: 'EDIT_POST',
@@ -1127,7 +1098,7 @@ describe( 'state', () => {
11271098
expect( state.present.edits ).toEqual( {} );
11281099
} );
11291100

1130-
it( 'unset top-level key of empty object value', () => {
1101+
it( 'unset reset post values by deep match', () => {
11311102
const original = editor( undefined, {
11321103
type: 'EDIT_POST',
11331104
edits: {

0 commit comments

Comments
 (0)