From f9d17bcde8f5a119f701bac53f4498209734524c Mon Sep 17 00:00:00 2001 From: Nicola Heald Date: Wed, 31 May 2017 09:57:17 +0100 Subject: [PATCH 01/16] Updated the embed block to use the oembed proxy API Added "html-embed" component which embeds html from the ombed proxy inside a div and makes sure any script elements get run. This initial version uses a div instead of a sandbox iframe due to some tricky rendering issues with reactive embdedded content from sites like tumblr. --- blocks/library/embed/index.js | 142 ++++++++++++++++++++++++--------- components/html-embed/index.js | 37 +++++++++ 2 files changed, 143 insertions(+), 36 deletions(-) create mode 100644 components/html-embed/index.js diff --git a/blocks/library/embed/index.js b/blocks/library/embed/index.js index 8fcbb551151be..5ec29f8193049 100644 --- a/blocks/library/embed/index.js +++ b/blocks/library/embed/index.js @@ -1,7 +1,9 @@ /** * WordPress dependencies */ -import { Button, Placeholder } from 'components'; +import Button from 'components/button'; +import Placeholder from 'components/placeholder'; +import HtmlEmbed from 'components/html-embed'; /** * Internal dependencies @@ -34,7 +36,6 @@ registerBlock( 'core/embed', { category: 'embed', attributes: { - url: attr( 'iframe', 'src' ), title: attr( 'iframe', 'title' ), caption: children( 'figcaption' ), }, @@ -73,52 +74,121 @@ registerBlock( 'core/embed', { } }, - edit( { attributes, setAttributes, focus, setFocus } ) { - const { url, title, caption } = attributes; + edit: class extends wp.element.Component { + constructor() { + super( ...arguments ); + this.doServerSideRender = this.doServerSideRender.bind( this ); + this.state = { + html: '', + type: '', + error: false, + fetching: false, + }; + this.noPreview = [ + 'facebook.com', + ]; + } - if ( ! url ) { - return ( - - - - + doServerSideRender( event ) { + event.preventDefault(); + const { url } = this.props.attributes; + const api_url = wpApiSettings.root + 'oembed/1.0/proxy?url=' + encodeURIComponent( url ) + '&_wpnonce=' + wpApiSettings.nonce + + this.setState( { error: false, fetching: true } ); + fetch( api_url, { + credentials: 'include', + } ).then( + ( response ) => { + response.json().then( ( obj ) => { + const { html, type } = obj; + if ( html ) { + this.setState( { html, type } ); + } else { + this.setState( { error: true } ); + } + this.setState( { fetching: false } ); + } ); + } ); } - return ( -
-
-
State of the Word 2016
- +
https://www.youtube.com/embed/Nl6U7UotA-M"
State of the Word 2016
+ \ No newline at end of file diff --git a/blocks/test/fixtures/core-embed-youtube-caption.json b/blocks/test/fixtures/core-embed-youtube-caption.json index aff60b23db6c1..4afa97efe35a3 100644 --- a/blocks/test/fixtures/core-embed-youtube-caption.json +++ b/blocks/test/fixtures/core-embed-youtube-caption.json @@ -3,7 +3,7 @@ "uid": "_uid_0", "blockType": "core/embed", "attributes": { - "url": "//www.youtube.com/embed/Nl6U7UotA-M", + "url": "https://www.youtube.com/watch?v=Nl6U7UotA-M", "caption": [ "State of the Word 2016" ] diff --git a/blocks/test/fixtures/core-embed-youtube-caption.serialized.html b/blocks/test/fixtures/core-embed-youtube-caption.serialized.html index bde2a8c300104..f75c6cc292c51 100644 --- a/blocks/test/fixtures/core-embed-youtube-caption.serialized.html +++ b/blocks/test/fixtures/core-embed-youtube-caption.serialized.html @@ -1,5 +1,5 @@ - -
+ +
https://www.youtube.com/watch?v=Nl6U7UotA-M
State of the Word 2016
diff --git a/post-content.js b/post-content.js index 7313647c435d3..185280888e2c5 100644 --- a/post-content.js +++ b/post-content.js @@ -41,7 +41,7 @@ window._wpGutenbergPost = { '', '', - '
State of the Word 2016
', + '
https://www.youtube.com/watch?v=Nl6U7UotA-M
State of the Word 2016
', '', '', From 6fea1e8e6976c94b3d78caf20b618b3b8795e102 Mon Sep 17 00:00:00 2001 From: Nicola Heald Date: Wed, 31 May 2017 11:19:38 +0100 Subject: [PATCH 04/16] Fix initial render of the embed block when loading a saved post --- blocks/library/embed/index.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/blocks/library/embed/index.js b/blocks/library/embed/index.js index 157158d72a601..edf33cd938a69 100644 --- a/blocks/library/embed/index.js +++ b/blocks/library/embed/index.js @@ -87,10 +87,16 @@ registerBlock( 'core/embed', { this.noPreview = [ 'facebook.com', ]; + if ( this.props.attributes.url ) { + // if the url is already there, we're loading a saved block, so we need to render + this.doServerSideRender(); + } } doServerSideRender( event ) { - event.preventDefault(); + if ( event ) { + event.preventDefault(); + } const { url } = this.props.attributes; const api_url = wpApiSettings.root + 'oembed/1.0/proxy?url=' + encodeURIComponent( url ) + '&_wpnonce=' + wpApiSettings.nonce; // eslint-disable-line no-undef From 830b74315336ddb8d84db9f7645ccc58d450829b Mon Sep 17 00:00:00 2001 From: Joen Asmussen Date: Thu, 1 Jun 2017 08:58:21 +0200 Subject: [PATCH 05/16] Polish the embed placeholder a bit. --- blocks/library/embed/index.js | 2 +- components/placeholder/style.scss | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/blocks/library/embed/index.js b/blocks/library/embed/index.js index edf33cd938a69..348028f9ec911 100644 --- a/blocks/library/embed/index.js +++ b/blocks/library/embed/index.js @@ -129,7 +129,7 @@ registerBlock( 'core/embed', {
setAttributes( { url: event.target.value } ) } /> { ! fetching ? diff --git a/components/placeholder/style.scss b/components/placeholder/style.scss index d28fea95f215c..cb1f1aee0fcb8 100644 --- a/components/placeholder/style.scss +++ b/components/placeholder/style.scss @@ -22,7 +22,8 @@ } } -.components-placeholder__fieldset { +.components-placeholder__fieldset, +.components-placeholder__fieldset form { display: flex; flex-direction: row; justify-content: center; From b99e42c7f8ba20c0f71f5500010949822c084007 Mon Sep 17 00:00:00 2001 From: Joen Asmussen Date: Thu, 1 Jun 2017 09:41:24 +0200 Subject: [PATCH 06/16] Fix video and "other" ambiguation. This makes videos responsive again. --- blocks/library/embed/index.js | 8 ++++---- blocks/library/embed/style.scss | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/blocks/library/embed/index.js b/blocks/library/embed/index.js index 348028f9ec911..78d0a4ca45d3e 100644 --- a/blocks/library/embed/index.js +++ b/blocks/library/embed/index.js @@ -153,16 +153,16 @@ registerBlock( 'core/embed', { const domain = url.split( '/' )[ 2 ].replace( /^www\./, '' ); const cannotPreview = this.noPreview.includes( domain ); - let placeholderClassName = 'blocks-embed'; + let typeClassName = 'blocks-embed'; if ( 'video' === type ) { - placeholderClassName = 'blocks-embed-video'; + typeClassName = 'blocks-embed-video'; } return ( -
+
{ ( cannotPreview ) ? ( - +

{ url }

{ wp.i18n.__( 'Previews for this are unavailable in the editor, sorry!' ) }

diff --git a/blocks/library/embed/style.scss b/blocks/library/embed/style.scss index 3b4a11df46927..7abbf2de16590 100644 --- a/blocks/library/embed/style.scss +++ b/blocks/library/embed/style.scss @@ -1,15 +1,16 @@ -.blocks-embed { +.blocks-embed, +.blocks-embed-video { margin: 0; } -.blocks-embed .iframe-overlay { +.blocks-embed-video > div:first-child { position: relative; width: 100%; height: 0; padding-bottom: 56.25%; /* 16:9 */ } -.blocks-embed iframe { +.blocks-embed-video > div > iframe { position: absolute; top: 0; left: 0; @@ -55,6 +56,5 @@ div[data-type="core/embed"] { margin-left: auto; margin-right: auto; } - } } From c55973f5a567a9b969e53d8a91bbfd187b22407d Mon Sep 17 00:00:00 2001 From: Joen Asmussen Date: Thu, 1 Jun 2017 12:49:41 +0200 Subject: [PATCH 07/16] Address a couple of PR review items - Use spinner component - Adjust some parenthesis syntax --- blocks/library/embed/index.js | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/blocks/library/embed/index.js b/blocks/library/embed/index.js index 78d0a4ca45d3e..2b7bdc0841b47 100644 --- a/blocks/library/embed/index.js +++ b/blocks/library/embed/index.js @@ -4,6 +4,7 @@ import Button from 'components/button'; import Placeholder from 'components/placeholder'; import HtmlEmbed from 'components/html-embed'; +import { Spinner } from 'components'; /** * Internal dependencies @@ -132,20 +133,15 @@ registerBlock( 'core/embed', { className="components-placeholder__input" placeholder={ wp.i18n.__( 'Enter URL to embed here...' ) } onChange={ ( event ) => setAttributes( { url: event.target.value } ) } /> - { ! fetching ? - ( - - ) : ( - - ) + { ! fetching + ? + : } - { ( error ) ? ( -

{ wp.i18n.__( 'Sorry, we could not embed that content.' ) }

- ) : null } + { error &&

{ wp.i18n.__( 'Sorry, we could not embed that content.' ) }

}
); From 540c43c3473600053b8d7f56083ef75475cc6add Mon Sep 17 00:00:00 2001 From: Nicola Heald Date: Thu, 1 Jun 2017 12:14:23 +0100 Subject: [PATCH 08/16] Fixed components import --- blocks/library/embed/index.js | 5 +---- components/index.js | 1 + 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/blocks/library/embed/index.js b/blocks/library/embed/index.js index 2b7bdc0841b47..5274585666b3a 100644 --- a/blocks/library/embed/index.js +++ b/blocks/library/embed/index.js @@ -1,10 +1,7 @@ /** * WordPress dependencies */ -import Button from 'components/button'; -import Placeholder from 'components/placeholder'; -import HtmlEmbed from 'components/html-embed'; -import { Spinner } from 'components'; +import { Button, Placeholder, HtmlEmbed, Spinner } from 'components'; /** * Internal dependencies diff --git a/components/index.js b/components/index.js index 50ca974a39f10..1582340f6b380 100644 --- a/components/index.js +++ b/components/index.js @@ -1,6 +1,7 @@ export { default as Button } from './button'; export { default as Dashicon } from './dashicon'; export { default as FormToggle } from './form-toggle'; +export { default as HtmlEmbed } from './html-embed'; export { default as IconButton } from './icon-button'; export { default as Panel } from './panel'; export { default as PanelHeader } from './panel/header'; From 42172c05b5050af206c7cce77310e0812b2e9709 Mon Sep 17 00:00:00 2001 From: Nicola Heald Date: Thu, 1 Jun 2017 12:17:23 +0100 Subject: [PATCH 09/16] Adds wpApiSettings to the globals in .eslintrc.json --- .eslintrc.json | 3 ++- blocks/library/embed/index.js | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index 19f53ee97f58d..7864b2732645c 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -18,7 +18,8 @@ } }, "globals": { - "wp": true + "wp": true, + "wpApiSettings": true }, "plugins": [ "react", diff --git a/blocks/library/embed/index.js b/blocks/library/embed/index.js index 5274585666b3a..519fd2ff1403f 100644 --- a/blocks/library/embed/index.js +++ b/blocks/library/embed/index.js @@ -96,7 +96,7 @@ registerBlock( 'core/embed', { event.preventDefault(); } const { url } = this.props.attributes; - const api_url = wpApiSettings.root + 'oembed/1.0/proxy?url=' + encodeURIComponent( url ) + '&_wpnonce=' + wpApiSettings.nonce; // eslint-disable-line no-undef + const api_url = wpApiSettings.root + 'oembed/1.0/proxy?url=' + encodeURIComponent( url ) + '&_wpnonce=' + wpApiSettings.nonce; this.setState( { error: false, fetching: true } ); fetch( api_url, { From ea6ff8726dfca1cd85d8ba126953d4e26e235f8e Mon Sep 17 00:00:00 2001 From: Nicola Heald Date: Thu, 1 Jun 2017 12:29:30 +0100 Subject: [PATCH 10/16] Deal with the component unmounting while a fetch is ongoing --- blocks/library/embed/index.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/blocks/library/embed/index.js b/blocks/library/embed/index.js index 519fd2ff1403f..3a3a35b485c72 100644 --- a/blocks/library/embed/index.js +++ b/blocks/library/embed/index.js @@ -91,6 +91,11 @@ registerBlock( 'core/embed', { } } + componentWillUnmount() { + // can't about the fetch promise, so let it know we will unmount + this.unmounting = true; + } + doServerSideRender( event ) { if ( event ) { event.preventDefault(); @@ -103,6 +108,9 @@ registerBlock( 'core/embed', { credentials: 'include', } ).then( ( response ) => { + if ( this.unmounting ) { + return; + } response.json().then( ( obj ) => { const { html, type } = obj; if ( html ) { From 19f84770ecd11e93fd2f104098f626bf8a764fe2 Mon Sep 17 00:00:00 2001 From: Nicola Heald Date: Thu, 1 Jun 2017 12:39:48 +0100 Subject: [PATCH 11/16] Comment explaining the purpose of HtmlEmbed component --- components/html-embed/index.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/components/html-embed/index.js b/components/html-embed/index.js index 052b68221df57..e5f9c1af14f37 100644 --- a/components/html-embed/index.js +++ b/components/html-embed/index.js @@ -1,3 +1,9 @@ +/*** + * When embedding HTML from the WP oEmbed proxy, we need to insert it + * into a div and make sure any scripts get run. This component takes + * HTML and puts it into a div element, and creates and adds new script + * elements so all scripts get run as expected. + */ export default class HtmlEmbed extends wp.element.Component { static get defaultProps() { From f09a47fd48cbd37bf4a6ea5c1a1ced684cd543a1 Mon Sep 17 00:00:00 2001 From: Nicola Heald Date: Thu, 1 Jun 2017 12:45:11 +0100 Subject: [PATCH 12/16] Remove default prop in HtmlEmbed --- components/html-embed/index.js | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/components/html-embed/index.js b/components/html-embed/index.js index e5f9c1af14f37..45cd5e3db1a3c 100644 --- a/components/html-embed/index.js +++ b/components/html-embed/index.js @@ -6,15 +6,9 @@ */ export default class HtmlEmbed extends wp.element.Component { - static get defaultProps() { - return { - html: '', - }; - } - componentDidMount() { const body = this.node; - const { html } = this.props; + const { html = '' } = this.props; body.innerHTML = html; From a2358618bbf51d73a7a03b278156746e6b8226f4 Mon Sep 17 00:00:00 2001 From: Nicola Heald Date: Thu, 1 Jun 2017 13:00:08 +0100 Subject: [PATCH 13/16] New script element creation tidied up --- components/html-embed/index.js | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/components/html-embed/index.js b/components/html-embed/index.js index 45cd5e3db1a3c..51f1ea7e5cf7e 100644 --- a/components/html-embed/index.js +++ b/components/html-embed/index.js @@ -13,20 +13,17 @@ export default class HtmlEmbed extends wp.element.Component { body.innerHTML = html; const scripts = body.getElementsByTagName( 'script' ); - const newscripts = []; - - for ( let i = 0; i < scripts.length; i++ ) { - const newscript = document.createElement( 'script' ); - if ( scripts[ i ].src ) { - newscript.src = scripts[ i ].src; + const newScripts = Array.from( scripts ).map( ( script ) => { + const newScript = document.createElement( 'script' ); + if ( script.src ) { + newScript.src = script.src; } else { - newscript.innerHTML = scripts[ i ].innerHTML; + newScript.innerHTML = script.innerHTML; } - newscripts.push( newscript ); - } - for ( let i = 0; i < newscripts.length; i++ ) { - body.appendChild( newscripts[ i ] ); - } + return newScript; + }); + + newScripts.forEach( ( script ) => body.appendChild( script ) ); } render() { From d934958d9570ba3cc1ff9d34f34ac1b42538232b Mon Sep 17 00:00:00 2001 From: Nicola Heald Date: Thu, 1 Jun 2017 13:03:24 +0100 Subject: [PATCH 14/16] Lint fix --- components/html-embed/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/html-embed/index.js b/components/html-embed/index.js index 51f1ea7e5cf7e..2ca90e23a0955 100644 --- a/components/html-embed/index.js +++ b/components/html-embed/index.js @@ -21,7 +21,7 @@ export default class HtmlEmbed extends wp.element.Component { newScript.innerHTML = script.innerHTML; } return newScript; - }); + } ); newScripts.forEach( ( script ) => body.appendChild( script ) ); } From 316fb7dc8ded9fcca4b0ebf1680f35532b9725b1 Mon Sep 17 00:00:00 2001 From: Nicola Heald Date: Thu, 1 Jun 2017 13:06:39 +0100 Subject: [PATCH 15/16] Fix typo --- blocks/library/embed/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blocks/library/embed/index.js b/blocks/library/embed/index.js index 3a3a35b485c72..9fef90e2839f7 100644 --- a/blocks/library/embed/index.js +++ b/blocks/library/embed/index.js @@ -92,7 +92,7 @@ registerBlock( 'core/embed', { } componentWillUnmount() { - // can't about the fetch promise, so let it know we will unmount + // can't abort the fetch promise, so let it know we will unmount this.unmounting = true; } From 58acca1bf0a9dded9b7648a1a1e5541688a86f61 Mon Sep 17 00:00:00 2001 From: Nicola Heald Date: Fri, 2 Jun 2017 11:19:59 +0100 Subject: [PATCH 16/16] Fixed comment style --- components/html-embed/index.js | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/components/html-embed/index.js b/components/html-embed/index.js index 2ca90e23a0955..c4e113f13e54d 100644 --- a/components/html-embed/index.js +++ b/components/html-embed/index.js @@ -1,9 +1,8 @@ -/*** - * When embedding HTML from the WP oEmbed proxy, we need to insert it - * into a div and make sure any scripts get run. This component takes - * HTML and puts it into a div element, and creates and adds new script - * elements so all scripts get run as expected. - */ +// When embedding HTML from the WP oEmbed proxy, we need to insert it +// into a div and make sure any scripts get run. This component takes +// HTML and puts it into a div element, and creates and adds new script +// elements so all scripts get run as expected. + export default class HtmlEmbed extends wp.element.Component { componentDidMount() {