Skip to content

Image: notify when several dropped files cannot become a Gallery - #85467

Draft
mtias wants to merge 1 commit into
trunkfrom
auto/quality/2026-10-21-image-multi-file-drop
Draft

mtias wants to merge 1 commit into
trunkfrom
auto/quality/2026-10-21-image-multi-file-drop

Conversation

@mtias

@mtias mtias commented Oct 23, 2026

Copy link
Copy Markdown
Member

What?

When several files are dropped on an Image block placeholder in a position where no Gallery can be inserted (a parent whose allowedBlocks excludes core/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 shared isFile() helper, which the Playlist block already carried a private copy of.

Why?

onSelectImagesList in packages/block-library/src/image/edit.jsx (from #65030) had two silent exits:

  1. No Gallery insertable and not inside one: it returned without feedback. That is the user-facing change here; the notice is the one the Cover placeholder and the media upload utilities already use in the same situation.
  2. file instanceof win.File, with win the 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's pageUtils.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 on name/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 DataTransfer in the top window).

How?

  • image/edit.jsx: two separate guards in onSelectImagesList: 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 File via Object.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

  1. Insert a Group, set its allowedBlocks to [ "core/image" ] (the code editor is the quickest way), and put an empty Image block inside it.
  2. Drag two image files from your desktop onto the placeholder. Trunk: nothing happens. This branch: the "Only one file can be used here." snackbar appears and the placeholder stays.
  3. Drop two images on a top-level Image placeholder: a Gallery of two, as before.
  4. Unit: npm run test:unit -- packages/block-library/src/utils packages/block-library/src/image (new is-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.png and video.webm for each build).

🤖 Generated with Claude Code

`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>
@github-actions github-actions Bot added the [Package] Block library /packages/block-library label Oct 23, 2026
@github-actions

github-actions Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

🤖 PR meta 🤖

Preview in WordPress Playground

🏷️ Labels

This pull request needs exactly one label indicating its type, and has 0.

  • Required: any label starting with [Type].
  • Found: none.

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

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[Package] Block library /packages/block-library

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant