From 71d867b6b622d8ef6bd9cf0451e1b04bad186d9a Mon Sep 17 00:00:00 2001 From: tellthemachines Date: Fri, 8 Nov 2019 10:01:27 +1100 Subject: [PATCH 01/11] Render preview in a modal with responsive sizes. --- .../components/post-preview-button/index.js | 210 +++++++----------- 1 file changed, 80 insertions(+), 130 deletions(-) diff --git a/packages/editor/src/components/post-preview-button/index.js b/packages/editor/src/components/post-preview-button/index.js index 415d9da9ba070d..47de5fb8f07e60 100644 --- a/packages/editor/src/components/post-preview-button/index.js +++ b/packages/editor/src/components/post-preview-button/index.js @@ -6,96 +6,28 @@ import { get } from 'lodash'; /** * WordPress dependencies */ -import { Component, renderToString } from '@wordpress/element'; -import { Button, Path, SVG } from '@wordpress/components'; +import { Component } from '@wordpress/element'; +import { Button, Modal } from '@wordpress/components'; import { __, _x } from '@wordpress/i18n'; import { withSelect, withDispatch } from '@wordpress/data'; import { ifCondition, compose } from '@wordpress/compose'; -import { applyFilters } from '@wordpress/hooks'; - -function writeInterstitialMessage( targetDocument ) { - let markup = renderToString( -
- - - - -

{ __( 'Generating preview…' ) }

-
- ); - - markup += ` - - `; - - /** - * Filters the interstitial message shown when generating previews. - * - * @param {string} markup The preview interstitial markup. - */ - markup = applyFilters( 'editor.PostPreview.interstitialMarkup', markup ); - - targetDocument.write( markup ); - targetDocument.title = __( 'Generating preview…' ); - targetDocument.close(); -} export class PostPreviewButton extends Component { constructor() { super( ...arguments ); + this.state = { + isPreviewOpen: false, + previewSize: { + width: '1200px', + height: '800px', + }, + }; this.openPreviewWindow = this.openPreviewWindow.bind( this ); + this.closePreviewWindow = this.closePreviewWindow.bind( this ); + this.setDesktopPreview = this.setDesktopPreview.bind( this ); + this.setTabletPreview = this.setTabletPreview.bind( this ); + this.setMobilePreview = this.setMobilePreview.bind( this ); } componentDidUpdate( prevProps ) { @@ -128,69 +60,87 @@ export class PostPreviewButton extends Component { return `wp-preview-${ postId }`; } - openPreviewWindow( event ) { - // Our Preview button has its 'href' and 'target' set correctly for a11y - // purposes. Unfortunately, though, we can't rely on the default 'click' - // handler since sometimes it incorrectly opens a new tab instead of reusing - // the existing one. - // https://github.com/WordPress/gutenberg/pull/8330 - event.preventDefault(); - - // Open up a Preview tab if needed. This is where we'll show the preview. - if ( ! this.previewWindow || this.previewWindow.closed ) { - this.previewWindow = window.open( '', this.getWindowTarget() ); - } + openPreviewWindow( ) { + this.setState( { isPreviewOpen: true } ); + } - // Focus the Preview tab. This might not do anything, depending on the browser's - // and user's preferences. - // https://html.spec.whatwg.org/multipage/interaction.html#dom-window-focus - this.previewWindow.focus(); + setDesktopPreview() { + this.setState( { + previewSize: { + width: '1200px', + height: '800px', + }, + } ); + } - // If we don't need to autosave the post before previewing, then we simply - // load the Preview URL in the Preview tab. - if ( ! this.props.isAutosaveable ) { - this.setPreviewWindowLink( event.target.href ); - return; - } + setTabletPreview() { + this.setState( { + previewSize: { + width: '768px', + height: '1024px', + }, + } ); + } - // Request an autosave. This happens asynchronously and causes the component - // to update when finished. - if ( this.props.isDraft ) { - this.props.savePost( { isPreview: true } ); - } else { - this.props.autosave( { isPreview: true } ); - } + setMobilePreview() { + this.setState( { + previewSize: { + width: '375px', + height: '812px', + }, + } ); + } - // Display a 'Generating preview' message in the Preview tab while we wait for the - // autosave to finish. - writeInterstitialMessage( this.previewWindow.document ); + closePreviewWindow() { + this.setState( { isPreviewOpen: false } ); } render() { - const { previewLink, currentPostLink, isSaveable } = this.props; + const { previewLink, isSaveable } = this.props; // Link to the `?preview=true` URL if we have it, since this lets us see // changes that were autosaved since the post was last published. Otherwise, // just link to the post's URL. - const href = previewLink || currentPostLink; return ( - + { this.state.isPreviewOpen && + - + onRequestClose={ this.closePreviewWindow } + className="editor-block-preview" + > + + + + + + } + ); } } From 1eed768a04d25031620d6dbd5d0d57f47a0aad54 Mon Sep 17 00:00:00 2001 From: tellthemachines Date: Fri, 8 Nov 2019 13:44:38 +1100 Subject: [PATCH 02/11] Base styling. --- .../components/post-preview-button/index.js | 28 +++++++++++-------- .../components/post-preview-button/style.scss | 18 ++++++++++++ packages/editor/src/style.scss | 1 + 3 files changed, 35 insertions(+), 12 deletions(-) create mode 100644 packages/editor/src/components/post-preview-button/style.scss diff --git a/packages/editor/src/components/post-preview-button/index.js b/packages/editor/src/components/post-preview-button/index.js index 47de5fb8f07e60..d1d63fa15e01da 100644 --- a/packages/editor/src/components/post-preview-button/index.js +++ b/packages/editor/src/components/post-preview-button/index.js @@ -125,19 +125,23 @@ export class PostPreviewButton extends Component { onRequestClose={ this.closePreviewWindow } className="editor-block-preview" > - - - - + > + } diff --git a/packages/editor/src/components/post-preview-button/style.scss b/packages/editor/src/components/post-preview-button/style.scss new file mode 100644 index 00000000000000..48cf9728877613 --- /dev/null +++ b/packages/editor/src/components/post-preview-button/style.scss @@ -0,0 +1,18 @@ +.editor-block-preview { + @include break-small() { + top: 5%; + right: 5%; + bottom: 5%; + left: 5%; + transform: none; + } +} + +.editor-block-preview__controls { + margin: $grid-size-large 0; +} + +.editor-block-preview__frame { + display: flex; + justify-content: center; +} diff --git a/packages/editor/src/style.scss b/packages/editor/src/style.scss index 949f751bd72af5..a085ac3217b103 100644 --- a/packages/editor/src/style.scss +++ b/packages/editor/src/style.scss @@ -9,6 +9,7 @@ @import "./components/post-last-revision/style.scss"; @import "./components/post-locked-modal/style.scss"; @import "./components/post-permalink/style.scss"; +@import "./components/post-preview-button/style.scss"; @import "./components/post-publish-panel/style.scss"; @import "./components/post-saved-state/style.scss"; @import "./components/post-taxonomies/style.scss"; From c210afacec60371fe5443da8b75b214acbbbc4d5 Mon Sep 17 00:00:00 2001 From: tellthemachines Date: Mon, 2 Dec 2019 19:33:21 +1100 Subject: [PATCH 03/11] Add open in new tab button --- .../components/post-preview-button/index.js | 89 ++++++++++++++++--- .../components/post-preview-button/style.scss | 19 +++- 2 files changed, 95 insertions(+), 13 deletions(-) diff --git a/packages/editor/src/components/post-preview-button/index.js b/packages/editor/src/components/post-preview-button/index.js index d1d63fa15e01da..60edaf32ede001 100644 --- a/packages/editor/src/components/post-preview-button/index.js +++ b/packages/editor/src/components/post-preview-button/index.js @@ -7,11 +7,15 @@ import { get } from 'lodash'; * WordPress dependencies */ import { Component } from '@wordpress/element'; -import { Button, Modal } from '@wordpress/components'; +import { Button, IconButton, Modal, Path, SVG } from '@wordpress/components'; import { __, _x } from '@wordpress/i18n'; import { withSelect, withDispatch } from '@wordpress/data'; import { ifCondition, compose } from '@wordpress/compose'; +const DesktopIcon = ; +const MobileIcon = ; +const TabletIcon = ; + export class PostPreviewButton extends Component { constructor() { super( ...arguments ); @@ -23,7 +27,10 @@ export class PostPreviewButton extends Component { height: '800px', }, }; - this.openPreviewWindow = this.openPreviewWindow.bind( this ); + this.openPreviewInNewTab = this.openPreviewInNewTab.bind( this ); + this.getWindowTarget = this.getWindowTarget.bind( this ); + this.setPreviewWindowLink = this.setPreviewWindowLink.bind( this ); + this.openPreviewOverlay = this.openPreviewOverlay.bind( this ); this.closePreviewWindow = this.closePreviewWindow.bind( this ); this.setDesktopPreview = this.setDesktopPreview.bind( this ); this.setTabletPreview = this.setTabletPreview.bind( this ); @@ -60,8 +67,43 @@ export class PostPreviewButton extends Component { return `wp-preview-${ postId }`; } - openPreviewWindow( ) { + openPreviewOverlay() { this.setState( { isPreviewOpen: true } ); + + // If we don't need to autosave the post before previewing, do nothing. + if ( ! this.props.isAutosaveable ) { + return; + } + + // Request an autosave. This happens asynchronously and causes the component + // to update when finished. + if ( this.props.isDraft ) { + this.props.savePost( { isPreview: true } ); + } else { + this.props.autosave( { isPreview: true } ); + } + } + + openPreviewInNewTab( event ) { + // Our Preview button has its 'href' and 'target' set correctly for a11y + // purposes. Unfortunately, though, we can't rely on the default 'click' + // handler since sometimes it incorrectly opens a new tab instead of reusing + // the existing one. + // https://github.com/WordPress/gutenberg/pull/8330 + event.preventDefault(); + + // Open up a Preview tab if needed. This is where we'll show the preview. + if ( ! this.previewWindow || this.previewWindow.closed ) { + this.previewWindow = window.open( '', this.getWindowTarget() ); + } + + // Focus the Preview tab. This might not do anything, depending on the browser's + // and user's preferences. + // https://html.spec.whatwg.org/multipage/interaction.html#dom-window-focus + this.previewWindow.focus(); + + // Load the Preview URL in the Preview tab. + this.setPreviewWindowLink( event.target.href ); } setDesktopPreview() { @@ -96,11 +138,11 @@ export class PostPreviewButton extends Component { } render() { - const { previewLink, isSaveable } = this.props; - + const { previewLink, currentPostLink, isSaveable } = this.props; // Link to the `?preview=true` URL if we have it, since this lets us see // changes that were autosaved since the post was last published. Otherwise, // just link to the post's URL. + const href = previewLink || currentPostLink; return ( <> @@ -108,7 +150,7 @@ export class PostPreviewButton extends Component { isLarge className="editor-post-preview" disabled={ ! isSaveable } - onClick={ this.openPreviewWindow } + onClick={ this.openPreviewOverlay } > { _x( 'Preview', 'imperative verb' ) } @@ -123,16 +165,41 @@ export class PostPreviewButton extends Component { __( 'Preview' ) } onRequestClose={ this.closePreviewWindow } + // Needed so the Modal doesn't close when tabbing into the iframe. + shouldCloseOnClickOutside={ false } className="editor-block-preview" >
- - - + + + +
-
+
-
- + > +
+ } ); diff --git a/packages/editor/src/components/post-preview-button/style.scss b/packages/editor/src/components/post-preview-button/style.scss index 8a0fafbdb5c739..b233c65673ac5e 100644 --- a/packages/editor/src/components/post-preview-button/style.scss +++ b/packages/editor/src/components/post-preview-button/style.scss @@ -1,4 +1,4 @@ -.editor-block-preview { +.editor-post-preview-button__preview-modal { @include break-small() { top: 5%; right: 5%; @@ -8,7 +8,7 @@ } } -.editor-block-preview__controls { +.editor-post-preview__controls { display: flex; align-items: center; margin: $grid-size-large 0; @@ -18,16 +18,16 @@ } } -.editor-block-preview__new-tab { +.editor-post-preview__new-tab { margin-left: $grid-size-large; } -.editor-block-preview__frame-container { +.editor-post-preview__frame-container { overflow-x: auto; margin-bottom: 40px; } -.editor-block-preview__frame { +.editor-post-preview__frame { display: block; margin: 0 auto; } diff --git a/packages/editor/src/components/post-preview-button/test/__snapshots__/index.js.snap b/packages/editor/src/components/post-preview-button/test/__snapshots__/index.js.snap index d40c9abe2272d3..4fc764eda68a5b 100644 --- a/packages/editor/src/components/post-preview-button/test/__snapshots__/index.js.snap +++ b/packages/editor/src/components/post-preview-button/test/__snapshots__/index.js.snap @@ -9,20 +9,20 @@ exports[`PostPreviewButton render() should render overlay when state is open 1`] onClick={[Function]} > Preview - - Click “Preview” to load a preview of this page, so you can make sure you’re happy with your blocks. - + (opens in a new tab) +