Skip to content

Commit

Permalink
Simplify logic thanks to changes made in #39985.
Browse files Browse the repository at this point in the history
  • Loading branch information
ZebulanStanphill committed May 4, 2022
1 parent be0659d commit 74dbd1c
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 73 deletions.
64 changes: 21 additions & 43 deletions packages/block-library/src/table-of-contents/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import { addQueryArgs, removeQueryArgs } from '@wordpress/url';
*/
import icon from './icon';
import TableOfContentsList from './list';
import { comparePathAToB, linearToNestedHeadingList } from './utils';
import { linearToNestedHeadingList } from './utils';

/** @typedef {import('./utils').HeadingData} HeadingData */

Expand Down Expand Up @@ -85,11 +85,8 @@ export default function TableOfContentsEdit( {
( select ) => {
const {
getBlockAttributes,
getBlockIndex,
getBlockName,
getBlockOrder,
getBlockParents,
getClientIdsOfDescendants,
getClientIdsWithDescendants,
__experimentalGetGlobalBlocksByName: getGlobalBlocksByName,
} = select( blockEditorStore );

Expand All @@ -105,49 +102,30 @@ export default function TableOfContentsEdit( {

const isPaginated = pageBreakClientIds.length !== 0;

/**
* Get the relative indices of the block from top to bottom nesting
* level.
*
* @param {string} blockClientId
*
* @return {number[]} The path of indices to the block.
*/
function getBlockPath( blockClientId ) {
const indices = getBlockParents(
blockClientId
).map( ( ancestorId ) => getBlockIndex( ancestorId ) );
indices.push( getBlockIndex( blockClientId ) );
return indices;
}

// We can't use just getBlockIndex because it only returns the index relative to sibling blocks, so we have to get all the indices from top to bottom.
const tocPath = getBlockPath( clientId );
// Get the client ids of all blocks in the editor.
const allBlockClientIds = getClientIdsWithDescendants();

// Calculate the page (of a paginated post) this block is part of.
// Note that pageBreakClientIds may not be in the order they appear on
// the page, so we have to iterate over all of them.
let tocPage = 1;
for ( const pageBreakClientId of pageBreakClientIds ) {
if (
comparePathAToB(
tocPath,
getBlockPath( pageBreakClientId )
) < 0
) {
tocPage++;
}
}

// Get the top-level block client ids, and add them and the client ids
// of their children to an ordered list. We don't use
// getClientIdsWithDescendants since it returns ids in the wrong order.
const allBlockClientIds = [];
for ( const blockClientId of getBlockOrder() ) {
allBlockClientIds.push(
if ( isPaginated ) {
// We can't use getBlockIndex because it only returns the index
// relative to sibling blocks.
const tocIndex = allBlockClientIds.indexOf( clientId );

for ( const [
blockIndex,
blockClientId,
...getClientIdsOfDescendants( [ blockClientId ] )
);
] of allBlockClientIds.entries() ) {
// If we've reached blocks after the Table of Contents, we've
// finished calculating which page the block is on.
if ( blockIndex >= tocIndex ) {
break;
}
if ( getBlockName( blockClientId ) === 'core/nextpage' ) {
tocPage++;
}
}
}

const _latestHeadings = [];
Expand Down
30 changes: 0 additions & 30 deletions packages/block-library/src/table-of-contents/utils.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,3 @@
/**
* Determines if the first path of indices leads to an earlier spot
* than the second path.
*
* @param pathA
* @param pathB
* @return Negative: A is before B; positive: A is after B; zero: the paths are identical.
*/
export function comparePathAToB( pathA: number[], pathB: number[] ): number {
let a: number | undefined = 0;
let b: number | undefined = 0;

// To avoid modifying the arrays passed into the function.
const clonedPathA = [ ...pathA ];
const clonedPathB = [ ...pathB ];

do {
a = clonedPathA.shift();
b = clonedPathB.shift();
} while ( a === b && a !== undefined && b !== undefined );

// Defaulting to -1 ensures that if a path terminates before the other, it
// is considered as leading to an earlier global index. This ensures that
// parent blocks are considered as coming before their first child.
// Technically, this isn't needed for the Table of Contents use-case, since
// neither it nor Page Break blocks support children, but it's good to play
// it safe in case this code gets reused elsewhere.
return ( a ?? -1 ) - ( b ?? -1 );
}

export interface HeadingData {
/** The plain text content of the heading. */
content: string;
Expand Down

0 comments on commit 74dbd1c

Please sign in to comment.