From 1e46e7e024845da8f4d794517d194a7aff40632f Mon Sep 17 00:00:00 2001 From: Nicola Heald Date: Tue, 18 Dec 2018 14:26:03 +0000 Subject: [PATCH 1/6] Require an initial click on embed previews for interactivity This fixes the block selection UX for video embeds. Previously the click on the video to select the block would start the video playing. Now that previous require a click to become interactive, the initial click selects the block without side effects. --- packages/block-library/src/embed/editor.scss | 10 ++ .../block-library/src/embed/embed-preview.js | 116 ++++++++++++------ 2 files changed, 86 insertions(+), 40 deletions(-) diff --git a/packages/block-library/src/embed/editor.scss b/packages/block-library/src/embed/editor.scss index 29cbd9fb932cff..9ddb3323e81c8f 100644 --- a/packages/block-library/src/embed/editor.scss +++ b/packages/block-library/src/embed/editor.scss @@ -31,3 +31,13 @@ word-break: break-word; } } + +.wp-block-embed-interactive-overlay { + position: absolute; + width: 100%; + height: 100%; + top: 0; + left: 0; + right: 0; + bottom: 0; +} diff --git a/packages/block-library/src/embed/embed-preview.js b/packages/block-library/src/embed/embed-preview.js index addc30e0cd341d..555209a1e3475c 100644 --- a/packages/block-library/src/embed/embed-preview.js +++ b/packages/block-library/src/embed/embed-preview.js @@ -17,57 +17,93 @@ import classnames from 'classnames/dedupe'; import { __, sprintf } from '@wordpress/i18n'; import { Placeholder, SandBox } from '@wordpress/components'; import { RichText, BlockIcon } from '@wordpress/editor'; +import { Component } from '@wordpress/element'; /** * Internal dependencies */ import WpEmbedPreview from './wp-embed-preview'; -const EmbedPreview = ( props ) => { - const { preview, url, type, caption, onCaptionChange, isSelected, className, icon, label } = props; - const { scripts } = preview; +const EmbedPreview = class extends Component { + constructor() { + super( ...arguments ); + this.hideOverlay = this.hideOverlay.bind( this ); + this.state = { + interactve: false, + }; + } - const html = 'photo' === type ? getPhotoHtml( preview ) : preview.html; - const parsedUrl = parse( url ); - const cannotPreview = includes( HOSTS_NO_PREVIEWS, parsedUrl.host.replace( /^www\./, '' ) ); - // translators: %s: host providing embed content e.g: www.youtube.com - const iframeTitle = sprintf( __( 'Embedded content from %s' ), parsedUrl.host ); - const sandboxClassnames = classnames( type, className, 'wp-block-embed__wrapper' ); + hideOverlay() { + // This is called onMouseUp on the overlay. We can't respond to the `isSelected` prop + // changing, because that happens on mouse down, and the overlay immediately disappears, + // and the mouse event can end up in the preview content. We can't use onClick on + // the overlay to hide it either, because then Gutenberg misses the mouseup event, and + // thinks we're multi-selecting blocks. + this.setState( { interactive: true } ); + } - const embedWrapper = 'wp-embed' === type ? ( - - ) : ( -
- -
- ); - - return ( -
- { ( cannotPreview ) ? ( - } label={ label }> -

{ url }

-

{ __( 'Sorry, we cannot preview this embedded content in the editor.' ) }

-
- ) : embedWrapper } - { ( ! RichText.isEmpty( caption ) || isSelected ) && ( - + - ) } -
- ); + { ! interactive &&
} +
+ ); + /* eslint-enable jsx-a11y/no-noninteractive-element-interactions */ + + return ( +
+ { ( cannotPreview ) ? ( + } label={ label }> +

{ url }

+

{ __( 'Sorry, we cannot preview this embedded content in the editor.' ) }

+
+ ) : embedWrapper } + { ( ! RichText.isEmpty( caption ) || isSelected ) && ( + + ) } +
+ ); + } }; export default EmbedPreview; From ebd88eeb2bf0c477dec8c6d69128ffbcf3f2065e Mon Sep 17 00:00:00 2001 From: Nicola Heald Date: Fri, 21 Dec 2018 11:50:20 +0000 Subject: [PATCH 2/6] Handle keyboard focus --- packages/block-library/src/embed/embed-preview.js | 1 + packages/components/src/sandbox/index.js | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/block-library/src/embed/embed-preview.js b/packages/block-library/src/embed/embed-preview.js index 555209a1e3475c..e8361517a2b96c 100644 --- a/packages/block-library/src/embed/embed-preview.js +++ b/packages/block-library/src/embed/embed-preview.js @@ -75,6 +75,7 @@ const EmbedPreview = class extends Component { scripts={ scripts } title={ iframeTitle } type={ sandboxClassnames } + onFocus={ this.hideOverlay } /> { ! interactive &&
); From 4053879acc5b42c37ac783ddb4a670ba2b61ebba Mon Sep 17 00:00:00 2001 From: Nicola Heald Date: Thu, 27 Dec 2018 10:48:47 +0000 Subject: [PATCH 3/6] Overlay color for demo --- packages/block-library/src/embed/editor.scss | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/block-library/src/embed/editor.scss b/packages/block-library/src/embed/editor.scss index 9ddb3323e81c8f..c81c2280862ef6 100644 --- a/packages/block-library/src/embed/editor.scss +++ b/packages/block-library/src/embed/editor.scss @@ -40,4 +40,6 @@ left: 0; right: 0; bottom: 0; + background: #f00; + opacity: 0.75; } From bb1336e57a21844b05e19fa1f2fab20db29758ed Mon Sep 17 00:00:00 2001 From: Nicola Heald Date: Fri, 1 Feb 2019 11:51:38 +0000 Subject: [PATCH 4/6] Remove dialog role, make overlay transparent --- packages/block-library/src/embed/editor.scss | 5 +---- packages/block-library/src/embed/embed-preview.js | 3 ++- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/packages/block-library/src/embed/editor.scss b/packages/block-library/src/embed/editor.scss index c81c2280862ef6..f386069d50a3f0 100644 --- a/packages/block-library/src/embed/editor.scss +++ b/packages/block-library/src/embed/editor.scss @@ -34,12 +34,9 @@ .wp-block-embed-interactive-overlay { position: absolute; - width: 100%; - height: 100%; top: 0; left: 0; right: 0; bottom: 0; - background: #f00; - opacity: 0.75; + opacity: 0; } diff --git a/packages/block-library/src/embed/embed-preview.js b/packages/block-library/src/embed/embed-preview.js index e8361517a2b96c..4868e228a00f28 100644 --- a/packages/block-library/src/embed/embed-preview.js +++ b/packages/block-library/src/embed/embed-preview.js @@ -64,6 +64,7 @@ const EmbedPreview = class extends Component { const sandboxClassnames = classnames( type, className, 'wp-block-embed__wrapper' ); /* eslint-disable jsx-a11y/no-noninteractive-element-interactions */ + /* eslint-disable jsx-a11y/no-static-element-interactions */ const embedWrapper = 'wp-embed' === type ? ( { ! interactive &&
}
); + /* eslint-enable jsx-a11y/no-static-element-interactions */ /* eslint-enable jsx-a11y/no-noninteractive-element-interactions */ return ( From b37acae9b58e7a31748745effe65c33dc1e607bd Mon Sep 17 00:00:00 2001 From: Nicola Heald Date: Tue, 5 Feb 2019 11:39:19 +0000 Subject: [PATCH 5/6] Review fixes --- packages/block-library/src/embed/editor.scss | 2 +- .../block-library/src/embed/embed-preview.js | 29 ++++++++++--------- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/packages/block-library/src/embed/editor.scss b/packages/block-library/src/embed/editor.scss index f386069d50a3f0..af0b050764ce77 100644 --- a/packages/block-library/src/embed/editor.scss +++ b/packages/block-library/src/embed/editor.scss @@ -32,7 +32,7 @@ } } -.wp-block-embed-interactive-overlay { +.block-library-embed__interactive-overlay { position: absolute; top: 0; left: 0; diff --git a/packages/block-library/src/embed/embed-preview.js b/packages/block-library/src/embed/embed-preview.js index 28b1f0e333df28..8ff9f0c9a1dff8 100644 --- a/packages/block-library/src/embed/embed-preview.js +++ b/packages/block-library/src/embed/embed-preview.js @@ -24,24 +24,15 @@ import { Component } from '@wordpress/element'; */ import WpEmbedPreview from './wp-embed-preview'; -const EmbedPreview = class extends Component { +class EmbedPreview extends Component { constructor() { super( ...arguments ); this.hideOverlay = this.hideOverlay.bind( this ); this.state = { - interactve: false, + interactive: false, }; } - hideOverlay() { - // This is called onMouseUp on the overlay. We can't respond to the `isSelected` prop - // changing, because that happens on mouse down, and the overlay immediately disappears, - // and the mouse event can end up in the preview content. We can't use onClick on - // the overlay to hide it either, because then Gutenberg misses the mouseup event, and - // thinks we're multi-selecting blocks. - this.setState( { interactive: true } ); - } - static getDerivedStateFromProps( nextProps ) { if ( ! nextProps.isSelected ) { // We only want to change this when the block is not selected, because changing it when @@ -51,6 +42,15 @@ const EmbedPreview = class extends Component { } } + hideOverlay() { + // This is called onMouseUp on the overlay. We can't respond to the `isSelected` prop + // changing, because that happens on mouse down, and the overlay immediately disappears, + // and the mouse event can end up in the preview content. We can't use onClick on + // the overlay to hide it either, because then the editor misses the mouseup event, and + // thinks we're multi-selecting blocks. + this.setState( { interactive: true } ); + } + render() { const { preview, url, type, caption, onCaptionChange, isSelected, className, icon, label } = this.props; const { scripts } = preview; @@ -64,6 +64,9 @@ const EmbedPreview = class extends Component { const iframeTitle = sprintf( __( 'Embedded content from %s' ), parsedHostBaseUrl ); const sandboxClassnames = classnames( type, className, 'wp-block-embed__wrapper' ); + // Disabled because the overlay div doesn't actually have a role or functionality + // as far as the user is concerned. We're just catching the first click so that + // the block can be selected without interacting with the embed preview that the overlay covers. /* eslint-disable jsx-a11y/no-noninteractive-element-interactions */ /* eslint-disable jsx-a11y/no-static-element-interactions */ const embedWrapper = 'wp-embed' === type ? ( @@ -80,7 +83,7 @@ const EmbedPreview = class extends Component { onFocus={ this.hideOverlay } /> { ! interactive &&
}
); @@ -107,6 +110,6 @@ const EmbedPreview = class extends Component { ); } -}; +} export default EmbedPreview; From a17ede1b4b2c3e1707470e015854e5c7ccf280a3 Mon Sep 17 00:00:00 2001 From: Nicola Heald Date: Thu, 7 Feb 2019 11:42:30 +0000 Subject: [PATCH 6/6] Only update state from props when interactive changes --- packages/block-library/src/embed/embed-preview.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/block-library/src/embed/embed-preview.js b/packages/block-library/src/embed/embed-preview.js index 3d42f804733c33..cf8d35460ae3df 100644 --- a/packages/block-library/src/embed/embed-preview.js +++ b/packages/block-library/src/embed/embed-preview.js @@ -33,13 +33,15 @@ class EmbedPreview extends Component { }; } - static getDerivedStateFromProps( nextProps ) { - if ( ! nextProps.isSelected ) { + static getDerivedStateFromProps( nextProps, state ) { + if ( ! nextProps.isSelected && state.interactive ) { // We only want to change this when the block is not selected, because changing it when // the block becomes selected makes the overlap disappear too early. Hiding the overlay // happens on mouseup when the overlay is clicked. return { interactive: false }; } + + return null; } hideOverlay() {