From 8d13605c1cbcc9509f947282b55c3b922ca09685 Mon Sep 17 00:00:00 2001 From: Ella <4710635+ellatrix@users.noreply.github.com> Date: Thu, 14 Dec 2023 17:35:04 +0100 Subject: [PATCH] Block editor: hooks: manage save props in one place (#57043) --- packages/block-editor/src/hooks/align.js | 6 +-- packages/block-editor/src/hooks/anchor.js | 6 +-- packages/block-editor/src/hooks/aria-label.js | 13 +++-- packages/block-editor/src/hooks/border.js | 7 +-- packages/block-editor/src/hooks/color.js | 7 +-- .../src/hooks/custom-class-name.js | 6 +-- .../src/hooks/custom-class-name.native.js | 13 +++-- .../block-editor/src/hooks/font-family.js | 7 +-- packages/block-editor/src/hooks/font-size.js | 7 +-- packages/block-editor/src/hooks/index.js | 19 ++++++- .../block-editor/src/hooks/index.native.js | 16 +++++- packages/block-editor/src/hooks/style.js | 7 +-- .../block-editor/src/hooks/test/anchor.js | 13 ++--- .../src/hooks/test/custom-class-name.js | 11 ++-- packages/block-editor/src/hooks/test/style.js | 18 ++----- packages/block-editor/src/hooks/utils.js | 50 ++++++++++++++++++- 16 files changed, 114 insertions(+), 92 deletions(-) diff --git a/packages/block-editor/src/hooks/align.js b/packages/block-editor/src/hooks/align.js index 189f82ccf429f8..3e4a49bb385558 100644 --- a/packages/block-editor/src/hooks/align.js +++ b/packages/block-editor/src/hooks/align.js @@ -155,6 +155,7 @@ export default { shareWithChildBlocks: true, edit: BlockEditAlignmentToolbarControlsPure, useBlockProps, + addSaveProps: addAssignedAlign, attributeKeys: [ 'align' ], hasSupport( name ) { return hasBlockSupport( name, 'align', false ); @@ -209,8 +210,3 @@ addFilter( 'core/editor/align/addAttribute', addAttribute ); -addFilter( - 'blocks.getSaveContent.extraProps', - 'core/editor/align/addAssignedAlign', - addAssignedAlign -); diff --git a/packages/block-editor/src/hooks/anchor.js b/packages/block-editor/src/hooks/anchor.js index 882820678aa870..2e79a9d9db17b2 100644 --- a/packages/block-editor/src/hooks/anchor.js +++ b/packages/block-editor/src/hooks/anchor.js @@ -120,6 +120,7 @@ function BlockEditAnchorControlPure( { } export default { + addSaveProps, edit: BlockEditAnchorControlPure, attributeKeys: [ 'anchor' ], hasSupport( name ) { @@ -147,8 +148,3 @@ export function addSaveProps( extraProps, blockType, attributes ) { } addFilter( 'blocks.registerBlockType', 'core/anchor/attribute', addAttribute ); -addFilter( - 'blocks.getSaveContent.extraProps', - 'core/editor/anchor/save-props', - addSaveProps -); diff --git a/packages/block-editor/src/hooks/aria-label.js b/packages/block-editor/src/hooks/aria-label.js index c4387daab71137..7f93aa4ff8c8b2 100644 --- a/packages/block-editor/src/hooks/aria-label.js +++ b/packages/block-editor/src/hooks/aria-label.js @@ -55,13 +55,16 @@ export function addSaveProps( extraProps, blockType, attributes ) { return extraProps; } +export default { + addSaveProps, + attributeKeys: [ 'ariaLabel' ], + hasSupport( name ) { + return hasBlockSupport( name, 'ariaLabel' ); + }, +}; + addFilter( 'blocks.registerBlockType', 'core/ariaLabel/attribute', addAttribute ); -addFilter( - 'blocks.getSaveContent.extraProps', - 'core/ariaLabel/save-props', - addSaveProps -); diff --git a/packages/block-editor/src/hooks/border.js b/packages/block-editor/src/hooks/border.js index c6947eeaa18e38..a11fdc4b97e48b 100644 --- a/packages/block-editor/src/hooks/border.js +++ b/packages/block-editor/src/hooks/border.js @@ -348,6 +348,7 @@ function useBlockProps( { name, borderColor, style } ) { export default { useBlockProps, + addSaveProps, attributeKeys: [ 'borderColor', 'style' ], hasSupport( name ) { return hasBorderSupport( name, 'color' ); @@ -359,9 +360,3 @@ addFilter( 'core/border/addAttributes', addAttributes ); - -addFilter( - 'blocks.getSaveContent.extraProps', - 'core/border/addSaveProps', - addSaveProps -); diff --git a/packages/block-editor/src/hooks/color.js b/packages/block-editor/src/hooks/color.js index db6c3dc8fd86ce..267bafe1201739 100644 --- a/packages/block-editor/src/hooks/color.js +++ b/packages/block-editor/src/hooks/color.js @@ -399,6 +399,7 @@ function useBlockProps( { export default { useBlockProps, + addSaveProps, attributeKeys: [ 'backgroundColor', 'textColor', 'gradient', 'style' ], hasSupport: hasColorSupport, }; @@ -437,12 +438,6 @@ addFilter( addAttributes ); -addFilter( - 'blocks.getSaveContent.extraProps', - 'core/color/addSaveProps', - addSaveProps -); - addFilter( 'blocks.switchToBlockType.transformedBlock', 'core/color/addTransforms', diff --git a/packages/block-editor/src/hooks/custom-class-name.js b/packages/block-editor/src/hooks/custom-class-name.js index 331edd9ef214a2..037fafe9ca840f 100644 --- a/packages/block-editor/src/hooks/custom-class-name.js +++ b/packages/block-editor/src/hooks/custom-class-name.js @@ -65,6 +65,7 @@ function CustomClassNameControlsPure( { className, setAttributes } ) { export default { edit: CustomClassNameControlsPure, + addSaveProps, attributeKeys: [ 'className' ], hasSupport( name ) { return hasBlockSupport( name, 'customClassName', true ); @@ -140,11 +141,6 @@ addFilter( 'core/editor/custom-class-name/attribute', addAttribute ); -addFilter( - 'blocks.getSaveContent.extraProps', - 'core/editor/custom-class-name/save-props', - addSaveProps -); addFilter( 'blocks.switchToBlockType.transformedBlock', diff --git a/packages/block-editor/src/hooks/custom-class-name.native.js b/packages/block-editor/src/hooks/custom-class-name.native.js index 65ba2505053755..8d2b6560332e45 100644 --- a/packages/block-editor/src/hooks/custom-class-name.native.js +++ b/packages/block-editor/src/hooks/custom-class-name.native.js @@ -60,8 +60,11 @@ addFilter( 'core/custom-class-name/attribute', addAttribute ); -addFilter( - 'blocks.getSaveContent.extraProps', - 'core/custom-class-name/save-props', - addSaveProps -); + +export default { + addSaveProps, + attributeKeys: [ 'className' ], + hasSupport( name ) { + return hasBlockSupport( name, 'customClassName', true ); + }, +}; diff --git a/packages/block-editor/src/hooks/font-family.js b/packages/block-editor/src/hooks/font-family.js index ae41b7fa34b1f5..db6515ef1c2fe0 100644 --- a/packages/block-editor/src/hooks/font-family.js +++ b/packages/block-editor/src/hooks/font-family.js @@ -82,6 +82,7 @@ function useBlockProps( { name, fontFamily } ) { export default { useBlockProps, + addSaveProps, attributeKeys: [ 'fontFamily' ], hasSupport( name ) { return hasBlockSupport( name, FONT_FAMILY_SUPPORT_KEY ); @@ -105,9 +106,3 @@ addFilter( 'core/fontFamily/addAttribute', addAttributes ); - -addFilter( - 'blocks.getSaveContent.extraProps', - 'core/fontFamily/addSaveProps', - addSaveProps -); diff --git a/packages/block-editor/src/hooks/font-size.js b/packages/block-editor/src/hooks/font-size.js index b30fcc82d99463..89491da44edce3 100644 --- a/packages/block-editor/src/hooks/font-size.js +++ b/packages/block-editor/src/hooks/font-size.js @@ -211,6 +211,7 @@ function useBlockProps( { name, fontSize, style } ) { export default { useBlockProps, + addSaveProps, attributeKeys: [ 'fontSize', 'style' ], hasSupport( name ) { return hasBlockSupport( name, FONT_SIZE_SUPPORT_KEY ); @@ -245,12 +246,6 @@ addFilter( addAttributes ); -addFilter( - 'blocks.getSaveContent.extraProps', - 'core/font/addSaveProps', - addSaveProps -); - addFilter( 'blocks.switchToBlockType.transformedBlock', 'core/font-size/addTransforms', diff --git a/packages/block-editor/src/hooks/index.js b/packages/block-editor/src/hooks/index.js index ec0dba5efb2b69..26d1d1ad12bc0b 100644 --- a/packages/block-editor/src/hooks/index.js +++ b/packages/block-editor/src/hooks/index.js @@ -1,12 +1,16 @@ /** * Internal dependencies */ -import { createBlockEditFilter, createBlockListBlockFilter } from './utils'; +import { + createBlockEditFilter, + createBlockListBlockFilter, + createBlockSaveFilter, +} from './utils'; import './compat'; import align from './align'; import './lock'; import anchor from './anchor'; -import './aria-label'; +import ariaLabel from './aria-label'; import customClassName from './custom-class-name'; import './generated-class-name'; import style from './style'; @@ -50,6 +54,17 @@ createBlockListBlockFilter( [ position, childLayout, ] ); +createBlockSaveFilter( [ + align, + anchor, + ariaLabel, + customClassName, + border, + color, + style, + fontFamily, + fontSize, +] ); export { useCustomSides } from './dimensions'; export { useLayoutClasses, useLayoutStyles } from './layout'; diff --git a/packages/block-editor/src/hooks/index.native.js b/packages/block-editor/src/hooks/index.native.js index c0530aedb37ca4..55ae7e19df7037 100644 --- a/packages/block-editor/src/hooks/index.native.js +++ b/packages/block-editor/src/hooks/index.native.js @@ -1,11 +1,15 @@ /** * Internal dependencies */ -import { createBlockEditFilter, createBlockListBlockFilter } from './utils'; +import { + createBlockEditFilter, + createBlockListBlockFilter, + createBlockSaveFilter, +} from './utils'; import './compat'; import align from './align'; import anchor from './anchor'; -import './custom-class-name'; +import customClassName from './custom-class-name'; import './generated-class-name'; import style from './style'; import color from './color'; @@ -14,6 +18,14 @@ import './layout'; createBlockEditFilter( [ align, anchor, style ] ); createBlockListBlockFilter( [ align, style, color, fontSize ] ); +createBlockSaveFilter( [ + align, + anchor, + customClassName, + color, + style, + fontSize, +] ); export { getBorderClassesAndStyles, useBorderProps } from './use-border-props'; export { getColorClassesAndStyles, useColorProps } from './use-color-props'; diff --git a/packages/block-editor/src/hooks/style.js b/packages/block-editor/src/hooks/style.js index b6098969bebb5e..7221de63456cd5 100644 --- a/packages/block-editor/src/hooks/style.js +++ b/packages/block-editor/src/hooks/style.js @@ -343,6 +343,7 @@ function BlockStyleControls( { export default { edit: BlockStyleControls, hasSupport: hasStyleSupport, + addSaveProps, attributeKeys: [ 'style' ], useBlockProps, }; @@ -455,9 +456,3 @@ addFilter( 'core/style/addAttribute', addAttribute ); - -addFilter( - 'blocks.getSaveContent.extraProps', - 'core/style/addSaveProps', - addSaveProps -); diff --git a/packages/block-editor/src/hooks/test/anchor.js b/packages/block-editor/src/hooks/test/anchor.js index a919fad575312e..557789b1c088f3 100644 --- a/packages/block-editor/src/hooks/test/anchor.js +++ b/packages/block-editor/src/hooks/test/anchor.js @@ -6,7 +6,7 @@ import { applyFilters } from '@wordpress/hooks'; /** * Internal dependencies */ -import '../anchor'; +import anchor from '../anchor'; const noop = () => {}; @@ -62,14 +62,9 @@ describe( 'anchor', () => { } ); describe( 'addSaveProps', () => { - const getSaveContentExtraProps = applyFilters.bind( - null, - 'blocks.getSaveContent.extraProps' - ); - it( 'should do nothing if the block settings do not define anchor support', () => { const attributes = { anchor: 'foo' }; - const extraProps = getSaveContentExtraProps( + const extraProps = anchor.addSaveProps( {}, blockSettings, attributes @@ -80,7 +75,7 @@ describe( 'anchor', () => { it( 'should inject anchor attribute ID', () => { const attributes = { anchor: 'foo' }; - const extraProps = getSaveContentExtraProps( + const extraProps = anchor.addSaveProps( {}, { ...blockSettings, @@ -96,7 +91,7 @@ describe( 'anchor', () => { it( 'should remove an anchor attribute ID when field is cleared', () => { const attributes = { anchor: '' }; - const extraProps = getSaveContentExtraProps( + const extraProps = anchor.addSaveProps( {}, { ...blockSettings, diff --git a/packages/block-editor/src/hooks/test/custom-class-name.js b/packages/block-editor/src/hooks/test/custom-class-name.js index 5a662a99d59aec..29d5d836bce8f7 100644 --- a/packages/block-editor/src/hooks/test/custom-class-name.js +++ b/packages/block-editor/src/hooks/test/custom-class-name.js @@ -6,7 +6,7 @@ import { applyFilters } from '@wordpress/hooks'; /** * Internal dependencies */ -import '../custom-class-name'; +import customClassName from '../custom-class-name'; describe( 'custom className', () => { const blockSettings = { @@ -40,14 +40,9 @@ describe( 'custom className', () => { } ); describe( 'addSaveProps', () => { - const addSaveProps = applyFilters.bind( - null, - 'blocks.getSaveContent.extraProps' - ); - it( 'should do nothing if the block settings do not define custom className support', () => { const attributes = { className: 'foo' }; - const extraProps = addSaveProps( + const extraProps = customClassName.addSaveProps( {}, { ...blockSettings, @@ -63,7 +58,7 @@ describe( 'custom className', () => { it( 'should inject the custom className', () => { const attributes = { className: 'bar' }; - const extraProps = addSaveProps( + const extraProps = customClassName.addSaveProps( { className: 'foo' }, blockSettings, attributes diff --git a/packages/block-editor/src/hooks/test/style.js b/packages/block-editor/src/hooks/test/style.js index 544361a47f1156..2cfe299b8c8d91 100644 --- a/packages/block-editor/src/hooks/test/style.js +++ b/packages/block-editor/src/hooks/test/style.js @@ -1,12 +1,7 @@ -/** - * WordPress dependencies - */ -import { applyFilters } from '@wordpress/hooks'; - /** * Internal dependencies */ -import { getInlineStyles, omitStyle } from '../style'; +import _style, { getInlineStyles, omitStyle } from '../style'; describe( 'getInlineStyles', () => { it( 'should return an empty object when called with undefined', () => { @@ -120,11 +115,6 @@ describe( 'getInlineStyles', () => { } ); describe( 'addSaveProps', () => { - const addSaveProps = applyFilters.bind( - null, - 'blocks.getSaveContent.extraProps' - ); - const blockSettings = { save: () =>
, category: 'text', @@ -166,7 +156,7 @@ describe( 'addSaveProps', () => { }; it( 'should serialize all styles by default', () => { - const extraProps = addSaveProps( {}, blockSettings, attributes ); + const extraProps = _style.addSaveProps( {}, blockSettings, attributes ); expect( extraProps.style ).toEqual( { background: @@ -183,7 +173,7 @@ describe( 'addSaveProps', () => { const settings = applySkipSerialization( { typography: true, } ); - const extraProps = addSaveProps( {}, settings, attributes ); + const extraProps = _style.addSaveProps( {}, settings, attributes ); expect( extraProps.style ).toEqual( { background: @@ -198,7 +188,7 @@ describe( 'addSaveProps', () => { color: [ 'gradient' ], typography: [ 'textDecoration', 'textTransform' ], } ); - const extraProps = addSaveProps( {}, settings, attributes ); + const extraProps = _style.addSaveProps( {}, settings, attributes ); expect( extraProps.style ).toEqual( { color: '#d92828', diff --git a/packages/block-editor/src/hooks/utils.js b/packages/block-editor/src/hooks/utils.js index 49617013dc1153..cd342af00d1a55 100644 --- a/packages/block-editor/src/hooks/utils.js +++ b/packages/block-editor/src/hooks/utils.js @@ -488,10 +488,10 @@ export function createBlockListBlockFilter( features ) { } if ( - ! hasSupport( props.name ) || // Skip rendering if none of the needed attributes are // set. - ! Object.keys( neededProps ).length + ! Object.keys( neededProps ).length || + ! hasSupport( props.name ) ) { return null; } @@ -543,3 +543,49 @@ export function createBlockListBlockFilter( features ) { withBlockListBlockHooks ); } + +export function createBlockSaveFilter( features ) { + function extraPropsFromHooks( props, name, attributes ) { + return features.reduce( ( accu, feature ) => { + const { hasSupport, attributeKeys = [], addSaveProps } = feature; + + const neededAttributes = {}; + for ( const key of attributeKeys ) { + if ( attributes[ key ] ) { + neededAttributes[ key ] = attributes[ key ]; + } + } + + if ( + // Skip rendering if none of the needed attributes are + // set. + ! Object.keys( neededAttributes ).length || + ! hasSupport( name ) + ) { + return accu; + } + + return addSaveProps( accu, name, neededAttributes ); + }, props ); + } + addFilter( + 'blocks.getSaveContent.extraProps', + 'core/editor/hooks', + extraPropsFromHooks, + 0 + ); + addFilter( + 'blocks.getSaveContent.extraProps', + 'core/editor/hooks', + ( props ) => { + // Previously we had a filter deleting the className if it was an empty + // string. That filter is no longer running, so now we need to delete it + // here. + if ( props.hasOwnProperty( 'className' ) && ! props.className ) { + delete props.className; + } + + return props; + } + ); +}