diff --git a/packages/block-editor/src/components/block-list/block.js b/packages/block-editor/src/components/block-list/block.js index deef2d75386fd..f6dd788e91ba1 100644 --- a/packages/block-editor/src/components/block-list/block.js +++ b/packages/block-editor/src/components/block-list/block.js @@ -6,7 +6,13 @@ import classnames from 'classnames'; /** * WordPress dependencies */ -import { memo, useCallback, RawHTML, useContext } from '@wordpress/element'; +import { + memo, + useCallback, + RawHTML, + useContext, + useMemo, +} from '@wordpress/element'; import { getBlockType, getSaveContent, @@ -497,7 +503,8 @@ function BlockListBlockProvider( props ) { getBlockMode, isSelectionEnabled, getTemplateLock, - __unstableGetBlockWithoutInnerBlocks, + getBlockWithoutAttributes, + getBlockAttributes, canRemoveBlock, canMoveBlock, @@ -524,13 +531,14 @@ function BlockListBlockProvider( props ) { __unstableGetEditorMode, getSelectedBlocksInitialCaretPosition, } = unlock( select( blockEditorStore ) ); - const block = __unstableGetBlockWithoutInnerBlocks( clientId ); + const blockWithoutAttributes = + getBlockWithoutAttributes( clientId ); // This is a temporary fix. // This function should never be called when a block is not // present in the state. It happens now because the order in // withSelect rendering is not correct. - if ( ! block ) { + if ( ! blockWithoutAttributes ) { return; } @@ -542,7 +550,8 @@ function BlockListBlockProvider( props ) { const templateLock = getTemplateLock( rootClientId ); const canRemove = canRemoveBlock( clientId, rootClientId ); const canMove = canMoveBlock( clientId, rootClientId ); - const { name: blockName, attributes, isValid } = block; + const attributes = getBlockAttributes( clientId ); + const { name: blockName, isValid } = blockWithoutAttributes; const blockType = getBlockType( blockName ); const match = getActiveBlockVariation( blockName, attributes ); const { outlineMode, supportsLayout } = getSettings(); @@ -562,11 +571,7 @@ function BlockListBlockProvider( props ) { isLocked: !! templateLock, canRemove, canMove, - // Users of the editor.BlockListBlock filter used to be able to - // access the block prop. - // Ideally these blocks would rely on the clientId prop only. - // This is kept for backward compatibility reasons. - block, + blockWithoutAttributes, name: blockName, attributes, isValid, @@ -634,7 +639,7 @@ function BlockListBlockProvider( props ) { isLocked, canRemove, canMove, - block, + blockWithoutAttributes, name, attributes, isValid, @@ -665,6 +670,15 @@ function BlockListBlockProvider( props ) { defaultClassName, } = selectedProps; + // Users of the editor.BlockListBlock filter used to be able to + // access the block prop. + // Ideally these blocks would rely on the clientId prop only. + // This is kept for backward compatibility reasons. + const block = useMemo( + () => ( { ...blockWithoutAttributes, attributes } ), + [ blockWithoutAttributes, attributes ] + ); + // Block is sometimes not mounted at the right time, causing it be // undefined see issue for more info // https://github.com/WordPress/gutenberg/issues/17013 diff --git a/packages/block-editor/src/components/block-list/block.native.js b/packages/block-editor/src/components/block-list/block.native.js index 1c0de681bd4c2..818fc6e1a9900 100644 --- a/packages/block-editor/src/components/block-list/block.native.js +++ b/packages/block-editor/src/components/block-list/block.native.js @@ -48,6 +48,7 @@ import { store as blockEditorStore } from '../../store'; import { useLayout } from './layout'; import useScrollUponInsertion from './use-scroll-upon-insertion'; import { useSettings } from '../use-settings'; +import { unlock } from '../../lock-unlock'; const EMPTY_ARRAY = []; @@ -418,11 +419,13 @@ const applyWithSelect = withSelect( ( select, { clientId, rootClientId } ) => { getBlockMode, isSelectionEnabled, getTemplateLock, - __unstableGetBlockWithoutInnerBlocks, + getBlockWithoutAttributes, + getBlockAttributes, canRemoveBlock, canMoveBlock, - } = select( blockEditorStore ); - const block = __unstableGetBlockWithoutInnerBlocks( clientId ); + } = unlock( select( blockEditorStore ) ); + const block = getBlockWithoutAttributes( clientId ); + const attributes = getBlockAttributes( clientId ); const isSelected = isBlockSelected( clientId ); const templateLock = getTemplateLock( rootClientId ); const canRemove = canRemoveBlock( clientId, rootClientId ); @@ -432,7 +435,7 @@ const applyWithSelect = withSelect( ( select, { clientId, rootClientId } ) => { // This function should never be called when a block is not present in // the state. It happens now because the order in withSelect rendering // is not correct. - const { name, attributes, isValid } = block || {}; + const { name, isValid } = block || {}; // Do not add new properties here, use `useSelect` instead to avoid // leaking new props to the public API (editor.BlockListBlock filter). diff --git a/packages/block-editor/src/store/private-selectors.js b/packages/block-editor/src/store/private-selectors.js index da32272c8ff23..9c8379a1f84cd 100644 --- a/packages/block-editor/src/store/private-selectors.js +++ b/packages/block-editor/src/store/private-selectors.js @@ -44,6 +44,10 @@ export function getLastInsertedBlocksClientIds( state ) { return state?.lastBlockInserted?.clientIds; } +export function getBlockWithoutAttributes( state, clientId ) { + return state.blocks.byClientId.get( clientId ); +} + /** * Returns true if all of the descendants of a block with the given client ID * have an editing mode of 'disabled', or false otherwise. @@ -53,25 +57,17 @@ export function getLastInsertedBlocksClientIds( state ) { * * @return {boolean} Whether the block descendants are disabled. */ -export const isBlockSubtreeDisabled = createSelector( - ( state, clientId ) => { - const isChildSubtreeDisabled = ( childClientId ) => { - return ( - getBlockEditingMode( state, childClientId ) === 'disabled' && - getBlockOrder( state, childClientId ).every( - isChildSubtreeDisabled - ) - ); - }; - return getBlockOrder( state, clientId ).every( isChildSubtreeDisabled ); - }, - ( state ) => [ - state.blocks.parents, - state.blocks.order, - state.blockEditingModes, - state.blockListSettings, - ] -); +export const isBlockSubtreeDisabled = ( state, clientId ) => { + const isChildSubtreeDisabled = ( childClientId ) => { + return ( + getBlockEditingMode( state, childClientId ) === 'disabled' && + getBlockOrder( state, childClientId ).every( + isChildSubtreeDisabled + ) + ); + }; + return getBlockOrder( state, clientId ).every( isChildSubtreeDisabled ); +}; /** * Returns a tree of block objects with only clientID and innerBlocks set.