From 9255d294bf021d0bd872fb337be45183e80d73f6 Mon Sep 17 00:00:00 2001 From: Nicola Heald Date: Fri, 31 Aug 2018 14:22:39 +0100 Subject: [PATCH 01/10] Set aspect ratio preserving CSS on previews with fixed size iframes --- packages/block-library/src/embed/index.js | 64 ++++++++++++++++++++++- 1 file changed, 63 insertions(+), 1 deletion(-) diff --git a/packages/block-library/src/embed/index.js b/packages/block-library/src/embed/index.js index 6b11992352bbc..8d959e93ead79 100644 --- a/packages/block-library/src/embed/index.js +++ b/packages/block-library/src/embed/index.js @@ -3,7 +3,7 @@ */ import { parse } from 'url'; import { includes, kebabCase, toLower } from 'lodash'; -import classnames from 'classnames'; +import classnames from 'classnames/dedupe'; /** * WordPress dependencies @@ -136,6 +136,28 @@ export function getEmbedEdit( title, icon ) { return false; } + /** + * Finds the first iframe with a width and height and returns + * an object with width and height attributes, empty object + * if there is no iframe with width and height. + * @param {string} html the preview HTML that possible contains an iframe with width and height set. + * @return {Object} Object with extracted height and width if available. + */ + getiFrameHeightWidth( html ) { + const previewDom = document.createElement( 'div' ); + previewDom.innerHTML = html; + const walker = document.createTreeWalker( previewDom ); + while ( walker.nextNode() ) { + if ( 'IFRAME' === walker.currentNode.tagName ) { + return { + height: walker.currentNode.height, + width: walker.currentNode.width, + }; + } + } + return {}; + } + /*** * Sets block attributes based on the preview data. */ @@ -156,6 +178,46 @@ export function getEmbedEdit( title, icon ) { if ( html || 'photo' === type ) { setAttributes( { type, providerNameSlug } ); } + + // If the embedded content is in an iframe with fixed width and height, we + // calculate the aspect ratio and set an extra css class so that the rendered + // content keeps the correct height no matter how wide the block is set to be. + const { height, width } = this.getiFrameHeightWidth( html ); + if ( undefined !== height && undefined !== width ) { + const aspectRatio = ( width / height ).toFixed( 2 ); + let aspectRatioClassName; + + switch ( aspectRatio ) { + // Common video resolutions. + case '2.33': + aspectRatioClassName = 'wp-embed-aspect-21-9'; + break; + case '2.00': + aspectRatioClassName = 'wp-embed-aspect-18-9'; + break; + case '1.78': + aspectRatioClassName = 'wp-embed-aspect-16-9'; + break; + case '1.33': + aspectRatioClassName = 'wp-embed-aspect-4-3'; + break; + // Vertical video and instagram square video support. + case '1.00': + aspectRatioClassName = 'wp-embed-aspect-1-1'; + break; + case '0.56': + aspectRatioClassName = 'wp-embed-aspect-9-16'; + break; + case '0.50': + aspectRatioClassName = 'wp-embed-aspect-1-2'; + break; + } + + if ( aspectRatioClassName ) { + const className = classnames( this.props.attributes.className, aspectRatioClassName ); + this.props.setAttributes( { className } ); + } + } } switchBackToURLInput() { From 5baab35ef8bd33b61f376815eb9ab7419925c7cf Mon Sep 17 00:00:00 2001 From: Joen Asmussen Date: Tue, 4 Sep 2018 13:14:53 +0200 Subject: [PATCH 02/10] Add aspect ratio CSS. --- packages/block-library/src/embed/theme.scss | 56 +++++++++++++++++++++ packages/block-library/src/theme.scss | 1 + 2 files changed, 57 insertions(+) create mode 100644 packages/block-library/src/embed/theme.scss diff --git a/packages/block-library/src/embed/theme.scss b/packages/block-library/src/embed/theme.scss new file mode 100644 index 0000000000000..f8eaf4689380a --- /dev/null +++ b/packages/block-library/src/embed/theme.scss @@ -0,0 +1,56 @@ +.wp-block-embed { + // Add responsiveness to common aspect ratios. + &.wp-embed-aspect-21-9, + &.wp-embed-aspect-18-9, + &.wp-embed-aspect-16-9, + &.wp-embed-aspect-4-3, + &.wp-embed-aspect-1-1, + &.wp-embed-aspect-9-16, + &.wp-embed-aspect-1-2 { + position: relative; + + &:before { + content: ""; + display: block; + padding-top: 50%; // Default to 2:1 aspect ratio. + } + + iframe { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + width: 100%; + height: 100%; + } + } + + &.wp-embed-aspect-21-9:before { + padding-top: 42.85%; // 9 / 21 * 100 + } + + &.wp-embed-aspect-18-9:before { + padding-top: 50%; // 9 / 18 * 100 + } + + &.wp-embed-aspect-16-9:before { + padding-top: 56.25%; // 9 / 16 * 100 + } + + &.wp-embed-aspect-4-3:before { + padding-top: 75%; // 3 / 4 * 100 + } + + &.wp-embed-aspect-1-1:before { + padding-top: 100%; // 1 / 1 * 100 + } + + &.wp-embed-aspect-9-6:before { + padding-top: 66.66%; // 6 / 9 * 100 + } + + &.wp-embed-aspect-1-2:before { + padding-top: 200%; // 2 / 1 * 100 + } +} diff --git a/packages/block-library/src/theme.scss b/packages/block-library/src/theme.scss index da6419fcf4701..1918654b749d7 100644 --- a/packages/block-library/src/theme.scss +++ b/packages/block-library/src/theme.scss @@ -5,3 +5,4 @@ @import "./separator/theme.scss"; @import "./table/theme.scss"; @import "./video/theme.scss"; +@import "./embed/theme.scss"; From fdfa43700de02c832e7d1a6733dc0760f27e9162 Mon Sep 17 00:00:00 2001 From: Nicola Heald Date: Tue, 4 Sep 2018 12:47:46 +0100 Subject: [PATCH 03/10] Add embed wrapper div in saved content for responsive classes --- packages/block-library/src/embed/index.js | 65 ++++++++++++++++------- 1 file changed, 47 insertions(+), 18 deletions(-) diff --git a/packages/block-library/src/embed/index.js b/packages/block-library/src/embed/index.js index 8d959e93ead79..b69869d0a04d8 100644 --- a/packages/block-library/src/embed/index.js +++ b/packages/block-library/src/embed/index.js @@ -319,6 +319,24 @@ export function getEmbedEdit( title, icon ) { }; } +const embedAttributes = { + url: { + type: 'string', + }, + caption: { + type: 'array', + source: 'children', + selector: 'figcaption', + default: [], + }, + type: { + type: 'string', + }, + providerNameSlug: { + type: 'string', + }, +}; + function getEmbedBlockSettings( { title, description, icon, category = 'embed', transforms, keywords = [] } ) { // translators: %s: Name of service (e.g. VideoPress, YouTube) const blockDescription = description || sprintf( __( 'Add a block that displays content pulled from other sites, like Twitter, Instagram or YouTube.' ), title ); @@ -328,23 +346,7 @@ function getEmbedBlockSettings( { title, description, icon, category = 'embed', icon, category, keywords, - attributes: { - url: { - type: 'string', - }, - caption: { - type: 'array', - source: 'children', - selector: 'figcaption', - default: [], - }, - type: { - type: 'string', - }, - providerNameSlug: { - type: 'string', - }, - }, + attributes: embedAttributes, supports: { align: true, @@ -382,11 +384,38 @@ function getEmbedBlockSettings( { title, description, icon, category = 'embed', return (
- { `\n${ url }\n` /* URL needs to be on its own line. */ } +
+ { `\n${ url }\n` /* URL needs to be on its own line. */ } +
{ ! RichText.isEmpty( caption ) && }
); }, + + deprecated: [ + { + attributes: embedAttributes, + save( { attributes } ) { + const { url, caption, type, providerNameSlug } = attributes; + + if ( ! url ) { + return null; + } + + const embedClassName = classnames( 'wp-block-embed', { + [ `is-type-${ type }` ]: type, + [ `is-provider-${ providerNameSlug }` ]: providerNameSlug, + } ); + + return ( +
+ { `\n${ url }\n` /* URL needs to be on its own line. */ } + { ! RichText.isEmpty( caption ) && } +
+ ); + }, + }, + ], }; } From 372078486c596e06eedd947945b2c9e634d661fb Mon Sep 17 00:00:00 2001 From: jasmussen Date: Tue, 4 Sep 2018 14:14:42 +0200 Subject: [PATCH 04/10] Fix things up. --- packages/block-library/src/embed/style.scss | 55 ++++++++++++++++++++ packages/block-library/src/embed/theme.scss | 56 --------------------- packages/block-library/src/theme.scss | 1 - 3 files changed, 55 insertions(+), 57 deletions(-) delete mode 100644 packages/block-library/src/embed/theme.scss diff --git a/packages/block-library/src/embed/style.scss b/packages/block-library/src/embed/style.scss index d6a8b0c81bcc5..782cabefe8e70 100644 --- a/packages/block-library/src/embed/style.scss +++ b/packages/block-library/src/embed/style.scss @@ -14,4 +14,59 @@ figcaption { @include caption-style(); } + + // Add responsiveness to common aspect ratios. + &.wp-embed-aspect-21-9 .wp-block-embed__wrapper, + &.wp-embed-aspect-18-9 .wp-block-embed__wrapper, + &.wp-embed-aspect-16-9 .wp-block-embed__wrapper, + &.wp-embed-aspect-4-3 .wp-block-embed__wrapper, + &.wp-embed-aspect-1-1 .wp-block-embed__wrapper, + &.wp-embed-aspect-9-16 .wp-block-embed__wrapper, + &.wp-embed-aspect-1-2 .wp-block-embed__wrapper { + position: relative; + + &::before { + content: ""; + display: block; + padding-top: 50%; // Default to 2:1 aspect ratio. + } + + iframe { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + width: 100%; + height: 100%; + } + } + + &.wp-embed-aspect-21-9 .wp-block-embed__wrapper::before { + padding-top: 42.85%; // 9 / 21 * 100 + } + + &.wp-embed-aspect-18-9 .wp-block-embed__wrapper::before { + padding-top: 50%; // 9 / 18 * 100 + } + + &.wp-embed-aspect-16-9 .wp-block-embed__wrapper::before { + padding-top: 56.25%; // 9 / 16 * 100 + } + + &.wp-embed-aspect-4-3 .wp-block-embed__wrapper::before { + padding-top: 75%; // 3 / 4 * 100 + } + + &.wp-embed-aspect-1-1 .wp-block-embed__wrapper::before { + padding-top: 100%; // 1 / 1 * 100 + } + + &.wp-embed-aspect-9-6 .wp-block-embed__wrapper::before { + padding-top: 66.66%; // 6 / 9 * 100 + } + + &.wp-embed-aspect-1-2 .wp-block-embed__wrapper::before { + padding-top: 200%; // 2 / 1 * 100 + } } diff --git a/packages/block-library/src/embed/theme.scss b/packages/block-library/src/embed/theme.scss deleted file mode 100644 index f8eaf4689380a..0000000000000 --- a/packages/block-library/src/embed/theme.scss +++ /dev/null @@ -1,56 +0,0 @@ -.wp-block-embed { - // Add responsiveness to common aspect ratios. - &.wp-embed-aspect-21-9, - &.wp-embed-aspect-18-9, - &.wp-embed-aspect-16-9, - &.wp-embed-aspect-4-3, - &.wp-embed-aspect-1-1, - &.wp-embed-aspect-9-16, - &.wp-embed-aspect-1-2 { - position: relative; - - &:before { - content: ""; - display: block; - padding-top: 50%; // Default to 2:1 aspect ratio. - } - - iframe { - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; - width: 100%; - height: 100%; - } - } - - &.wp-embed-aspect-21-9:before { - padding-top: 42.85%; // 9 / 21 * 100 - } - - &.wp-embed-aspect-18-9:before { - padding-top: 50%; // 9 / 18 * 100 - } - - &.wp-embed-aspect-16-9:before { - padding-top: 56.25%; // 9 / 16 * 100 - } - - &.wp-embed-aspect-4-3:before { - padding-top: 75%; // 3 / 4 * 100 - } - - &.wp-embed-aspect-1-1:before { - padding-top: 100%; // 1 / 1 * 100 - } - - &.wp-embed-aspect-9-6:before { - padding-top: 66.66%; // 6 / 9 * 100 - } - - &.wp-embed-aspect-1-2:before { - padding-top: 200%; // 2 / 1 * 100 - } -} diff --git a/packages/block-library/src/theme.scss b/packages/block-library/src/theme.scss index 1918654b749d7..da6419fcf4701 100644 --- a/packages/block-library/src/theme.scss +++ b/packages/block-library/src/theme.scss @@ -5,4 +5,3 @@ @import "./separator/theme.scss"; @import "./table/theme.scss"; @import "./video/theme.scss"; -@import "./embed/theme.scss"; From a81372e77a471d02e325b170913ddb3faac5372c Mon Sep 17 00:00:00 2001 From: Nicola Heald Date: Tue, 4 Sep 2018 13:33:40 +0100 Subject: [PATCH 05/10] Remove the aspect ratio preservation from sandbox --- packages/components/src/sandbox/index.js | 27 ------------------------ 1 file changed, 27 deletions(-) diff --git a/packages/components/src/sandbox/index.js b/packages/components/src/sandbox/index.js index bbc5097aa4624..b78e5cb8a6984 100644 --- a/packages/components/src/sandbox/index.js +++ b/packages/components/src/sandbox/index.js @@ -79,8 +79,6 @@ class Sandbox extends Component { const observeAndResizeJS = ` ( function() { var observer; - var aspectRatio = false; - var iframe = false; if ( ! window.MutationObserver || ! document.body || ! window.parent ) { return; @@ -88,17 +86,6 @@ class Sandbox extends Component { function sendResize() { var clientBoundingRect = document.body.getBoundingClientRect(); - var height = aspectRatio ? Math.ceil( clientBoundingRect.width / aspectRatio ) : clientBoundingRect.height; - - if ( iframe && aspectRatio ) { - // This is embedded content delivered in an iframe with a fixed aspect ratio, - // so set the height correctly and stop processing. The DOM mutation will trigger - // another event and the resize message will get posted. - if ( iframe.height != height ) { - iframe.height = height; - return; - } - } window.parent.postMessage( { action: 'resize', @@ -139,20 +126,6 @@ class Sandbox extends Component { document.body.style.width = '100%'; document.body.setAttribute( 'data-resizable-iframe-connected', '' ); - // Make embedded content in an iframe with a fixed size responsive, - // keeping the correct aspect ratio. - var potentialIframe = document.body.children[0]; - if ( 'DIV' === potentialIframe.tagName || 'SPAN' === potentialIframe.tagName ) { - potentialIframe = potentialIframe.children[0]; - } - if ( potentialIframe && 'IFRAME' === potentialIframe.tagName ) { - if ( potentialIframe.width ) { - iframe = potentialIframe; - aspectRatio = potentialIframe.width / potentialIframe.height; - potentialIframe.width = '100%'; - } - } - sendResize(); // Resize events can change the width of elements with 100% width, but we don't From f75ac26bfa96f45652ca0cf9e4669ee25db0df96 Mon Sep 17 00:00:00 2001 From: Nicola Heald Date: Tue, 4 Sep 2018 13:54:39 +0100 Subject: [PATCH 06/10] Fix embed tests --- test/integration/full-content/fixtures/core__embed.html | 4 +++- test/integration/full-content/fixtures/core__embed.json | 2 +- .../integration/full-content/fixtures/core__embed.parsed.json | 2 +- .../full-content/fixtures/core__embed.serialized.html | 4 ++-- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/test/integration/full-content/fixtures/core__embed.html b/test/integration/full-content/fixtures/core__embed.html index a75136b0413ef..211e9e114ec54 100644 --- a/test/integration/full-content/fixtures/core__embed.html +++ b/test/integration/full-content/fixtures/core__embed.html @@ -1,6 +1,8 @@
- https://example.com/ +
+ https://example.com/ +
Embedded content from an example URL
diff --git a/test/integration/full-content/fixtures/core__embed.json b/test/integration/full-content/fixtures/core__embed.json index ec2cbd732a343..542ed68080d1d 100644 --- a/test/integration/full-content/fixtures/core__embed.json +++ b/test/integration/full-content/fixtures/core__embed.json @@ -10,6 +10,6 @@ ] }, "innerBlocks": [], - "originalContent": "
\n https://example.com/\n
Embedded content from an example URL
\n
" + "originalContent": "
\n
\n https://example.com/\n
\n
Embedded content from an example URL
\n
" } ] diff --git a/test/integration/full-content/fixtures/core__embed.parsed.json b/test/integration/full-content/fixtures/core__embed.parsed.json index 7a827c4445f05..70c14e2a61868 100644 --- a/test/integration/full-content/fixtures/core__embed.parsed.json +++ b/test/integration/full-content/fixtures/core__embed.parsed.json @@ -5,7 +5,7 @@ "url": "https://example.com/" }, "innerBlocks": [], - "innerHTML": "\n
\n https://example.com/\n
Embedded content from an example URL
\n
\n" + "innerHTML": "\n
\n
\n https://example.com/\n
\n
Embedded content from an example URL
\n
\n" }, { "attrs": {}, diff --git a/test/integration/full-content/fixtures/core__embed.serialized.html b/test/integration/full-content/fixtures/core__embed.serialized.html index b84300ecadc7b..3906dd45ee541 100644 --- a/test/integration/full-content/fixtures/core__embed.serialized.html +++ b/test/integration/full-content/fixtures/core__embed.serialized.html @@ -1,5 +1,5 @@ -
+
https://example.com/ -
Embedded content from an example URL
+
Embedded content from an example URL
From 6ed5c5828d160ec3398556baaaa3189c45f1a8ce Mon Sep 17 00:00:00 2001 From: jasmussen Date: Tue, 4 Sep 2018 15:42:39 +0200 Subject: [PATCH 07/10] Fix for responsiveness in the editor also. Note that this changes the sandbox component a little bit. We want to make sure that the changes we made here don't negatively affect other things that use the same component. --- packages/components/src/sandbox/index.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/components/src/sandbox/index.js b/packages/components/src/sandbox/index.js index b78e5cb8a6984..367fd2d32a44e 100644 --- a/packages/components/src/sandbox/index.js +++ b/packages/components/src/sandbox/index.js @@ -137,8 +137,12 @@ class Sandbox extends Component { body { margin: 0; } + html, + body, + body > div, body > div > iframe { width: 100%; + height: 100%; } body > div > * { margin-top: 0 !important; /* has to have !important to override inline styles */ From 27c15c76da86654db7199c2ed0af7f3953a59998 Mon Sep 17 00:00:00 2001 From: Nicola Heald Date: Tue, 4 Sep 2018 15:14:27 +0100 Subject: [PATCH 08/10] Fix height for video sandboxing --- packages/block-library/src/embed/index.js | 1 + packages/components/src/sandbox/index.js | 9 +++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/block-library/src/embed/index.js b/packages/block-library/src/embed/index.js index b69869d0a04d8..19b0e7fdbe4c2 100644 --- a/packages/block-library/src/embed/index.js +++ b/packages/block-library/src/embed/index.js @@ -214,6 +214,7 @@ export function getEmbedEdit( title, icon ) { } if ( aspectRatioClassName ) { + aspectRatioClassName += ' wp-embed-has-aspect-ratio'; const className = classnames( this.props.attributes.className, aspectRatioClassName ); this.props.setAttributes( { className } ); } diff --git a/packages/components/src/sandbox/index.js b/packages/components/src/sandbox/index.js index 367fd2d32a44e..bff77a2d9413b 100644 --- a/packages/components/src/sandbox/index.js +++ b/packages/components/src/sandbox/index.js @@ -90,7 +90,7 @@ class Sandbox extends Component { window.parent.postMessage( { action: 'resize', width: clientBoundingRect.width, - height: height, + height: clientBoundingRect.height, }, '*' ); } @@ -142,6 +142,11 @@ class Sandbox extends Component { body > div, body > div > iframe { width: 100%; + } + html.video, + body.video, + body.video > div, + body.video > div > iframe { height: 100%; } body > div > * { @@ -153,7 +158,7 @@ class Sandbox extends Component { // put the html snippet into a html document, and then write it to the iframe's document // we can use this in the future to inject custom styles or scripts const htmlDoc = ( - + { this.props.title }