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 53f1a49c5de1b..25659caaecf83 100644 --- a/blocks/library/embed/index.js +++ b/blocks/library/embed/index.js @@ -1,7 +1,7 @@ /** * WordPress dependencies */ -import { Button, Placeholder } from 'components'; +import { Button, Placeholder, HtmlEmbed, Spinner } from 'components'; /** * Internal dependencies @@ -34,7 +34,6 @@ registerBlockType( 'core/embed', { category: 'embed', attributes: { - url: attr( 'iframe', 'src' ), title: attr( 'iframe', 'title' ), caption: children( 'figcaption' ), }, @@ -73,52 +72,130 @@ registerBlockType( '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 ( this.props.attributes.url ) { + // if the url is already there, we're loading a saved block, so we need to render + this.doServerSideRender(); + } + } - if ( ! url ) { - return ( - - - - + componentWillUnmount() { + // can't abort the fetch promise, so let it know we will unmount + this.unmounting = true; + } + + doServerSideRender( event ) { + if ( 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 ) => { + if ( this.unmounting ) { + return; + } + 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 81689a7432fd0..104b854351cf9 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", "name": "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/components/html-embed/index.js b/components/html-embed/index.js new file mode 100644 index 0000000000000..c4e113f13e54d --- /dev/null +++ b/components/html-embed/index.js @@ -0,0 +1,33 @@ +// 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() { + const body = this.node; + const { html = '' } = this.props; + + body.innerHTML = html; + + const scripts = body.getElementsByTagName( 'script' ); + const newScripts = Array.from( scripts ).map( ( script ) => { + const newScript = document.createElement( 'script' ); + if ( script.src ) { + newScript.src = script.src; + } else { + newScript.innerHTML = script.innerHTML; + } + return newScript; + } ); + + newScripts.forEach( ( script ) => body.appendChild( script ) ); + } + + render() { + return ( +
this.node = node } /> + ); + } +} 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'; 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; 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
', '', '',