diff --git a/lib/full-site-editing/edit-site-page.php b/lib/full-site-editing/edit-site-page.php
index 3418054f12b9a..076beff97f12d 100644
--- a/lib/full-site-editing/edit-site-page.php
+++ b/lib/full-site-editing/edit-site-page.php
@@ -165,16 +165,6 @@ static function( $classes ) {
)
);
- add_action(
- 'admin_head',
- function() {
- $filters = wp_get_global_styles_svg_filters();
- if ( ! empty( $filters ) ) {
- printf( '', wp_json_encode( $filters ) );
- }
- }
- );
-
wp_add_inline_script(
'wp-blocks',
sprintf( 'wp.blocks.setCategories( %s );', wp_json_encode( get_block_categories( $post ) ) ),
diff --git a/packages/block-editor/src/hooks/duotone.js b/packages/block-editor/src/hooks/duotone.js
index 13de8f2a4d79a..dafd92020da37 100644
--- a/packages/block-editor/src/hooks/duotone.js
+++ b/packages/block-editor/src/hooks/duotone.js
@@ -60,82 +60,109 @@ export function getValuesFromColors( colors = [] ) {
*/
/**
- * SVG and stylesheet needed for rendering the duotone filter.
+ * Stylesheet for rendering the duotone filter.
*
* @param {Object} props Duotone props.
* @param {string} props.selector Selector to apply the filter to.
* @param {string} props.id Unique id for this duotone filter.
- * @param {Values} props.values R, G, B, and A values to filter with.
*
* @return {WPElement} Duotone element.
*/
-function DuotoneFilter( { selector, id, values } ) {
- const stylesheet = `
+function DuotoneStylesheet( { selector, id } ) {
+ const css = `
${ selector } {
filter: url( #${ id } );
}
`;
+ return ;
+}
+/**
+ * SVG for rendering the duotone filter.
+ *
+ * @param {Object} props Duotone props.
+ * @param {string} props.id Unique id for this duotone filter.
+ * @param {Values} props.values R, G, B, and A values to filter with.
+ *
+ * @return {WPElement} Duotone element.
+ */
+function DuotoneFilter( { id, values } ) {
return (
- <>
-
-
+
+
+
+
+
+
+
+ );
+}
+
+/**
+ * SVG and stylesheet needed for rendering the duotone filter.
+ *
+ * @param {Object} props Duotone props.
+ * @param {string} props.selector Selector to apply the filter to.
+ * @param {string} props.id Unique id for this duotone filter.
+ * @param {Values} props.values R, G, B, and A values to filter with.
+ *
+ * @return {WPElement} Duotone element.
+ */
+function InlineDuotone( { selector, id, values } ) {
+ return (
+ <>
+
+
>
);
}
@@ -297,7 +324,7 @@ const withDuotoneStyles = createHigherOrderComponent(
<>
{ element &&
createPortal(
- ( { metadata, preset } ) => {
+ if ( metadata.svgFilter !== 'duotone' ) {
+ return ;
+ }
+ return (
+ <>
+
+
+ >
+ );
+ },
+ 'withDuotoneFilter'
+);
+
addFilter(
'blocks.registerBlockType',
'core/editor/duotone/add-attributes',
@@ -326,3 +371,8 @@ addFilter(
'core/editor/duotone/with-styles',
withDuotoneStyles
);
+addFilter(
+ 'editor.PresetSvgFilter',
+ 'core/editor/duotone/with-svg-filter',
+ withDuotoneFilter
+);
diff --git a/packages/edit-site/src/components/block-editor/resizable-editor.js b/packages/edit-site/src/components/block-editor/resizable-editor.js
index 71500b26914e5..c2c27f0dade01 100644
--- a/packages/edit-site/src/components/block-editor/resizable-editor.js
+++ b/packages/edit-site/src/components/block-editor/resizable-editor.js
@@ -183,11 +183,7 @@ function ResizableEditor( { enableResizing, settings, children, ...props } ) {
className="edit-site-visual-editor__editor-canvas"
{ ...props }
>
-
+ { settings.svgFilters }
{ children }
diff --git a/packages/edit-site/src/components/editor/global-styles-renderer.js b/packages/edit-site/src/components/editor/global-styles-renderer.js
index f046cf7d46409..dec35703dfcdf 100644
--- a/packages/edit-site/src/components/editor/global-styles-renderer.js
+++ b/packages/edit-site/src/components/editor/global-styles-renderer.js
@@ -15,7 +15,7 @@ import { store as editSiteStore } from '../../store';
import { useGlobalStylesOutput } from '../global-styles/use-global-styles-output';
function useGlobalStylesRenderer() {
- const [ styles, settings ] = useGlobalStylesOutput();
+ const [ styles, settings, svgFilters ] = useGlobalStylesOutput();
const { getSettings } = useSelect( editSiteStore );
const { updateSettings } = useDispatch( editSiteStore );
@@ -31,6 +31,7 @@ function useGlobalStylesRenderer() {
updateSettings( {
...currentStoreSettings,
styles: [ ...nonGlobalStyles, ...styles ],
+ svgFilters,
__experimentalFeatures: settings,
} );
}, [ styles, settings ] );
diff --git a/packages/edit-site/src/components/global-styles/use-global-styles-output.js b/packages/edit-site/src/components/global-styles/use-global-styles-output.js
index 96ec67eaa7653..ba671ae29b228 100644
--- a/packages/edit-site/src/components/global-styles/use-global-styles-output.js
+++ b/packages/edit-site/src/components/global-styles/use-global-styles-output.js
@@ -22,6 +22,7 @@ import {
__EXPERIMENTAL_ELEMENTS as ELEMENTS,
getBlockTypes,
} from '@wordpress/blocks';
+import { withFilters } from '@wordpress/components';
import { useEffect, useState, useContext } from '@wordpress/element';
/**
@@ -133,6 +134,27 @@ function getPresetsClasses( blockSelector, blockPresets = {} ) {
);
}
+const PresetSvgFilter = withFilters( 'editor.PresetSvgFilter' )( () => null );
+
+function getPresetsSvgFilters( blockPresets = {} ) {
+ return PRESET_METADATA.filter( ( metadata ) => metadata.svgFilter ).flatMap(
+ ( metadata ) => {
+ const presetByOrigin = get( blockPresets, metadata.path, {} );
+ return [ 'default', 'theme' ]
+ .filter( ( origin ) => presetByOrigin[ origin ] )
+ .flatMap( ( origin ) =>
+ presetByOrigin[ origin ].map( ( preset ) => (
+
+ ) )
+ );
+ }
+ );
+}
+
function flattenTree( input = {}, prefix, token ) {
let result = [];
Object.keys( input ).forEach( ( key ) => {
@@ -355,6 +377,13 @@ export const toStyles = ( tree, blockSelectors ) => {
return ruleset;
};
+export function toSvgFilters( tree, blockSelectors ) {
+ const nodesWithSettings = getNodesWithSettings( tree, blockSelectors );
+ return nodesWithSettings.flatMap( ( { presets } ) => {
+ return getPresetsSvgFilters( presets );
+ } );
+}
+
const getBlockSelectors = ( blockTypes ) => {
const result = {};
blockTypes.forEach( ( blockType ) => {
@@ -374,6 +403,7 @@ const getBlockSelectors = ( blockTypes ) => {
export function useGlobalStylesOutput() {
const [ stylesheets, setStylesheets ] = useState( [] );
const [ settings, setSettings ] = useState( {} );
+ const [ svgFilters, setSvgFilters ] = useState( {} );
const { merged: mergedConfig } = useContext( GlobalStylesContext );
useEffect( () => {
@@ -387,6 +417,7 @@ export function useGlobalStylesOutput() {
blockSelectors
);
const globalStyles = toStyles( mergedConfig, blockSelectors );
+ const filters = toSvgFilters( mergedConfig, blockSelectors );
setStylesheets( [
{
css: customProperties,
@@ -398,7 +429,8 @@ export function useGlobalStylesOutput() {
},
] );
setSettings( mergedConfig.settings );
+ setSvgFilters( filters );
}, [ mergedConfig ] );
- return [ stylesheets, settings ];
+ return [ stylesheets, settings, svgFilters ];
}
diff --git a/packages/edit-site/src/components/global-styles/utils.js b/packages/edit-site/src/components/global-styles/utils.js
index 882ab23e83ee2..e1124cf84c904 100644
--- a/packages/edit-site/src/components/global-styles/utils.js
+++ b/packages/edit-site/src/components/global-styles/utils.js
@@ -53,6 +53,7 @@ export const PRESET_METADATA = [
path: [ 'color', 'duotone' ],
cssVarInfix: 'duotone',
valueFunc: ( { slug } ) => `url( '#wp-duotone-${ slug }' )`,
+ svgFilter: 'duotone',
},
{
path: [ 'typography', 'fontSizes' ],