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

Block API: Introduce "local" attributes and use it for the image block #63076

Merged
merged 7 commits into from
Jul 8, 2024

Conversation

youknowriad
Copy link
Contributor

@youknowriad youknowriad commented Jul 3, 2024

Related #39223
Related discussion #49466.

What?

For some blocks (mostly media blocks), we need a way to create the blocks from transforms using temporary files. After the temporary image is inserted, we upload the image to the media library and upon success update the block with the Right URL.

So far, we were doing this using "blob urls" (local urls) in the URL attribute for images. The problem with this approach is that if you're fast enough and save your post while the image is still being uploaded, you might end up with "temporary urls" in the saved post. This should never be the case.

One potential solution that has been considered is to block "saving" when an upload is in progress. I think that's not ideal and doesn't address the root cause where anyone can actually trigger the saving programmatically.

The root cause is that we're actually putting local state (temporary urls) in the block attributes that are meant to be saved because we need immediate feedback (block insertion) when drag and dropping blocks. So a solution I'm proposing in this PR is to introduce the concept of "temporary block attributes":

  • These are attributes that don't get saved into the database. When you call serialize for a block, they are actually ignored and do not persist in the HTML.
  • In this PR, I've updated the image block to use this attribute instead of the previous blob urls.

Note: There's probably some undo/related logic that need updating but I'm thinking that most of the time, when we actually set this attribute, we'll also be setting another non temporary attribute, so in most cases, there's no impact on undo/redo.

Note 2: I know that this idea has been discussed previously on multiple occasions, feel free to update the PR descriptions and link into any relevant issue or discussion.

Testing Instructions

1- Throttle your network speed (that way uploading images will take a long time)
2- Drag and drop an image file into the post editor.
3- Save the post immediately.
4- Open the post in a new tab and notice that the inserted image is actually empty.
5- Go back to the old tab, and wait until the upload completes.
6- Notice that the image block has been updated properly with the right URL.

@youknowriad youknowriad added [Feature] Block API API that allows to express the block paradigm. [Block] Image Affects the Image Block [Type] New API New API to be used by plugin developers or package users. labels Jul 3, 2024
@youknowriad youknowriad self-assigned this Jul 3, 2024
Copy link

github-actions bot commented Jul 3, 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: youknowriad <youknowriad@git.wordpress.org>
Co-authored-by: mtias <matveb@git.wordpress.org>
Co-authored-by: talldan <talldanwp@git.wordpress.org>
Co-authored-by: Mamaduka <mamaduka@git.wordpress.org>
Co-authored-by: ntsekouras <ntsekouras@git.wordpress.org>
Co-authored-by: noisysocks <noisysocks@git.wordpress.org>
Co-authored-by: ellatrix <ellatrix@git.wordpress.org>
Co-authored-by: gziolo <gziolo@git.wordpress.org>

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

Copy link

github-actions bot commented Jul 3, 2024

Size Change: +4.28 kB (+0.24%)

Total Size: 1.76 MB

Filename Size Change
build/block-editor/index.min.js 252 kB +56 B (+0.02%)
build/block-library/index.min.js 219 kB -14 B (-0.01%)
build/blocks/index.min.js 52.2 kB +8 B (+0.02%)
build/components/index.min.js 227 kB +4.08 kB (+1.83%)
build/core-data/index.min.js 72.6 kB +28 B (+0.04%)
build/edit-site/index.min.js 208 kB +21 B (+0.01%)
build/edit-site/posts-rtl.css 6.51 kB -24 B (-0.37%)
build/edit-site/posts.css 6.52 kB -23 B (-0.35%)
build/edit-site/style-rtl.css 11.7 kB -25 B (-0.21%)
build/edit-site/style.css 11.7 kB -25 B (-0.21%)
build/editor/index.min.js 98.4 kB +192 B (+0.2%)
ℹ️ View Unchanged
Filename Size
build/a11y/index.min.js 951 B
build/annotations/index.min.js 2.26 kB
build/api-fetch/index.min.js 2.31 kB
build/autop/index.min.js 2.12 kB
build/blob/index.min.js 579 B
build/block-directory/index.min.js 7.31 kB
build/block-directory/style-rtl.css 1.01 kB
build/block-directory/style.css 1.01 kB
build/block-editor/content-rtl.css 4.58 kB
build/block-editor/content.css 4.58 kB
build/block-editor/default-editor-styles-rtl.css 394 B
build/block-editor/default-editor-styles.css 394 B
build/block-editor/style-rtl.css 15.9 kB
build/block-editor/style.css 15.9 kB
build/block-library/blocks/archives/editor-rtl.css 61 B
build/block-library/blocks/archives/editor.css 60 B
build/block-library/blocks/archives/style-rtl.css 90 B
build/block-library/blocks/archives/style.css 90 B
build/block-library/blocks/audio/editor-rtl.css 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 310 B
build/block-library/blocks/button/editor.css 310 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 336 B
build/block-library/blocks/buttons/editor.css 336 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 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 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-content/style-rtl.css 90 B
build/block-library/blocks/comment-content/style.css 90 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 221 B
build/block-library/blocks/comments-pagination/editor.css 211 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 668 B
build/block-library/blocks/cover/editor.css 669 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 314 B
build/block-library/blocks/embed/editor.css 314 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 342 B
build/block-library/blocks/form-input/style.css 342 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 958 B
build/block-library/blocks/gallery/editor.css 962 B
build/block-library/blocks/gallery/style-rtl.css 1.71 kB
build/block-library/blocks/gallery/style.css 1.71 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 402 B
build/block-library/blocks/group/editor.css 402 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 845 B
build/block-library/blocks/image/editor.css 843 B
build/block-library/blocks/image/style-rtl.css 1.54 kB
build/block-library/blocks/image/style.css 1.54 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.54 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 204 B
build/block-library/blocks/latest-posts/editor.css 204 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 104 B
build/block-library/blocks/list/style.css 104 B
build/block-library/blocks/media-text/editor-rtl.css 304 B
build/block-library/blocks/media-text/editor.css 303 B
build/block-library/blocks/media-text/style-rtl.css 516 B
build/block-library/blocks/media-text/style.css 515 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 663 B
build/block-library/blocks/navigation-link/editor.css 664 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.2 kB
build/block-library/blocks/navigation/editor.css 2.21 kB
build/block-library/blocks/navigation/style-rtl.css 2.26 kB
build/block-library/blocks/navigation/style.css 2.25 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/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 506 B
build/block-library/blocks/post-comments-form/style.css 506 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-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 141 B
build/block-library/blocks/post-excerpt/style.css 141 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 341 B
build/block-library/blocks/post-featured-image/style.css 341 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 100 B
build/block-library/blocks/post-title/style.css 100 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 220 B
build/block-library/blocks/query-pagination/editor.css 208 B
build/block-library/blocks/query-pagination/style-rtl.css 287 B
build/block-library/blocks/query-pagination/style.css 283 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 502 B
build/block-library/blocks/query/editor.css 502 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 221 B
build/block-library/blocks/quote/theme.css 225 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 183 B
build/block-library/blocks/search/editor.css 183 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-title/editor-rtl.css 123 B
build/block-library/blocks/site-title/editor.css 123 B
build/block-library/blocks/site-title/style-rtl.css 71 B
build/block-library/blocks/site-title/style.css 71 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 676 B
build/block-library/blocks/social-links/editor.css 675 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/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/style-rtl.css 266 B
build/block-library/blocks/tag-cloud/style.css 265 B
build/block-library/blocks/template-part/editor-rtl.css 393 B
build/block-library/blocks/template-part/editor.css 393 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 108 B
build/block-library/blocks/term-description/style.css 108 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 553 B
build/block-library/blocks/video/editor.css 554 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.9 kB
build/block-library/editor.css 11.9 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.6 kB
build/block-library/style.css 14.6 kB
build/block-library/theme-rtl.css 702 B
build/block-library/theme.css 707 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 15.2 kB
build/commands/style-rtl.css 955 B
build/commands/style.css 952 B
build/components/style-rtl.css 12.1 kB
build/components/style.css 12.1 kB
build/compose/index.min.js 12.9 kB
build/core-commands/index.min.js 2.77 kB
build/customize-widgets/index.min.js 10.9 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.65 kB
build/edit-post/classic-rtl.css 578 B
build/edit-post/classic.css 580 B
build/edit-post/index.min.js 12.5 kB
build/edit-post/style-rtl.css 2.34 kB
build/edit-post/style.css 2.33 kB
build/edit-widgets/index.min.js 17.6 kB
build/edit-widgets/style-rtl.css 4.18 kB
build/edit-widgets/style.css 4.18 kB
build/editor/style-rtl.css 9.15 kB
build/editor/style.css 9.15 kB
build/element/index.min.js 4.83 kB
build/escape-html/index.min.js 537 B
build/format-library/index.min.js 8.07 kB
build/format-library/style-rtl.css 494 B
build/format-library/style.css 493 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/interactivity/debug.min.js 16.5 kB
build/interactivity/file.min.js 447 B
build/interactivity/image.min.js 1.68 kB
build/interactivity/index.min.js 13.4 kB
build/interactivity/navigation.min.js 1.16 kB
build/interactivity/query.min.js 742 B
build/interactivity/router.min.js 2.8 kB
build/interactivity/search.min.js 615 B
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.17 kB
build/list-reusable-blocks/style-rtl.css 846 B
build/list-reusable-blocks/style.css 846 B
build/media-utils/index.min.js 2.92 kB
build/modules/importmap-polyfill.min.js 12.3 kB
build/notices/index.min.js 946 B
build/nux/index.min.js 1.58 kB
build/nux/style-rtl.css 749 B
build/nux/style.css 745 B
build/patterns/index.min.js 7.35 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 578 B
build/preferences/style.css 578 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.73 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.01 kB
build/token-list/index.min.js 581 B
build/url/index.min.js 3.85 kB
build/vendors/react-dom.min.js 42.8 kB
build/vendors/react-jsx-runtime.min.js 560 B
build/vendors/react.min.js 2.65 kB
build/viewport/index.min.js 965 B
build/warning/index.min.js 250 B
build/widgets/index.min.js 7.19 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

@ellatrix
Copy link
Member

ellatrix commented Jul 3, 2024

When did we start doing this? The last thing I remember was that we wait to set attributes until the image is uploaded until we set the URL attribute, and the blob was just a local state. That's how the undo trap was fixed too. I wonder what changed where we put blob URLs in the attributes?

@ellatrix
Copy link
Member

ellatrix commented Jul 3, 2024

Super dumb idea:

What if we saved images when the post is saved, and replace URLs server side as images are uploaded and URLs resolved? This would also fix any sort of undo issues.

@Mamaduka
Copy link
Member

Mamaduka commented Jul 3, 2024

I wonder what changed where we put blob URLs in the attributes?

The file type block transformations. Currently, it can't be avoided there.

@youknowriad
Copy link
Contributor Author

When did we start doing this? The last thing I remember was that we wait to set attributes until the image is uploaded until we set the URL attribute, and the blob was just a local state. That's how the undo trap was fixed too. I wonder what changed where we put blob URLs in the attributes?

To be honest, that's very old, almost from the start (when we implemented drag and drop files)

@youknowriad
Copy link
Contributor Author

What if we saved images when the post is saved, and replace URLs server side as images are uploaded and URLs resolved? This would also fix any sort of undo issues.

Not dumb at all but I think it's way too complex to implement. It would be good if we had a way to "create entities" with temporary ids or things like that and refer to them in other places of our data (things like categories, tags, images, even patterns, ...) but it's a huge and very unclear undertaking.

@youknowriad
Copy link
Contributor Author

Should we consider the __experimentalRole instead of isTemporary?

I think that's a good point. so __experimentalRole="local" or something instead of a separate isLocal flag. Any thoughts @mtias ?

@mtias
Copy link
Member

mtias commented Jul 3, 2024

Could work.

@noisysocks
Copy link
Member

noisysocks commented Jul 4, 2024

A simpler solution for just the image block issue is 37d6855. Basically we store the blob in a @wordpress/block-library module variable.

This PR is the same approach that #34750 took so it's worth reading the discussion there.

In revisiting it again, I do like this approach and I'm keen to just try it out instead of discussing it again ad nauseam.

You'll need to add a check for __experimentalRole === 'local' to the code that handles copying a block so that, if you duplicate an image block while it is in its temporary blob state, you get a new image block showing the placeholder.

I like local or internal as a name better than temporary as attributes like this can be useful for non-temporary things e.g. storing widgetId in the widget block or storing productId in a Pay with PayPal block. See #49466.

That brings me to the real question I want us to consider here:

Sometimes we want an attribute that is not serialised to HTML and is not copied when you duplicate a block. For example: blob, widgetId. Other times we want an attribute that is serialised to HTML but is not copied when you duplicate a block. For example: productId.

This PR handles the former but not the latter. Do you think we should, in addition to __experimentalRole = 'local' to handle the former, add another __experimentalRole to handle the latter? Then we can close #29693.

@youknowriad
Copy link
Contributor Author

Sometimes we want an attribute that is not serialised to HTML and is not copied when you duplicate a block. For example: blob, widgetId. Other times we want an attribute that is serialised to HTML but is not copied when you duplicate a block. For example: productId.

This PR handles the former but not the latter. Do you think we should, in addition to __experimentalRole = 'local' to handle the former, add another __experimentalRole to handle the latter? Then we can close #29693.

I'm not sure, why would you not want to duplicate a product block with a productID ? I'm wondering if there's something we're missing on the UX side here and that duplication is actually fine here. Do you have more use-cases in mind.

Overall though, you I think it should be fine to have a shouldDuplicate = false or something but to be honest, I have a lot of doubt here. Because can be created in different ways anyway (outside duplication), like programmatically and in that case, it's not possible to handle duplication, so this leave me to think that maybe a better UX here is to actually show something in the block itself that it's a duplicate block, like we do for blocks that should only be used once.

@youknowriad
Copy link
Contributor Author

I'm actually even hesitant to prevent these local attributes from being duplicated. Sure, in our current case it will result in two image blocks with the same images but uploaded twice but isn't that better than an empty image and an uploaded image from a user's perspective.

@youknowriad
Copy link
Contributor Author

For the widgetId and as implemented today, I think it can be seen as a "local" attribute but ultimately, I also wonder if our widgets editor is the right UI for these and I would love if in the future (I know it's not priority) we merge it with template parts as widget areas are template parts are actually the exact same thing, so I can see the site editor's approach to editing template parts used for widget editor too (we could even use the @wordpress/editor package in that case). Which makes me think that we shouldn't be optimizing for that use-case for now.

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.

I think it's okay to go with this approach and I was in favor of this way back with the other PR.

Let's 🚢

@noisysocks
Copy link
Member

I'm not sure, why would you not want to duplicate a product block with a productID ? I'm wondering if there's something we're missing on the UX side here and that duplication is actually fine here. Do you have more use-cases in mind.

From #29693:

I'm working on the Jetpack Pay with PayPal block. It contains a productId attribute which uniquely identifies the actual product record referenced by the block. When a new block is inserted this attribute will be undefined; we hit the API to create a new product, and store the returned id in this attribute.

When the block is duplicated, I'd like to create a new product record with identical fields (title/price/etc). But because the productId is cloned along with all the other attributes, both blocks will point to the same resource. It's possible to keep track of the block's unique clientId and reset the product when this value changes — but while this detects block duplication, it also changes every time the post loads, and I only want to reset the product on duplication.

@noisysocks
Copy link
Member

noisysocks commented Jul 5, 2024

OK, but if we don't care about the productId use case or the widgetId use case then why not go with an approach that doesn't require a new API?

Either something like 37d6855 which stores the blob in a module variable.

Or set the blob attribute when calling createBlock() but don't add blob to block.json. The block editor currently ignores attributes that aren't in block.json when serialising a block. In other words this PR should work fine without the changes to packages/block-library/image/block.json and packages/blocks.

@Mamaduka
Copy link
Member

Mamaduka commented Jul 5, 2024

Here's yet another duplication-related issue, #55823.

@youknowriad
Copy link
Contributor Author

@noisysocks I'm not disregarding the duplication issue but I think it's less important and unclear to me still. It feels like a separate concern to me at this point than local attributes.

For the solution you propose, it doesn't work, because we want to be able to create blocks with these temporary attributes from outside the block itself (block transforms...) and createBlock function calls sanitize the attributes and remove the unnecessary ones. I think there's value in being explicit about the things that you can pass when creating a block.

Copy link
Member

@noisysocks noisysocks left a comment

Choose a reason for hiding this comment

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

I don't want to make perfect the enemy of good, let's try it. Thanks for listening 😀

@gziolo gziolo changed the title Block API: Introduce temporary attributes and use it for the image block Jul 8, 2024
@gziolo
Copy link
Member

gziolo commented Jul 8, 2024

I updated the title to use the local keyword to reflect the implementation better.

As a follow-up, it would finally rename the field __experimentalRole to role and document it so folks can use it confidently in 3rd party projects. It seems like a step in the right direction to help resolve several similar issues outlined by @noisysocks in #49466 and highlighted in this PR.

@youknowriad youknowriad merged commit 89f7197 into trunk Jul 8, 2024
63 checks passed
@youknowriad youknowriad deleted the add/introduce-temporary-attributes branch July 8, 2024 11:10
@github-actions github-actions bot added this to the Gutenberg 18.8 milestone Jul 8, 2024
@adamsilverstein
Copy link
Member

adamsilverstein commented Jul 8, 2024

One potential solution that has been considered is to block "saving" when an upload is in progress. I think that's not ideal and doesn't address the root cause where anyone can actually trigger the saving programmatically.

I still feel the UI should reflect the incomplete state of uploading media. If the media shows a spinner and the image is being uploaded, users should be prevented from publishing a post or from updating a published post.

If they do so, the front end of the post will reflect a "broken" state where media is only partially uploaded. Even if revisiting the editor will automatically complete the upload, we should provide a better user experience by not letting users inadvertently publish broken content.

See #39223

@youknowriad
Copy link
Contributor Author

@adamsilverstein yes, I didn't close that issue because I also think there's value in letting the user know that there are things in progress. I think both things are necessary though. We need the data to be correct, which this PR does, and we need the UI to be controllable by blocks somehow which we don't have a good API for yet.

@talldan
Copy link
Contributor

talldan commented Jul 9, 2024

users should be prevented from publishing a post or from updating a published post.

Just to put another option out there, rather than preventing, the save button could still be clickable, but the save request could wait for the image upload to be complete before initiating. This way it could be almost imperceptible for users, except for saving taking a bit longer while the two requests complete.

huubl pushed a commit to huubl/gutenberg that referenced this pull request Jul 10, 2024
WordPress#63076)

Co-authored-by: youknowriad <youknowriad@git.wordpress.org>
Co-authored-by: mtias <matveb@git.wordpress.org>
Co-authored-by: talldan <talldanwp@git.wordpress.org>
Co-authored-by: Mamaduka <mamaduka@git.wordpress.org>
Co-authored-by: ntsekouras <ntsekouras@git.wordpress.org>
Co-authored-by: noisysocks <noisysocks@git.wordpress.org>
Co-authored-by: ellatrix <ellatrix@git.wordpress.org>
Co-authored-by: gziolo <gziolo@git.wordpress.org>
carstingaxion pushed a commit to carstingaxion/gutenberg that referenced this pull request Jul 18, 2024
WordPress#63076)

Co-authored-by: youknowriad <youknowriad@git.wordpress.org>
Co-authored-by: mtias <matveb@git.wordpress.org>
Co-authored-by: talldan <talldanwp@git.wordpress.org>
Co-authored-by: Mamaduka <mamaduka@git.wordpress.org>
Co-authored-by: ntsekouras <ntsekouras@git.wordpress.org>
Co-authored-by: noisysocks <noisysocks@git.wordpress.org>
Co-authored-by: ellatrix <ellatrix@git.wordpress.org>
Co-authored-by: gziolo <gziolo@git.wordpress.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Block] Image Affects the Image Block [Feature] Block API API that allows to express the block paradigm. [Type] New API New API to be used by plugin developers or package users.
9 participants