From 39b665d00724155d6bc0370cf22fe4480b90707a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Thu, 24 Oct 2024 11:29:07 +0200 Subject: [PATCH] Block registration: normalize blockType.parent to `array` (#66250) Co-authored-by: oandregal Co-authored-by: ntsekouras Co-authored-by: mcsf --- packages/block-editor/src/store/selectors.js | 14 ++------ packages/blocks/CHANGELOG.md | 4 +++ packages/blocks/src/api/registration.js | 9 ----- packages/blocks/src/api/test/registration.js | 33 +++++++++++++++++ .../blocks/src/store/process-block-type.js | 36 +++++++++++++++++++ 5 files changed, 75 insertions(+), 21 deletions(-) diff --git a/packages/block-editor/src/store/selectors.js b/packages/block-editor/src/store/selectors.js index 787225f18a0a57..b5afb2891ef1cf 100644 --- a/packages/block-editor/src/store/selectors.js +++ b/packages/block-editor/src/store/selectors.js @@ -1628,18 +1628,8 @@ const isBlockVisibleInTheInserter = ( checkedBlocks.add( blockName ); // If parent blocks are not visible, child blocks should be hidden too. - // - // In some scenarios, blockType.parent may be a string. - // A better approach would be sanitize parent in all the places that can be modified: - // block registration, processBlockType, filters, etc. - // In the meantime, this is a hotfix to prevent the editor from crashing. - const parent = - typeof blockType.parent === 'string' || - blockType.parent instanceof String - ? [ blockType.parent ] - : blockType.parent; - if ( Array.isArray( parent ) ) { - return parent.some( + if ( Array.isArray( blockType.parent ) ) { + return blockType.parent.some( ( name ) => ( blockName !== name && isBlockVisibleInTheInserter( diff --git a/packages/blocks/CHANGELOG.md b/packages/blocks/CHANGELOG.md index 73a700428674b2..eebbe7148e8055 100644 --- a/packages/blocks/CHANGELOG.md +++ b/packages/blocks/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +### Breaking changes + +- Normalize `blockType.parent` to be an array. While string values were never supported, they appeared to work with some unintended side-effects that have been fixed by [#66250](https://github.com/WordPress/gutenberg/pull/66250). For that reason, we've added some code that automatically migrates strings to arrays — though it still raises a warning. + ## 13.10.0 (2024-10-16) ## 13.9.0 (2024-10-03) diff --git a/packages/blocks/src/api/registration.js b/packages/blocks/src/api/registration.js index ef1b6bd20a4cdd..2f4bab2b5f2589 100644 --- a/packages/blocks/src/api/registration.js +++ b/packages/blocks/src/api/registration.js @@ -232,15 +232,6 @@ export function registerBlockType( blockNameOrMetadata, settings ) { return; } - if ( 1 === settings?.parent?.length && name === settings.parent[ 0 ] ) { - warning( - 'Block "' + - name + - '" cannot be a parent of itself. Please remove the block name from the parent list.' - ); - return; - } - if ( ! /^[a-z][a-z0-9-]*\/[a-z][a-z0-9-]*$/.test( name ) ) { warning( 'Block names must contain a namespace prefix, include only lowercase alphanumeric characters or dashes, and start with a letter. Example: my-plugin/my-custom-block' diff --git a/packages/blocks/src/api/test/registration.js b/packages/blocks/src/api/test/registration.js index 656e9471a541b8..5941415e61fe55 100644 --- a/packages/blocks/src/api/test/registration.js +++ b/packages/blocks/src/api/test/registration.js @@ -742,6 +742,39 @@ describe( 'blocks', () => { } ); } ); + it( 'should transform parent string to array', () => { + const blockType = { + save: noop, + category: 'text', + title: 'block title', + parent: 'core/paragraph', + }; + const block = registerBlockType( + 'core/test-block-parent-string', + blockType + ); + expect( console ).toHaveWarnedWith( + 'Parent must be undefined or an array of strings (block types), but it is a string.' + ); + expect( block ).toEqual( { + name: 'core/test-block-parent-string', + save: noop, + category: 'text', + title: 'block title', + icon: { src: BLOCK_ICON_DEFAULT }, + attributes: {}, + providesContext: {}, + usesContext: [], + keywords: [], + selectors: {}, + supports: {}, + styles: [], + variations: [], + blockHooks: {}, + parent: [ 'core/paragraph' ], + } ); + } ); + describe( 'applyFilters', () => { afterEach( () => { removeAllFilters( 'blocks.registerBlockType' ); diff --git a/packages/blocks/src/store/process-block-type.js b/packages/blocks/src/store/process-block-type.js index ae8f92f84cfabb..bc7b1a0e10e774 100644 --- a/packages/blocks/src/store/process-block-type.js +++ b/packages/blocks/src/store/process-block-type.js @@ -197,5 +197,41 @@ export const processBlockType = return; } + if ( + typeof settings?.parent === 'string' || + settings?.parent instanceof String + ) { + settings.parent = [ settings.parent ]; + warning( + 'Parent must be undefined or an array of strings (block types), but it is a string.' + ); + // Intentionally continue: + // + // While string values were never supported, they appeared to work with some unintended side-effects + // that have been fixed by [#66250](https://github.com/WordPress/gutenberg/pull/66250). + // + // To be backwards-compatible, this code that automatically migrates strings to arrays. + } + + if ( + ! Array.isArray( settings?.parent ) && + settings?.parent !== undefined + ) { + warning( + 'Parent must be undefined or an array of block types, but it is ', + settings.parent + ); + return; + } + + if ( 1 === settings?.parent?.length && name === settings.parent[ 0 ] ) { + warning( + 'Block "' + + name + + '" cannot be a parent of itself. Please remove the block name from the parent list.' + ); + return; + } + return settings; };