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

Block editor: move layout styles to document head (instead of rendering inline) #32083

Merged
merged 7 commits into from
Jul 13, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion lib/block-supports/duotone.php
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,15 @@ function ( $selector ) use ( $duotone_id ) {
1
);

return $content . $duotone;
add_action(
// Ideally we should use wp_head, but SVG defs can't be put in there.
'wp_footer',
function () use ( $duotone ) {
echo $duotone;
}
);

return $content;
}

// Register the block support.
Expand Down
12 changes: 11 additions & 1 deletion lib/block-supports/layout.php
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,17 @@ function gutenberg_render_layout_support_flag( $block_content, $block ) {
1
);

return $content . '<style>' . $style . '</style>';
// Ideally styles should be loaded in the head, but blocks may be parsed
// after that, so loading in the footer for now.
// See https://core.trac.wordpress.org/ticket/53494.
add_action(
'wp_footer',
function () use ( $style ) {
echo '<style>' . $style . '</style>';
}
);

return $content;
}

// This can be removed when plugin support requires WordPress 5.8.0+.
Expand Down
18 changes: 18 additions & 0 deletions packages/block-editor/src/components/block-list/head.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/**
* WordPress dependencies
*/
import { createContext, useState } from '@wordpress/element';

const context = createContext();

export function Head( { children } ) {
const [ element, setElement ] = useState();
return (
<context.Provider value={ element }>
<div ref={ setElement } />
{ children }
</context.Provider>
);
}

Head.context = context;
39 changes: 21 additions & 18 deletions packages/block-editor/src/components/block-list/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { usePreParsePatterns } from '../../utils/pre-parse-patterns';
import { LayoutProvider, defaultLayout } from './layout';
import BlockToolsBackCompat from '../block-tools/back-compat';
import { useBlockSelectionClearer } from '../block-selection-clearer';
import { Head } from './head';

export const IntersectionObserver = createContext();

Expand All @@ -42,24 +43,26 @@ function Root( { className, children } ) {
[]
);
return (
<div
ref={ useMergeRefs( [
useBlockSelectionClearer(),
useBlockDropZone(),
useInBetweenInserter(),
] ) }
className={ classnames(
'block-editor-block-list__layout is-root-container',
className,
{
'is-outline-mode': isOutlineMode,
'is-focus-mode': isFocusMode && isLargeViewport,
'is-navigate-mode': isNavigationMode,
}
) }
>
{ children }
</div>
<Head>
<div
ref={ useMergeRefs( [
useBlockSelectionClearer(),
useBlockDropZone(),
useInBetweenInserter(),
] ) }
className={ classnames(
'block-editor-block-list__layout is-root-container',
className,
{
'is-outline-mode': isOutlineMode,
'is-focus-mode': isFocusMode && isLargeViewport,
'is-navigate-mode': isNavigationMode,
}
) }
>
{ children }
</div>
</Head>
);
}

Expand Down
18 changes: 13 additions & 5 deletions packages/block-editor/src/hooks/duotone.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { getBlockSupport, hasBlockSupport } from '@wordpress/blocks';
import { SVG } from '@wordpress/components';
import { createHigherOrderComponent, useInstanceId } from '@wordpress/compose';
import { addFilter } from '@wordpress/hooks';
import { useContext, createPortal } from '@wordpress/element';

/**
* Internal dependencies
Expand All @@ -20,6 +21,7 @@ import {
__experimentalDuotoneControl as DuotoneControl,
useSetting,
} from '../components';
import { Head } from '../components/block-list/head';

const EMPTY_ARRAY = [];

Expand Down Expand Up @@ -240,13 +242,19 @@ const withDuotoneStyles = createHigherOrderComponent(

const className = classnames( props?.className, id );

const element = useContext( Head.context );
Copy link
Contributor

Choose a reason for hiding this comment

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

This breaks the hooks rules (it should be called before the if call above)


return (
<>
<DuotoneFilter
selector={ selectorsGroup }
id={ id }
values={ getValuesFromColors( values ) }
/>
{ element &&
createPortal(
<DuotoneFilter
selector={ selectorsGroup }
id={ id }
values={ getValuesFromColors( values ) }
/>,
element
) }
<BlockListBlock { ...props } className={ className } />
</>
);
Expand Down
16 changes: 12 additions & 4 deletions packages/block-editor/src/hooks/layout.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
} from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import { Icon, positionCenter, stretchWide } from '@wordpress/icons';
import { useContext, createPortal } from '@wordpress/element';

/**
* Internal dependencies
Expand All @@ -28,6 +29,7 @@ import { store as blockEditorStore } from '../store';
import { InspectorControls } from '../components';
import useSetting from '../components/use-setting';
import { LayoutStyle } from '../components/block-list/layout';
import { Head } from '../components/block-list/head';

function LayoutPanel( { setAttributes, attributes } ) {
const { layout = {} } = attributes;
Expand Down Expand Up @@ -210,12 +212,18 @@ export const withLayoutStyles = createHigherOrderComponent(
`wp-container-${ id }`
);

const element = useContext( Head.context );
Copy link
Contributor

Choose a reason for hiding this comment

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

same here


return (
<>
<LayoutStyle
selector={ `.wp-container-${ id }` }
layout={ usedLayout }
/>
{ element &&
createPortal(
<LayoutStyle
selector={ `.wp-container-${ id }` }
layout={ usedLayout }
/>,
element
) }
<BlockListBlock { ...props } className={ className } />
</>
);
Expand Down