From 879bde0401e0152fdbf6089cdfd92856eb3cd6e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Tue, 19 Oct 2021 13:19:23 +0200 Subject: [PATCH 1/2] add new filter called `blocks.cloneBlock` to modify behavior of cloning --- packages/blocks/src/api/factory.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/packages/blocks/src/api/factory.js b/packages/blocks/src/api/factory.js index 4abd12a802f03f..83a23ac47986be 100644 --- a/packages/blocks/src/api/factory.js +++ b/packages/blocks/src/api/factory.js @@ -118,7 +118,14 @@ export function __experimentalCloneSanitizedBlock( } ); - return { + /** + * Filters the cloned block. + * The entire new block object is passed and can be modified + * + * @param {string} blockType block type of the block being transformed. + * @param {Object} block cloned block object + */ + return applyFilters( 'blocks.cloneBlock', block.name, { ...block, clientId, attributes: sanitizedAttributes, @@ -127,7 +134,7 @@ export function __experimentalCloneSanitizedBlock( block.innerBlocks.map( ( innerBlock ) => __experimentalCloneSanitizedBlock( innerBlock ) ), - }; + } ); } /** From 25c3fb2c53f2d4f11d799cfa059242a6daa7b4d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Tue, 19 Oct 2021 13:21:40 +0200 Subject: [PATCH 2/2] use `blocks.cloneBlock` hook to make sure the anchor stays unique --- packages/block-editor/src/hooks/anchor.js | 41 +++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/packages/block-editor/src/hooks/anchor.js b/packages/block-editor/src/hooks/anchor.js index bed166dceb8807..dc8e1396879d1b 100644 --- a/packages/block-editor/src/hooks/anchor.js +++ b/packages/block-editor/src/hooks/anchor.js @@ -153,7 +153,48 @@ export function addSaveProps( extraProps, blockType, attributes ) { return extraProps; } +/** + * Make sure the anchor continues to stay unique when the block is cloned + * + * @param {string} blockType type of the block + * @param {Object} block cloned block object + * @return {Object} modified cloned block object + */ +export function cloneAttribute( blockType, block ) { + if ( + hasBlockSupport( blockType, 'anchor' ) && + has( block, 'attributes.anchor' ) + ) { + // check wether the anchor already ends with a `-${number}` + const index = block.attributes.anchor.lastIndexOf( '-' ); + const result = block.attributes.anchor.substring( index + 1 ); + + // store the anchor without the `-${number}` + const shortendAnchor = + index > 0 + ? block.attributes.anchor.substring( 0, index ) + : block.attributes.anchor; + + // generate the suffix number + let suffix = 1; + if ( result ) { + const number = parseInt( result ); + + if ( number ) { + suffix = number + 1; + } + } + + // add the suffix to the anchor + block.attributes.anchor = `${ shortendAnchor }-${ suffix }`; + } + + // return the modified cloned block + return block; +} + addFilter( 'blocks.registerBlockType', 'core/anchor/attribute', addAttribute ); +addFilter( 'blocks.cloneBlock', 'core/anchor/clone', cloneAttribute ); addFilter( 'editor.BlockEdit', 'core/editor/anchor/with-inspector-control',