diff --git a/docs/data/data-core-editor.md b/docs/data/data-core-editor.md index d4c7b602001943..d0ccaabda71fb8 100644 --- a/docs/data/data-core-editor.md +++ b/docs/data/data-core-editor.md @@ -1071,6 +1071,18 @@ Returns true if the post is autosaving, or false otherwise. Whether the post is autosaving. +### isPreviewingPost + +Returns true if the post is being previewed, or false otherwise. + +*Parameters* + + * state: Global application state. + +*Returns* + +Whether the post is being previewed. + ### getSuggestedPostFormat Returns a suggested post format for the current post, inferred only if there @@ -1628,7 +1640,7 @@ Returns an action object to save the post. *Parameters* * options: Options for the save. - * options.autosave: Perform an autosave if true. + * options.isAutosave: Perform an autosave if true. ### mergeBlocks @@ -1643,6 +1655,10 @@ Returns an action object used in signalling that two blocks should be merged Returns an action object used in signalling that the post should autosave. +*Parameters* + + * options: Extra flags to identify the autosave. + ### redo Returns an action object used in signalling that undo history should diff --git a/packages/edit-post/src/components/header/index.js b/packages/edit-post/src/components/header/index.js index c63a7058eeb7cc..6fb3ec96eab749 100644 --- a/packages/edit-post/src/components/header/index.js +++ b/packages/edit-post/src/components/header/index.js @@ -51,7 +51,10 @@ function Header( { forceIsSaving={ isSaving } /> ) } - + { const isSavingPost = select( 'core/editor' ).isSavingPost(); const isAutosavingPost = select( 'core/editor' ).isAutosavingPost(); + const isPreviewingPost = select( 'core/editor' ).isPreviewingPost(); const hasActiveMetaBoxes = select( 'core/edit-post' ).hasMetaBoxes(); - // Save metaboxes on save completion when past save wasn't an autosave. + // Save metaboxes on save completion, except for autosaves that are not a post preview. const shouldTriggerMetaboxesSave = ( - hasActiveMetaBoxes && - wasSavingPost && - ! wasAutosavingPost && - ! isSavingPost && - ! isAutosavingPost + hasActiveMetaBoxes && ( + ( wasSavingPost && ! isSavingPost && ! wasAutosavingPost ) || + ( wasAutosavingPost && wasPreviewingPost && ! isPreviewingPost ) + ) ); // Save current state for next inspection. wasSavingPost = isSavingPost; wasAutosavingPost = isAutosavingPost; + wasPreviewingPost = isPreviewingPost; if ( shouldTriggerMetaboxesSave ) { store.dispatch( requestMetaBoxUpdates() ); diff --git a/packages/editor/src/components/post-preview-button/index.js b/packages/editor/src/components/post-preview-button/index.js index 0cf5350a5672f5..9dac5eedddef55 100644 --- a/packages/editor/src/components/post-preview-button/index.js +++ b/packages/editor/src/components/post-preview-button/index.js @@ -99,10 +99,6 @@ export class PostPreviewButton extends Component { // unintentional forceful redirects. if ( previewLink && ! prevProps.previewLink ) { this.setPreviewWindowLink( previewLink ); - - // Once popup redirect is evaluated, even if already closed, delete - // reference to avoid later assignment of location in post update. - delete this.previewWindow; } } @@ -152,7 +148,7 @@ export class PostPreviewButton extends Component { // Request an autosave. This happens asynchronously and causes the component // to update when finished. - this.props.autosave(); + this.props.autosave( { isPreview: true } ); // Display a 'Generating preview' message in the Preview tab while we wait for the // autosave to finish. @@ -192,7 +188,7 @@ export class PostPreviewButton extends Component { } export default compose( [ - withSelect( ( select ) => { + withSelect( ( select, { forcePreviewLink, forceIsAutosaveable } ) => { const { getCurrentPostId, getCurrentPostAttribute, @@ -215,9 +211,9 @@ export default compose( [ return { postId: getCurrentPostId(), currentPostLink: getCurrentPostAttribute( 'link' ), - previewLink, + previewLink: forcePreviewLink !== undefined ? forcePreviewLink : getAutosaveAttribute( 'preview_link' ), isSaveable: isEditedPostSaveable(), - isAutosaveable: isEditedPostAutosaveable(), + isAutosaveable: forceIsAutosaveable || isEditedPostAutosaveable(), isViewable: get( postType, [ 'viewable' ], false ), }; } ), diff --git a/packages/editor/src/store/actions.js b/packages/editor/src/store/actions.js index 864fcfdd518e5a..6302ce88947560 100644 --- a/packages/editor/src/store/actions.js +++ b/packages/editor/src/store/actions.js @@ -396,7 +396,7 @@ export function editPost( edits ) { * Returns an action object to save the post. * * @param {Object} options Options for the save. - * @param {boolean} options.autosave Perform an autosave if true. + * @param {boolean} options.isAutosave Perform an autosave if true. * * @return {Object} Action object. */ @@ -439,10 +439,12 @@ export function mergeBlocks( firstBlockClientId, secondBlockClientId ) { /** * Returns an action object used in signalling that the post should autosave. * + * @param {Object?} options Extra flags to identify the autosave. + * * @return {Object} Action object. */ -export function autosave() { - return savePost( { autosave: true } ); +export function autosave( options ) { + return savePost( { isAutosave: true, ...options } ); } /** diff --git a/packages/editor/src/store/effects/posts.js b/packages/editor/src/store/effects/posts.js index af722dd4512bd8..fd33234a53a5db 100644 --- a/packages/editor/src/store/effects/posts.js +++ b/packages/editor/src/store/effects/posts.js @@ -28,7 +28,6 @@ import { getEditedPostContent, getAutosave, getCurrentPostType, - isEditedPostAutosaveable, isEditedPostSaveable, isEditedPostNew, POST_UPDATE_TRANSACTION_ID, @@ -51,12 +50,11 @@ export const requestPostUpdate = async ( action, store ) => { const { dispatch, getState } = store; const state = getState(); const post = getCurrentPost( state ); - const isAutosave = !! action.options.autosave; + const isAutosave = !! action.options.isAutosave; // Prevent save if not saveable. - const isSaveable = isAutosave ? isEditedPostAutosaveable : isEditedPostSaveable; - - if ( ! isSaveable( state ) ) { + // We don't check for dirtiness here as this can be overriden in the UI. + if ( ! isEditedPostSaveable( state ) ) { return; } @@ -91,7 +89,7 @@ export const requestPostUpdate = async ( action, store ) => { dispatch( { type: 'REQUEST_POST_UPDATE_START', optimist: { type: BEGIN, id: POST_UPDATE_TRANSACTION_ID }, - isAutosave, + options: action.options, } ); // Optimistically apply updates under the assumption that the post @@ -150,7 +148,7 @@ export const requestPostUpdate = async ( action, store ) => { type: isRevision ? REVERT : COMMIT, id: POST_UPDATE_TRANSACTION_ID, }, - isAutosave, + options: action.options, postType, } ); } catch ( error ) { @@ -160,6 +158,7 @@ export const requestPostUpdate = async ( action, store ) => { post, edits, error, + options: action.options, } ); } }; diff --git a/packages/editor/src/store/reducer.js b/packages/editor/src/store/reducer.js index cc7cdeedb55f3c..e21d2c3d990b11 100644 --- a/packages/editor/src/store/reducer.js +++ b/packages/editor/src/store/reducer.js @@ -967,7 +967,7 @@ export function saving( state = {}, action ) { requesting: true, successful: false, error: null, - isAutosave: action.isAutosave, + options: action.options || {}, }; case 'REQUEST_POST_UPDATE_SUCCESS': @@ -975,6 +975,7 @@ export function saving( state = {}, action ) { requesting: false, successful: true, error: null, + options: action.options || {}, }; case 'REQUEST_POST_UPDATE_FAILURE': @@ -982,6 +983,7 @@ export function saving( state = {}, action ) { requesting: false, successful: false, error: action.error, + options: action.options || {}, }; } @@ -1204,9 +1206,9 @@ export function autosave( state = null, action ) { preview_link: post.preview_link, }; - case 'REQUEST_POST_UPDATE': + case 'REQUEST_POST_UPDATE_START': // Invalidate known preview link when autosave starts. - if ( state && action.options.autosave ) { + if ( state && action.options.isAutosave ) { return omit( state, 'preview_link' ); } break; diff --git a/packages/editor/src/store/selectors.js b/packages/editor/src/store/selectors.js index 3c8d2d121acd92..9d7855830d3b1d 100644 --- a/packages/editor/src/store/selectors.js +++ b/packages/editor/src/store/selectors.js @@ -1518,7 +1518,18 @@ export function didPostSaveRequestFail( state ) { * @return {boolean} Whether the post is autosaving. */ export function isAutosavingPost( state ) { - return isSavingPost( state ) && state.saving.isAutosave; + return isSavingPost( state ) && !! state.saving.options.isAutosave; +} + +/** + * Returns true if the post is being previewed, or false otherwise. + * + * @param {Object} state Global application state. + * + * @return {boolean} Whether the post is being previewed. + */ +export function isPreviewingPost( state ) { + return isSavingPost( state ) && !! state.saving.options.isPreview; } /** diff --git a/packages/editor/src/store/test/reducer.js b/packages/editor/src/store/test/reducer.js index 99ac0c6e369967..788e361a6a929e 100644 --- a/packages/editor/src/store/test/reducer.js +++ b/packages/editor/src/store/test/reducer.js @@ -1943,6 +1943,7 @@ describe( 'state', () => { requesting: true, successful: false, error: null, + options: {}, } ); } ); @@ -1954,6 +1955,7 @@ describe( 'state', () => { requesting: false, successful: true, error: null, + options: {}, } ); } ); @@ -1972,6 +1974,7 @@ describe( 'state', () => { code: 'pretend_error', message: 'update failed', }, + options: {}, } ); } ); } );