Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Blocks: simplify/optimise isUnmodifiedBlock #56919

Merged
merged 2 commits into from
Dec 13, 2023
Merged
Changes from all 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
29 changes: 16 additions & 13 deletions packages/blocks/src/api/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import { RichTextData } from '@wordpress/rich-text';
*/
import { BLOCK_ICON_DEFAULT } from './constants';
import { getBlockType, getDefaultBlockName } from './registration';
import { createBlock } from './factory';

extend( [ namesPlugin, a11yPlugin ] );

Expand All @@ -39,21 +38,25 @@ const ICON_COLORS = [ '#191e23', '#f8f9f9' ];
* @return {boolean} Whether the block is an unmodified block.
*/
export function isUnmodifiedBlock( block ) {
// Cache a created default block if no cache exists or the default block
// name changed.
if ( ! isUnmodifiedBlock[ block.name ] ) {
isUnmodifiedBlock[ block.name ] = createBlock( block.name );
}
return Object.entries( getBlockType( block.name )?.attributes ?? {} ).every(
Copy link
Member

Choose a reason for hiding this comment

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

we're checking the attributes on the block type here, but would it be important to compare also the attributes on this particular block instance that may not be on the block type?

for instance, if I setAttribute('formerlyNotPresentAttribute', true) then I would imagine I have a modified block, but the block type won't have formerlyNotPresentAttribute so it won't show different here

Copy link
Member Author

Choose a reason for hiding this comment

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

We didn't before. And I guess if it's not officially declared, why check?

Copy link
Member

Choose a reason for hiding this comment

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

I missed that in the before code. makes me wonder anyway if it's been a latent bug. no need to make it part of this change.

( [ key, definition ] ) => {
const value = block.attributes[ key ];

const newBlock = isUnmodifiedBlock[ block.name ];
const blockType = getBlockType( block.name );
// Every attribute that has a default must match the default.
if ( definition.hasOwnProperty( 'default' ) ) {
return value === definition.default;
}

function isEqual( a, b ) {
return ( a?.valueOf() ?? a ) === ( b?.valueOf() ?? b );
}
// The rich text type is a bit different from the rest because it
// has an implicit default value of an empty RichTextData instance,
// so check the length of the value.
if ( definition.type === 'rich-text' ) {
return ! value?.length;
}

return Object.keys( blockType?.attributes ?? {} ).every( ( key ) =>
isEqual( newBlock.attributes[ key ], block.attributes[ key ] )
// Every attribute that doesn't have a default should be undefined.
return value === undefined;
}
);
}

Expand Down
Loading