Repository navigation
Conversation
`onSelectImagesList` in the Image block, which turns several files dropped on the placeholder into a Gallery, had two silent exits: 1. When no Gallery can be inserted at the block's position (a parent whose `allowedBlocks` excludes `core/gallery`) and the block is not already inside one, it returned without doing anything. The user got no feedback at all. It now shows the "Only one file can be used here." notice that the Cover placeholder and the media upload utilities show in the same situation. 2. Its file check was `file instanceof win.File`, with `win` the window rendering the block (the editor canvas iframe). A drop dispatched by the browser creates the files in that iframe's realm, so a user's drag passed the check; files created in another realm did not and were dropped on the floor. That is reachable from synthetic drops (Playwright's `pageUtils.dragFiles` builds its `DataTransfer` in the top window; scripts and other embeddings can do the same), not from a user's drag. The check now uses a realm-agnostic `isFile` helper in `utils/is-file.ts`, based on the `Object.prototype.toString` tag that every realm's `File` shares; the Playlist block had its own copy of that helper and now uses the shared one. The e2e test drops two top-realm files on the placeholder and expects a Gallery with both uploaded; it fails on trunk because of (2). Considered and rejected: accepting `window.File` next to `win.File` (still realm-bound, untestable in jsdom); duck-typing on `name`/`type`/`size` (media library objects carry the same keys); dropping the file check (the array branch is also where a multi-selection of library items would land). Quality walkthrough finding Q-2026-10-21-1. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
🤖 PR meta 🤖🏷️ LabelsThis pull request needs exactly one label indicating its type, and has 0.
Read more about Type labels in Gutenberg. If you cannot add labels yourself, a reviewer can do it for you. |
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What?
When several files are dropped on an Image block placeholder in a position where no Gallery can be inserted (a parent whose
allowedBlocksexcludescore/gallery), the block now shows the "Only one file can be used here." notice instead of doing nothing. The file check behind the multi-file drop also becomes realm-agnostic through a sharedisFile()helper, which the Playlist block already carried a private copy of.Why?
onSelectImagesListinpackages/block-library/src/image/edit.jsx(from #65030) had two silent exits:file instanceof win.File, withwinthe canvas iframe window. A browser-dispatched drop creates the files in that realm, so a real drag was never affected; files created in another window (synthetic drops such as Playwright'spageUtils.dragFiles, scripts, other embeddings) failed the check and were dropped on the floor. This part is hardening, not a bug users hit by dragging.Considered and rejected:
window.File || win.File(still realm-bound, untestable in jsdom); duck-typing onname/type/size(media library objects carry the same keys, and this branch is also where a multi-selection of library items lands); removing the check (same).Found by a quality walkthrough (finding Q-2026-10-21-1, initially filed as "dropping two images does nothing", which turned out to be the test harness building its
DataTransferin the top window).How?
image/edit.jsx: two separate guards inonSelectImagesList: not a list of Files → return; no Gallery insertable and not inside one → error notice and return. Also an early return when no valid image remains after filtering, so an all-invalid drop no longer creates an empty Gallery.utils/is-file.ts:isFile( value ): value is FileviaObject.prototype.toString.call( value ) === '[object File]', with a JSDoc explaining the realm issue.playlist/edit.jsx: uses the shared helper (no behaviour change).block-library/CHANGELOG.md: Bug Fixes line under Unreleased.Testing Instructions
allowedBlocksto[ "core/image" ](the code editor is the quickest way), and put an empty Image block inside it.npm run test:unit -- packages/block-library/src/utils packages/block-library/src/image(newis-file.jsdom.test.ts). E2e:npm run test:e2e -- test/e2e/specs/editor/blocks/image.spec.js(the new test fails on trunk, passes here).Verified locally: unit (135 tests), eslint, prettier, tsc, build; Playwright on a local site for the notice case (trunk vs branch, with video), mixed PNG+txt (format notice + Gallery of one), two txt (notice, placeholder kept), placeholder inside a Gallery (two sibling images), browser-dispatched drop of two PNGs on trunk and branch (Gallery of two on both).
Screenshots or screencast
Before (trunk) and after (branch) of step 2: to be attached from the local review recording (
3-after-drop.pngandvideo.webmfor each build).🤖 Generated with Claude Code