-
Notifications
You must be signed in to change notification settings - Fork 4.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Perform a complete draft save on preview #12097
Changes from all commits
0c46e21
b17b85f
8e54535
acde4a5
20691f3
89660bc
ecf175d
ee275cc
a842446
b757300
74035ca
8ab9863
f2f1514
da53820
de2a5f1
ffcc886
cc7df56
08bfa21
196a3ff
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,7 +12,6 @@ import { __, _x } from '@wordpress/i18n'; | |
import { withSelect, withDispatch } from '@wordpress/data'; | ||
import { DotTip } from '@wordpress/nux'; | ||
import { ifCondition, compose } from '@wordpress/compose'; | ||
import { addQueryArgs } from '@wordpress/url'; | ||
|
||
function writeInterstitialMessage( targetDocument ) { | ||
let markup = renderToString( | ||
|
@@ -148,7 +147,11 @@ export class PostPreviewButton extends Component { | |
|
||
// Request an autosave. This happens asynchronously and causes the component | ||
// to update when finished. | ||
this.props.autosave( { isPreview: true } ); | ||
if ( this.props.isDraft ) { | ||
this.props.savePost( { isPreview: true } ); | ||
} else { | ||
this.props.autosave( { isPreview: true } ); | ||
} | ||
|
||
// Display a 'Generating preview' message in the Preview tab while we wait for the | ||
// autosave to finish. | ||
|
@@ -192,33 +195,30 @@ export default compose( [ | |
const { | ||
getCurrentPostId, | ||
getCurrentPostAttribute, | ||
getAutosaveAttribute, | ||
getEditedPostAttribute, | ||
isEditedPostSaveable, | ||
isEditedPostAutosaveable, | ||
getEditedPostPreviewLink, | ||
} = select( 'core/editor' ); | ||
const { | ||
getPostType, | ||
} = select( 'core' ); | ||
|
||
let previewLink = getAutosaveAttribute( 'preview_link' ); | ||
const featuredImageId = getEditedPostAttribute( 'featured_media' ); | ||
if ( previewLink && featuredImageId ) { | ||
previewLink = addQueryArgs( previewLink, { _thumbnail_id: featuredImageId } ); | ||
} | ||
|
||
const previewLink = getEditedPostPreviewLink(); | ||
const postType = getPostType( getEditedPostAttribute( 'type' ) ); | ||
return { | ||
postId: getCurrentPostId(), | ||
currentPostLink: getCurrentPostAttribute( 'link' ), | ||
previewLink: forcePreviewLink !== undefined ? forcePreviewLink : getAutosaveAttribute( 'preview_link' ), | ||
previewLink: forcePreviewLink !== undefined ? forcePreviewLink : previewLink, | ||
isSaveable: isEditedPostSaveable(), | ||
isAutosaveable: forceIsAutosaveable || isEditedPostAutosaveable(), | ||
isViewable: get( postType, [ 'viewable' ], false ), | ||
isDraft: [ 'draft', 'auto-draft' ].indexOf( getEditedPostAttribute( 'status' ) ) !== -1, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Seems like a possible candidate for a selector. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We do have a bunch of But overall agreed, for now it's specific to this component so maybe fine to leave it as is? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can add it later. |
||
}; | ||
} ), | ||
withDispatch( ( dispatch ) => ( { | ||
autosave: dispatch( 'core/editor' ).autosave, | ||
savePost: dispatch( 'core/editor' ).savePost, | ||
} ) ), | ||
ifCondition( ( { isViewable } ) => isViewable ), | ||
] )( PostPreviewButton ); |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,6 +22,7 @@ import { | |
*/ | ||
import { isReusableBlock } from '@wordpress/blocks'; | ||
import { combineReducers } from '@wordpress/data'; | ||
import { addQueryArgs } from '@wordpress/url'; | ||
|
||
/** | ||
* Internal dependencies | ||
|
@@ -1203,13 +1204,29 @@ export function autosave( state = null, action ) { | |
title, | ||
excerpt, | ||
content, | ||
preview_link: post.preview_link, | ||
}; | ||
} | ||
|
||
return state; | ||
} | ||
|
||
/** | ||
* Reducer returning the poost preview link | ||
* | ||
* @param {string?} state The preview link | ||
* @param {Object} action Dispatched action. | ||
* | ||
* @return {string?} Updated state. | ||
*/ | ||
export function previewLink( state = null, action ) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Preview link is tracked separately as it's not directly related to autodrafts anymore. |
||
switch ( action.type ) { | ||
case 'REQUEST_POST_UPDATE_SUCCESS': | ||
return action.post.preview_link || addQueryArgs( action.post.link, { preview: true } ); | ||
|
||
case 'REQUEST_POST_UPDATE_START': | ||
// Invalidate known preview link when autosave starts. | ||
if ( state && action.options.isAutosave ) { | ||
return omit( state, 'preview_link' ); | ||
if ( state && action.options.isPreview ) { | ||
return null; | ||
} | ||
break; | ||
} | ||
|
@@ -1233,6 +1250,7 @@ export default optimist( combineReducers( { | |
reusableBlocks, | ||
template, | ||
autosave, | ||
previewLink, | ||
settings, | ||
postSavingLock, | ||
} ) ); |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -33,6 +33,7 @@ import { | |
} from '@wordpress/blocks'; | ||
import { isInTheFuture, getDate } from '@wordpress/date'; | ||
import { removep } from '@wordpress/autop'; | ||
import { addQueryArgs } from '@wordpress/url'; | ||
|
||
/** | ||
* Dependencies | ||
|
@@ -1532,6 +1533,23 @@ export function isPreviewingPost( state ) { | |
return isSavingPost( state ) && !! state.saving.options.isPreview; | ||
} | ||
|
||
/** | ||
* Returns the post preview link | ||
* | ||
* @param {Object} state Global application state. | ||
* | ||
* @return {string?} Preview Link. | ||
*/ | ||
export function getEditedPostPreviewLink( state ) { | ||
const featuredImageId = getEditedPostAttribute( state, 'featured_media' ); | ||
const previewLink = state.previewLink; | ||
if ( previewLink && featuredImageId ) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we should add also a unit test, can be a follow-up PR |
||
return addQueryArgs( previewLink, { _thumbnail_id: featuredImageId } ); | ||
} | ||
|
||
return previewLink; | ||
} | ||
|
||
/** | ||
* Returns a suggested post format for the current post, inferred only if there | ||
* is a single block within the post and it is of a type known to match a | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -71,7 +71,7 @@ describe( 'Preview', () => { | |
return window.location.search.match( /[\?&]post=(\d+)/ ); | ||
} ) ).jsonValue(); | ||
|
||
let expectedPreviewURL = getUrl( '', `?p=${ postId }&preview=true` ); | ||
const expectedPreviewURL = getUrl( '', `?p=${ postId }&preview=true` ); | ||
expect( previewPage.url() ).toBe( expectedPreviewURL ); | ||
|
||
// Title in preview should match input. | ||
|
@@ -97,16 +97,6 @@ describe( 'Preview', () => { | |
// Preview for published post (no unsaved changes) directs to canonical URL for post. | ||
await editorPage.bringToFront(); | ||
await publishPost(); | ||
// Wait until the publish panel is closed | ||
await Promise.all( [ | ||
editorPage.waitForFunction( () => ! document.querySelector( '.editor-post-publish-panel' ) ), | ||
editorPage.click( '.editor-post-publish-panel__header button' ), | ||
] ); | ||
expectedPreviewURL = await editorPage.$eval( '.components-notice.is-success a', ( node ) => node.href ); | ||
|
||
await editorPage.bringToFront(); | ||
await waitForPreviewNavigation( previewPage ); | ||
expect( previewPage.url() ).toBe( expectedPreviewURL ); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I removed this part because in my testing even if the url is a preview url and not the final url, it works as intended. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It works this way in classic, so maybe we should keep it with this param. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't remember why this part is here, @aduth should confirm whether we can remove it. I remember that this test was very fragile in the past. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the idea was that if there is nothing to save and we have a known preview URL, we don't save, we go straight to the preview URL. I don't know that it's necessarily breaking to let the save go through, however. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes, that was my thinking, if the save request returns a URL, just use it whether there are dirtiness or not shouldn't affect it. and also restoring the old behavior was adding a bit of unnecessary complexity. |
||
|
||
// Return to editor to change title. | ||
await editorPage.bringToFront(); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
previewLink
can be inlined again.