diff --git a/docs/reference-guides/data/data-core-block-editor.md b/docs/reference-guides/data/data-core-block-editor.md index b03e905d166bc..eaffc0a875ca3 100644 --- a/docs/reference-guides/data/data-core-block-editor.md +++ b/docs/reference-guides/data/data-core-block-editor.md @@ -486,7 +486,7 @@ Returns an array containing the clientIds of all descendants of the blocks given _Parameters_ - _state_ `Object`: Global application state. -- _clientIds_ `string|string[]`: Client ID(s) for which descendant blocks are to be returned. +- _rootIds_ `string|string[]`: Client ID(s) for which descendant blocks are to be returned. _Returns_ diff --git a/packages/block-editor/src/store/selectors.js b/packages/block-editor/src/store/selectors.js index 099c6b30222ef..5aabfca4aa22f 100644 --- a/packages/block-editor/src/store/selectors.js +++ b/packages/block-editor/src/store/selectors.js @@ -251,24 +251,33 @@ export const __unstableGetClientIdsTree = createSelector( * given. Returned ids are ordered first by the order of the ids given, then * by the order that they appear in the editor. * - * @param {Object} state Global application state. - * @param {string|string[]} clientIds Client ID(s) for which descendant blocks are to be returned. + * @param {Object} state Global application state. + * @param {string|string[]} rootIds Client ID(s) for which descendant blocks are to be returned. * * @return {Array} Client IDs of descendants. */ export const getClientIdsOfDescendants = createSelector( - ( state, clientIds ) => { - const givenIds = Array.isArray( clientIds ) ? clientIds : [ clientIds ]; - const collectedIds = []; - for ( const givenId of givenIds ) { - for ( const descendantId of getBlockOrder( state, givenId ) ) { - collectedIds.push( - descendantId, - ...getClientIdsOfDescendants( state, descendantId ) - ); + ( state, rootIds ) => { + rootIds = Array.isArray( rootIds ) ? [ ...rootIds ] : [ rootIds ]; + const ids = []; + + // Add the descendants of the root blocks first. + for ( const rootId of rootIds ) { + const order = state.blocks.order.get( rootId ); + if ( order ) { + ids.push( ...order ); + } + } + + // Add the descendants of the descendants, recursively. + for ( const id of ids ) { + const order = state.blocks.order.get( id ); + if ( order ) { + ids.push( ...order ); } } - return collectedIds; + + return ids; }, ( state ) => [ state.blocks.order ] ); @@ -282,19 +291,8 @@ export const getClientIdsOfDescendants = createSelector( * * @return {Array} ids of top-level and descendant blocks. */ -export const getClientIdsWithDescendants = createSelector( - ( state ) => { - const collectedIds = []; - for ( const topLevelId of getBlockOrder( state ) ) { - collectedIds.push( - topLevelId, - ...getClientIdsOfDescendants( state, topLevelId ) - ); - } - return collectedIds; - }, - ( state ) => [ state.blocks.order ] -); +export const getClientIdsWithDescendants = ( state ) => + getClientIdsOfDescendants( state, '' ); /** * Returns the total number of blocks, or the total number of blocks with a specific name in a post. @@ -311,10 +309,14 @@ export const getGlobalBlockCount = createSelector( if ( ! blockName ) { return clientIds.length; } - return clientIds.reduce( ( accumulator, clientId ) => { + let count = 0; + for ( const clientId of clientIds ) { const block = state.blocks.byClientId.get( clientId ); - return block.name === blockName ? accumulator + 1 : accumulator; - }, 0 ); + if ( block.name === blockName ) { + count++; + } + } + return count; }, ( state ) => [ state.blocks.order, state.blocks.byClientId ] );