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 initial block parsing #52417

Merged
merged 4 commits into from
Jul 19, 2023
Merged

Fix initial block parsing #52417

merged 4 commits into from
Jul 19, 2023

Conversation

youknowriad
Copy link
Contributor

What?

This fixes a small bug (not something you can see at the moment), where if a post is loaded and then refreshed from the server before any edits happen on that post locally, we will see the previous version of that post and not the last one.

While right now, this bug is not visible, it can be programmatically triggered potentially and also if ever we add an offline cache (say local storage or index db or whatever) for our remote objects (posts), we'll start noticing this post. The editor loads an outdated version of the blocks.

This is also a code quality and performance improvement anyway as we avoid a useless action from being triggered so avoid a lot of useless re-renders...

Also since we're not triggering these useless actions, I expect improvements for things like reusable blocks, template part, post content block loading.

How?

The solution here is to replace the useEffect that was responsible for initializing the blocks (initial parsing) with a useMemo because the "blocks" is actually a computed value based on "content" or any previous block edits.

Testing Instructions

  • All tests should pass.
  • Loading a saved post continues to work as intended.

@youknowriad youknowriad added the [Type] Bug An existing feature does not function as intended label Jul 7, 2023
@youknowriad youknowriad requested a review from nerrad as a code owner July 7, 2023 11:19
@youknowriad youknowriad self-assigned this Jul 7, 2023
@github-actions
Copy link

github-actions bot commented Jul 7, 2023

Size Change: -12 B (0%)

Total Size: 1.43 MB

Filename Size Change
build/core-data/index.min.js 16.4 kB -15 B (0%)
build/editor/index.min.js 45.5 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.26 kB
build/block-editor/content.css 4.25 kB
build/block-editor/default-editor-styles-rtl.css 381 B
build/block-editor/default-editor-styles.css 381 B
build/block-editor/index.min.js 209 kB
build/block-editor/style-rtl.css 14.8 kB
build/block-editor/style.css 14.8 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 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 178 B
build/block-library/blocks/details/style.css 178 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-interactivity.min.js 317 B
build/block-library/blocks/file/view.min.js 375 B
build/block-library/blocks/footnotes/style-rtl.css 201 B
build/block-library/blocks/footnotes/style.css 199 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.23 kB
build/block-library/blocks/navigation/style.css 2.22 kB
build/block-library/blocks/navigation/view-interactivity.min.js 988 B
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 302 B
build/block-library/blocks/query-pagination/style.css 299 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/index.min.js 202 kB
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/index.min.js 14.9 kB
build/commands/style-rtl.css 827 B
build/commands/style.css 827 B
build/components/index.min.js 241 kB
build/components/style-rtl.css 11.8 kB
build/components/style.css 11.8 kB
build/compose/index.min.js 12 kB
build/core-commands/index.min.js 2.26 kB
build/customize-widgets/index.min.js 12 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/data/index.min.js 8.28 kB
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-site/index.min.js 88.8 kB
build/edit-site/style-rtl.css 13.1 kB
build/edit-site/style.css 13.1 kB
build/edit-widgets/index.min.js 16.9 kB
build/edit-widgets/style-rtl.css 4.52 kB
build/edit-widgets/style.css 4.52 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.4 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.18 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 951 B
build/react-i18n/index.min.js 615 B
build/react-refresh-entry/index.min.js 9.47 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.71 kB
build/reusable-blocks/style-rtl.css 243 B
build/reusable-blocks/style.css 243 B
build/rich-text/index.min.js 11 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

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.

The useMemo makes more sense here and kind of reminds me of this tweet - https://twitter.com/sophiebits/status/1293710971274289152.

The failing tests might be related to the change. Do you mind rebasing the branch so we can be sure?

@github-actions
Copy link

Flaky tests detected in 0a83da8.
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/5519472039
📝 Reported issues:

@Mamaduka
Copy link
Member

@youknowriad, I checked both undo e2e failures, which are somehow related to this change. The block selection is lost in both cases.

Screencasts

video.webm
video.webm

@youknowriad
Copy link
Contributor Author

@Mamaduka I think both behaviors in this PR and trunk are kind of random for the initial selection. I'll see if there's a way to restore trunk's behavior though.

@youknowriad
Copy link
Contributor Author

I know wonder whether the behavior in this branch is actually better. At least it's more "logical".

  • In trunk when you undo a change on a saved post, the selection is restored to the start of the paragraph/post
  • In this branch, it's just lost (undefined) but it's more correct in the sense that, this is the actual selection before the change happened.

On a new post, both this PR and trunk lose selection.

Any thoughts on this @ellatrix

@ellatrix
Copy link
Member

@youknowriad My opinion is that undo/redo selection is flawed, so we shouldn't let that block any other changes. We should look into history with selection again because it doesn't make sense in a lot of cases.

@ellatrix
Copy link
Member

So let's just adjust the e2e test and maybe leave a note with it :)

@youknowriad
Copy link
Contributor Author

Ok I went ahead and just updated the tests here.

@youknowriad
Copy link
Contributor Author

This seems to be breaking some mobile tests sigh

@youknowriad
Copy link
Contributor Author

@geriux @fluiddot Any idea why this might be impacting the mobile tests?

@fluiddot
Copy link
Contributor

@geriux @fluiddot Any idea why this might be impacting the mobile tests?

Hey @youknowriad 👋 , I can take a look tomorrow and share the findings. After a preliminary check, seems that on some tests the HTML generated in the editor is not being propagated to the mocked host app. Hence, when checking the snapshots they don't match.

@youknowriad
Copy link
Contributor Author

This PR prevents the editor from creating an "edit" for the "blocks" property in the core state if no changes have been made. Maybe the tests are always serializing the blocks "edit" and not falling back to the actual "content" property in that case. but not sure where this happens.

@fluiddot
Copy link
Contributor

This PR prevents the editor from creating an "edit" for the "blocks" property in the core state if no changes have been made. Maybe the tests are always serializing the blocks "edit" and not falling back to the actual "content" property in that case. but not sure where this happens.

@youknowriad I investigated the issue and seems the test failure seems to actually identify a breakage in the app. If I edit the content and undo all modifications, when saving the post it clears all content.

ios-empty-content-after-saving.mp4

As far as I checked, the problem is related to the initial HTML and getting the blocks in the editor provider. For the latter, if no edits are made it returns an empty list. This is used in the bridge function that synchronizes the post content with the host app to save it.

serializeToNativeAction() {
const title = this.props.title;
let html;
if ( this.props.mode === 'text' ) {
// The HTMLTextInput component does not update the store when user is doing changes
// Let's request the HTML from the component's state directly.
html = applyFilters( 'native.persist-html' );
} else {
html = serialize( this.props.blocks );
}
const hasChanges =
title !== this.post.title.raw || html !== this.post.content.raw;
// Variable to store the content structure metrics.
const contentInfo = {};
contentInfo.characterCount = wordCount(
html,
'characters_including_spaces'
);
contentInfo.wordCount = wordCount( html, 'words' );
contentInfo.paragraphCount = this.props.paragraphCount;
contentInfo.blockCount = this.props.blockCount;
RNReactNativeGutenbergBridge.provideToNative_Html(
html,
title,
hasChanges,
contentInfo
);
if ( hasChanges ) {
this.post.title.raw = title;
this.post.content.raw = html;
}
}

If you check the return of the above call in the native version of EditorProvider component, unless an edit is made to the content, it's returning []. Not sure if this is expected, but might be a bit confusing getting an empty list when getting the blocks via that selector before modifying the content. WDYT?

@fluiddot
Copy link
Contributor

Following the changes of this PR, I understand that the block list returned by useEntityBlockEditor hook would contain the ones parsed from the initial HTML before editing the post. I'm wondering if now on we should rely on that hook in the native version of EditorProvider component to get the blocks 🤔. However, I still have a concern regarding the getEditorBlocks selector returning an empty list, not sure if that might have other unknown side effects.

@youknowriad
Copy link
Contributor Author

@fluiddot We have two options: either "parse" the blocks in the selector of getEditorBlocks if there's no edits but IMO that's the wrong approach because the fact that this selector used to return values is only a result of it relying on an implicit assumption that there's always a "blocks" property in the "edited entity" but this assumption is not true at all, it's just that it happened that we had some logic in place that was triggering an edit on mount.

So for me the right fix would be to update the component instead.

@fluiddot
Copy link
Contributor

@fluiddot We have two options: either "parse" the blocks in the selector of getEditorBlocks if there's no edits but IMO that's the wrong approach because the fact that this selector used to return values is only a result of it relying on an implicit assumption that there's always a "blocks" property in the "edited entity" but this assumption is not true at all, it's just that it happened that we had some logic in place that was triggering an edit on mount.

Ah, I see. Thanks for elaborating @youknowriad 🙇. However, wouldn't be expected that the selector returns the current block list before editing? At least, based on the selector description, I'd assume that's the case.

/**
* Return the current block list.
*
* @param {Object} state
* @return {Array} Block list.
*/
export function getEditorBlocks( state ) {
return getEditedPostAttribute( state, 'blocks' ) || EMPTY_ARRAY;
}

I'm not opposed to keeping it as-is, but if we go this way, probably we should reflect this nuance in the description to avoid confusion.

So for me the right fix would be to update the component instead.

I can create a follow-up issue to update this component in the native version following the above convo. Probably I can try to spare some time over the next few days to tackle it. I assume the change would be straight-forward but I'd like to double check no regressions are introduced, especially as that component is a core one.

@youknowriad
Copy link
Contributor Author

Ah, I see. Thanks for elaborating @youknowriad 🙇. However, wouldn't be expected that the selector returns the current block list before editing? At least, based on the selector description, I'd assume that's the case.

I agree but the thing is that it never worked that way and I'm worry about changing the selector now.

@youknowriad
Copy link
Contributor Author

Seems like it worked. This PR should be ready now.

@fluiddot
Copy link
Contributor

fluiddot commented Jul 18, 2023

Seems like it worked. This PR should be ready now.

I've tested the iOS app and confirmed that this issue is not happening. Thanks Riad for updating the selector 🙇 !

@youknowriad youknowriad requested a review from mcsf July 18, 2023 15:03
@youknowriad
Copy link
Contributor Author

Any approvals here :)

Copy link
Contributor

@ntsekouras ntsekouras left a comment

Choose a reason for hiding this comment

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

This makes sense. Thanks Riad!

@youknowriad youknowriad merged commit f9ec882 into trunk Jul 19, 2023
@youknowriad youknowriad deleted the fix/initial-block-parsing branch July 19, 2023 07:54
@github-actions github-actions bot added this to the Gutenberg 16.3 milestone Jul 19, 2023
@youknowriad
Copy link
Contributor Author

Ok there's something wrong in this PR. It multiplied the "type" metric by a factor of 10 :) That's obviously wrong, I'm not sure yet why, but I'll take a look :) and revert if I don't find anything.

@youknowriad
Copy link
Contributor Author

Ok, so it's actually the "getEditorBlocks" selector change that is impactful here. Let me see if I can find the reason for that.

@aaronrobertshaw
Copy link
Contributor

It appears the changes in this PR lead to no blocks property on a customized template part entity which in turn now prevents the sidebar navigation editing for these template parts. A git bisect also pointed to this PR as breaking that feature.

@youknowriad
Copy link
Contributor Author

@aaronrobertshaw Can you clarify the steps to reproduce the issue here?

@aaronrobertshaw
Copy link
Contributor

@youknowriad, apologies, I should have added those replication steps to my initial comment. They are covered in the PR fixing this issue for sidebar navigation editing #52899.

  1. Open the Site Editor
  2. Open a template part that contains a navigation

As noted, for the specific case of editing navigation blocks contained within template parts, this has been fixed as of #52899. I'm not currently aware of any other use cases that might have relied on the blocks property being returned for edited entities.

jorgefilipecosta pushed a commit that referenced this pull request Aug 8, 2023
@noisysocks
Copy link
Member

noisysocks commented Aug 11, 2023

This also broke the BlockPreview that appears in the sidebar when editing a page in the site editor.

Screenshot 2023-08-11 at 10 45 57

The blocks attribute returned from getEditedEntityRecord is now undefined.

I'll open a PR similar to #52899.

@youknowriad: Do you think we need to add some backwards compatibility logic to getEditedEntityRecord for this change? It seems like we were accessing blocks in a few places so it may be that lots of plugins are doing the same thing.

@youknowriad
Copy link
Contributor Author

@youknowriad: Do you think we need to add some backwards compatibility logic to getEditedEntityRecord for this change? It seems like we were accessing blocks in a few places so it may be that lots of plugins are doing the same thing.

If it doesn't hurt performance, I'm all for it. But I want to note that the previous behavior was not guaranteed, it was just an "effect" that was triggered in a random component, that effect could have been triggered or not, depending on the context. It happens that it was in most contexts though.

@noisysocks
Copy link
Member

I guess let's wait to see if we get reports about this from third parties.

I assume it won't impact performance if we make blocks a getter.

get blocks() {
	return parse( record.content );
}

@youknowriad
Copy link
Contributor Author

I think there's something imperfect with the "transient edits", we haven't specified exactly how these should work and who's responsible for setting them, saving them back to regular edits...

return content && typeof content !== 'function'
? parse( content )
: EMPTY_ARRAY;
}, [ editedBlocks, content ] );
Copy link
Member

Choose a reason for hiding this comment

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

This change has had one unpleasant side effect on the undo stack. When the post editor is initially loaded, the post entity in the Core Data store will have the content attribute, but there is no blocks attribute. The parsed blocks are stored only as a local memo state in this provider component, and there is no longer any editEntityRecord call that would save them in the store. The blocks attribute is set only on the first real edit.

The first real edit will produce an EDIT_ENTITY_RECORD action that has action.meta.undo.edits.blocks set to undefined. The state.undo reducer will create an undo stack record for this edit, and it will look like { property: 'blocks', from: undefined, to: [ ... ] }.

Applying that undo record means that the blocks attribute will be set to undefined, the value of the from field of the undo record. But instead of undefined, it should have been the original parsed blocks, the value is known.

Setting blocks to undefined means that on undo, they will need to be parsed from scratch from the content string and all client IDs will be different.

This will cause all blocks' edit components to be unmounted and re-created from scratch, on a simple undo operation that shouldn't do this. It should just update one little attribute of one little block.

We've seen the unpleasant effect of this when refactoring the TOC block in #54094 (comment).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Setting blocks to undefined means that on undo, they will need to be parsed from scratch from the content string and all client IDs will be different.
This will cause all blocks' edit components to be unmounted and re-created from scratch, on a simple undo operation that shouldn't do this. It should just update one little attribute of one little block.

I agree that ideally the components should be unmounted and recreated from scratch but making the "blocks" edit undefined on undo is (in isolation) a fine.

That said, I think maybe we need a way to tell core-data to load these transient values on initial "fetch" of the entities instead of leaving that to consumer code which will always lead to inconsistencies.

Copy link
Member

Choose a reason for hiding this comment

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

making the "blocks" edit undefined on undo is (in isolation) a fine.

In this case it's not fine, because conceptually the blocks value is known and it's not undefined. It just lives outside the data store, in React state. Losing that value leads to losing information, namely the blocks' already assigned client IDs.

I don't know how to fix it, and the issue is not terribly urgent. I mainly wanted to document that it exists and write down what I found.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Package] Editor /packages/editor [Type] Bug An existing feature does not function as intended
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants