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

Update the behavior of the cached undo/redo stack #51644

Merged
merged 4 commits into from
Jul 5, 2023
Merged

Conversation

youknowriad
Copy link
Contributor

What?

Until now, any change to what we call "transient properties" (like blocks, selection) was considered as a change that doesn't create an undo/redo step. This PR makes the assumption that this heuristic is wrong. IMO any change to "blocks" for instance should actually create an undo/redo step.

That said, we do have some smart behavior in places where we want sometimes to cache changes and only create an undo step after some time, for instance when typing quickly in a RichText component. For these cases, the isCached flag is the solution proposed by this PR.

Also, this PR enables a new behavior to unblock #51201

Basically, with the new flag, it's possible to have calls to editEntityRecords updating non-transient properties like "meta" or "title" and cache these changes and only create an undo/redo once for these changes potential consecutive changes.

Testing Instructions

1- Open the post editor
2- Try doing a few different things
3- Make sure that undo/redo still behaves similarly to trunk.

(We also have e2e tests to validate that)

@youknowriad youknowriad added [Type] Enhancement A suggestion for improvement. [Feature] History History, undo, redo, revisions, autosave. labels Jun 19, 2023
@youknowriad youknowriad requested a review from ellatrix June 19, 2023 10:21
@youknowriad youknowriad requested a review from nerrad as a code owner June 19, 2023 10:21
@youknowriad youknowriad self-assigned this Jun 19, 2023
@github-actions
Copy link

github-actions bot commented Jun 19, 2023

Size Change: +714 B (0%)

Total Size: 1.42 MB

Filename Size Change
build/block-editor/index.min.js 209 kB +314 B (0%)
build/block-editor/style-rtl.css 14.7 kB +79 B (+1%)
build/block-editor/style.css 14.7 kB +80 B (+1%)
build/block-library/index.min.js 201 kB +121 B (0%)
build/commands/index.min.js 14.9 kB -7 B (0%)
build/components/index.min.js 240 kB +8 B (0%)
build/core-data/index.min.js 16.1 kB -28 B (0%)
build/customize-widgets/index.min.js 12 kB +5 B (0%)
build/data/index.min.js 8.28 kB +7 B (0%)
build/edit-site/index.min.js 85.4 kB +123 B (0%)
build/edit-site/style-rtl.css 12.6 kB +2 B (0%)
build/edit-site/style.css 12.6 kB +2 B (0%)
build/edit-widgets/index.min.js 16.9 kB +5 B (0%)
build/editor/index.min.js 45.4 kB +3 B (0%)
ℹ️ 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 6.99 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.25 kB
build/block-editor/content.css 4.24 kB
build/block-editor/default-editor-styles-rtl.css 381 B
build/block-editor/default-editor-styles.css 381 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 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 104 B
build/block-library/blocks/avatar/style.css 104 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/style-rtl.css 269 B
build/block-library/blocks/file/style.css 270 B
build/block-library/blocks/file/view.min.js 312 B
build/block-library/blocks/footnotes/style-rtl.css 191 B
build/block-library/blocks/footnotes/style.css 188 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/style-rtl.css 1.42 kB
build/block-library/blocks/image/style.css 1.42 kB
build/block-library/blocks/image/theme-rtl.css 126 B
build/block-library/blocks/image/theme.css 126 B
build/block-library/blocks/image/view-interactivity.min.js 1.46 kB
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.26 kB
build/block-library/blocks/navigation/editor.css 2.26 kB
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.min.js 906 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 587 B
build/block-library/blocks/search/style.css 584 B
build/block-library/blocks/search/theme-rtl.css 114 B
build/block-library/blocks/search/theme.css 114 B
build/block-library/blocks/search/view.min.js 531 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.43 kB
build/block-library/blocks/social-links/style.css 1.42 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.1 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/reset-rtl.css 478 B
build/block-library/reset.css 478 B
build/block-library/style-rtl.css 13.7 kB
build/block-library/style.css 13.7 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 51 kB
build/commands/style-rtl.css 827 B
build/commands/style.css 827 B
build/components/style-rtl.css 11.7 kB
build/components/style.css 11.7 kB
build/compose/index.min.js 12 kB
build/core-commands/index.min.js 2.26 kB
build/customize-widgets/style-rtl.css 1.46 kB
build/customize-widgets/style.css 1.45 kB
build/data-controls/index.min.js 640 B
build/date/index.min.js 17.8 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 35.3 kB
build/edit-post/style-rtl.css 7.58 kB
build/edit-post/style.css 7.57 kB
build/edit-widgets/style-rtl.css 4.53 kB
build/edit-widgets/style.css 4.53 kB
build/editor/style-rtl.css 3.58 kB
build/editor/style.css 3.58 kB
build/element/index.min.js 4.8 kB
build/escape-html/index.min.js 537 B
build/format-library/index.min.js 7.62 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/interactivity/index.min.js 10 kB
build/is-shallow-equal/index.min.js 527 B
build/keyboard-shortcuts/index.min.js 1.64 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.77 kB
build/preferences-persistence/index.min.js 1.84 kB
build/preferences/index.min.js 1.24 kB
build/primitives/index.min.js 943 B
build/priority-queue/index.min.js 1.52 kB
build/private-apis/index.min.js 943 B
build/react-i18n/index.min.js 615 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.39 kB
build/reusable-blocks/style-rtl.css 243 B
build/reusable-blocks/style.css 243 B
build/rich-text/index.min.js 10.9 kB
build/router/index.min.js 1.77 kB
build/server-side-render/index.min.js 1.94 kB
build/shortcode/index.min.js 1.39 kB
build/style-engine/index.min.js 1.83 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 958 B
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

@Mamaduka
Copy link
Member

Will this also unblock #37171?

@youknowriad
Copy link
Contributor Author

@Mamaduka It will not solve it but will provide us a way to do it yes.

Copy link
Contributor

@paulopmt1 paulopmt1 left a comment

Choose a reason for hiding this comment

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

Tested blocks, images, templates, and text edition and everything worked as expected.

it's possible to have calls to editEntityRecords updating non-transient properties like "meta" or "title"

That's great to hear! I'm planning to tackle this one in my next 20% time to see if I really understand undo/redo now 😅

By default all calls to `editEntityRecord` are considered "non-cached" unless the `isCached` option is passed as true. Example:

```js
wp.data.dispatch( 'core' ).editEntityRecord( 'postType', 'post', 1, { title: 'Hello World' }, { isCached: true } );
Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks for that example!

@ellatrix ellatrix added this to the Gutenberg 16.2 milestone Jul 1, 2023
@@ -275,7 +275,7 @@ export function useEntityBlockEditor( kind, name, { id: _id } = {} ) {
const edits = { blocks: newBlocks, selection };
registry.batch( () => {
updateFootnotes( edits.blocks );
editEntityRecord( kind, name, id, edits );
editEntityRecord( kind, name, id, edits, { isCached: false } );
Copy link
Member

Choose a reason for hiding this comment

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

@youknowriad I rebase this PR to try it with footnotes, but undo still doesn't seem batched. Do we need to update the editEntityRecord call in useEntityProp as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That change is not correct. For this PR to only create one undo level for footnotes, you need one of the editEntityRecord calls (either footnotes one or actual change) to be isChached: true (isCached: false is the default)

Copy link
Member

Choose a reason for hiding this comment

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

Oh, sorry. I just rebased with the previous change.

Copy link
Member

@ellatrix ellatrix left a comment

Choose a reason for hiding this comment

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

If you reorder two paragraph blocks with a footnote in each, undo will now revert the change as a whole correctly, but only after you undo, redo, and undo again. Somehow on the first time it messes up. 🤔

If a page already has footnotes, and you add another one, undoing the addition right away will only remove the footnote from the block. But somehow when you press redo, then undo again, it will undo the entire change. So same problem happening here.

But if you start off with no footnotes, and a footnotes block needs to be inserted, the first undo seems to do nothing, and consecutive redo/undo does it in two steps. Not sure why, since everything is batched:

registry.batch( () => {
const id = createId();
const newValue = insertObject(
value,
{
type: formatName,
attributes: {
href: '#' + id,
id: `${ id }-link`,
'data-fn': id,
},
innerHTML: '*',
},
value.end,
value.end
);
newValue.start = newValue.end - 1;
onChange( newValue );
// BFS search to find the first footnote block.
let fnBlock = null;
{
const queue = [ ...getBlocks() ];
while ( queue.length ) {
const block = queue.shift();
if ( block.name === name ) {
fnBlock = block;
break;
}
queue.push( ...block.innerBlocks );
}
}
// Maybe this should all also be moved to the entity provider.
// When there is no footnotes block in the post, create one and
// insert it at the bottom.
if ( ! fnBlock ) {
const clientId = getSelectedBlockClientId();
let rootClientId = getBlockRootClientId( clientId );
while (
rootClientId &&
getBlockName( rootClientId ) !== 'core/post-content'
) {
rootClientId = getBlockRootClientId( rootClientId );
}
fnBlock = createBlock( name );
insertBlock( fnBlock, undefined, rootClientId );
}
selectionChange( fnBlock.clientId, id, 0, 0 );
} );

@youknowriad
Copy link
Contributor Author

I'm happy to solve the footnotes undo as well, but just wanted to note that this initial PR was not meant to solve the footnotes behavior. It just gives us the tools to do so. I can include in the PR though.

@ellatrix
Copy link
Member

ellatrix commented Jul 4, 2023

@youknowriad Sorry, didn't meant to derail your PR :D

@youknowriad
Copy link
Contributor Author

No worries @ellatrix in the last commit I went ahead and fixed footnotes undo/redo. There's one small remaining issue when we insert the first initial footnote, there's one undo level for the footnote addition and one for the block addition. That's because onChange is called twice between these two operations. Other than that, all is good in my testing.

@youknowriad youknowriad 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 Jul 4, 2023
@youknowriad
Copy link
Contributor Author

@ellatrix I've just realized that you were already batching these two actions but it was still resulting in two onChange calls. The reason was a bug in nested registry.batch calls (we also have a batch call within RichText). This is fixed in the last commit (also added a unit test)

@youknowriad youknowriad added the [Type] Bug An existing feature does not function as intended label Jul 5, 2023
selection,
content: ( { blocks: blocksForSerialization = [] } ) =>
__unstableSerializeAndClean( blocksForSerialization ),
...updateFootnotes( newBlocks ),
Copy link
Member

Choose a reason for hiding this comment

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

Oh interesting, I didn't know there was a key for meta.

Copy link
Member

@ellatrix ellatrix left a comment

Choose a reason for hiding this comment

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

Undo works great for footnotes!

@youknowriad youknowriad merged commit 966d20f into trunk Jul 5, 2023
@youknowriad youknowriad deleted the update/undo branch July 5, 2023 14:31
tellthemachines pushed a commit that referenced this pull request Jul 7, 2023
@tellthemachines
Copy link
Contributor

I just cherry-picked this PR to the update/first-pre-beta-4 branch to get it included in the next release: ed76244

@tellthemachines tellthemachines 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 Jul 7, 2023
tellthemachines added a commit that referenced this pull request Jul 7, 2023
* add hint to show template part move (#52395)

* Page Content Focus: Ignore page content within a Query Loop block (#52351)

* Block Editor: Pass context and className props to editor.BlockEdit filter

* Page Content Focus: Ignore content blocks that are within a Query Loop

* Patterns: stop endless snackbars appearing (#52012)

* Patterns: Distinguish between theme patterns and template parts in category list (#52382)

* Allow opt out of auto-creation of Navigation fallback (#52319)

* Update welcome guide copy (#52282)

* Patterns: Update pattern copy (#52340)

* Post Title: The changes should be reflected when previewing a post (#52369)

* Update fixed block toolbar (#52123)

* update the icons for expanding and collapsing the fixed block toolbar

* hide the tools selector item in document tools for fixed toolbar preference

* reveal undo, redo and list view buttons

* tweaks for show icon labels and hide zoom out for top toolbar option

* improve the responsiveness of the fixed block toolbar

* remove the overflow rule - bad experiment

* update top toolbar test with the new label for buttons

* update the toolbar tests to account for moving the collapse button

* Drop PHP 5.6 CI jobs (#52345)

* Remove PHP 5.6 PHPUnit CI job
* Raise version in phpcs / WPCS

* Patterns: Add handling of sync status to the wp-admin patterns list page (#52346)

* Exit template focus when opening the W menu (#52235)

* wrap buttons (#52249)

* Update the behavior of the cached undo/redo stack (#51644)

Co-authored-by: Ella van Durpe <[email protected]>

* Adjust top position (#52248)

* Patterns: add a hint about the rename of reusable blocks to menu and inserter  (#51771)

Co-authored-by: Saxon Fletcher <[email protected]>

* Site Editor: update headings hierarchy in the 'Manage all' screens (#52271)

* This commit:
- updates heading levels on the template and template part pages
- passes a `level` prop to Header from Page

* update h2 size

* Rolling back custom sizes

* Rolling back unnecessary classNames
There was a rogue space in trunk. Let's let it live

* Check randomizer experiment is enabled before rendering button (#52306)

* Hide parent selector when parent is 'disabled' or 'contentOnly' (#52264)

* Fix incorrect aria-describedby attributes for theme patterns (#52263)

* Patterns: rename sync_status and move to top level field on rest return instead of a meta field (#52146)

* Fix default block dimensions visibility (#52256)

* core/heading

* core/details

* core/list

* core/table

* core/video

* core/verse

* core/social-links

* core/site-title

* core/site-tagline

* core/site-logo

* core/post-time-to-read

* core/gallery

* core/code

* core/categories

* core/audio

* core/archives

* Patterns: Display all custom template part areas in sidebar nav (#52355)

* Revert phpcs back to PHP 5.6 (#52384)

Reverts phpcs PHP compatibility version back to 5.6.

* Check if experiment enabled fr this time (#52315)

* Navigation: Remove one preloaded endpoint (#52115)

* default to showing status (#52226)

* Command palette: rename (#52153)

* Revise use of “command menu” to “command palette”.

Dropping "global" where it was used as well.

* Find “command center” and replace with “command palette”

* Image block and behaviors: Fix some warnings (#52109)

* Fix first warning

* Fix second warning - dividing a NaN

* Turn off DFM for style book and style editing (#52117)

* Add confirmation step when deleting a Template (#52236)

* [Command Palette]: Remove suggestion for deleting templates/parts (#52168)

* Update stepper styling in Home template details panel (#51972)

* Update stepper styling

* Remove !important

* [Edit Post]: Add toggle fullscreen mode and list view commands (#52184)

* Style Book: Show tabs and make blocks clickable when entering edit mode from the Styles menu (#52222)

* Style Book: Show tabs and make blocks clickable when entering edit mode from the Styles menu

* Move lines

* !important (#52025)

* Navigation in Site View: Readd the edit button (#52111)

* Fix UnitControl crashing on regex control characters.

Units are now escaped using `escapeRegExp` before concatenating them into a regular expression.

Fixes #52211.
---------

Co-authored-by: Mitchell Austin <[email protected]>

* Patterns: rename wp_block sync_status postmeta to wp_pattern_sync_status (#52232)

---------

Co-authored-by: Kai Hao <[email protected]>

* Site Editor Frame: Ignore Spotlight in view mode (#52262)

* Guide: Place focus on the guide's container instead of its first tabbable (#52300)

* Guide: Place focus on the guide's container instead of its first tabbable

* Update CHANGELOG

* Post editor: Require confirmation before removing Footnotes (#52277)

* Post editor: Require confirmation before removing Footnotes

Context: #52176

* BlockRemovalWarningModal: Limit width to 40rem

* Explain that footnotes are preserved. Add warning to Site Editor

* Fix react-dropdown-menu version to avoid breaking change from one of … (#52356)

* Fix react-dropdown-menu version to avoid breaking change from one if its dependencies.

* Changelog update

* move changelog entry to the right place

* Update package-lock

---------

Co-authored-by: Saxon Fletcher <[email protected]>
Co-authored-by: Robert Anderson <[email protected]>
Co-authored-by: Glen Davies <[email protected]>
Co-authored-by: James Koster <[email protected]>
Co-authored-by: Dave Smith <[email protected]>
Co-authored-by: George Mamadashvili <[email protected]>
Co-authored-by: Andrei Draganescu <[email protected]>
Co-authored-by: Tonya Mork <[email protected]>
Co-authored-by: Riad Benguella <[email protected]>
Co-authored-by: Ella van Durpe <[email protected]>
Co-authored-by: Ramon <[email protected]>
Co-authored-by: Kai Hao <[email protected]>
Co-authored-by: Rich Tabor <[email protected]>
Co-authored-by: Aaron Robertshaw <[email protected]>
Co-authored-by: Ben Dwyer <[email protected]>
Co-authored-by: Mitchell Austin <[email protected]>
Co-authored-by: Carlos Bravo <[email protected]>
Co-authored-by: Nik Tsekouras <[email protected]>
Co-authored-by: Aki Hamano <[email protected]>
Co-authored-by: Timothy Jacobs <[email protected]>
Co-authored-by: Kai Hao <[email protected]>
Co-authored-by: Miguel Fonseca <[email protected]>
@Mamaduka
Copy link
Member

@youknowriad, I'm experimenting with this updated behavior/new flag. I wanted to check if the following behavior is expected or if I miss understanding the feature.

Gist for the case

I've got three edits and I want to "cache" the second edit; the first two should be stored in the history stack.

Expected undo stack

  • three
  • one
  • original post title

What I see now

  • three
  • two
  • original post title

Example code

const edits = [ 'one', 'two', 'three' ];
const postId = wp.data.select( 'core/editor' ).getCurrentPostId();

edits.forEach(( edit, index ) => {
   // Cache the second edit.
   const isCached = index === 1;

    wp.data.dispatch( 'core' ).editEntityRecord( 'postType', 'post', postId, { title: edit }, { isCached } );
   
   console.log( { edit, isCached } );
});

@youknowriad
Copy link
Contributor Author

I'm not entirely sure what you want to achieve but here's the behavior:

1- When isCached is false: a new undo "step" is created for the change
2- When isCached is true: no undo step is created for the change, instead the change is put into a "pending" area.
3- Once a new edit is made that is supposed to create a new undo step (isCached: false) / or we explicitly call "createUndoStep", the "pending" area is merged into the previous undo (So in this case, 1 is merged with 2 in the same undo step) and 3 creates a new undo step.

So we end up with 1+2 ---> 3 as a history.

I'd say it's arguable whether we should merge 2 with 1 or 3 here but in my changes, I just left what we had for a long time because that was a proven behavior.

@Mamaduka
Copy link
Member

This was just a simplified example. I was experimenting with the "coalescing edits" implementation in the useEntityProp hook, and the created undo stack wasn't matching my expectations.

Thanks for the explanation!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] History History, undo, redo, revisions, autosave. [Type] Bug An existing feature does not function as intended [Type] Enhancement A suggestion for improvement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants