diff --git a/packages/block-library/src/heading/autogenerate-anchors.js b/packages/block-library/src/heading/autogenerate-anchors.js index ba8150e6e7e69e..acaee196d9c774 100644 --- a/packages/block-library/src/heading/autogenerate-anchors.js +++ b/packages/block-library/src/heading/autogenerate-anchors.js @@ -3,6 +3,13 @@ */ import { deburr, trim } from 'lodash'; +/** + * Object map tracking anchors. + * + * @type {Record} + */ +const anchors = {}; + /** * Returns the text without markup. * @@ -36,13 +43,12 @@ const getSlug = ( content ) => { /** * Generate the anchor for a heading. * - * @param {string} clientId The block ID. - * @param {string} content The block content. - * @param {string[]} allHeadingAnchors An array containing all headings anchors. + * @param {string} clientId The block ID. + * @param {string} content The block content. * * @return {string|null} Return the heading anchor. */ -export const generateAnchor = ( clientId, content, allHeadingAnchors ) => { +export const generateAnchor = ( clientId, content ) => { const slug = getSlug( content ); // If slug is empty, then return null. // Returning null instead of an empty string allows us to check again when the content changes. @@ -50,16 +56,26 @@ export const generateAnchor = ( clientId, content, allHeadingAnchors ) => { return null; } - delete allHeadingAnchors[ clientId ]; + delete anchors[ clientId ]; let anchor = slug; let i = 0; // If the anchor already exists in another heading, append -i. - while ( Object.values( allHeadingAnchors ).includes( anchor ) ) { + while ( Object.values( anchors ).includes( anchor ) ) { i += 1; anchor = slug + '-' + i; } return anchor; }; + +/** + * Set the anchor for a heading. + * + * @param {string} clientId The block ID. + * @param {string|null} anchor The block anchor. + */ +export const setAnchor = ( clientId, anchor ) => { + anchors[ clientId ] = anchor; +}; diff --git a/packages/block-library/src/heading/edit.js b/packages/block-library/src/heading/edit.js index 4694ccde5a46e5..d093f92c837562 100644 --- a/packages/block-library/src/heading/edit.js +++ b/packages/block-library/src/heading/edit.js @@ -22,9 +22,7 @@ import { * Internal dependencies */ import HeadingLevelDropdown from './heading-level-dropdown'; -import { generateAnchor } from './autogenerate-anchors'; - -const allHeadingAnchors = {}; +import { generateAnchor, setAnchor } from './autogenerate-anchors'; function HeadingEdit( { attributes, @@ -54,14 +52,13 @@ function HeadingEdit( { // This side-effect should not create an undo level. __unstableMarkNextChangeAsNotPersistent(); setAttributes( { - anchor: generateAnchor( clientId, content, allHeadingAnchors ), + anchor: generateAnchor( clientId, content ), } ); } + setAnchor( clientId, anchor ); - allHeadingAnchors[ clientId ] = anchor; - return () => { - delete allHeadingAnchors[ clientId ]; - }; + // Remove anchor map when block unmounts. + return () => setAnchor( clientId, null ); }, [ content, anchor ] ); const onContentChange = ( value ) => { @@ -69,13 +66,9 @@ function HeadingEdit( { if ( ! anchor || ! value || - generateAnchor( clientId, content, allHeadingAnchors ) === anchor + generateAnchor( clientId, content ) === anchor ) { - newAttrs.anchor = generateAnchor( - clientId, - value, - allHeadingAnchors - ); + newAttrs.anchor = generateAnchor( clientId, value ); } setAttributes( newAttrs ); };