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

Fix: duplicate markup on anchor attribute #48438

Closed
wants to merge 9 commits into from

Conversation

t-hamano
Copy link
Contributor

@t-hamano t-hamano commented Feb 25, 2023

Fixes: #48232
Fixes: #49382
Fixes: #49578

Related to: #44771
Alternative to #48246

What?

This PR fixes a problem that id attribute is saved to both the comment delimiter and markup in blocks that support anchor attribute. This will prevent block validation from breaking blocks that previously stored the id attribute only in the markup.

Why?

In #44771, dynamic blocks now support the anchor. The server registers the anchor attribute for all blocks that support the anchor in the register_attributes callback function. The attribute then has only a type property of type string.

However, previous blocks that supported the anchor read the id attribute from the markup and don't store the value in the comment delimiter. If the anchor attribute is already registered on the server side, it will take precedence, so its definition will be different from the conventional attributes.

As a result, I think the difference in the definition of this property caused the generation of incorrect markup, the anchor attribute as an unnecessary comment delimiter, and the failure of block validation as reported in #48232.

I think we need to separate the definition of the anchor property between blocks that save the id attribute as markup and those that don't save any markup in the save function, as many dynamic blocks do.

How?

On the server side, we don't know whether the block saves the id attribute as markup, i.e., whether the save function returns null or not. Therefore, I have decided NOT to register the anchor attribute on the server side, but to check the rendering result of the save function on the client side and register the anchor attribute with an appropriate definition according to the result.

Testing Instructions

The addition of server-side anchor support has already been incorporated into the core, so comment out the following line:

https://github.com/WordPress/wordpress-develop/blob/7d8b5e89bc8b980e74eb7ba39b10ba68d52da7b4/src/wp-includes/block-supports/anchor.php#L70
(@edit: In #48592, anchor support in core blocks has been reverted. Therefore, the above is not necessary.)

Confirm that anchor attributes are saved and rendered as expected in the following two types of blocks.

Blocks that have a save function

Blocks with anchor property true or "html"

  • As before, the id attribute should be saved as part of the markup and not in the comment delimiter.

Blocks that don't have a save function or return null

Blocks with anchor property delimiter

  • The anchor attribute should be saved in the comment delimiter.
  • Blocks rendered server-side by the ServerSideRender component should not cause errors when the anchor attribute is set.

@github-actions
Copy link

github-actions bot commented Feb 25, 2023

Size Change: +185 B (0%)

Total Size: 1.39 MB

Filename Size Change
build/block-editor/index.min.js 195 kB +74 B (0%)
build/block-library/index.min.js 201 kB +96 B (0%)
build/server-side-render/index.min.js 2.04 kB +15 B (+1%)
ℹ️ View Unchanged
Filename Size
build/a11y/index.min.js 955 B
build/annotations/index.min.js 2.69 kB
build/api-fetch/index.min.js 2.28 kB
build/autop/index.min.js 2.1 kB
build/blob/index.min.js 451 B
build/block-directory/index.min.js 7.05 kB
build/block-directory/style-rtl.css 1.02 kB
build/block-directory/style.css 1.02 kB
build/block-editor/content-rtl.css 4.22 kB
build/block-editor/content.css 4.22 kB
build/block-editor/default-editor-styles-rtl.css 381 B
build/block-editor/default-editor-styles.css 381 B
build/block-editor/style-rtl.css 14.9 kB
build/block-editor/style.css 14.9 kB
build/block-library/blocks/archives/editor-rtl.css 61 B
build/block-library/blocks/archives/editor.css 60 B
build/block-library/blocks/archives/style-rtl.css 90 B
build/block-library/blocks/archives/style.css 90 B
build/block-library/blocks/audio/editor-rtl.css 150 B
build/block-library/blocks/audio/editor.css 150 B
build/block-library/blocks/audio/style-rtl.css 122 B
build/block-library/blocks/audio/style.css 122 B
build/block-library/blocks/audio/theme-rtl.css 126 B
build/block-library/blocks/audio/theme.css 126 B
build/block-library/blocks/avatar/editor-rtl.css 116 B
build/block-library/blocks/avatar/editor.css 116 B
build/block-library/blocks/avatar/style-rtl.css 91 B
build/block-library/blocks/avatar/style.css 91 B
build/block-library/blocks/block/editor-rtl.css 305 B
build/block-library/blocks/block/editor.css 305 B
build/block-library/blocks/button/editor-rtl.css 584 B
build/block-library/blocks/button/editor.css 582 B
build/block-library/blocks/button/style-rtl.css 624 B
build/block-library/blocks/button/style.css 623 B
build/block-library/blocks/buttons/editor-rtl.css 337 B
build/block-library/blocks/buttons/editor.css 337 B
build/block-library/blocks/buttons/style-rtl.css 332 B
build/block-library/blocks/buttons/style.css 332 B
build/block-library/blocks/calendar/style-rtl.css 239 B
build/block-library/blocks/calendar/style.css 239 B
build/block-library/blocks/categories/editor-rtl.css 113 B
build/block-library/blocks/categories/editor.css 112 B
build/block-library/blocks/categories/style-rtl.css 124 B
build/block-library/blocks/categories/style.css 124 B
build/block-library/blocks/code/editor-rtl.css 53 B
build/block-library/blocks/code/editor.css 53 B
build/block-library/blocks/code/style-rtl.css 121 B
build/block-library/blocks/code/style.css 121 B
build/block-library/blocks/code/theme-rtl.css 124 B
build/block-library/blocks/code/theme.css 124 B
build/block-library/blocks/columns/editor-rtl.css 108 B
build/block-library/blocks/columns/editor.css 108 B
build/block-library/blocks/columns/style-rtl.css 409 B
build/block-library/blocks/columns/style.css 409 B
build/block-library/blocks/comment-author-avatar/editor-rtl.css 125 B
build/block-library/blocks/comment-author-avatar/editor.css 125 B
build/block-library/blocks/comment-content/style-rtl.css 92 B
build/block-library/blocks/comment-content/style.css 92 B
build/block-library/blocks/comment-template/style-rtl.css 199 B
build/block-library/blocks/comment-template/style.css 198 B
build/block-library/blocks/comments-pagination-numbers/editor-rtl.css 123 B
build/block-library/blocks/comments-pagination-numbers/editor.css 121 B
build/block-library/blocks/comments-pagination/editor-rtl.css 222 B
build/block-library/blocks/comments-pagination/editor.css 209 B
build/block-library/blocks/comments-pagination/style-rtl.css 235 B
build/block-library/blocks/comments-pagination/style.css 231 B
build/block-library/blocks/comments-title/editor-rtl.css 75 B
build/block-library/blocks/comments-title/editor.css 75 B
build/block-library/blocks/comments/editor-rtl.css 840 B
build/block-library/blocks/comments/editor.css 839 B
build/block-library/blocks/comments/style-rtl.css 637 B
build/block-library/blocks/comments/style.css 636 B
build/block-library/blocks/cover/editor-rtl.css 647 B
build/block-library/blocks/cover/editor.css 650 B
build/block-library/blocks/cover/style-rtl.css 1.61 kB
build/block-library/blocks/cover/style.css 1.6 kB
build/block-library/blocks/details/editor-rtl.css 65 B
build/block-library/blocks/details/editor.css 65 B
build/block-library/blocks/details/style-rtl.css 159 B
build/block-library/blocks/details/style.css 159 B
build/block-library/blocks/embed/editor-rtl.css 293 B
build/block-library/blocks/embed/editor.css 293 B
build/block-library/blocks/embed/style-rtl.css 410 B
build/block-library/blocks/embed/style.css 410 B
build/block-library/blocks/embed/theme-rtl.css 126 B
build/block-library/blocks/embed/theme.css 126 B
build/block-library/blocks/file/editor-rtl.css 316 B
build/block-library/blocks/file/editor.css 316 B
build/block-library/blocks/file/interactivity.min.js 395 B
build/block-library/blocks/file/style-rtl.css 269 B
build/block-library/blocks/file/style.css 270 B
build/block-library/blocks/file/view.min.js 375 B
build/block-library/blocks/freeform/editor-rtl.css 2.58 kB
build/block-library/blocks/freeform/editor.css 2.58 kB
build/block-library/blocks/gallery/editor-rtl.css 947 B
build/block-library/blocks/gallery/editor.css 952 B
build/block-library/blocks/gallery/style-rtl.css 1.53 kB
build/block-library/blocks/gallery/style.css 1.53 kB
build/block-library/blocks/gallery/theme-rtl.css 108 B
build/block-library/blocks/gallery/theme.css 108 B
build/block-library/blocks/group/editor-rtl.css 654 B
build/block-library/blocks/group/editor.css 654 B
build/block-library/blocks/group/style-rtl.css 57 B
build/block-library/blocks/group/style.css 57 B
build/block-library/blocks/group/theme-rtl.css 78 B
build/block-library/blocks/group/theme.css 78 B
build/block-library/blocks/heading/style-rtl.css 76 B
build/block-library/blocks/heading/style.css 76 B
build/block-library/blocks/html/editor-rtl.css 336 B
build/block-library/blocks/html/editor.css 337 B
build/block-library/blocks/image/editor-rtl.css 834 B
build/block-library/blocks/image/editor.css 833 B
build/block-library/blocks/image/interactivity.min.js 783 B
build/block-library/blocks/image/style-rtl.css 1.07 kB
build/block-library/blocks/image/style.css 1.07 kB
build/block-library/blocks/image/theme-rtl.css 126 B
build/block-library/blocks/image/theme.css 126 B
build/block-library/blocks/latest-comments/style-rtl.css 357 B
build/block-library/blocks/latest-comments/style.css 357 B
build/block-library/blocks/latest-posts/editor-rtl.css 213 B
build/block-library/blocks/latest-posts/editor.css 212 B
build/block-library/blocks/latest-posts/style-rtl.css 478 B
build/block-library/blocks/latest-posts/style.css 478 B
build/block-library/blocks/list/style-rtl.css 88 B
build/block-library/blocks/list/style.css 88 B
build/block-library/blocks/media-text/editor-rtl.css 266 B
build/block-library/blocks/media-text/editor.css 263 B
build/block-library/blocks/media-text/style-rtl.css 507 B
build/block-library/blocks/media-text/style.css 505 B
build/block-library/blocks/more/editor-rtl.css 431 B
build/block-library/blocks/more/editor.css 431 B
build/block-library/blocks/navigation-link/editor-rtl.css 712 B
build/block-library/blocks/navigation-link/editor.css 711 B
build/block-library/blocks/navigation-link/style-rtl.css 115 B
build/block-library/blocks/navigation-link/style.css 115 B
build/block-library/blocks/navigation-submenu/editor-rtl.css 296 B
build/block-library/blocks/navigation-submenu/editor.css 295 B
build/block-library/blocks/navigation/editor-rtl.css 2.35 kB
build/block-library/blocks/navigation/editor.css 2.36 kB
build/block-library/blocks/navigation/interactivity.min.js 976 B
build/block-library/blocks/navigation/style-rtl.css 2.21 kB
build/block-library/blocks/navigation/style.css 2.2 kB
build/block-library/blocks/navigation/view-modal.min.js 2.78 kB
build/block-library/blocks/navigation/view.min.js 438 B
build/block-library/blocks/nextpage/editor-rtl.css 395 B
build/block-library/blocks/nextpage/editor.css 395 B
build/block-library/blocks/page-list/editor-rtl.css 401 B
build/block-library/blocks/page-list/editor.css 401 B
build/block-library/blocks/page-list/style-rtl.css 175 B
build/block-library/blocks/page-list/style.css 175 B
build/block-library/blocks/paragraph/editor-rtl.css 174 B
build/block-library/blocks/paragraph/editor.css 174 B
build/block-library/blocks/paragraph/style-rtl.css 279 B
build/block-library/blocks/paragraph/style.css 281 B
build/block-library/blocks/post-author/style-rtl.css 175 B
build/block-library/blocks/post-author/style.css 176 B
build/block-library/blocks/post-comments-form/editor-rtl.css 96 B
build/block-library/blocks/post-comments-form/editor.css 96 B
build/block-library/blocks/post-comments-form/style-rtl.css 508 B
build/block-library/blocks/post-comments-form/style.css 508 B
build/block-library/blocks/post-date/style-rtl.css 61 B
build/block-library/blocks/post-date/style.css 61 B
build/block-library/blocks/post-excerpt/editor-rtl.css 71 B
build/block-library/blocks/post-excerpt/editor.css 71 B
build/block-library/blocks/post-excerpt/style-rtl.css 141 B
build/block-library/blocks/post-excerpt/style.css 141 B
build/block-library/blocks/post-featured-image/editor-rtl.css 588 B
build/block-library/blocks/post-featured-image/editor.css 586 B
build/block-library/blocks/post-featured-image/style-rtl.css 319 B
build/block-library/blocks/post-featured-image/style.css 319 B
build/block-library/blocks/post-navigation-link/style-rtl.css 153 B
build/block-library/blocks/post-navigation-link/style.css 153 B
build/block-library/blocks/post-template/editor-rtl.css 99 B
build/block-library/blocks/post-template/editor.css 98 B
build/block-library/blocks/post-template/style-rtl.css 314 B
build/block-library/blocks/post-template/style.css 314 B
build/block-library/blocks/post-terms/style-rtl.css 96 B
build/block-library/blocks/post-terms/style.css 96 B
build/block-library/blocks/post-time-to-read/style-rtl.css 69 B
build/block-library/blocks/post-time-to-read/style.css 69 B
build/block-library/blocks/post-title/style-rtl.css 100 B
build/block-library/blocks/post-title/style.css 100 B
build/block-library/blocks/preformatted/style-rtl.css 103 B
build/block-library/blocks/preformatted/style.css 103 B
build/block-library/blocks/pullquote/editor-rtl.css 135 B
build/block-library/blocks/pullquote/editor.css 135 B
build/block-library/blocks/pullquote/style-rtl.css 335 B
build/block-library/blocks/pullquote/style.css 335 B
build/block-library/blocks/pullquote/theme-rtl.css 167 B
build/block-library/blocks/pullquote/theme.css 167 B
build/block-library/blocks/query-pagination-numbers/editor-rtl.css 122 B
build/block-library/blocks/query-pagination-numbers/editor.css 121 B
build/block-library/blocks/query-pagination/editor-rtl.css 221 B
build/block-library/blocks/query-pagination/editor.css 211 B
build/block-library/blocks/query-pagination/style-rtl.css 288 B
build/block-library/blocks/query-pagination/style.css 284 B
build/block-library/blocks/query-title/style-rtl.css 63 B
build/block-library/blocks/query-title/style.css 63 B
build/block-library/blocks/query/editor-rtl.css 450 B
build/block-library/blocks/query/editor.css 449 B
build/block-library/blocks/quote/style-rtl.css 222 B
build/block-library/blocks/quote/style.css 222 B
build/block-library/blocks/quote/theme-rtl.css 223 B
build/block-library/blocks/quote/theme.css 226 B
build/block-library/blocks/read-more/style-rtl.css 132 B
build/block-library/blocks/read-more/style.css 132 B
build/block-library/blocks/rss/editor-rtl.css 149 B
build/block-library/blocks/rss/editor.css 149 B
build/block-library/blocks/rss/style-rtl.css 289 B
build/block-library/blocks/rss/style.css 288 B
build/block-library/blocks/search/editor-rtl.css 178 B
build/block-library/blocks/search/editor.css 178 B
build/block-library/blocks/search/style-rtl.css 434 B
build/block-library/blocks/search/style.css 432 B
build/block-library/blocks/search/theme-rtl.css 114 B
build/block-library/blocks/search/theme.css 114 B
build/block-library/blocks/separator/editor-rtl.css 146 B
build/block-library/blocks/separator/editor.css 146 B
build/block-library/blocks/separator/style-rtl.css 234 B
build/block-library/blocks/separator/style.css 234 B
build/block-library/blocks/separator/theme-rtl.css 194 B
build/block-library/blocks/separator/theme.css 194 B
build/block-library/blocks/shortcode/editor-rtl.css 323 B
build/block-library/blocks/shortcode/editor.css 323 B
build/block-library/blocks/site-logo/editor-rtl.css 754 B
build/block-library/blocks/site-logo/editor.css 754 B
build/block-library/blocks/site-logo/style-rtl.css 203 B
build/block-library/blocks/site-logo/style.css 203 B
build/block-library/blocks/site-tagline/editor-rtl.css 86 B
build/block-library/blocks/site-tagline/editor.css 86 B
build/block-library/blocks/site-title/editor-rtl.css 116 B
build/block-library/blocks/site-title/editor.css 116 B
build/block-library/blocks/site-title/style-rtl.css 57 B
build/block-library/blocks/site-title/style.css 57 B
build/block-library/blocks/social-link/editor-rtl.css 184 B
build/block-library/blocks/social-link/editor.css 184 B
build/block-library/blocks/social-links/editor-rtl.css 674 B
build/block-library/blocks/social-links/editor.css 673 B
build/block-library/blocks/social-links/style-rtl.css 1.4 kB
build/block-library/blocks/social-links/style.css 1.39 kB
build/block-library/blocks/spacer/editor-rtl.css 348 B
build/block-library/blocks/spacer/editor.css 348 B
build/block-library/blocks/spacer/style-rtl.css 48 B
build/block-library/blocks/spacer/style.css 48 B
build/block-library/blocks/table/editor-rtl.css 433 B
build/block-library/blocks/table/editor.css 433 B
build/block-library/blocks/table/style-rtl.css 645 B
build/block-library/blocks/table/style.css 644 B
build/block-library/blocks/table/theme-rtl.css 146 B
build/block-library/blocks/table/theme.css 146 B
build/block-library/blocks/tag-cloud/style-rtl.css 251 B
build/block-library/blocks/tag-cloud/style.css 253 B
build/block-library/blocks/template-part/editor-rtl.css 403 B
build/block-library/blocks/template-part/editor.css 403 B
build/block-library/blocks/template-part/theme-rtl.css 101 B
build/block-library/blocks/template-part/theme.css 101 B
build/block-library/blocks/term-description/style-rtl.css 111 B
build/block-library/blocks/term-description/style.css 111 B
build/block-library/blocks/text-columns/editor-rtl.css 95 B
build/block-library/blocks/text-columns/editor.css 95 B
build/block-library/blocks/text-columns/style-rtl.css 166 B
build/block-library/blocks/text-columns/style.css 166 B
build/block-library/blocks/verse/style-rtl.css 99 B
build/block-library/blocks/verse/style.css 99 B
build/block-library/blocks/video/editor-rtl.css 552 B
build/block-library/blocks/video/editor.css 555 B
build/block-library/blocks/video/style-rtl.css 174 B
build/block-library/blocks/video/style.css 174 B
build/block-library/blocks/video/theme-rtl.css 126 B
build/block-library/blocks/video/theme.css 126 B
build/block-library/classic-rtl.css 179 B
build/block-library/classic.css 179 B
build/block-library/common-rtl.css 1.1 kB
build/block-library/common.css 1.1 kB
build/block-library/editor-elements-rtl.css 75 B
build/block-library/editor-elements.css 75 B
build/block-library/editor-rtl.css 12.2 kB
build/block-library/editor.css 12.1 kB
build/block-library/elements-rtl.css 54 B
build/block-library/elements.css 54 B
build/block-library/interactivity/runtime.min.js 2.71 kB
build/block-library/interactivity/vendors.min.js 8.2 kB
build/block-library/reset-rtl.css 478 B
build/block-library/reset.css 478 B
build/block-library/style-rtl.css 13.1 kB
build/block-library/style.css 13.1 kB
build/block-library/theme-rtl.css 686 B
build/block-library/theme.css 691 B
build/block-serialization-default-parser/index.min.js 1.12 kB
build/block-serialization-spec-parser/index.min.js 2.87 kB
build/blocks/index.min.js 50.3 kB
build/commands/index.min.js 14.9 kB
build/commands/style-rtl.css 827 B
build/commands/style.css 827 B
build/components/index.min.js 231 kB
build/components/style-rtl.css 11.8 kB
build/components/style.css 11.8 kB
build/compose/index.min.js 12.1 kB
build/core-commands/index.min.js 1.74 kB
build/core-data/index.min.js 15.7 kB
build/customize-widgets/index.min.js 12 kB
build/customize-widgets/style-rtl.css 1.38 kB
build/customize-widgets/style.css 1.38 kB
build/data-controls/index.min.js 640 B
build/data/index.min.js 8.23 kB
build/date/index.min.js 40.4 kB
build/deprecated/index.min.js 451 B
build/dom-ready/index.min.js 324 B
build/dom/index.min.js 4.63 kB
build/edit-post/classic-rtl.css 544 B
build/edit-post/classic.css 545 B
build/edit-post/index.min.js 33.8 kB
build/edit-post/style-rtl.css 7.57 kB
build/edit-post/style.css 7.56 kB
build/edit-site/index.min.js 67.3 kB
build/edit-site/style-rtl.css 11 kB
build/edit-site/style.css 11 kB
build/edit-widgets/index.min.js 16.8 kB
build/edit-widgets/style-rtl.css 4.53 kB
build/edit-widgets/style.css 4.53 kB
build/editor/index.min.js 44.6 kB
build/editor/style-rtl.css 3.54 kB
build/editor/style.css 3.53 kB
build/element/index.min.js 4.8 kB
build/escape-html/index.min.js 537 B
build/format-library/index.min.js 7.57 kB
build/format-library/style-rtl.css 554 B
build/format-library/style.css 553 B
build/hooks/index.min.js 1.55 kB
build/html-entities/index.min.js 448 B
build/i18n/index.min.js 3.58 kB
build/is-shallow-equal/index.min.js 527 B
build/keyboard-shortcuts/index.min.js 1.71 kB
build/keycodes/index.min.js 1.84 kB
build/list-reusable-blocks/index.min.js 2.13 kB
build/list-reusable-blocks/style-rtl.css 836 B
build/list-reusable-blocks/style.css 836 B
build/media-utils/index.min.js 2.9 kB
build/notices/index.min.js 948 B
build/plugins/index.min.js 1.84 kB
build/preferences-persistence/index.min.js 1.84 kB
build/preferences/index.min.js 1.24 kB
build/primitives/index.min.js 941 B
build/priority-queue/index.min.js 1.52 kB
build/private-apis/index.min.js 939 B
build/react-i18n/index.min.js 696 B
build/react-refresh-entry/index.min.js 8.44 kB
build/react-refresh-runtime/index.min.js 7.31 kB
build/redux-routine/index.min.js 2.7 kB
build/reusable-blocks/index.min.js 2.21 kB
build/reusable-blocks/style-rtl.css 243 B
build/reusable-blocks/style.css 243 B
build/rich-text/index.min.js 10.7 kB
build/router/index.min.js 1.77 kB
build/shortcode/index.min.js 1.39 kB
build/style-engine/index.min.js 1.42 kB
build/token-list/index.min.js 582 B
build/url/index.min.js 3.57 kB
build/vendors/inert-polyfill.min.js 2.48 kB
build/vendors/react-dom.min.js 41.8 kB
build/vendors/react.min.js 4.02 kB
build/viewport/index.min.js 1.04 kB
build/warning/index.min.js 268 B
build/widgets/index.min.js 7.16 kB
build/widgets/style-rtl.css 1.15 kB
build/widgets/style.css 1.16 kB
build/wordcount/index.min.js 1.02 kB

compressed-size-action

@github-actions
Copy link

github-actions bot commented Feb 25, 2023

Flaky tests detected in 99ff106.
Some tests passed with failed attempts. The failures may not be related to this commit but are still reported for visibility. See the documentation for more information.

🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/4539390688
📝 Reported issues:

@t-hamano t-hamano self-assigned this Feb 25, 2023
@t-hamano t-hamano added [Type] Bug An existing feature does not function as intended [Feature] Blocks Overall functionality of blocks Backwards Compatibility Issues or PRs that impact backwards compatability [Type] Regression Related to a regression in the latest release Backport to WP 6.6 Beta/RC Pull request that needs to be backported to the WordPress major release that's currently in beta Needs PHP backport Needs PHP backport to Core labels Feb 25, 2023
Comment on lines 46 to 75
let saveElement;
try {
saveElement =
typeof settings.save === 'function'
? settings.save()
: settings.save;
if ( saveElement === null || saveElement === undefined ) {
// If the save function returns null or undefined, save the anchor
// attribute as a block's comment delimiter without specifying
// the source.
settings.attributes = {
...settings.attributes,
anchor: {
type: ANCHOR_SCHEMA.type,
},
};
} else {
settings.attributes = {
...settings.attributes,
anchor: ANCHOR_SCHEMA,
};
}
} catch ( error ) {
// If the save function returns an error, the anchor will be saved
// in the markup as an id attribute.
settings.attributes = {
...settings.attributes,
anchor: ANCHOR_SCHEMA,
};
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is probably the most complicated part, but depending on the result of the value of the save property, I register the anchor attribute with the appropriate definition.

Copy link
Contributor

Choose a reason for hiding this comment

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

It does feel a bit complicated.

I'd probably be more in favor of something declarative on the blocks that need it rather than magically detecting how it should work.

i.e.

supports: {
    anchor: { attributeSource: 'html'|'delimiter' } // defaults to 'html' when `anchor: true`
}

Another possible option is to migrate static blocks to use the block delimiter attribute instead of the id html attribute, so that it works the same on client and server.

Comment on lines 166 to 175
saveDefinitions.forEach( ( { value, schema } ) => {
const settings = registerBlockType( {
...blockSettings,
save: value,
supports: {
anchor: true,
},
} );
expect( settings.attributes.anchor ).toEqual( schema );
} );
Copy link
Contributor Author

Choose a reason for hiding this comment

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

In the unit test, it is checked whether the anchor attribute with the correct definition is registered according to the value of the save property.

Comment on lines -115 to +123
let sanitizedAttributes =
attributes &&
__experimentalSanitizeBlockAttributes( block, attributes );
let sanitizedAttributes;
if ( attributes ) {
// Anchor attribute isn't supported on the server side and
// should be excluded from the parameters.
const { anchor, ...restAttributes } = attributes;
sanitizedAttributes =
restAttributes &&
__experimentalSanitizeBlockAttributes( block, restAttributes );
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

On the server side, the id attribute is no longer recognized and must be explicitly removed from the parameter. Also, the id attribute should not be rendered on the block editor.

@t-hamano t-hamano marked this pull request as ready for review February 25, 2023 05:41
Copy link
Contributor

@aaronrobertshaw aaronrobertshaw left a comment

Choose a reason for hiding this comment

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

Thanks for tackling this issue @t-hamano 🙇

While reviewing the code I had a vague feeling that even "dynamic" blocks can have saved content that might not be 100% representative of what would be rendered normally. This is a different situation than discussed in #48246 (comment).

The Gutenberg Handbook states the following:

For dynamic blocks, the return value of save could represent a cached copy of the block’s content to be shown only in case the plugin implementing the block is ever disabled.

That suggests to me it is at least possible for a "dynamic" block to have saved content but still need to have its anchor attribute value saved within the block comment.

Is that how you see it?

@t-hamano
Copy link
Contributor Author

Thank you for the review, @aaronrobertshaw and @talldan!

I wondered if I could somehow automatically determine the schema of the anchor attributes, but after listening to your advice, I am beginning to think that this may be practically difficult 😅

I'd probably be more in favor of something declarative on the blocks that need it rather than magically detecting how it should work.

I think this approach might make sense. For example, I am considering the following approach:

if ( hasBlockSupport( settings, 'anchor' ) ) {
	if ( settings.attributes.anchor === true ) {
		// Refer to the id attribute in html.
		settings.attributes = {
			...settings.attributes,
			anchor: {
				type: 'string',
				source: 'attribute',
				attribute: 'id',
				selector: '*',
			},
		};
	} else if ( settings.attributes.anchor === 'delimiter' ) {
		// Save as the comment delimiter.
		settings.attributes = {
			...settings.attributes,
			anchor: {
				type: 'string',
			},
		};
	}
}

Or, as I mentioned in this comment, the approach is to explicitly define an attribute for each block that needs to be saved as a comment delimiter.

@aaronrobertshaw
Copy link
Contributor

Personally, I'd lean towards the modified support property or migrating all static blocks as Dan suggested. The modified support property is basically what I had in mind in my comment over on #48246 so I could be biased there.

One alternative to requiring block authors to manually define and maintain an anchor attribute might be a tweak to the block.json supports config. Maybe something could be added or supported there that flags the anchor attribute needs registering.

It might be splitting hairs but I think discovering or remembering a single config value is less burdensome than remembering to register the attribute. Making the attribute registration part of the block support gives us control should we ever need to change it.

@t-hamano
Copy link
Contributor Author

t-hamano commented Feb 27, 2023

I think more test and discussion may be needed to ideally fix this issue. We don't have much time left before the release of WordPress 6.2. If allowed, one idea might be to revert anchor support for dynamic blocks as done in #44771.

@t-hamano
Copy link
Contributor Author

I will change the status of the project as I think we need to discuss and decide on a direction for this PR.

Copy link
Member

@Mamaduka Mamaduka left a comment

Choose a reason for hiding this comment

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

Thanks for working on this, @t-hamano!

Maybe we should revert the feature from 6.2 and not rush the solution. We can leave the change required for this feature to be implemented in the plugin - https://github.com/WordPress/wordpress-develop/pull/3497/files#diff-c6bbd1a7e8a627a4c08445569689f029a68156e3b00a69e20564fe410ca0e66fR181.

What do you think?

cc/ @ntsekouras, @ndiego, @annezazu

@t-hamano
Copy link
Contributor Author

@Mamaduka
I was just reading the discussion on Slack. I too thought it would be a good idea to revert until the best solution is found.

To revert this feature, I think we also need to remove the anchor support added to the dynamic block's block.json in #44771. Would it make sense to first create a PR on Gutenberg that reverts #44771?

@Mamaduka
Copy link
Member

@t-hamano, this is the "revert" roadmap I've in mind:

  • Revert block.json anchor support from Add anchor support for dynamic blocks #44771.
  • Remove block-supports/anchor.php from the core.
  • Leave the $attributes_to_merge change in the core so that the feature can be implemented from the plugin.

@t-hamano
Copy link
Contributor Author

Thanks for the clarification, @Mamaduka!

Revert block.json anchor support from #44771.

I would like to work on this first step now.

@Mamaduka
Copy link
Member

Thank you, @t-hamano!

Use the wp/6.2 branch as a base, so we only revert the feature from the release and continue working on the fix in the plugin.

@Mamaduka Mamaduka removed the Needs PHP backport Needs PHP backport to Core label Mar 1, 2023
@t-hamano
Copy link
Contributor Author

t-hamano commented Mar 2, 2023

In WordPress 6.2, anchor support was reverted from dynamic blocks in #48592. The code to automatically add anchor attributes on the server side has been reverted from the core:

I will leave this PR open to continue to try to resolve this issue on the Gutenberg plugin.

@t-hamano
Copy link
Contributor Author

Update: I have tried the following approach to solve this problem:

  • The allowed values for supports.anchor are false, true, "html", or "delimiter". The block.json schema and document have also been updated.
  • If the value is true or "html", the attribute is taken from the markup of the root element.
  • If the value is delimiter, the attribute is taken from the comment delimiter.
  • Based on these specifications, in dynamic blocks where anchor support was added in #44771, the value of the anchor property was changed to "delimiter".
  • With the increased selection of possible values for anchor, several tests have been added to the unit test for addAttribute().

Another approach would be to change the anchor schema to be saved as a comment delimiter in all blocks, as described in this comment.

I would love to hear your opinion on whether my approach makes sense 🙏


Also #47868 which adds role attribute to the block is submitted. This PR seems to add role support only to the group block for now. However, considering adding role support to dynamic blocks in the future, the same approach as for anchor support could be applied.

@t-hamano t-hamano requested a review from ndiego as a code owner June 2, 2023 12:20
@t-hamano
Copy link
Contributor Author

t-hamano commented Jun 2, 2023

@talldan @aaronrobertshaw

As we approach the beta phase of WordPress 6.3, I would love to discuss again what we should do with this PR. This PR fixes the static block issue while maintaining anchor support for dynamic blocks.

Currently, all dynamic blocks on the Gutenberg plugin support anchor. At the same time, as reported in #48232, #49382, and #49578, a problem exists where static blocks are broken when activating the latest Gutenberg plugin or updating from an older Gutenberg plugin. Therefore, if the current Gutenberg is bundled with the WordPress beta, the same problem will occur in WordPress core.

To avoid this, I see three options.

  1. Keep the current specification on the Gutenberg plugin. Instead, cancel anchor support for dynamic blocks for the wp6.3 branch, as we did in [WP6.2] Revert dynamic block anchor support #48592, and at the same time fix the static block bug.

  2. Cancel support for dynamic blocks on the Gutenberg plugin and submit another PR that fixes the static block bug. This will ensure that the defects will not be passed on to the WordPress core. The ideal solution can be explored in this or another PR.

  3. We will move forward with this PR. The specifications I have in mind are as per this comment and I believe this PR follows these specifications.

My opinion is the second or third.

@Mamaduka
Copy link
Member

Mamaduka commented Jun 2, 2023

Thanks for the excellent summary, @t-hamano!

I like the second option; it will give us more time to thoroughly test the implementation without worrying about WP 6.3 timeline.

@t-hamano
Copy link
Contributor Author

t-hamano commented Jun 7, 2023

Thanks for your input, @Mamaduka! I have submitted #51288 to remove anchor support for dynamic blocks in the Gutenberg plugin. Therefore, we would like to close this PR for the time being.

@t-hamano t-hamano closed this Jun 7, 2023
@t-hamano t-hamano deleted the fix/anchor-dynamic-block branch August 31, 2023 16:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Backwards Compatibility Issues or PRs that impact backwards compatability [Feature] Blocks Overall functionality of blocks [Type] Bug An existing feature does not function as intended [Type] Regression Related to a regression in the latest release
Projects
4 participants