Skip to content

Commit

Permalink
Iframed editor: support scripts (#31873)
Browse files Browse the repository at this point in the history
  • Loading branch information
ellatrix authored and jffng committed May 19, 2021
1 parent 2d7efc7 commit d8f813c
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 24 deletions.
39 changes: 31 additions & 8 deletions lib/client-assets.php
Original file line number Diff line number Diff line change
Expand Up @@ -708,7 +708,8 @@ function gutenberg_extend_block_editor_settings_with_fse_theme_flag( $settings )
* Sets the editor styles to be consumed by JS.
*/
function gutenberg_extend_block_editor_styles_html() {
$handles = array(
$script_handles = array();
$style_handles = array(
'wp-block-editor',
'wp-block-library',
'wp-block-library-theme',
Expand All @@ -719,26 +720,48 @@ function gutenberg_extend_block_editor_styles_html() {

foreach ( $block_registry->get_all_registered() as $block_type ) {
if ( ! empty( $block_type->style ) ) {
$handles[] = $block_type->style;
$style_handles[] = $block_type->style;
}

if ( ! empty( $block_type->editor_style ) ) {
$handles[] = $block_type->editor_style;
$style_handles[] = $block_type->editor_style;
}

if ( ! empty( $block_type->script ) ) {
$script_handles[] = $block_type->script;
}
}

$handles = array_unique( $handles );
$done = wp_styles()->done;
$style_handles = array_unique( $style_handles );
$done = wp_styles()->done;

ob_start();

wp_styles()->done = array();
wp_styles()->do_items( $handles );
wp_styles()->do_items( $style_handles );
wp_styles()->done = $done;

$editor_styles = wp_json_encode( array( 'html' => ob_get_clean() ) );
$styles = ob_get_clean();

$script_handles = array_unique( $script_handles );
$done = wp_scripts()->done;

ob_start();

wp_scripts()->done = array();
wp_scripts()->do_items( $script_handles );
wp_scripts()->done = $done;

$scripts = ob_get_clean();

$editor_assets = wp_json_encode(
array(
'styles' => $styles,
'scripts' => $scripts,
)
);

echo "<script>window.__editorStyles = $editor_styles</script>";
echo "<script>window.__editorAssets = $editor_assets</script>";
}
add_action( 'admin_footer-toplevel_page_gutenberg-edit-site', 'gutenberg_extend_block_editor_styles_html' );
add_action( 'admin_footer-post.php', 'gutenberg_extend_block_editor_styles_html' );
Expand Down
65 changes: 51 additions & 14 deletions packages/block-editor/src/components/iframe/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import {
createPortal,
useCallback,
forwardRef,
useEffect,
useMemo,
} from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { useMergeRefs } from '@wordpress/compose';
Expand Down Expand Up @@ -133,21 +135,33 @@ function setBodyClassName( doc ) {
}
}

/**
* Sets the document head and default styles.
*
* @param {Document} doc Document to set the head for.
* @param {string} head HTML to set as the head.
*/
function setHead( doc, head ) {
doc.head.innerHTML =
// Body margin must be overridable by themes.
'<style>body{margin:0}</style>' + head;
function useParsedAssets( html ) {
return useMemo( () => {
const doc = document.implementation.createHTMLDocument( '' );
doc.body.innerHTML = html;
return Array.from( doc.body.children );
}, [ html ] );
}

function Iframe( { contentRef, children, head, headHTML, ...props }, ref ) {
const [ iframeDocument, setIframeDocument ] = useState();
async function loadScript( doc, { id, src } ) {
return new Promise( ( resolve, reject ) => {
const script = doc.createElement( 'script' );
script.id = id;
if ( src ) {
script.src = src;
script.onload = () => resolve();
script.onerror = () => reject();
} else {
resolve();
}
doc.head.appendChild( script );
} );
}

function Iframe( { contentRef, children, head, ...props }, ref ) {
const [ iframeDocument, setIframeDocument ] = useState();
const styles = useParsedAssets( window.__editorAssets.styles );
const scripts = useParsedAssets( window.__editorAssets.scripts );
const clearerRef = useBlockSelectionClearer();
const setRef = useCallback( ( node ) => {
if ( ! node ) {
Expand All @@ -168,15 +182,19 @@ function Iframe( { contentRef, children, head, headHTML, ...props }, ref ) {
contentRef.current = body;
}

setHead( contentDocument, headHTML );
setBodyClassName( contentDocument );
styleSheetsCompat( contentDocument );
bubbleEvents( contentDocument );
setBodyClassName( contentDocument );
setIframeDocument( contentDocument );
clearerRef( documentElement );
clearerRef( body );

scripts.reduce(
( promise, script ) =>
promise.then( () => loadScript( contentDocument, script ) ),
Promise.resolve()
);

return true;
}

Expand All @@ -190,6 +208,25 @@ function Iframe( { contentRef, children, head, headHTML, ...props }, ref ) {
} );
}, [] );

useEffect( () => {
if ( iframeDocument ) {
styleSheetsCompat( iframeDocument );
}
}, [ iframeDocument ] );

head = (
<>
<style>{ 'body{margin:0}' }</style>
{ styles.map( ( { tagName, href, id, rel, media }, index ) => {
const TagName = tagName.toLowerCase();
return (
<TagName { ...{ href, id, rel, media } } key={ index } />
);
} ) }
{ head }
</>
);

return (
<iframe
{ ...props }
Expand Down
1 change: 0 additions & 1 deletion packages/edit-post/src/components/visual-editor/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ function MaybeIframe( {

return (
<Iframe
headHTML={ window.__editorStyles.html }
head={ <EditorStyles styles={ styles } /> }
ref={ ref }
contentRef={ contentRef }
Expand Down
1 change: 0 additions & 1 deletion packages/edit-site/src/components/block-editor/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@ export default function BlockEditor( { setIsInserterOpen } ) {
<BlockTools __unstableContentRef={ contentRef }>
<Iframe
style={ resizedCanvasStyles }
headHTML={ window.__editorStyles.html }
head={ <EditorStyles styles={ settings.styles } /> }
ref={ ref }
contentRef={ mergedRefs }
Expand Down

0 comments on commit d8f813c

Please sign in to comment.