Skip to content

Commit

Permalink
Merge pull request #816 from WordPress/update/embed-block
Browse files Browse the repository at this point in the history
Enhance the embed block to support all WP_oEmbed embeds
  • Loading branch information
notnownikki committed Jun 2, 2017
2 parents 97ee1a3 + 58acca1 commit a5c1487
Show file tree
Hide file tree
Showing 10 changed files with 161 additions and 48 deletions.
3 changes: 2 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
}
},
"globals": {
"wp": true
"wp": true,
"wpApiSettings": true
},
"plugins": [
"react",
Expand Down
149 changes: 113 additions & 36 deletions blocks/library/embed/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* WordPress dependencies
*/
import { Button, Placeholder } from 'components';
import { Button, Placeholder, HtmlEmbed, Spinner } from 'components';

/**
* Internal dependencies
Expand Down Expand Up @@ -34,7 +34,6 @@ registerBlockType( 'core/embed', {
category: 'embed',

attributes: {
url: attr( 'iframe', 'src' ),
title: attr( 'iframe', 'title' ),
caption: children( 'figcaption' ),
},
Expand Down Expand Up @@ -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 (
<Placeholder icon="cloud" label={ wp.i18n.__( 'Embed URL' ) } className="blocks-embed">
<input type="url" className="placeholder__input" placeholder={ wp.i18n.__( 'Enter URL to embed here...' ) } />
<Button isLarge>
{ wp.i18n.__( 'Embed' ) }
</Button>
</Placeholder>
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 (
<figure className="blocks-embed">
<div className="iframe-overlay">
<iframe src={ url } title={ title } />
</div>
{ ( caption && caption.length > 0 ) || !! focus ? (
<Editable
tagName="figcaption"
placeholder={ wp.i18n.__( 'Write caption…' ) }
value={ caption }
focus={ focus }
onFocus={ setFocus }
onChange={ ( value ) => setAttributes( { caption: value } ) }
inline
inlineToolbar
/>
) : null }
</figure>
);
render() {
const { html, type, error, fetching } = this.state;
const { url, caption } = this.props.attributes;
const { setAttributes, focus, setFocus } = this.props;

if ( ! html ) {
return (
<Placeholder icon="cloud" label={ wp.i18n.__( 'Embed URL' ) } className="blocks-embed">
<form onSubmit={ this.doServerSideRender }>
<input
type="url"
className="components-placeholder__input"
placeholder={ wp.i18n.__( 'Enter URL to embed here...' ) }
onChange={ ( event ) => setAttributes( { url: event.target.value } ) } />
{ ! fetching
? <Button
isLarge
type="submit">
{ wp.i18n.__( 'Embed' ) }
</Button>
: <Spinner />
}
{ error && <p className="components-placeholder__error">{ wp.i18n.__( 'Sorry, we could not embed that content.' ) }</p> }
</form>
</Placeholder>
);
}

const domain = url.split( '/' )[ 2 ].replace( /^www\./, '' );
const cannotPreview = this.noPreview.includes( domain );
let typeClassName = 'blocks-embed';

if ( 'video' === type ) {
typeClassName = 'blocks-embed-video';
}

return (
<figure className={ typeClassName }>
{ ( cannotPreview ) ? (
<Placeholder icon="cloud" label={ wp.i18n.__( 'Embed URL' ) }>
<p className="components-placeholder__error"><a href={ url }>{ url }</a></p>
<p className="components-placeholder__error">{ wp.i18n.__( 'Previews for this are unavailable in the editor, sorry!' ) }</p>
</Placeholder>
) : (
<HtmlEmbed html={ html } />
) }
{ ( caption && caption.length > 0 ) || !! focus ? (
<Editable
tagName="figcaption"
placeholder={ wp.i18n.__( 'Write caption…' ) }
value={ caption }
focus={ focus }
onFocus={ setFocus }
onChange={ ( value ) => setAttributes( { caption: value } ) }
inline
inlineToolbar
/>
) : null }
</figure>
);
}
},

save( { attributes } ) {
const { url, title, caption } = attributes;
const iframe = <iframe src={ url } title={ title } />;

const { url, caption } = attributes;
if ( ! caption || ! caption.length ) {
return iframe;
return url;
}

return (
<figure>
{ iframe }
{ url }
<figcaption>{ caption }</figcaption>
</figure>
);
Expand Down
8 changes: 4 additions & 4 deletions blocks/library/embed/style.scss
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -55,6 +56,5 @@ div[data-type="core/embed"] {
margin-left: auto;
margin-right: auto;
}

}
}
4 changes: 2 additions & 2 deletions blocks/test/fixtures/core-embed-youtube-caption.html
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
<!-- wp:core/embed url="https://www.youtube.com/watch?v=Nl6U7UotA-M" -->
<figure><iframe src="//www.youtube.com/embed/Nl6U7UotA-M" frameborder="0" allowfullscreen></iframe><figcaption>State of the Word 2016</figcaption></figure>
<!-- /wp:core/embed -->
<figure>https://www.youtube.com/embed/Nl6U7UotA-M"<figcaption>State of the Word 2016</figcaption></figure>
<!-- /wp:core/embed -->
2 changes: 1 addition & 1 deletion blocks/test/fixtures/core-embed-youtube-caption.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<!-- wp:core/embed -->
<figure><iframe src="//www.youtube.com/embed/Nl6U7UotA-M"></iframe>
<!-- wp:core/embed url="https://www.youtube.com/watch?v=Nl6U7UotA-M" -->
<figure>https://www.youtube.com/watch?v=Nl6U7UotA-M
<figcaption>State of the Word 2016</figcaption>
</figure>
<!-- /wp:core/embed -->
Expand Down
33 changes: 33 additions & 0 deletions components/html-embed/index.js
Original file line number Diff line number Diff line change
@@ -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 (
<div ref={ ( node ) => this.node = node } />
);
}
}
1 change: 1 addition & 0 deletions components/index.js
Original file line number Diff line number Diff line change
@@ -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';
Expand Down
3 changes: 2 additions & 1 deletion components/placeholder/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@
}
}

.components-placeholder__fieldset {
.components-placeholder__fieldset,
.components-placeholder__fieldset form {
display: flex;
flex-direction: row;
justify-content: center;
Expand Down
2 changes: 1 addition & 1 deletion post-content.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ window._wpGutenbergPost = {
'<!-- /wp:core/text -->',

'<!-- wp:core/embed url="https://www.youtube.com/watch?v=Nl6U7UotA-M" -->',
'<figure><iframe src="//www.youtube.com/embed/Nl6U7UotA-M" frameborder="0" allowfullscreen></iframe><figcaption>State of the Word 2016</figcaption></figure>',
'<figure>https://www.youtube.com/watch?v=Nl6U7UotA-M<figcaption>State of the Word 2016</figcaption></figure>',
'<!-- /wp:core/embed -->',

'<!-- wp:core/heading -->',
Expand Down

0 comments on commit a5c1487

Please sign in to comment.