From db397420851172a51f8437d55e155a64b785dd2b Mon Sep 17 00:00:00 2001 From: James Nylen Date: Fri, 19 May 2017 18:00:59 -0400 Subject: [PATCH 01/11] Register `post-content.js` properties as edits --- editor/index.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/editor/index.js b/editor/index.js index 892323312d4ee..dca45a4d41445 100644 --- a/editor/index.js +++ b/editor/index.js @@ -25,6 +25,17 @@ export function createEditorInstance( id, post ) { blocks: wp.blocks.parse( post.content.raw ), } ); + // Each property that is set in `post-content.js` (other than `content`) + // needs to be registered as an edit now. Otherwise it will not be saved + // with the post. + store.dispatch( { + type: 'EDIT_POST', + edits: { + title: post.title.raw, + // ...omit( post, 'title', 'content' ), + }, + } ); + wp.element.render( From 765f4ee4b01210bfb907071faeb3b9871ca5e3b7 Mon Sep 17 00:00:00 2001 From: James Nylen Date: Fri, 19 May 2017 18:01:12 -0400 Subject: [PATCH 02/11] Mark post as dirty when `EDIT_POST` occurs --- editor/state.js | 1 + 1 file changed, 1 insertion(+) diff --git a/editor/state.js b/editor/state.js index 405ce0f84a6ea..17a86a0844c5d 100644 --- a/editor/state.js +++ b/editor/state.js @@ -48,6 +48,7 @@ export const editor = combineUndoableReducers( { case 'MOVE_BLOCK_UP': case 'REPLACE_BLOCKS': case 'REMOVE_BLOCK': + case 'EDIT_POST': return true; } From 826cc6752bffaccc82068180429998eabc8926a4 Mon Sep 17 00:00:00 2001 From: James Nylen Date: Fri, 19 May 2017 18:44:20 -0400 Subject: [PATCH 03/11] Make `SavedState` aware of whether a post is new or existing Adds a new selector: `isEditedPostNew` based on whether or not our representation of the currently edited post has an ID. --- editor/header/saved-state/index.js | 26 +++++++++++++++++--------- editor/selectors.js | 4 ++++ editor/test/selectors.js | 21 +++++++++++++++++++++ 3 files changed, 42 insertions(+), 9 deletions(-) diff --git a/editor/header/saved-state/index.js b/editor/header/saved-state/index.js index 0b5e16fe50237..d48826f243e98 100644 --- a/editor/header/saved-state/index.js +++ b/editor/header/saved-state/index.js @@ -13,18 +13,25 @@ import Dashicon from 'components/dashicon'; * Internal dependencies */ import './style.scss'; -import { isEditedPostDirty } from '../../selectors'; +import { isEditedPostNew, isEditedPostDirty } from '../../selectors'; -function SavedState( { isDirty } ) { +function SavedState( { isNew, isDirty } ) { const classes = classNames( 'editor-saved-state', { - 'is-dirty': isDirty, + 'is-new': isNew, + 'is-existing-dirty': isDirty && ! isNew, } ); - const icon = isDirty - ? 'warning' - : 'saved'; - const text = isDirty - ? wp.i18n.__( 'Unsaved changes' ) - : wp.i18n.__( 'Saved' ); + + let icon, text; + if ( isNew ) { + icon = 'edit'; + text = wp.i18n.__( 'New post' ); + } else if ( isDirty ) { + icon = 'warning'; + text = wp.i18n.__( 'Unsaved changes' ); + } else { + icon = 'saved'; + text = wp.i18n.__( 'Saved' ); + } return (
@@ -36,6 +43,7 @@ function SavedState( { isDirty } ) { export default connect( ( state ) => ( { + isNew: isEditedPostNew( state ), isDirty: isEditedPostDirty( state ), } ) )( SavedState ); diff --git a/editor/selectors.js b/editor/selectors.js index 886314c4082b5..8aa33e6c97ea1 100644 --- a/editor/selectors.js +++ b/editor/selectors.js @@ -24,6 +24,10 @@ export function hasEditorRedo( state ) { return state.editor.history.future.length > 0; } +export function isEditedPostNew( state ) { + return ! state.currentPost.id; +} + export function isEditedPostDirty( state ) { return state.editor.dirty; } diff --git a/editor/test/selectors.js b/editor/test/selectors.js index f64e30bd87656..cb922842a5071 100644 --- a/editor/test/selectors.js +++ b/editor/test/selectors.js @@ -11,6 +11,7 @@ import { isEditorSidebarOpened, hasEditorUndo, hasEditorRedo, + isEditedPostNew, isEditedPostDirty, getCurrentPost, getPostEdits, @@ -123,6 +124,26 @@ describe( 'selectors', () => { } ); } ); + describe( 'isEditedPostNew', () => { + it( 'should return true when the post is new', () => { + const state = { + currentPost: {}, + }; + + expect( isEditedPostNew( state ) ).to.be.true(); + } ); + + it( 'should return false when the post has an ID', () => { + const state = { + currentPost: { + id: 1, + }, + }; + + expect( isEditedPostNew( state ) ).to.be.false(); + } ); + } ); + describe( 'isEditedPostDirty', () => { it( 'should return true when the post is dirty', () => { const state = { From a538f8976515af7927d6c2248744100e00001b4d Mon Sep 17 00:00:00 2001 From: James Nylen Date: Fri, 19 May 2017 18:47:07 -0400 Subject: [PATCH 04/11] Set `status: 'draft'` as the default for a new post --- editor/index.js | 10 ++++++---- post-content.js | 1 + 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/editor/index.js b/editor/index.js index dca45a4d41445..17f9042713fb3 100644 --- a/editor/index.js +++ b/editor/index.js @@ -3,6 +3,7 @@ */ import { Provider as ReduxProvider } from 'react-redux'; import { Provider as SlotFillProvider } from 'react-slot-fill'; +import { omit } from 'lodash'; /** * Internal dependencies @@ -25,14 +26,15 @@ export function createEditorInstance( id, post ) { blocks: wp.blocks.parse( post.content.raw ), } ); - // Each property that is set in `post-content.js` (other than `content`) - // needs to be registered as an edit now. Otherwise it will not be saved - // with the post. + // Each property that is set in `post-content.js` (other than `content` + // because it is serialized when a save is requested) needs to be + // registered as an edit now. Otherwise the initial values of these + // properties will not be properly saved with the post. store.dispatch( { type: 'EDIT_POST', edits: { title: post.title.raw, - // ...omit( post, 'title', 'content' ), + ...omit( post, 'title', 'content' ), }, } ); diff --git a/post-content.js b/post-content.js index e6dd3800243ab..3be62ff1eca16 100644 --- a/post-content.js +++ b/post-content.js @@ -5,6 +5,7 @@ window._wpGutenbergPost = { title: { raw: 'Welcome to the Gutenberg Editor', }, + status: 'draft', content: { raw: [ '', From bbeff331af5e01a3bf98f42f4f9dacff0eadf851 Mon Sep 17 00:00:00 2001 From: James Nylen Date: Fri, 19 May 2017 18:47:31 -0400 Subject: [PATCH 05/11] Unify `onSaveDraft` and `onUpdate` into a single callback --- editor/header/tools/publish-button.js | 23 ++++------------------- 1 file changed, 4 insertions(+), 19 deletions(-) diff --git a/editor/header/tools/publish-button.js b/editor/header/tools/publish-button.js index f20fef3a95a89..6eaacb891296f 100644 --- a/editor/header/tools/publish-button.js +++ b/editor/header/tools/publish-button.js @@ -32,12 +32,11 @@ function PublishButton( { isRequesting, isError, requestIsNewPost, - onUpdate, - onSaveDraft, + onSave, } ) { const buttonEnabled = ! isRequesting; - let buttonText, saveCallback; + let buttonText; if ( isRequesting ) { buttonText = requestIsNewPost ? wp.i18n.__( 'Saving…' ) @@ -56,12 +55,6 @@ function PublishButton( { buttonText = wp.i18n.__( 'Save draft' ); } - if ( post && post.id ) { - saveCallback = onUpdate; - } else { - saveCallback = onSaveDraft; - } - const buttonDisabledHint = process.env.NODE_ENV === 'production' ? wp.i18n.__( 'The Save button is disabled during early alpha releases.' ) : null; @@ -70,7 +63,7 @@ function PublishButton( {