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
Block serialization: correctly compare default attribute values #53521
Conversation
"items": { | ||
"type": "object" | ||
} | ||
}, | ||
"default": [] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is just an aesthetic drive-by change. The intent is to consistently declare the default
as the last field. See, for example, the ids
definition that precedes the shortCodeTransforms
one.
Size Change: +3 B (0%) Total Size: 1.5 MB
ℹ️ View Unchanged
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great find @jsnajdr, LGTM 🚀
@@ -238,7 +238,8 @@ export function getCommentAttributes( blockType, attributes ) { | |||
// Ignore default value. | |||
if ( | |||
'default' in attributeSchema && | |||
attributeSchema.default === value | |||
JSON.stringify( attributeSchema.default ) === |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test coverage is there, the test/integration/full-content
suite does almost 300 tests on various block that are all about parsing and serialization.
Good point about the { a, b } === { b, a }
issue. Instead of JSON.stringify
, we could probably use something like fast-deep-equal
that sorts object keys before comparing them.
In practice, however, default attribute values tend to be empty-ish objects, and serialization wants to omit values that haven't been modified at all from the default value. So, pragmatically, the JSON.stringify
solution is likely to be pretty good.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In practice, however, default attribute values tend to be empty-ish objects, and serialization wants to omit values that haven't been modified at all from the default value. So, pragmatically, the
JSON.stringify
solution is likely to be pretty good.
We have an example in the core block (it also applies to its variations, but we override the default value in that case):
gutenberg/packages/block-library/src/query/block.json
Lines 15 to 29 in 1bb7014
"default": { | |
"perPage": null, | |
"pages": 0, | |
"offset": 0, | |
"postType": "post", | |
"order": "desc", | |
"orderBy": "date", | |
"author": "", | |
"search": "", | |
"exclude": [], | |
"sticky": "", | |
"inherit": true, | |
"taxQuery": null, | |
"parents": [] | |
} |
However, it's a common issue that plugins encounter, example:
More details in the following issues:
- Style default attributes for block supports are not respected in dynamic render #52600
- Default attributes for block-support properties don't apply on dynamic blocks #50229
- Default block alignment class is not in get_block_wrapper_attributes #50027
- Dynamic blocks: default values for attributes aren't converted into html comments #7342
Great discover. Thank you for working on the fix. |
Fixes a little bug in block serialization that I accidentally discovered when working on #53470. When a block declares its attributes, in the
block.json
file, it can also supply a default value. The block serialization, then, when an attribute value equals to the default value, will omit that attribute from the serialized form.This doesn't work well when the default value is something like empty array (
[]
). Different empty arrays are not equal to each other,[] !== []
. It's better to compare their serialized forms, i.e., the strings produced byJSON.stringify
. That's what this PR does.How to test:
There are two unit tests, for the Gallery and Video blocks, that are affected by this.