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 unable to remove empty blocks on merge #65262

Merged
merged 3 commits into from
Sep 27, 2024
Merged

Conversation

kevin940726
Copy link
Member

@kevin940726 kevin940726 commented Sep 12, 2024

What and why?

Fix #65174.

Arguably considered intended, but it could be clearer for users when trying to delete an empty block on merge.

This PR prevents empty unmodified blocks from being moved to the parent on merge. Modified blocks can still be moved to the parent to retain backward compatibility and user expectations.

How?

Refactor and reorder the moveFirstItemUp implementation. Now it follows the following rules:

  1. Transform the block to a default block if it's empty and can be transformed.
  2. Remove the block if the block is already a default block and empty.
  3. Move the block up to the parent if it can be moved.
  4. Move the transformed block up to the parent if the block can be transformed to a default block and can be inserted at the new location.
  5. Continue the fallback behavior:
  6. Transform the block to a default block if it can be transformed
  7. Remove the block if it's an unmodified default block

An "empty" block is defined as if the content attributes are empty.

One use case for these complicated rules is to handle the empty list item v.s. empty heading.

In #65174, an empty heading is expected to be removed on backspace, but an empty list item should be converted to a default block and lifted to the parent. Both blocks are "empty" and not default blocks. The only difference is that an empty list item cannot be transformed to a default block inline, while an empty heading block can. So we try converting the empty heading block to an empty paragraph block on the first backspace (instead of removing it) to provide users instant feedback on backspace. I think it's an acceptable trade-off but there could be other better solutions!

Testing Instructions

Added e2e tests should handle unwrapping and merging blocks.

Follow the testing instructions in the original issue: #65174.

Or, you can try copy-paste this markup and try interacting with it.

Code

<!-- wp:group {"layout":{"type":"constrained"}} -->
<div class="wp-block-group"><!-- wp:group {"layout":{"type":"constrained"}} -->
<div class="wp-block-group"><!-- wp:paragraph {"align":"center"} -->
<p class="has-text-align-center"></p>
<!-- /wp:paragraph -->

<!-- wp:heading {"textAlign":"center"} -->
<h2 class="wp-block-heading has-text-align-center"></h2>
<!-- /wp:heading -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Heading</h2>
<!-- /wp:heading -->

<!-- wp:separator -->
<hr class="wp-block-separator has-alpha-channel-opacity"/>
<!-- /wp:separator --></div>
<!-- /wp:group --></div>
<!-- /wp:group -->

Otherwise, follow the steps below:

  1. Open the post editor.
  2. Insert a group block, and insert an empty paragraph in the group block. Insert another arbitrary block at the end of the group block.
  3. Focus on the empty block and press Backspace
  4. Expect the block to be deleted rather than moved up.
  5. Try the same setup again with a heading block and expect it to be moved to parent and converted to a paragraph block.
  6. Try other combinations.

Testing Instructions for Keyboard

Same as above.

Screenshots or screencast

Kapture.2024-09-23.at.16.14.11.mp4

@kevin940726 kevin940726 added [Type] Bug An existing feature does not function as intended [Feature] Writing Flow Block selection, navigation, splitting, merging, deletion... labels Sep 12, 2024
@kevin940726 kevin940726 self-assigned this Sep 12, 2024
Copy link

github-actions bot commented Sep 12, 2024

Size Change: +1.31 kB (+0.07%)

Total Size: 1.77 MB

Filename Size Change
build-module/interactivity-router/index.min.js 3 kB -6 B (-0.2%)
build/block-directory/style-rtl.css 1.07 kB +11 B (+1.04%)
build/block-directory/style.css 1.07 kB +10 B (+0.94%)
build/block-editor/index.min.js 256 kB +217 B (+0.08%)
build/block-editor/style-rtl.css 15.6 kB -29 B (-0.19%)
build/block-editor/style.css 15.5 kB -28 B (-0.18%)
build/block-library/index.min.js 219 kB -6 B (0%)
build/blocks/index.min.js 52.6 kB +52 B (+0.1%)
build/components/index.min.js 226 kB +719 B (+0.32%)
build/edit-post/index.min.js 13.6 kB +1 B (+0.01%)
build/edit-site/index.min.js 217 kB +1 B (0%)
build/edit-site/posts-rtl.css 7.36 kB +60 B (+0.82%)
build/edit-site/posts.css 7.36 kB +62 B (+0.85%)
build/edit-site/style-rtl.css 12.6 kB +64 B (+0.51%)
build/edit-site/style.css 12.6 kB +68 B (+0.54%)
build/edit-widgets/index.min.js 17.8 kB +57 B (+0.32%)
build/editor/index.min.js 103 kB +58 B (+0.06%)
ℹ️ View Unchanged
Filename Size
build-module/a11y/index.min.js 482 B
build-module/block-library/file/view.min.js 447 B
build-module/block-library/image/view.min.js 1.78 kB
build-module/block-library/navigation/view.min.js 1.16 kB
build-module/block-library/query/view.min.js 743 B
build-module/block-library/search/view.min.js 616 B
build-module/interactivity/debug.min.js 16.7 kB
build-module/interactivity/index.min.js 13.4 kB
build/a11y/index.min.js 952 B
build/annotations/index.min.js 2.26 kB
build/api-fetch/index.min.js 2.32 kB
build/autop/index.min.js 2.12 kB
build/blob/index.min.js 579 B
build/block-directory/index.min.js 7.26 kB
build/block-editor/content-rtl.css 4.42 kB
build/block-editor/content.css 4.41 kB
build/block-editor/default-editor-styles-rtl.css 394 B
build/block-editor/default-editor-styles.css 394 B
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 149 B
build/block-library/blocks/audio/editor.css 151 B
build/block-library/blocks/audio/style-rtl.css 132 B
build/block-library/blocks/audio/style.css 132 B
build/block-library/blocks/audio/theme-rtl.css 134 B
build/block-library/blocks/audio/theme.css 134 B
build/block-library/blocks/avatar/editor-rtl.css 115 B
build/block-library/blocks/avatar/editor.css 115 B
build/block-library/blocks/avatar/style-rtl.css 104 B
build/block-library/blocks/avatar/style.css 104 B
build/block-library/blocks/button/editor-rtl.css 265 B
build/block-library/blocks/button/editor.css 265 B
build/block-library/blocks/button/style-rtl.css 538 B
build/block-library/blocks/button/style.css 538 B
build/block-library/blocks/buttons/editor-rtl.css 291 B
build/block-library/blocks/buttons/editor.css 291 B
build/block-library/blocks/buttons/style-rtl.css 328 B
build/block-library/blocks/buttons/style.css 328 B
build/block-library/blocks/calendar/style-rtl.css 240 B
build/block-library/blocks/calendar/style.css 240 B
build/block-library/blocks/categories/editor-rtl.css 132 B
build/block-library/blocks/categories/editor.css 131 B
build/block-library/blocks/categories/style-rtl.css 152 B
build/block-library/blocks/categories/style.css 152 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 122 B
build/block-library/blocks/code/theme.css 122 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 420 B
build/block-library/blocks/columns/style.css 420 B
build/block-library/blocks/comment-author-avatar/editor-rtl.css 124 B
build/block-library/blocks/comment-author-avatar/editor.css 124 B
build/block-library/blocks/comment-author-name/style-rtl.css 72 B
build/block-library/blocks/comment-author-name/style.css 72 B
build/block-library/blocks/comment-content/style-rtl.css 120 B
build/block-library/blocks/comment-content/style.css 120 B
build/block-library/blocks/comment-date/style-rtl.css 65 B
build/block-library/blocks/comment-date/style.css 65 B
build/block-library/blocks/comment-edit-link/style-rtl.css 70 B
build/block-library/blocks/comment-edit-link/style.css 70 B
build/block-library/blocks/comment-reply-link/style-rtl.css 71 B
build/block-library/blocks/comment-reply-link/style.css 71 B
build/block-library/blocks/comment-template/style-rtl.css 200 B
build/block-library/blocks/comment-template/style.css 199 B
build/block-library/blocks/comments-pagination-numbers/editor-rtl.css 122 B
build/block-library/blocks/comments-pagination-numbers/editor.css 121 B
build/block-library/blocks/comments-pagination/editor-rtl.css 228 B
build/block-library/blocks/comments-pagination/editor.css 217 B
build/block-library/blocks/comments-pagination/style-rtl.css 234 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 832 B
build/block-library/blocks/comments/editor.css 832 B
build/block-library/blocks/comments/style-rtl.css 632 B
build/block-library/blocks/comments/style.css 631 B
build/block-library/blocks/cover/editor-rtl.css 641 B
build/block-library/blocks/cover/editor.css 642 B
build/block-library/blocks/cover/style-rtl.css 1.62 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 86 B
build/block-library/blocks/details/style.css 86 B
build/block-library/blocks/embed/editor-rtl.css 331 B
build/block-library/blocks/embed/editor.css 331 B
build/block-library/blocks/embed/style-rtl.css 419 B
build/block-library/blocks/embed/style.css 419 B
build/block-library/blocks/embed/theme-rtl.css 133 B
build/block-library/blocks/embed/theme.css 133 B
build/block-library/blocks/file/editor-rtl.css 326 B
build/block-library/blocks/file/editor.css 326 B
build/block-library/blocks/file/style-rtl.css 278 B
build/block-library/blocks/file/style.css 279 B
build/block-library/blocks/file/view.min.js 324 B
build/block-library/blocks/footnotes/style-rtl.css 198 B
build/block-library/blocks/footnotes/style.css 197 B
build/block-library/blocks/form-input/editor-rtl.css 229 B
build/block-library/blocks/form-input/editor.css 229 B
build/block-library/blocks/form-input/style-rtl.css 357 B
build/block-library/blocks/form-input/style.css 357 B
build/block-library/blocks/form-submission-notification/editor-rtl.css 344 B
build/block-library/blocks/form-submission-notification/editor.css 341 B
build/block-library/blocks/form-submit-button/style-rtl.css 69 B
build/block-library/blocks/form-submit-button/style.css 69 B
build/block-library/blocks/form/view.min.js 470 B
build/block-library/blocks/freeform/editor-rtl.css 2.6 kB
build/block-library/blocks/freeform/editor.css 2.6 kB
build/block-library/blocks/gallery/editor-rtl.css 946 B
build/block-library/blocks/gallery/editor.css 951 B
build/block-library/blocks/gallery/style-rtl.css 1.83 kB
build/block-library/blocks/gallery/style.css 1.82 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 334 B
build/block-library/blocks/group/editor.css 334 B
build/block-library/blocks/group/style-rtl.css 103 B
build/block-library/blocks/group/style.css 103 B
build/block-library/blocks/group/theme-rtl.css 79 B
build/block-library/blocks/group/theme.css 79 B
build/block-library/blocks/heading/style-rtl.css 188 B
build/block-library/blocks/heading/style.css 188 B
build/block-library/blocks/html/editor-rtl.css 346 B
build/block-library/blocks/html/editor.css 347 B
build/block-library/blocks/image/editor-rtl.css 785 B
build/block-library/blocks/image/editor.css 787 B
build/block-library/blocks/image/style-rtl.css 1.59 kB
build/block-library/blocks/image/style.css 1.59 kB
build/block-library/blocks/image/theme-rtl.css 137 B
build/block-library/blocks/image/theme.css 137 B
build/block-library/blocks/image/view.min.js 1.65 kB
build/block-library/blocks/latest-comments/style-rtl.css 355 B
build/block-library/blocks/latest-comments/style.css 354 B
build/block-library/blocks/latest-posts/editor-rtl.css 179 B
build/block-library/blocks/latest-posts/editor.css 179 B
build/block-library/blocks/latest-posts/style-rtl.css 509 B
build/block-library/blocks/latest-posts/style.css 510 B
build/block-library/blocks/list/style-rtl.css 107 B
build/block-library/blocks/list/style.css 107 B
build/block-library/blocks/loginout/style-rtl.css 61 B
build/block-library/blocks/loginout/style.css 61 B
build/block-library/blocks/media-text/editor-rtl.css 321 B
build/block-library/blocks/media-text/editor.css 320 B
build/block-library/blocks/media-text/style-rtl.css 558 B
build/block-library/blocks/media-text/style.css 556 B
build/block-library/blocks/more/editor-rtl.css 427 B
build/block-library/blocks/more/editor.css 427 B
build/block-library/blocks/navigation-link/editor-rtl.css 644 B
build/block-library/blocks/navigation-link/editor.css 645 B
build/block-library/blocks/navigation-link/style-rtl.css 192 B
build/block-library/blocks/navigation-link/style.css 191 B
build/block-library/blocks/navigation-submenu/editor-rtl.css 295 B
build/block-library/blocks/navigation-submenu/editor.css 294 B
build/block-library/blocks/navigation/editor-rtl.css 2.19 kB
build/block-library/blocks/navigation/editor.css 2.2 kB
build/block-library/blocks/navigation/style-rtl.css 2.25 kB
build/block-library/blocks/navigation/style.css 2.23 kB
build/block-library/blocks/navigation/view.min.js 1.03 kB
build/block-library/blocks/nextpage/editor-rtl.css 392 B
build/block-library/blocks/nextpage/editor.css 392 B
build/block-library/blocks/page-list/editor-rtl.css 378 B
build/block-library/blocks/page-list/editor.css 378 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 236 B
build/block-library/blocks/paragraph/editor.css 236 B
build/block-library/blocks/paragraph/style-rtl.css 341 B
build/block-library/blocks/paragraph/style.css 340 B
build/block-library/blocks/post-author-biography/style-rtl.css 74 B
build/block-library/blocks/post-author-biography/style.css 74 B
build/block-library/blocks/post-author-name/style-rtl.css 69 B
build/block-library/blocks/post-author-name/style.css 69 B
build/block-library/blocks/post-author/editor-rtl.css 107 B
build/block-library/blocks/post-author/editor.css 107 B
build/block-library/blocks/post-author/style-rtl.css 188 B
build/block-library/blocks/post-author/style.css 189 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 527 B
build/block-library/blocks/post-comments-form/style.css 528 B
build/block-library/blocks/post-content/editor-rtl.css 74 B
build/block-library/blocks/post-content/editor.css 74 B
build/block-library/blocks/post-content/style-rtl.css 79 B
build/block-library/blocks/post-content/style.css 79 B
build/block-library/blocks/post-date/style-rtl.css 62 B
build/block-library/blocks/post-date/style.css 62 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 155 B
build/block-library/blocks/post-excerpt/style.css 155 B
build/block-library/blocks/post-featured-image/editor-rtl.css 729 B
build/block-library/blocks/post-featured-image/editor.css 726 B
build/block-library/blocks/post-featured-image/style-rtl.css 347 B
build/block-library/blocks/post-featured-image/style.css 347 B
build/block-library/blocks/post-navigation-link/style-rtl.css 215 B
build/block-library/blocks/post-navigation-link/style.css 214 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 399 B
build/block-library/blocks/post-template/style.css 398 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 70 B
build/block-library/blocks/post-time-to-read/style.css 70 B
build/block-library/blocks/post-title/style-rtl.css 162 B
build/block-library/blocks/post-title/style.css 162 B
build/block-library/blocks/preformatted/style-rtl.css 125 B
build/block-library/blocks/preformatted/style.css 125 B
build/block-library/blocks/pullquote/editor-rtl.css 134 B
build/block-library/blocks/pullquote/editor.css 134 B
build/block-library/blocks/pullquote/style-rtl.css 342 B
build/block-library/blocks/pullquote/style.css 342 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 121 B
build/block-library/blocks/query-pagination-numbers/editor.css 118 B
build/block-library/blocks/query-pagination/editor-rtl.css 154 B
build/block-library/blocks/query-pagination/editor.css 154 B
build/block-library/blocks/query-pagination/style-rtl.css 237 B
build/block-library/blocks/query-pagination/style.css 237 B
build/block-library/blocks/query-title/style-rtl.css 64 B
build/block-library/blocks/query-title/style.css 64 B
build/block-library/blocks/query/editor-rtl.css 452 B
build/block-library/blocks/query/editor.css 451 B
build/block-library/blocks/query/view.min.js 958 B
build/block-library/blocks/quote/style-rtl.css 238 B
build/block-library/blocks/quote/style.css 238 B
build/block-library/blocks/quote/theme-rtl.css 233 B
build/block-library/blocks/quote/theme.css 236 B
build/block-library/blocks/read-more/style-rtl.css 138 B
build/block-library/blocks/read-more/style.css 138 B
build/block-library/blocks/rss/editor-rtl.css 101 B
build/block-library/blocks/rss/editor.css 101 B
build/block-library/blocks/rss/style-rtl.css 288 B
build/block-library/blocks/rss/style.css 287 B
build/block-library/blocks/search/editor-rtl.css 199 B
build/block-library/blocks/search/editor.css 199 B
build/block-library/blocks/search/style-rtl.css 672 B
build/block-library/blocks/search/style.css 671 B
build/block-library/blocks/search/theme-rtl.css 113 B
build/block-library/blocks/search/theme.css 113 B
build/block-library/blocks/search/view.min.js 475 B
build/block-library/blocks/separator/editor-rtl.css 100 B
build/block-library/blocks/separator/editor.css 100 B
build/block-library/blocks/separator/style-rtl.css 248 B
build/block-library/blocks/separator/style.css 248 B
build/block-library/blocks/separator/theme-rtl.css 195 B
build/block-library/blocks/separator/theme.css 195 B
build/block-library/blocks/shortcode/editor-rtl.css 286 B
build/block-library/blocks/shortcode/editor.css 286 B
build/block-library/blocks/site-logo/editor-rtl.css 806 B
build/block-library/blocks/site-logo/editor.css 803 B
build/block-library/blocks/site-logo/style-rtl.css 218 B
build/block-library/blocks/site-logo/style.css 218 B
build/block-library/blocks/site-tagline/editor-rtl.css 87 B
build/block-library/blocks/site-tagline/editor.css 87 B
build/block-library/blocks/site-tagline/style-rtl.css 65 B
build/block-library/blocks/site-tagline/style.css 65 B
build/block-library/blocks/site-title/editor-rtl.css 85 B
build/block-library/blocks/site-title/editor.css 85 B
build/block-library/blocks/site-title/style-rtl.css 143 B
build/block-library/blocks/site-title/style.css 143 B
build/block-library/blocks/social-link/editor-rtl.css 338 B
build/block-library/blocks/social-link/editor.css 338 B
build/block-library/blocks/social-links/editor-rtl.css 757 B
build/block-library/blocks/social-links/editor.css 756 B
build/block-library/blocks/social-links/style-rtl.css 1.51 kB
build/block-library/blocks/social-links/style.css 1.5 kB
build/block-library/blocks/spacer/editor-rtl.css 346 B
build/block-library/blocks/spacer/editor.css 346 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-of-contents/style-rtl.css 83 B
build/block-library/blocks/table-of-contents/style.css 83 B
build/block-library/blocks/table/editor-rtl.css 394 B
build/block-library/blocks/table/editor.css 394 B
build/block-library/blocks/table/style-rtl.css 640 B
build/block-library/blocks/table/style.css 639 B
build/block-library/blocks/table/theme-rtl.css 152 B
build/block-library/blocks/table/theme.css 152 B
build/block-library/blocks/tag-cloud/editor-rtl.css 144 B
build/block-library/blocks/tag-cloud/editor.css 144 B
build/block-library/blocks/tag-cloud/style-rtl.css 266 B
build/block-library/blocks/tag-cloud/style.css 265 B
build/block-library/blocks/template-part/editor-rtl.css 368 B
build/block-library/blocks/template-part/editor.css 368 B
build/block-library/blocks/template-part/theme-rtl.css 113 B
build/block-library/blocks/template-part/theme.css 113 B
build/block-library/blocks/term-description/style-rtl.css 126 B
build/block-library/blocks/term-description/style.css 126 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 165 B
build/block-library/blocks/text-columns/style.css 165 B
build/block-library/blocks/verse/style-rtl.css 98 B
build/block-library/blocks/verse/style.css 98 B
build/block-library/blocks/video/editor-rtl.css 396 B
build/block-library/blocks/video/editor.css 397 B
build/block-library/blocks/video/style-rtl.css 192 B
build/block-library/blocks/video/style.css 192 B
build/block-library/blocks/video/theme-rtl.css 134 B
build/block-library/blocks/video/theme.css 134 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 11.7 kB
build/block-library/editor.css 11.7 kB
build/block-library/elements-rtl.css 54 B
build/block-library/elements.css 54 B
build/block-library/reset-rtl.css 472 B
build/block-library/reset.css 472 B
build/block-library/style-rtl.css 14.9 kB
build/block-library/style.css 14.9 kB
build/block-library/theme-rtl.css 708 B
build/block-library/theme.css 712 B
build/block-serialization-default-parser/index.min.js 1.12 kB
build/block-serialization-spec-parser/index.min.js 2.87 kB
build/commands/index.min.js 16.1 kB
build/commands/style-rtl.css 955 B
build/commands/style.css 952 B
build/components/style-rtl.css 12.3 kB
build/components/style.css 12.3 kB
build/compose/index.min.js 12.7 kB
build/core-commands/index.min.js 3.11 kB
build/core-data/index.min.js 73.4 kB
build/customize-widgets/index.min.js 11 kB
build/customize-widgets/style-rtl.css 1.35 kB
build/customize-widgets/style.css 1.35 kB
build/data-controls/index.min.js 641 B
build/data/index.min.js 8.98 kB
build/date/index.min.js 18 kB
build/deprecated/index.min.js 458 B
build/dom-ready/index.min.js 325 B
build/dom/index.min.js 4.66 kB
build/edit-post/classic-rtl.css 578 B
build/edit-post/classic.css 580 B
build/edit-post/style-rtl.css 2.54 kB
build/edit-post/style.css 2.54 kB
build/edit-widgets/style-rtl.css 4.19 kB
build/edit-widgets/style.css 4.19 kB
build/editor/style-rtl.css 9.34 kB
build/editor/style.css 9.34 kB
build/element/index.min.js 4.83 kB
build/escape-html/index.min.js 537 B
build/format-library/index.min.js 8.11 kB
build/format-library/style-rtl.css 476 B
build/format-library/style.css 476 B
build/hooks/index.min.js 1.54 kB
build/html-entities/index.min.js 445 B
build/i18n/index.min.js 3.58 kB
build/is-shallow-equal/index.min.js 526 B
build/keyboard-shortcuts/index.min.js 1.31 kB
build/keycodes/index.min.js 1.46 kB
build/list-reusable-blocks/index.min.js 2.18 kB
build/list-reusable-blocks/style-rtl.css 846 B
build/list-reusable-blocks/style.css 846 B
build/media-utils/index.min.js 3.2 kB
build/notices/index.min.js 946 B
build/nux/index.min.js 1.61 kB
build/nux/style-rtl.css 749 B
build/nux/style.css 745 B
build/patterns/index.min.js 7.34 kB
build/patterns/style-rtl.css 687 B
build/patterns/style.css 685 B
build/plugins/index.min.js 1.81 kB
build/preferences-persistence/index.min.js 2.06 kB
build/preferences/index.min.js 2.9 kB
build/preferences/style-rtl.css 554 B
build/preferences/style.css 554 B
build/primitives/index.min.js 829 B
build/priority-queue/index.min.js 1.54 kB
build/private-apis/index.min.js 1.01 kB
build/react-i18n/index.min.js 630 B
build/react-refresh-entry/index.min.js 9.47 kB
build/react-refresh-runtime/index.min.js 6.76 kB
build/redux-routine/index.min.js 2.69 kB
build/reusable-blocks/index.min.js 2.55 kB
build/reusable-blocks/style-rtl.css 256 B
build/reusable-blocks/style.css 256 B
build/rich-text/index.min.js 10.1 kB
build/router/index.min.js 1.96 kB
build/server-side-render/index.min.js 1.94 kB
build/shortcode/index.min.js 1.4 kB
build/style-engine/index.min.js 2.04 kB
build/token-list/index.min.js 581 B
build/url/index.min.js 3.9 kB
build/vendors/react-dom.min.js 41.7 kB
build/vendors/react-jsx-runtime.min.js 560 B
build/vendors/react.min.js 4.02 kB
build/viewport/index.min.js 965 B
build/warning/index.min.js 250 B
build/widgets/index.min.js 7.17 kB
build/widgets/style-rtl.css 1.16 kB
build/widgets/style.css 1.16 kB
build/wordcount/index.min.js 1.03 kB

compressed-size-action

@kevin940726 kevin940726 marked this pull request as ready for review September 12, 2024 08:54
Copy link

github-actions bot commented Sep 12, 2024

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Co-authored-by: kevin940726 <[email protected]>
Co-authored-by: ntsekouras <[email protected]>
Co-authored-by: talldan <[email protected]>
Co-authored-by: andrewserong <[email protected]>
Co-authored-by: youknowriad <[email protected]>
Co-authored-by: getdave <[email protected]>
Co-authored-by: Mamaduka <[email protected]>
Co-authored-by: ramonjd <[email protected]>
Co-authored-by: kspilarski <[email protected]>
Co-authored-by: ndiego <[email protected]>
Co-authored-by: richtabor <[email protected]>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@talldan
Copy link
Contributor

talldan commented Sep 12, 2024

Unfortunately it seems this fix breaks the feature introduced in #45075. If I had to pick one, I feel like it'd be better to keep the behavior in trunk, the way it works for lists is pretty useful.

I'm not sure if there's a way to keep the behavior for lists (and maybe quotes) but delete blocks like headings and paragraphs in groups.

The code here is very generic, not really reasoning about block types, so it might be tricky.

@kevin940726
Copy link
Member Author

Unfortunately it seems this fix breaks the feature introduced in #45075.

I think unwrapping list items still works from my testing and the e2e tests? Could you point me to the features that are breaking after this PR?

@andrewserong
Copy link
Contributor

Unfortunately it seems this fix breaks the feature introduced in #45075. If I had to pick one, I feel like it'd be better to keep the behavior in trunk, the way it works for lists is pretty useful.

I was a bit stumped trying to reproduce this at first, as this PR mostly feels quite good to me in testing. As far as I could tell the main difference for lists appears to be what happens when you press backspace from an empty list item.

I.e. in this PR, the overall list becomes selected:

2024-09-13.11.28.01.mp4

Whereas on trunk, if we hit backspace from that first list item, we get an empty paragraph block. I think that's probably the desired behaviour so that it's easy to continue writing in a paragraph?

2024-09-13.11.29.07.mp4

I'm not sure if there's a way to keep the behavior for lists (and maybe quotes) but delete blocks like headings and paragraphs in groups.

I'm not sure how we'd do it either, but I tend to agree that it'd be ideal if we could have it working as in this PR for headings and paragraphs in groups, but retain the behaviour in trunk for lists.

Were there any other details from #45075 that aren't working in this PR @talldan?

if ( definition.hasOwnProperty( 'default' ) ) {
return value === definition.default;
}
export function isUnmodifiedBlock( block, attributeKeys ) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Might it better to leave isUnmodifiedBlock intact and create a new util with our implementation of whether a block can be considered empty?

Additionally, should the empty block function just check for

if ( definition.type === 'rich-text' ) {
	return ! value?.length;
}

Do you see any drawbacks on that?

Copy link
Member Author

Choose a reason for hiding this comment

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

Third-party blocks could have content attributes that are not rich-text, (but would it able to call onMerge?). I think it's better to keep it a little bit generic for now. 😅

Copy link
Contributor

Choose a reason for hiding this comment

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

I think many third party blocks are also unlikely to have __experimentalRole defined because of the way it's experimental.

Copy link
Contributor

Choose a reason for hiding this comment

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

Just FYI it's been stablised now but Dan's point still stands:

#65484

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, I'm just trying to be safe and future-compatible here. (On the other hand, an attribute could also have the rich-text type but not be considered content.)

Thanks for the link! I can rebase this to use the stabilized function.

@kevin940726 kevin940726 force-pushed the fix/remove-empty-on-merge branch 4 times, most recently from 550773b to 91dcb16 Compare September 13, 2024 19:10
@kevin940726
Copy link
Member Author

I updated the PR to include some more testing cases and rules. This is getting a lot more complicated though. Some feedback on the desired behavior is appreciated! I applied some predefined rules that I think are less frustrating to regular users but also tried to maintain maximum backward compatibility. See the recordings in the PR descriptions for some edge cases.

@talldan
Copy link
Contributor

talldan commented Sep 16, 2024

Were there any other details from #45075 that aren't working in this PR @talldan?

Yes, sorry for not providing more details, it was just the empty list item case you mentioned. I didn't notice that unwrapping works ok in this PR when the list item has some text, so thought that it'd be enough info!

@andrewserong
Copy link
Contributor

Thanks for the updates, Kai!

This is getting a lot more complicated though. Some feedback on the desired behavior is appreciated!

The behaviour for the first item in a List feels good to me know (conversion to the default block), same with an empty Paragraph block within a Group.

However, with the Heading block, I'd expect hitting backspace on an empty Heading block within a Group block to work the same as for the paragraph block — that is, for it to delete the Heading block. In the screengrabs and in local testing, it looks like it now moves up a level and converts to a default block, similar to the List item, which felt a bit unexpected to me:

2024-09-17.16.48.55.mp4

In the above video:

  • Deleting the Paragraph block works as expected
  • Deleting the Heading block moves up a level and converts to an empty paragraph block which felt unexpected to me

Unfortunately I can't quite think of a good way to handle this, but it seems to me like the behaviour of headings and paragraphs should probably be much the same as each other, but the behaviour for list items is the outlier? Are there any other primitive blocks we'd need to consider here, or is it mostly about paragraphs and headings that we want to deal with?

Just wondering if it'd help to make it about the specific blocks we're dealing with, rather than keeping the logic generic, or would that only create further complexity?

@ramonjd
Copy link
Member

ramonjd commented Sep 18, 2024

I can confirm that the base case of deleting an empty paragraph block (and that block being removed) is working on this PR

Deleting the Heading block moves up a level and converts to an empty paragraph block which felt unexpected to me

I would expect the empty block to be deleted in all cases.

But, in general, think I failed the IQ test - testing this stuff seems very subtle and I'm not sure what's right or wrong anymore 🤣 For example, not related to this PR, but it's confusing for me how subsequent blocks are pushed outside the Group block when I create new empty blocks.

2024-09-18.11.56.02.mp4

@kevin940726
Copy link
Member Author

However, with the Heading block, I'd expect hitting backspace on an empty Heading block within a Group block to work the same as for the paragraph block — that is, for it to delete the Heading block.

Yeah, I think we have a few options, I'm not sure which one is the best TBH.

  1. Delete it
  2. Convert to an empty paragraph block

I think both solutions make sense in a way. The first solution might be the most straightforward but a little bit destructive. The second solution conveys the meaning of "resetting formatting" when pressing backspace on an empty block. This kind of design language can be seen in some rich text editors, but very subtle. It also matches the behavior of pressing backspace on a non-empty block more closely too. That said, I feel it might not be worth it at this stage, so I'll try the first approach first 😅.

@noisysocks noisysocks added the Backport to WP 6.7 Beta/RC Pull request that needs to be backported to the WordPress major release that's currently in beta label Sep 18, 2024
@kevin940726 kevin940726 force-pushed the fix/remove-empty-on-merge branch 2 times, most recently from f9a4453 to 163a568 Compare September 22, 2024 18:19
@kevin940726
Copy link
Member Author

I updated the PR yet again to hopefully handle the list item use case, too 😅. I also updated the PR description, but I'll copy-paste it here for visibility.

Now it follows the following rules:

  1. Transform the block to a default block if it's empty and can be transformed.
  2. Remove the block if the block is already a default block and empty.
  3. Move the block up to the parent if it can be moved.
  4. Move the transformed block up to the parent if the block can be transformed to a default block and can be inserted at the new location.
  5. Continue the fallback behavior:
  6. Transform the block to a default block if it can be transformed
  7. Remove the block if it's an unmodified default block

An "empty" block is defined as if the content attributes are empty.

One use case for these complicated rules is to handle the empty list item v.s. empty heading.

In #65174, an empty heading is expected to be removed on backspace, but an empty list item should be converted to a default block and lifted to the parent. Both blocks are "empty" and not default blocks. The only difference is that an empty list item cannot be transformed to a default block inline, while an empty heading block can. So we try converting the empty heading block to an empty paragraph block on the first backspace (instead of removing it) to provide users instant feedback on backspace. I think it's an acceptable trade-off but there could be other better solutions!

Kapture.2024-09-23.at.16.14.11.mp4

@ramonjd
Copy link
Member

ramonjd commented Sep 24, 2024

Tested with paragraph and heading blocks:

  1. Empty blocks are removed as expected when hitting backspace
  2. Non-empty blocks are moved up to parent as expected

I can't really see anything strange with list blocks so far, but like I said - there are many subtleties to this behaviour I'm not completely covering.

However in my testing this PR satisfies the reported issue: #65174

Copy link
Contributor

@andrewserong andrewserong left a comment

Choose a reason for hiding this comment

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

Tested with paragraph and heading blocks:

Same, this is testing well for me with headings, paragraphs, and lists 👍. Since it is a little nuanced this one, I'll just ping @WordPress/gutenberg-core for visibility in case anyone has any concerns about the proposed change here.

Copy link

Flaky tests detected in 47b223b.
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/11047394625
📝 Reported issues:

@youknowriad
Copy link
Contributor

Would appreciate an approval from someone else as I didn't get to test this deeply but I do appreciate the changes and I think it's looking good. Thanks

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.

This is testing well for me. As far as I remember, the e2e test coverage is pretty good for this area.

I think it's better to ship this a follow-up with bug fixes if they're discovered during the beta/RC cycle.

@kevin940726 kevin940726 enabled auto-merge (squash) September 27, 2024 06:17
@kevin940726 kevin940726 merged commit 93323fd into trunk Sep 27, 2024
63 checks passed
@kevin940726 kevin940726 deleted the fix/remove-empty-on-merge branch September 27, 2024 06:18
@github-actions github-actions bot added this to the Gutenberg 19.4 milestone Sep 27, 2024
gutenbergplugin pushed a commit that referenced this pull request Sep 27, 2024
Co-authored-by: kevin940726 <[email protected]>
Co-authored-by: ntsekouras <[email protected]>
Co-authored-by: talldan <[email protected]>
Co-authored-by: andrewserong <[email protected]>
Co-authored-by: youknowriad <[email protected]>
Co-authored-by: getdave <[email protected]>
Co-authored-by: Mamaduka <[email protected]>
Co-authored-by: ramonjd <[email protected]>
Co-authored-by: kspilarski <[email protected]>
Co-authored-by: ndiego <[email protected]>
Co-authored-by: richtabor <[email protected]>
* Fix unable to remove empty blocks on merge

* Update to the stabilized API

* Rename the utils
@github-actions github-actions bot removed the Backport to WP 6.7 Beta/RC Pull request that needs to be backported to the WordPress major release that's currently in beta label Sep 27, 2024
Copy link

I just cherry-picked this PR to the wp/6.7 branch to get it included in the next release: 76759ef

@github-actions github-actions bot added the Backported to WP Core Pull request that has been successfully merged into WP Core label Sep 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Backported to WP Core Pull request that has been successfully merged into WP Core [Feature] Writing Flow Block selection, navigation, splitting, merging, deletion... [Type] Bug An existing feature does not function as intended
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

Difficulty removing empty heading blocks
9 participants