From 046f27825b86c3d1b05e3291af07faeab2e35d3b Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Fri, 1 Jun 2018 16:06:40 -0400 Subject: [PATCH 1/4] Ensure autosaves contain all fields (title, content & excerpt), not just edited fields --- editor/store/effects.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/editor/store/effects.js b/editor/store/effects.js index dd4531055d87b..1188647dfa6fb 100644 --- a/editor/store/effects.js +++ b/editor/store/effects.js @@ -120,6 +120,14 @@ export default { if ( isAutosave ) { toSend.parent = post.id; + // Ensure autosaves contain all fields. + Object.assign( toSend, + { + title: post.title, + content: post.content, + excerpt: post.excerpt, + }, toSend ); + request = wp.apiRequest( { path: `/wp/v2/${ basePath }/${ post.id }/autosaves`, method: 'POST', From e9a18c337af93368fe2820c4ff737b8db71e10c2 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Fri, 1 Jun 2018 16:18:32 -0400 Subject: [PATCH 2/4] use a new data to send to autosave --- editor/store/effects.js | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/editor/store/effects.js b/editor/store/effects.js index 1188647dfa6fb..3ed9c53713f5c 100644 --- a/editor/store/effects.js +++ b/editor/store/effects.js @@ -118,20 +118,23 @@ export default { let request; if ( isAutosave ) { - toSend.parent = post.id; + const autosaveData = {}; // Ensure autosaves contain all fields. - Object.assign( toSend, - { - title: post.title, - content: post.content, - excerpt: post.excerpt, - }, toSend ); + Object.assign( autosaveData, + { + title: post.title, + content: post.content, + excerpt: post.excerpt, + }, + toSend + ); + autosaveData.parent = post.id; request = wp.apiRequest( { path: `/wp/v2/${ basePath }/${ post.id }/autosaves`, method: 'POST', - data: toSend, + data: autosaveData, } ); } else { dispatch( { From d10a64e8874950607b6c642d23ab48a8bcc8ab23 Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Mon, 4 Jun 2018 10:24:03 -0400 Subject: [PATCH 3/4] State: Account for autosave values in fallback spread --- editor/store/effects.js | 27 +++++++++----------- editor/store/selectors.js | 18 ++++++++++++-- editor/store/test/selectors.js | 45 ++++++++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+), 17 deletions(-) diff --git a/editor/store/effects.js b/editor/store/effects.js index 3ed9c53713f5c..2d78b96c8b32c 100644 --- a/editor/store/effects.js +++ b/editor/store/effects.js @@ -2,7 +2,7 @@ * External dependencies */ import { BEGIN, COMMIT, REVERT } from 'redux-optimist'; -import { get, includes, last, map, castArray, uniqueId } from 'lodash'; +import { get, includes, last, map, castArray, uniqueId, pick } from 'lodash'; /** * WordPress dependencies @@ -62,6 +62,7 @@ import { isBlockSelected, getTemplate, getTemplateLock, + getCurrentAutosave, POST_UPDATE_TRANSACTION_ID, } from './selectors'; @@ -103,7 +104,7 @@ export default { const post = getCurrentPost( state ); const edits = getPostEdits( state ); - const toSend = { + let toSend = { ...edits, content: getEditedPostContent( state ), id: post.id, @@ -118,23 +119,19 @@ export default { let request; if ( isAutosave ) { - const autosaveData = {}; - - // Ensure autosaves contain all fields. - Object.assign( autosaveData, - { - title: post.title, - content: post.content, - excerpt: post.excerpt, - }, - toSend - ); - autosaveData.parent = post.id; + // Ensure autosaves contain all expected fields, using autosave or + // post values as fallback if not otherwise included in edits. + toSend = { + ...pick( post, [ 'title', 'content', 'excerpt' ] ), + ...getCurrentAutosave( state ), + ...toSend, + parent: post.id, + }; request = wp.apiRequest( { path: `/wp/v2/${ basePath }/${ post.id }/autosaves`, method: 'POST', - data: autosaveData, + data: toSend, } ); } else { dispatch( { diff --git a/editor/store/selectors.js b/editor/store/selectors.js index c5793bdd7fe7b..6475de99ad3ed 100644 --- a/editor/store/selectors.js +++ b/editor/store/selectors.js @@ -345,11 +345,25 @@ export function isEditedPostAutosaveable( state ) { } // If the title, excerpt or content has changed, the post is autosaveable. + const autosave = getAutosave( state ); return [ 'title', 'excerpt', 'content' ].some( ( field ) => ( - state.autosave[ field ] !== getEditedPostAttribute( state, field ) + autosave[ field ] !== getEditedPostAttribute( state, field ) ) ); } +/** + * Returns the current autosave, or null if one is not set (i.e. if the post + * has yet to be autosaved, or has been saved or published since the last + * autosave). + * + * @param {Object} state Editor state. + * + * @return {?Object} Current autosave, if exists. + */ +export function getAutosave( state ) { + return state.autosave; +} + /** * Returns the true if there is an existing autosave, otherwise false. * @@ -358,7 +372,7 @@ export function isEditedPostAutosaveable( state ) { * @return {boolean} Whether there is an existing autosave. */ export function hasAutosave( state ) { - return !! state.autosave; + return !! getAutosave( state ); } /** diff --git a/editor/store/test/selectors.js b/editor/store/test/selectors.js index 831ac8d72d451..a58ea995d15eb 100644 --- a/editor/store/test/selectors.js +++ b/editor/store/test/selectors.js @@ -36,6 +36,8 @@ const { isEditedPostPublishable, isEditedPostSaveable, isEditedPostAutosaveable, + getAutosave, + hasAutosave, isEditedPostEmpty, isEditedPostBeingScheduled, getEditedPostPreviewLink, @@ -1108,6 +1110,49 @@ describe( 'selectors', () => { } ); } ); + describe( 'getAutosave', () => { + it( 'returns null if there is no autosave', () => { + const state = { + autosave: null, + }; + + const result = getAutosave( state ); + + expect( result ).toBe( null ); + } ); + + it( 'returns the autosave', () => { + const autosave = { title: '', excerpt: '', content: '' }; + const state = { autosave }; + + const result = getAutosave( state ); + + expect( result ).toEqual( autosave ); + } ); + } ); + + describe( 'hasAutosave', () => { + it( 'returns false if there is no autosave', () => { + const state = { + autosave: null, + }; + + const result = hasAutosave( state ); + + expect( result ).toBe( false ); + } ); + + it( 'returns true if there is a autosave', () => { + const state = { + autosave: { title: '', excerpt: '', content: '' }, + }; + + const result = hasAutosave( state ); + + expect( result ).toBe( true ); + } ); + } ); + describe( 'isEditedPostEmpty', () => { it( 'should return true if no blocks and no content', () => { const state = { From aedf98dffddcde007ccce208b6e21beab7c16330 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Mon, 4 Jun 2018 16:58:25 +0100 Subject: [PATCH 4/4] Fix renamed selector --- editor/store/effects.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/editor/store/effects.js b/editor/store/effects.js index 2d78b96c8b32c..91d5795575bfb 100644 --- a/editor/store/effects.js +++ b/editor/store/effects.js @@ -62,7 +62,7 @@ import { isBlockSelected, getTemplate, getTemplateLock, - getCurrentAutosave, + getAutosave, POST_UPDATE_TRANSACTION_ID, } from './selectors'; @@ -123,7 +123,7 @@ export default { // post values as fallback if not otherwise included in edits. toSend = { ...pick( post, [ 'title', 'content', 'excerpt' ] ), - ...getCurrentAutosave( state ), + ...getAutosave( state ), ...toSend, parent: post.id, };