From a65b156238a514a7fc03c3262f7cac4091d38fb5 Mon Sep 17 00:00:00 2001 From: Bernie Reiter <96308+ockham@users.noreply.github.com> Date: Wed, 28 Feb 2024 15:28:29 +0100 Subject: [PATCH] Block Hooks: Display toggle for hooked blocks added via filter (#59396) Show the Block Hooks toggle for hooked blocks that were added via the `hooked_block_types` filter (rather than at block registration time, i.e. via the `blockHooks` field in `block.json`), by evaluating the anchor block's `ignoredHookedBlocks` metadata attribute. (This attribute is only present if the containing template/part/pattern has user modifications.) Co-authored-by: ockham Co-authored-by: gziolo Co-authored-by: michalczaplinski Co-authored-by: sirreal --- .../block-editor/src/hooks/block-hooks.js | 39 +++++++++++++++++-- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/packages/block-editor/src/hooks/block-hooks.js b/packages/block-editor/src/hooks/block-hooks.js index eb84352ab62f0..93bf87f42124b 100644 --- a/packages/block-editor/src/hooks/block-hooks.js +++ b/packages/block-editor/src/hooks/block-hooks.js @@ -19,18 +19,28 @@ import { store as blockEditorStore } from '../store'; const EMPTY_OBJECT = {}; -function BlockHooksControlPure( { name, clientId } ) { +function BlockHooksControlPure( { + name, + clientId, + metadata: { ignoredHookedBlocks = [] } = {}, +} ) { const blockTypes = useSelect( ( select ) => select( blocksStore ).getBlockTypes(), [] ); + // A hooked block added via a filter will not be exposed through a block + // type's `blockHooks` property; however, if the containing layout has been + // modified, it will be present in the anchor block's `ignoredHookedBlocks` + // metadata. const hookedBlocksForCurrentBlock = useMemo( () => blockTypes?.filter( - ( { blockHooks } ) => blockHooks && name in blockHooks + ( { name: blockName, blockHooks } ) => + ( blockHooks && name in blockHooks ) || + ignoredHookedBlocks.includes( blockName ) ), - [ blockTypes, name ] + [ blockTypes, name, ignoredHookedBlocks ] ); const { blockIndex, rootClientId, innerBlocksLength } = useSelect( @@ -79,6 +89,16 @@ function BlockHooksControlPure( { name, clientId } ) { // inserted and then moved around a bit by the user. candidates = getBlocks( clientId ); break; + + case undefined: + // If we haven't found a blockHooks field with a relative position for the hooked + // block, it means that it was added by a filter. In this case, we look for the block + // both among the current block's siblings and its children. + candidates = [ + ...getBlocks( rootClientId ), + ...getBlocks( clientId ), + ]; + break; } const hookedBlock = candidates?.find( @@ -151,6 +171,18 @@ function BlockHooksControlPure( { name, clientId } ) { false ); break; + + case undefined: + // If we do not know the relative position, it is because the block was + // added via a filter. In this case, we default to inserting it after the + // current block. + insertBlock( + block, + blockIndex + 1, + rootClientId, // Insert as a child of the current block's parent + false + ); + break; } }; @@ -219,6 +251,7 @@ function BlockHooksControlPure( { name, clientId } ) { export default { edit: BlockHooksControlPure, + attributeKeys: [ 'metadata' ], hasSupport() { return true; },