Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Show preview of WordPress embed in editor #25370

Merged
merged 9 commits into from
Sep 24, 2020
Merged
49 changes: 47 additions & 2 deletions packages/block-library/src/embed/wp-embed-preview.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@
import { Component, createRef } from '@wordpress/element';
import { withGlobalEvents } from '@wordpress/compose';

/** @typedef {import('@wordpress/element').WPSyntheticEvent} WPSyntheticEvent */

/**
* Browser dependencies
*/

const { FocusEvent } = window;
const { FocusEvent, DOMParser } = window;

class WpEmbedPreview extends Component {
constructor() {
Expand All @@ -18,6 +20,43 @@ class WpEmbedPreview extends Component {
this.node = createRef();
}

componentDidMount() {
window.addEventListener( 'message', this.resizeWPembeds );
}

componentWillUnmount() {
window.removeEventListener( 'message', this.resizeWPembeds );
}

/**
* Checks for WordPress embed events signaling the height change when iframe
* content loads or iframe's window is resized. The event is sent from
* WordPress core via the window.postMessage API.
*
* References:
* window.postMessage: https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage
* WordPress core embed-template on load: https://github.com/WordPress/WordPress/blob/master/wp-includes/js/wp-embed-template.js#L143
* WordPress core embed-template on resize: https://github.com/WordPress/WordPress/blob/master/wp-includes/js/wp-embed-template.js#L187
*
* @param {WPSyntheticEvent} event Message event.
*/
resizeWPembeds( { data: { secret, message, value } = {} } ) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This all reads a bit like dark magic. :) I had never come across this height signalling before.

I'm not too confident to approve the change.

In any case, providing some context and linking to adequate prior art would be nice.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right! I've updated the jsdoc.

if (
[ secret, message, value ].some( ( attribute ) => ! attribute ) ||
message !== 'height'
) {
return;
}

document
.querySelectorAll( `iframe[data-secret="${ secret }"` )
.forEach( ( iframe ) => {
if ( +iframe.height !== value ) {
iframe.height = value;
}
} );
}

/**
* Checks whether the wp embed iframe is the activeElement,
* if it is dispatch a focus event.
Expand All @@ -38,11 +77,17 @@ class WpEmbedPreview extends Component {

render() {
const { html } = this.props;
const doc = new DOMParser().parseFromString( html, 'text/html' );
const iframe = doc.querySelector( 'iframe' );
if ( iframe ) iframe.removeAttribute( 'style' );
const blockQuote = doc.querySelector( 'blockquote' );
if ( blockQuote ) blockQuote.style.display = 'none';

return (
<div
ref={ this.node }
className="wp-block-embed__wrapper"
dangerouslySetInnerHTML={ { __html: html } }
dangerouslySetInnerHTML={ { __html: doc.body.innerHTML } }
/>
);
}
Expand Down