Skip to content

Commit

Permalink
Fix error when using circlular parent blocks (#66121)
Browse files Browse the repository at this point in the history
Co-authored-by: SH4LIN <sh4lin@git.wordpress.org>
Co-authored-by: youknowriad <youknowriad@git.wordpress.org>
Co-authored-by: t-hamano <wildworks@git.wordpress.org>
Co-authored-by: yuliyan <yuliyan@git.wordpress.org>
  • Loading branch information
5 people authored Oct 16, 2024
1 parent 1f528cc commit 2177aed
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 2 deletions.
22 changes: 20 additions & 2 deletions packages/block-editor/src/store/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -1552,19 +1552,26 @@ export function getTemplateLock( state, rootClientId ) {
* @param {string|Object} blockNameOrType The block type object, e.g., the response
* from the block directory; or a string name of
* an installed block type, e.g.' core/paragraph'.
* @param {Set} checkedBlocks Set of block names that have already been checked.
*
* @return {boolean} Whether the given block type is allowed to be inserted.
*/
const isBlockVisibleInTheInserter = ( state, blockNameOrType ) => {
const isBlockVisibleInTheInserter = (
state,
blockNameOrType,
checkedBlocks = new Set()
) => {
let blockType;
let blockName;

if ( blockNameOrType && 'object' === typeof blockNameOrType ) {
blockType = blockNameOrType;
blockName = blockNameOrType.name;
} else {
blockType = getBlockType( blockNameOrType );
blockName = blockNameOrType;
}

if ( ! blockType ) {
return false;
}
Expand All @@ -1580,11 +1587,22 @@ const isBlockVisibleInTheInserter = ( state, blockNameOrType ) => {
return false;
}

if ( checkedBlocks.has( blockName ) ) {
return false;
}

checkedBlocks.add( blockName );

// If parent blocks are not visible, child blocks should be hidden too.
if ( !! blockType.parent?.length ) {
return blockType.parent.some(
( name ) =>
isBlockVisibleInTheInserter( state, name ) ||
( blockName !== name &&
isBlockVisibleInTheInserter(
state,
name,
checkedBlocks
) ) ||
// Exception for blocks with post-content parent,
// the root level is often consider as "core/post-content".
// This exception should only apply to the post editor ideally though.
Expand Down
9 changes: 9 additions & 0 deletions packages/blocks/src/api/registration.js
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,15 @@ 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'
Expand Down
11 changes: 11 additions & 0 deletions packages/blocks/src/api/test/registration.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,17 @@ describe( 'blocks', () => {
expect( block ).toBeUndefined();
} );

it( 'Should reject blocks with the block name itself as the only parent attribute value', () => {
const block = registerBlockType( 'core/test-block', {
...defaultBlockSettings,
parent: [ 'core/test-block' ],
} );
expect( console ).toHaveWarnedWith(
'Block "core/test-block" cannot be a parent of itself. Please remove the block name from the parent list.'
);
expect( block ).toBeUndefined();
} );

it( 'should reject blocks with uppercase characters', () => {
const block = registerBlockType( 'Core/Paragraph' );
expect( console ).toHaveWarnedWith(
Expand Down

0 comments on commit 2177aed

Please sign in to comment.