From 31cb65250817407c663a6587af88696571f305f8 Mon Sep 17 00:00:00 2001 From: Nicola Heald Date: Wed, 19 Sep 2018 16:18:42 +0100 Subject: [PATCH 1/4] Fix WordPress block resolution and embeds as reusable blocks --- lib/blocks.php | 2 +- packages/block-library/src/embed/index.js | 62 ++++++++++++++++++----- 2 files changed, 49 insertions(+), 15 deletions(-) diff --git a/lib/blocks.php b/lib/blocks.php index 92e89abddd646..799686e268a0d 100644 --- a/lib/blocks.php +++ b/lib/blocks.php @@ -249,7 +249,7 @@ function do_blocks( $content ) { return $rendered_content; } -add_filter( 'the_content', 'do_blocks', 9 ); // BEFORE do_shortcode(). +add_filter( 'the_content', 'do_blocks', 7 ); // BEFORE do_shortcode() and oembed. /** * Remove all dynamic blocks from the given content. diff --git a/packages/block-library/src/embed/index.js b/packages/block-library/src/embed/index.js index a82b2a474649c..62ee774dca36d 100644 --- a/packages/block-library/src/embed/index.js +++ b/packages/block-library/src/embed/index.js @@ -38,18 +38,22 @@ export function getEmbedEdit( title, icon ) { return class extends Component { constructor() { super( ...arguments ); - this.switchBackToURLInput = this.switchBackToURLInput.bind( this ); this.setUrl = this.setUrl.bind( this ); this.maybeSwitchBlock = this.maybeSwitchBlock.bind( this ); + this.getAttributesFromPreview = this.getAttributesFromPreview.bind( this ); this.setAttributesFromPreview = this.setAttributesFromPreview.bind( this ); - this.maybeSetAspectRatioClassName = this.maybeSetAspectRatioClassName.bind( this ); + this.getClassNamesWithAspectRatio = this.getClassNamesWithAspectRatio.bind( this ); this.state = { editingURL: false, url: this.props.attributes.url, }; + if ( this.props.preview && ! this.props.previewIsFallback ) { + this.setAttributesFromPreview(); + } + this.maybeSwitchBlock(); } @@ -65,7 +69,7 @@ export function getEmbedEdit( title, icon ) { const switchedPreview = this.props.preview && this.props.attributes.url !== prevProps.attributes.url; const switchedURL = this.props.attributes.url !== prevProps.attributes.url; - if ( switchedURL && this.maybeSwitchBlock() ) { + if ( ( switchedURL || ( hasPreview && ! hadPreview ) ) && this.maybeSwitchBlock() ) { return; } @@ -128,7 +132,22 @@ export function getEmbedEdit( title, icon ) { if ( includes( html, 'class="wp-embedded-content" data-secret' ) ) { // If this is not the WordPress embed block, transform it into one. if ( this.props.name !== 'core-embed/wordpress' ) { - this.props.onReplace( createBlock( 'core-embed/wordpress', { url } ) ); + this.props.onReplace( + createBlock( + 'core-embed/wordpress', + { + url, + // By now we have the preview, but when the new block first renders, it + // won't have had all the attributes set, and so won't get the correct + // type and it won't render correctly. So, we work out the attributes + // here so that the initial render works when we switch to the WordPress + // block. This only affects the WordPress block because it can't be + // rendered in the usual Sandbox (it has a sandbox of its own) and it + // relies on the preview to set the correct render type. + ...this.getAttributesFromPreview( this.props.preview ), + } + ) + ); return true; } } @@ -142,14 +161,15 @@ export function getEmbedEdit( title, icon ) { * if the HTML has an iframe with width and height set. * * @param {string} html The preview HTML that possibly contains an iframe with width and height set. + * @return {string} The CSS classes with any aspect ratio classes included. */ - maybeSetAspectRatioClassName( html ) { + getClassNamesWithAspectRatio( html ) { const previewDocument = document.implementation.createHTMLDocument( '' ); previewDocument.body.innerHTML = html; const iframe = previewDocument.body.querySelector( 'iframe' ); if ( ! iframe ) { - return; + return this.props.attributes.className; } if ( iframe.height && iframe.width ) { @@ -183,18 +203,21 @@ export function getEmbedEdit( title, icon ) { } if ( aspectRatioClassName ) { - const className = classnames( this.props.attributes.className, 'wp-has-aspect-ratio', aspectRatioClassName ); - this.props.setAttributes( { className } ); + return classnames( this.props.attributes.className, 'wp-has-aspect-ratio', aspectRatioClassName ); } + + return this.props.attributes.className; } } /*** - * Sets block attributes based on the preview data. + * Gets block attributes based on the preview. + * + * @param {string} preview The preview data. + * @return {Object} Attributes and values. */ - setAttributesFromPreview() { - const { setAttributes, preview } = this.props; - + getAttributesFromPreview( preview ) { + const attributes = {}; // Some plugins only return HTML with no type info, so default this to 'rich'. let { type = 'rich' } = preview; // If we got a provider name from the API, use it for the slug, otherwise we use the title, @@ -207,10 +230,21 @@ export function getEmbedEdit( title, icon ) { } if ( html || 'photo' === type ) { - setAttributes( { type, providerNameSlug } ); + attributes.type = type; + attributes.providerNameSlug = providerNameSlug; } - this.maybeSetAspectRatioClassName( html ); + attributes.className = this.getClassNamesWithAspectRatio( html ); + + return attributes; + } + + /*** + * Sets block attributes based on the preview data. + */ + setAttributesFromPreview() { + const { setAttributes, preview } = this.props; + setAttributes( this.getAttributesFromPreview( preview ) ); } switchBackToURLInput() { From 958d6dc174c67927f52edd847bfbf0940e20a27d Mon Sep 17 00:00:00 2001 From: Nicola Heald Date: Wed, 19 Sep 2018 16:48:36 +0100 Subject: [PATCH 2/4] Let's not infinitely recurse and crash. --- lib/blocks.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/blocks.php b/lib/blocks.php index 799686e268a0d..a07253706ad8d 100644 --- a/lib/blocks.php +++ b/lib/blocks.php @@ -275,7 +275,7 @@ function strip_dynamic_blocks( $content ) { * @return string */ function strip_dynamic_blocks_add_filter( $text ) { - add_filter( 'the_content', 'strip_dynamic_blocks', 8 ); // Before do_blocks(). + add_filter( 'the_content', 'strip_dynamic_blocks', 6 ); // Before do_blocks(). return $text; } From a1c299f5448ae1b75adbce93af7978e98c6bd772 Mon Sep 17 00:00:00 2001 From: Nicola Heald Date: Fri, 21 Sep 2018 09:52:54 +0100 Subject: [PATCH 3/4] Reduce the amount of return points --- packages/block-library/src/embed/index.js | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/packages/block-library/src/embed/index.js b/packages/block-library/src/embed/index.js index 62ee774dca36d..0845e3389ae4e 100644 --- a/packages/block-library/src/embed/index.js +++ b/packages/block-library/src/embed/index.js @@ -168,11 +168,7 @@ export function getEmbedEdit( title, icon ) { previewDocument.body.innerHTML = html; const iframe = previewDocument.body.querySelector( 'iframe' ); - if ( ! iframe ) { - return this.props.attributes.className; - } - - if ( iframe.height && iframe.width ) { + if ( iframe && iframe.height && iframe.width ) { const aspectRatio = ( iframe.width / iframe.height ).toFixed( 2 ); let aspectRatioClassName; @@ -205,9 +201,9 @@ export function getEmbedEdit( title, icon ) { if ( aspectRatioClassName ) { return classnames( this.props.attributes.className, 'wp-has-aspect-ratio', aspectRatioClassName ); } - - return this.props.attributes.className; } + + return this.props.attributes.className; } /*** From 953c26ba0cb3a0f6bfb80f13d68c51e8aa3821fe Mon Sep 17 00:00:00 2001 From: Nicola Heald Date: Fri, 28 Sep 2018 10:51:06 +0100 Subject: [PATCH 4/4] Doc update --- packages/block-library/src/embed/index.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/block-library/src/embed/index.js b/packages/block-library/src/embed/index.js index 4329b3e53ce70..8abd0984c5700 100644 --- a/packages/block-library/src/embed/index.js +++ b/packages/block-library/src/embed/index.js @@ -242,9 +242,10 @@ export function getEmbedEdit( title, icon ) { } /*** - * Gets block attributes based on the preview. + * Gets block attributes based on the preview and responsive state. * * @param {string} preview The preview data. + * @param {boolean} allowResponsive Apply responsive classes to fixed size content. * @return {Object} Attributes and values. */ getAttributesFromPreview( preview, allowResponsive = true ) {