Skip to content

Commit

Permalink
Heading: Auto-generated anchors hide implementation details (#35747)
Browse files Browse the repository at this point in the history
  • Loading branch information
Mamaduka authored Oct 25, 2021
1 parent 7ce8867 commit f885488
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 20 deletions.
28 changes: 22 additions & 6 deletions packages/block-library/src/heading/autogenerate-anchors.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@
*/
import { deburr, trim } from 'lodash';

/**
* Object map tracking anchors.
*
* @type {Record<string, string | null>}
*/
const anchors = {};

/**
* Returns the text without markup.
*
Expand Down Expand Up @@ -36,30 +43,39 @@ 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.
if ( '' === slug ) {
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;
};
21 changes: 7 additions & 14 deletions packages/block-library/src/heading/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -54,28 +52,23 @@ 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 ) => {
const newAttrs = { content: value };
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 );
};
Expand Down

0 comments on commit f885488

Please sign in to comment.