Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 25 additions & 11 deletions packages/block-editor/src/components/block-list/block.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -497,7 +503,8 @@ function BlockListBlockProvider( props ) {
getBlockMode,
isSelectionEnabled,
getTemplateLock,
__unstableGetBlockWithoutInnerBlocks,
getBlockWithoutAttributes,
getBlockAttributes,
canRemoveBlock,
canMoveBlock,

Expand All @@ -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;
}

Expand All @@ -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();
Expand All @@ -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,
Expand Down Expand Up @@ -634,7 +639,7 @@ function BlockListBlockProvider( props ) {
isLocked,
canRemove,
canMove,
block,
blockWithoutAttributes,
name,
attributes,
isValid,
Expand Down Expand Up @@ -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 ]
);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason this is better than selector cache is because it's stored by component instance, not globally.


// 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
Expand Down
34 changes: 15 additions & 19 deletions packages/block-editor/src/store/private-selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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 );
};
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After #58349, this is no longer called, so the performance improvement of this PR will be lessened.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably still worth to remove the memoization I think... Also the dependencies of this selector weren't fully correct.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, this selector should also check the editing mode of the top-level clientId, not just its children.

If I look at the only call in BlockListBlockProvider, I see that it's done anyway, checking blockEditingMode === 'disabled' && isBlockSubtreeDisabled().


/**
* Returns a tree of block objects with only clientID and innerBlocks set.
Expand Down