close
Skip to content

Allow isUnmodifiedBlock to bypass certain (unique/autogenerated attributes) #48806

@albanyacademy

Description

@albanyacademy

What problem does this address?

In a nutshell, when using filters [blocks/registerBlockType] and/or [editor.BlockEdit] to automatically generate unique block ids, this indicates to the editor that these blocks are now modified.

I know theres several issues about handling unique attributes within Gutenberg, but this deals with auto-generated attributes specifically.

In my opinion, automatically generated attribute values should be optionally ignored when considering if the block has been modified - what we really care about is user input that modifies the block, not something like an automatically generated block ID. we don't care about knowing whether or not the block ID is generated.

Some of this is partially addressed via __unstableMarkNextChangeAsNotPersistent from a UI perspective, however there's a lot of builtin functionality within the editor that utilizes isUnmodifiedBlock specifically, particularly the block inserter.

On a fresh paragraph block, an inserter appears that allows the user to replace that block with another, as core/paragraph functions as a placeholder.

When adding an autogenerated attribute to core/paragraph - or using it in a custom block that then uses setDefaultBlockName to override core/paragraph - this behaviour stops, and the block has been treated as modified despite the user only just clicking add new post and waiting for the page to load.

What is your proposed solution?

I propose adding a flag to the attribute itself that will tell isUnmodifiedBlock to ignore it.

https://github.com/WordPress/gutenberg/blob/trunk/packages/blocks/src/api/utils.js#L40

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 );
    }

    const newBlock = isUnmodifiedBlock[ block.name ];
    const blockType = getBlockType( block.name );


    return Object.keys( blockType?.attributes ?? {} ).every(
        ( key ) => {
                const attr = blockType.attributes[key];
                if (attr?.ignoreModified === true) {
                    return true;
                }
                return  newBlock.attributes[ key ] === block.attributes[ key ];
        }
    );
}

ignoreModified kinda sucks as a name, but this is the gist of it.

Metadata

Metadata

Assignees

Labels

[Feature] Block APIAPI that allows to express the block paradigm.[Status] In ProgressTracking issues with work in progress[Status] In discussionUsed to indicate that an issue is in the process of being discussed[Type] EnhancementA suggestion for improvement.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions