diff --git a/packages/block-editor/src/store/private-selectors.js b/packages/block-editor/src/store/private-selectors.js index d31a710fd94fe3..e8230eea89daa3 100644 --- a/packages/block-editor/src/store/private-selectors.js +++ b/packages/block-editor/src/store/private-selectors.js @@ -15,7 +15,7 @@ import { canInsertBlockType, __experimentalGetAllowedPatterns, } from './selectors'; -import { getUserPatterns, checkAllowListRecursive } from './utils'; +import { getAllPatterns, checkAllowListRecursive } from './utils'; /** * Returns true if the block interface is hidden, or false otherwise. @@ -253,26 +253,20 @@ export const getInserterMediaCategories = createSelector( */ export const hasAllowedPatterns = createSelector( ( state, rootClientId = null ) => { - const patterns = state.settings.__experimentalBlockPatterns; - const userPatterns = getUserPatterns( state ); + const patterns = getAllPatterns( state ); const { allowedBlockTypes } = getSettings( state ); - return [ ...userPatterns, ...patterns ].some( - ( { name, inserter = true } ) => { - if ( ! inserter ) { - return false; - } - const { blocks } = __experimentalGetParsedPattern( - state, - name - ); - return ( - checkAllowListRecursive( blocks, allowedBlockTypes ) && - blocks.every( ( { name: blockName } ) => - canInsertBlockType( state, blockName, rootClientId ) - ) - ); + return patterns.some( ( { name, inserter = true } ) => { + if ( ! inserter ) { + return false; } - ); + const { blocks } = __experimentalGetParsedPattern( state, name ); + return ( + checkAllowListRecursive( blocks, allowedBlockTypes ) && + blocks.every( ( { name: blockName } ) => + canInsertBlockType( state, blockName, rootClientId ) + ) + ); + } ); }, ( state, rootClientId ) => [ ...__experimentalGetAllowedPatterns.getDependants( diff --git a/packages/block-editor/src/store/selectors.js b/packages/block-editor/src/store/selectors.js index 1cf3705454f9bd..5e47e966ef3345 100644 --- a/packages/block-editor/src/store/selectors.js +++ b/packages/block-editor/src/store/selectors.js @@ -27,7 +27,7 @@ import { createRegistrySelector } from '@wordpress/data'; * Internal dependencies */ import { - getUserPatterns, + getAllPatterns, checkAllowListRecursive, checkAllowList, } from './utils'; @@ -2015,7 +2015,7 @@ export const getInserterItems = createSelector( }, ( state, rootClientId ) => [ state.blockListSettings[ rootClientId ], - state.blocks.byClientId, + state.blocks.byClientId.get( rootClientId ), state.blocks.order, state.preferences.insertUsage, state.settings.allowedBlockTypes, @@ -2086,7 +2086,7 @@ export const getBlockTransformItems = createSelector( }, ( state, blocks, rootClientId ) => [ state.blockListSettings[ rootClientId ], - state.blocks.byClientId, + state.blocks.byClientId.get( rootClientId ), state.preferences.insertUsage, state.settings.allowedBlockTypes, state.settings.templateLock, @@ -2118,7 +2118,7 @@ export const hasInserterItems = createSelector( }, ( state, rootClientId ) => [ state.blockListSettings[ rootClientId ], - state.blocks.byClientId, + state.blocks.byClientId.get( rootClientId ), state.settings.allowedBlockTypes, state.settings.templateLock, getReusableBlocks( state ), @@ -2143,18 +2143,20 @@ export const getAllowedBlocks = createSelector( const blockTypes = getBlockTypes().filter( ( blockType ) => canIncludeBlockTypeInInserter( state, blockType, rootClientId ) ); + const hasReusableBlock = canInsertBlockTypeUnmemoized( state, 'core/block', rootClientId ) && getReusableBlocks( state ).length > 0; - return [ - ...blockTypes, - ...( hasReusableBlock ? [ 'core/block' ] : [] ), - ]; + if ( hasReusableBlock ) { + blockTypes.push( 'core/block' ); + } + + return blockTypes; }, ( state, rootClientId ) => [ state.blockListSettings[ rootClientId ], - state.blocks.byClientId, + state.blocks.byClientId.get( rootClientId ), state.settings.allowedBlockTypes, state.settings.templateLock, getReusableBlocks( state ), @@ -2237,21 +2239,10 @@ export const __experimentalGetDirectInsertBlock = createSelector( ] ); -export const __experimentalUserPatternCategories = createSelector( - ( state ) => { - return state?.settings?.__experimentalUserPatternCategories; - }, - ( state ) => [ state.settings.__experimentalUserPatternCategories ] -); - export const __experimentalGetParsedPattern = createSelector( ( state, patternName ) => { - const patterns = state.settings.__experimentalBlockPatterns; - const userPatterns = getUserPatterns( state ); - - const pattern = [ ...patterns, ...userPatterns ].find( - ( { name } ) => name === patternName - ); + const patterns = getAllPatterns( state ); + const pattern = patterns.find( ( { name } ) => name === patternName ); if ( ! pattern ) { return null; } @@ -2262,21 +2253,15 @@ export const __experimentalGetParsedPattern = createSelector( } ), }; }, - ( state ) => [ - state.settings.__experimentalBlockPatterns, - state.settings.__experimentalReusableBlocks, - state?.settings?.__experimentalUserPatternCategories, - ] + ( state ) => [ getAllPatterns( state ) ] ); const getAllAllowedPatterns = createSelector( ( state ) => { - const patterns = state.settings.__experimentalBlockPatterns; - const userPatterns = getUserPatterns( state ); - + const patterns = getAllPatterns( state ); const { allowedBlockTypes } = getSettings( state ); - const parsedPatterns = [ ...userPatterns, ...patterns ] + const parsedPatterns = patterns .filter( ( { inserter = true } ) => !! inserter ) .map( ( { name } ) => __experimentalGetParsedPattern( state, name ) @@ -2286,12 +2271,7 @@ const getAllAllowedPatterns = createSelector( ); return allowedPatterns; }, - ( state ) => [ - state.settings.__experimentalBlockPatterns, - state.settings.__experimentalReusableBlocks, - state.settings.allowedBlockTypes, - state?.settings?.__experimentalUserPatternCategories, - ] + ( state ) => [ getAllPatterns( state ), state.settings.allowedBlockTypes ] ); /** @@ -2315,9 +2295,7 @@ export const __experimentalGetAllowedPatterns = createSelector( return patternsAllowed; }, ( state, rootClientId ) => [ - state.settings.__experimentalBlockPatterns, - state.settings.__experimentalReusableBlocks, - state.settings.allowedBlockTypes, + getAllAllowedPatterns( state ), state.settings.templateLock, state.blockListSettings[ rootClientId ], state.blocks.byClientId.get( rootClientId ), @@ -2566,7 +2544,7 @@ export function __experimentalGetLastBlockAttributeChanges( state ) { * @return {Array} Reusable blocks */ function getReusableBlocks( state ) { - return state?.settings?.__experimentalReusableBlocks ?? EMPTY_ARRAY; + return state.settings.__experimentalReusableBlocks ?? EMPTY_ARRAY; } /** diff --git a/packages/block-editor/src/store/utils.js b/packages/block-editor/src/store/utils.js index 99281f55fcd093..7587dcdf56fd79 100644 --- a/packages/block-editor/src/store/utils.js +++ b/packages/block-editor/src/store/utils.js @@ -1,35 +1,52 @@ +/** + * External dependencies + */ +import createSelector from 'rememo'; + /** * Internal dependencies */ import { INSERTER_PATTERN_TYPES } from '../components/inserter/block-patterns-tab/utils'; -const EMPTY_ARRAY = []; +export const getUserPatterns = createSelector( + ( state ) => { + const userPatterns = state.settings.__experimentalReusableBlocks ?? []; + const userPatternCategories = + state.settings.__experimentalUserPatternCategories ?? []; + return userPatterns.map( ( userPattern ) => { + return { + name: `core/block/${ userPattern.id }`, + id: userPattern.id, + type: INSERTER_PATTERN_TYPES.user, + title: userPattern.title.raw, + categories: userPattern.wp_pattern_category.map( ( catId ) => { + const category = userPatternCategories.find( + ( { id } ) => id === catId + ); + return category ? category.slug : catId; + } ), + content: userPattern.content.raw, + syncStatus: userPattern.wp_pattern_sync_status, + }; + } ); + }, + ( state ) => [ + state.settings.__experimentalReusableBlocks, + state.settings.__experimentalUserPatternCategories, + ] +); -export function getUserPatterns( state ) { - const userPatterns = - state?.settings?.__experimentalReusableBlocks ?? EMPTY_ARRAY; - const userPatternCategories = - state?.settings?.__experimentalUserPatternCategories ?? []; - const categories = new Map(); - userPatternCategories.forEach( ( userCategory ) => - categories.set( userCategory.id, userCategory ) - ); - return userPatterns.map( ( userPattern ) => { - return { - name: `core/block/${ userPattern.id }`, - id: userPattern.id, - type: INSERTER_PATTERN_TYPES.user, - title: userPattern.title.raw, - categories: userPattern.wp_pattern_category.map( ( catId ) => - categories && categories.get( catId ) - ? categories.get( catId ).slug - : catId - ), - content: userPattern.content.raw, - syncStatus: userPattern.wp_pattern_sync_status, - }; - } ); -} +export const getAllPatterns = createSelector( + ( state ) => { + const patterns = state.settings.__experimentalBlockPatterns; + const userPatterns = getUserPatterns( state ); + return [ ...userPatterns, ...patterns ]; + }, + ( state ) => [ + state.settings.__experimentalBlockPatterns, + getUserPatterns( state ), + ] +); export const checkAllowList = ( list, item, defaultResult = null ) => { if ( typeof list === 'boolean' ) {