Skip to content

Commit

Permalink
Iframe: avoid asset parsing & fix script localisation
Browse files Browse the repository at this point in the history
  • Loading branch information
ellatrix committed Jul 7, 2023
1 parent 4baf207 commit 244de6e
Showing 1 changed file with 16 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

0 comments on commit 244de6e

Please sign in to comment.