Skip to content

Commit

Permalink
Iframe: avoid asset parsing & fix script localisation (#52405)
Browse files Browse the repository at this point in the history
* Iframe: avoid asset parsing & fix script localisation

* Add e2e test for script localisation
  • Loading branch information
ellatrix authored and fullofcaffeine committed Jul 10, 2023
1 parent 7ab272b commit 2f29108
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 47 deletions.
63 changes: 16 additions & 47 deletions packages/block-editor/src/components/iframe/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import {
createPortal,
forwardRef,
useMemo,
useReducer,
useEffect,
} from '@wordpress/element';
import { __ } from '@wordpress/i18n';
Expand Down Expand Up @@ -78,29 +77,6 @@ function bubbleEvents( doc ) {
}
}

function useParsedAssets( html ) {
return useMemo( () => {
const doc = document.implementation.createHTMLDocument( '' );
doc.body.innerHTML = html;
return Array.from( doc.body.children );
}, [ html ] );
}

async function loadScript( head, { id, src } ) {
return new Promise( ( resolve, reject ) => {
const script = head.ownerDocument.createElement( 'script' );
script.id = id;
if ( src ) {
script.src = src;
script.onload = () => resolve();
script.onerror = () => reject();
} else {
resolve();
}
head.appendChild( script );
} );
}

function Iframe( {
contentRef,
children,
Expand All @@ -112,21 +88,22 @@ function Iframe( {
forwardedRef: ref,
...props
} ) {
const assets = useSelect(
const { styles = '', scripts = '' } = useSelect(
( select ) =>
select( blockEditorStore ).getSettings().__unstableResolvedAssets,
[]
);
const [ , forceRender ] = useReducer( () => ( {} ) );
const [ iframeDocument, setIframeDocument ] = useState();
const [ bodyClasses, setBodyClasses ] = useState( [] );
const compatStyles = useCompatibilityStyles();
const scripts = useParsedAssets( assets?.scripts );
const clearerRef = useBlockSelectionClearer();
const [ before, writingFlowRef, after ] = useWritingFlow();
const [ contentResizeListener, { height: contentHeight } ] =
useResizeObserver();
const setRef = useRefEffect( ( node ) => {
node._load = () => {
setIframeDocument( node.contentDocument );
};
let iFrameDocument;
// Prevent the default browser action for files dropped outside of dropzones.
function preventFileDropDefault( event ) {
Expand All @@ -138,7 +115,6 @@ function Iframe( {
iFrameDocument = contentDocument;

bubbleEvents( contentDocument );
setIframeDocument( contentDocument );
clearerRef( documentElement );

// Ideally ALL classes that are added through get_body_class should
Expand All @@ -154,7 +130,6 @@ function Iframe( {
);

contentDocument.dir = ownerDocument.dir;
documentElement.removeChild( contentDocument.body );

for ( const compatStyle of compatStyles ) {
if ( contentDocument.getElementById( compatStyle.id ) ) {
Expand Down Expand Up @@ -199,35 +174,29 @@ function Iframe( {
};
}, [] );

const headRef = useRefEffect( ( element ) => {
scripts
.reduce(
( promise, script ) =>
promise.then( () => loadScript( element, script ) ),
Promise.resolve()
)
.finally( () => {
// When script are loaded, re-render blocks to allow them
// to initialise.
forceRender();
} );
}, [] );
const disabledRef = useDisabled( { isDisabled: ! readonly } );
const bodyRef = useMergeRefs( [
contentRef,
clearerRef,
writingFlowRef,
disabledRef,
headRef,
] );

// Correct doctype is required to enable rendering in standards
// mode. Also preload the styles to avoid a flash of unstyled
// content.
const html =
'<!doctype html>' +
'<style>html{height:auto!important;min-height:100%;}body{margin:0}</style>' +
( assets?.styles ?? '' );
const html = `<!doctype html>
<html>
<head>
<script>window.frameElement._load()</script>
<style>html{height:auto!important;min-height:100%;}body{margin:0}</style>
${ styles }
${ scripts }
</head>
<body>
<script>document.currentScript.parentElement.remove()</script>
</body>
</html>`;

const [ src, cleanup ] = useMemo( () => {
const _src = URL.createObjectURL(
Expand Down
13 changes: 13 additions & 0 deletions packages/e2e-tests/plugins/iframed-enqueue-block-assets.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,18 @@ static function() {
filemtime( plugin_dir_path( __FILE__ ) . 'iframed-enqueue-block-assets/style.css' )
);
wp_add_inline_style( 'iframed-enqueue-block-assets', 'body{padding:20px!important}' );
wp_enqueue_script(
'iframed-enqueue-block-assets-script',
plugin_dir_url( __FILE__ ) . 'iframed-enqueue-block-assets/script.js',
array(),
filemtime( plugin_dir_path( __FILE__ ) . 'iframed-enqueue-block-assets/script.js' )
);
wp_localize_script(
'iframed-enqueue-block-assets-script',
'iframedEnqueueBlockAssetsL10n',
array(
'test' => 'Iframed Enqueue Block Assets!',
)
);
}
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
window.addEventListener( 'load', () => {
document.body.dataset.iframedEnqueueBlockAssetsL10n = window.iframedEnqueueBlockAssetsL10n.test;
} );
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ describe( 'iframed inline styles', () => {
} );

it( 'should load styles added through enqueue_block_assets', async () => {
await page.waitForSelector( 'iframe[name="editor-canvas"]' );
// Check stylesheet.
expect(
await getComputedStyle( canvas(), 'body', 'background-color' )
Expand All @@ -40,5 +41,11 @@ describe( 'iframed inline styles', () => {
expect( await getComputedStyle( canvas(), 'body', 'padding' ) ).toBe(
'20px'
);

expect(
await canvas().evaluate( () => ( { ...document.body.dataset } ) )
).toEqual( {
iframedEnqueueBlockAssetsL10n: 'Iframed Enqueue Block Assets!',
} );
} );
} );

0 comments on commit 2f29108

Please sign in to comment.