Skip to content

Guard off-slot/page drops on the example layout canvas so video isn't…#1345

Open
minion1227 wants to merge 1 commit into
e35dev:mainfrom
minion1227:minion_example-canvas-drop-guard
Open

Guard off-slot/page drops on the example layout canvas so video isn't…#1345
minion1227 wants to merge 1 commit into
e35dev:mainfrom
minion1227:minion_example-canvas-drop-guard

Conversation

@minion1227

Copy link
Copy Markdown
Contributor

What & why

The preview shell's example layout canvas (preview/index.html) accepts
real video uploads into its slots — each slot has a <input type="file" accept="video/*"> and a drop zone wired to placeVideoFile. But the drop and
dragover handlers were attached only to the slot elements. There was no
document-level guard.

So a real video file released off a slot — on a canvas gap, the header, or
the page margin — fell through to the browser's default "open this file"
behavior, which navigates the page away and discards the single-page shell
and every placement the creator had made.

This is the same #1213 data-loss scenario the layout-first canvas
(preview/layout-first.js) was already hardened against at the document level.
The example canvas had the identical exposure (it accepts real uploads and
renders them) but never received the guard.

Reproduce (before)

  1. On the example layout canvas, place a real host + guest video.
  2. Drag another real video file from the desktop and drop it on the canvas gap
    (or the page margin), not on a slot.
  3. The browser navigates away to open the file — the shell and both placements
    are gone.

Change

Mirror the layout-first.js fix in the example-canvas inline script:

  • Add a document-level dragover guard (preventDefault) so off-slot drops
    are catchable instead of navigating.
  • Add a document-level drop guard that prevents the default navigation and
    routes an off-slot real video into the first open slot (Host → Guest →
    Guest 2 → optional B-roll), so a near-miss still places. When every slot is
    filled, it tells the creator to make room rather than letting the file vanish.
  • On-slot drops now stopPropagation, so a slot drop isn't also re-routed by the
    document handler.
  • A dragged sample track carries no file, so it stays a harmless no-op.
  • The guard is feature-detected (typeof document.addEventListener === "function")
    so it never throws in the project's dependency-free DOM-stub tests.

Testing

  • npm test — all 104 test files pass.
  • preview/preview-canvas-video.test.js — adds an executed off-slot-drop test:
    a page-level drop is prevented (no navigation) and routes into the first open
    slot; on a full layout it's still prevented and surfaces "make room" guidance.
  • preview/preview.test.js — adds a static assertion pinning the document-level
    dragover/drop guard so a refactor can't silently drop it.

No visual/UI change to the canvas; on-slot placement, the sample tracks, the
layout picker, and the gated Continue all behave exactly as before.

Files

  • preview/index.html — document-level off-slot drop guard + firstOpenSlot
    helper + on-slot stopPropagation.
  • preview/preview-canvas-video.test.js — executed off-slot-drop-guard test.
  • preview/preview.test.js — static guard assertion.

… lost

The preview shell's example layout canvas accepts real video uploads into its
slots (file inputs + drop zones), but it wired drop/dragover handlers ONLY on
the slot elements — there was no document-level guard. So a real video dropped
on a canvas gap, the header, or the page margin triggered the browser's default
"open this file" navigation, discarding the shell and every placement the
creator had made. This is the same e35dev#1213 data-loss scenario the layout-first
canvas (layout-first.js) was already hardened against; the example canvas had
the same exposure but not the guard.

Add a document-level dragover/drop guard (mirroring layout-first.js): keep drops
catchable (preventDefault on dragover) and route an off-slot real video into the
first open slot so a near-miss still places, with creator-facing guidance when
every slot is filled. On-slot drops now stopPropagation so they aren't double-
handled. A dragged sample track carries no file, so it stays a no-op. The guard
is feature-detected (typeof document.addEventListener) so it never throws in the
dependency-free DOM-stub tests.

Adds an executed off-slot drop-guard test to preview-canvas-video.test.js and a
static guard assertion to preview.test.js. Full suite: 104 files pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant