Skip to content

Fix drag preview revert wedging further drags (#1296) - #1298

Merged
microbit-matt-hillsdon merged 1 commit into
mainfrom
fix/dnd-revert-preview-1296
Sep 4, 2026
Merged

Fix drag preview revert wedging further drags (#1296)#1298
microbit-matt-hillsdon merged 1 commit into
mainfrom
fix/dnd-revert-preview-1296

Conversation

@microbit-matt-hillsdon

@microbit-matt-hillsdon microbit-matt-hillsdon commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator

revertPreview replayed a ChangeSet captured when the preview was inserted. If the document length moved on before the revert, ChangeSet.apply threw, and because lastDragPos was cleared only after the dispatch, every later dragover and drop re-threw with the same stale change set until reload. This is the top error by volume in Sentry.

Three changes, none dependent on which path trips it:

  • Clear the stashed drag position before dispatching the revert, so one failure cannot wedge later drags.
  • Map the preview undo through any document changes made while the preview is showing, and skip the revert if the length still doesn't match, so an edit under the preview no longer throws.
  • Revert a leftover preview when the drag ends by any route, not only via dragleave/drop on the editor. Clearing the drag context (dragend) now reverts the preview and removes the stuck cm-drag-in-progress class, covering a drag cancelled or dropped elsewhere.

Reworked the bare domEventHandlers into a ViewPlugin so the handlers can observe document updates and clean up on view destroy.

Added two e2e cases: a document change during a drag, and a drag that ends without a dragleave. Both fail on the previous code.

Not reproduced manually. The precondition and fix were worked out from the Sentry stack and the code; the mechanism was exercised via emulated drags under Playwright, not a real pointer (Firefox + Chrome).

Fixes #1296

revertPreview replayed a ChangeSet captured when the preview was inserted.
If the document length moved on before the revert, ChangeSet.apply threw,
and because lastDragPos was cleared only after the dispatch, every later
dragover and drop re-threw with the same stale change set until reload.
This is the top error by volume in Sentry.

Three changes, none dependent on which path trips it:

- Clear the stashed drag position before dispatching the revert, so one
  failure cannot wedge later drags.
- Map the preview undo through any document changes made while the preview
  is showing, and skip the revert if the length still doesn't match, so an
  edit under the preview no longer throws.
- Revert a leftover preview when the drag ends by any route, not only via
  dragleave/drop on the editor. Clearing the drag context (dragend) now
  reverts the preview and removes the stuck cm-drag-in-progress class,
  covering a drag cancelled or dropped elsewhere.

Reworked the bare domEventHandlers into a ViewPlugin so the handlers can
observe document updates and clean up on view destroy.

Added two e2e cases: a document change during a drag, and a drag that ends
without a dragleave. Both fail on the previous code.

Not reproduced manually. The precondition and fix were worked out from the
Sentry stack and the code; the mechanism was exercised via emulated drags
under Playwright, not a real pointer, and not in Firefox where Sentry saw
it. The e2e tests pin the behaviour going forward.
@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown

@microbit-matt-hillsdon

Copy link
Copy Markdown
Collaborator Author

I've spent quite a while trying to figure out a repro for this one that doesn't rely on synthetic drag events without success. The logic holds up but how either of the scenarios identified above happens I do not know. I suspect it's the missing event rather than the doc change which I can't see a source for (at least for length, maybe a diagnostic could arrive late).

@microbit-robert microbit-robert left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM. Code changes look good. I can't seem to break anything via drag and drop.

@microbit-matt-hillsdon
microbit-matt-hillsdon merged commit e6dcb45 into main Sep 4, 2026
2 checks passed
@microbit-matt-hillsdon
microbit-matt-hillsdon deleted the fix/dnd-revert-preview-1296 branch September 4, 2026 12:33
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.

Drag and drop: revertPreview throws on a stale change set and wedges further drags

2 participants