Skip to content

Commit

Permalink
Editor: Shallow merge on whitelisted post property edits
Browse files Browse the repository at this point in the history
  • Loading branch information
aduth committed Nov 8, 2018
1 parent 7b6bccd commit 40a96ee
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 208 deletions.
88 changes: 0 additions & 88 deletions packages/editor/src/store/object.js

This file was deleted.

64 changes: 55 additions & 9 deletions packages/editor/src/store/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,16 @@ import {
INITIAL_EDITS_DEFAULTS,
} from './defaults';
import { insertAt, moveTo } from './array';
import { getMutateSafeObject, merge, diff } from './object';

/**
* Set of post properties for which edits should assume a merging behavior,
* assuming an object value.
*
* @type {Set}
*/
const EDIT_MERGE_PROPERTIES = new Set( [
'meta',
] );

/**
* Returns a post attribute value, flattening nested rendered content using its
Expand Down Expand Up @@ -102,6 +111,23 @@ function getFlattenedBlocks( blocks ) {
return flattenedBlocks;
}

/**
* Returns an object against which it is safe to perform mutating operations,
* given the original object and its current working copy.
*
* @param {Object} original Original object.
* @param {Object} working Working object.
*
* @return {Object} Mutation-safe object.
*/
function getMutateSafeObject( original, working ) {
if ( original === working ) {
return { ...original };
}

return working;
}

/**
* Returns true if the two object arguments have the same keys, or false
* otherwise.
Expand Down Expand Up @@ -224,7 +250,22 @@ export const editor = flow( [
edits( state = {}, action ) {
switch ( action.type ) {
case 'EDIT_POST':
return merge( state, action.edits );
return reduce( action.edits, ( result, value, key ) => {
// Only assign into result if not already same value
if ( value !== state[ key ] ) {
result = getMutateSafeObject( state, result );

if ( EDIT_MERGE_PROPERTIES.has( key ) ) {
// Merge properties should assign to current value.
result[ key ] = { ...result[ key ], ...value };
} else {
// Otherwise override.
result[ key ] = value;
}
}

return result;
}, state );

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

case 'UPDATE_POST':
case 'RESET_POST':
let updates;
if ( action.type === 'UPDATE_POST' ) {
updates = action.edits;
} else {
updates = mapValues( action.post, getPostRawValue );
}
const getCanonicalValue = action.type === 'UPDATE_POST' ?
( key ) => action.edits[ key ] :
( key ) => getPostRawValue( action.post[ key ] );

return reduce( state, ( result, value, key ) => {
if ( ! isEqual( value, getCanonicalValue( key ) ) ) {
return result;
}

return diff( updates, state );
result = getMutateSafeObject( state, result );
delete result[ key ];
return result;
}, state );
}

return state;
Expand Down
81 changes: 0 additions & 81 deletions packages/editor/src/store/test/object.js

This file was deleted.

31 changes: 1 addition & 30 deletions packages/editor/src/store/test/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -1078,35 +1078,6 @@ describe( 'state', () => {
expect( state.present.edits ).toBe( original.present.edits );
} );

it( 'unset updated post values which match', () => {
const original = editor( undefined, {
type: 'EDIT_POST',
edits: {
title: 'modified title',
meta: {
a: 1,
b: 2,
},
},
} );

const state = editor( original, {
type: 'UPDATE_POST',
edits: {
title: 'modified title',
meta: {
a: 1,
},
},
} );

expect( state.present.edits ).toEqual( {
meta: {
b: 2,
},
} );
} );

it( 'unset reset post values which match by canonical value', () => {
const original = editor( undefined, {
type: 'EDIT_POST',
Expand All @@ -1127,7 +1098,7 @@ describe( 'state', () => {
expect( state.present.edits ).toEqual( {} );
} );

it( 'unset top-level key of empty object value', () => {
it( 'unset reset post values by deep match', () => {
const original = editor( undefined, {
type: 'EDIT_POST',
edits: {
Expand Down

0 comments on commit 40a96ee

Please sign in to comment.