diff --git a/editor/components/post-preview-button/index.js b/editor/components/post-preview-button/index.js index 00244ec04afd16..e01731a12fa94b 100644 --- a/editor/components/post-preview-button/index.js +++ b/editor/components/post-preview-button/index.js @@ -16,26 +16,34 @@ export class PostPreviewButton extends Component { super( ...arguments ); this.saveForPreview = this.saveForPreview.bind( this ); - - this.state = { - isAwaitingSave: false, - }; } - componentWillReceiveProps( nextProps ) { - const { modified, link } = nextProps; - const { isAwaitingSave } = this.state; - const hasFinishedSaving = ( - isAwaitingSave && - modified !== this.props.modified - ); + componentDidUpdate( prevProps ) { + const { previewLink } = this.props; - if ( hasFinishedSaving && this.previewWindow ) { - this.previewWindow.location = link; - this.setState( { isAwaitingSave: false } ); + // This relies on the window being responsible to unset itself when + // navigation occurs or a new preview window is opened, to avoid + // unintentional forceful redirects. + if ( previewLink && previewLink !== prevProps.previewLink ) { + this.setPreviewWindowLink( previewLink ); } } + /** + * Sets the preview window's location to the given URL, if a preview window + * exists and is not already at that location. + * + * @param {string} url URL to assign as preview window location. + */ + setPreviewWindowLink( url ) { + const { previewWindow } = this; + if ( ! previewWindow || previewWindow.location.href === url ) { + return; + } + + previewWindow.location = url; + } + getWindowTarget() { const { postId } = this.props; return `wp-preview-${ postId }`; @@ -43,6 +51,7 @@ export class PostPreviewButton extends Component { saveForPreview( event ) { const { isDirty, isNew } = this.props; + // Let default link behavior occur if no changes to saved post if ( ! isDirty && ! isNew ) { return; @@ -50,9 +59,6 @@ export class PostPreviewButton extends Component { // Save post prior to opening window this.props.autosave(); - this.setState( { - isAwaitingSave: true, - } ); // Open a popup, BUT: Set it to a blank page until save completes. This // is necessary because popups can only be opened in response to user @@ -63,10 +69,6 @@ export class PostPreviewButton extends Component { this.getWindowTarget() ); - // When popup is closed, delete reference to avoid later assignment of - // location in a post update. - this.previewWindow.onbeforeunload = () => delete this.previewWindow; - const markup = `

Please wait…

@@ -92,16 +94,20 @@ export class PostPreviewButton extends Component { this.previewWindow.document.write( markup ); this.previewWindow.document.close(); + + // When popup is closed or redirected by setPreviewWindowLink, delete + // reference to avoid later assignment of location in a post update. + this.previewWindow.onbeforeunload = () => delete this.previewWindow; } render() { - const { link, isSaveable } = this.props; + const { currentPostLink, isSaveable } = this.props; return (