Preview rich-text editor: open with drag-selection preserved (bd-abo9m23f)#383
Merged
Merged
Conversation
…m23f) A mouse drag inside a single block now opens the rich-text editor with the dragged selection recreated (direction-aware, so a right-to-left drag keeps its focus at the release end), instead of a bare caret at the release point. This makes the selection-driven toolbar (bold, italic, link, ...) immediately usable after a drag. A drag whose selection spans multiple blocks no longer activates an editor at all: the previous behavior swapped the DOM under the release block and destroyed a selection the user may have made just to copy text. Mechanism: extends the bd-q9lyghv2 caret-at-click coordinate bridge from a single point to an anchor/head pair. `classifyOpenSelection` (new dragSelectionCapture.ts) classifies the DOM selection at the activate() chokepoint into caret / range / suppress; the payload rides the renamed `pendingOpenSelectionRef` (read-once at editor mount) and is replayed through `posAtCoords` x2 + `TextSelection.between` (`placeSelectionFromDrag`), falling back range -> caret -> end-of-block. Tests: 9 new capture unit tests, 5 new replay unit tests against a real EditorState, hover/editor integration tests extended (suppression, fallback chain, read-once), and a new Playwright e2e (q2-preview-spa/e2e/drag-selection-open.spec.ts) driving real trusted mouse drags against the real q2 binary: forward drag, backward drag direction, cross-block suppression. Verified end-to-end with `q2 preview --allow-edit`: drag-selecting text opens the editor with the selection highlighted; toolbar Bold applies to exactly the dragged range. `cargo xtask verify` green except the pre-existing changelog.md ~37MB / Q-2-17 WASM-render failure on main (fix already in flight in an open PR). Plan: claude-notes/plans/2026-07-07-preview-drag-selection-into-richtext.md Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…af08ef) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
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.
Summary
In
q2 preview --allow-edit(and hub-client'sformat: q2-preview), a mouse drag inside a single block now opens the rich-text editor with the dragged selection recreated — direction-aware, so a right-to-left drag keeps its focus at the release end — instead of a bare caret at the mouse-release point. This makes the selection-driven toolbar (bold, italic, link, …) immediately usable after a drag: drag, click B, done.A drag whose selection spans multiple blocks no longer activates an editor at all. Previously the release block opened with a caret and the DOM swap destroyed the user's selection — breaking plain copy gestures.
Mechanism
Extends the bd-q9lyghv2 caret-at-click coordinate bridge from a single point to an anchor/head pair (same geometric premise: the editor renders the same visual text in the same measured box, so viewport coords captured before the DOM swap land on the same glyphs after it):
dragSelectionCapture.ts(new):classifyOpenSelectionclassifies the DOM selection at theactivate()chokepoint intocaret/range/suppress, using direction-aware selection endpoints (anchor/focus, not the normalized range) andownerDocument-relative lookups (iframe-safe).pendingClickCoordsRef→pendingOpenSelectionRefwith a union payload; read-once-and-clear semantics at editor mount unchanged (self-heal remounts still fall back to end-of-block).placeSelectionFromDrag: replays both endpoints throughposAtCoordsand appliesTextSelection.between(resolve(anchor), resolve(head))— direction preserved, endpoints nudged to valid text positions.focus('end').Keyboard and touch activation are untouched (no click coords → no classification).
Tests
EditorState(direction preserved; misses and degenerate same-pos return false).q2-preview-spa/e2e/drag-selection-open.spec.ts) driving real trusted mouse drags against the realq2binary: forward drag (editor selection equals the selection recorded atpointerup), backward drag stays backward, cross-block drag opens nothing and preserves the selection. 3/3 passed.q2 preview --allow-edit: drag-selecting "quick brown fox jumps over the lazy" opens the editor with that exact selection highlighted; toolbar Bold produces<strong>around exactly that range.cargo xtask verifygreen (the previously-failing changelog Q-2-17 WASM test passes after rebasing onto fix(hub-client): unbreak main — escape lone tilde in changelog (bd-q5o7ekzn) #381's fix).Plan/design record:
claude-notes/plans/2026-07-07-preview-drag-selection-into-richtext.md(strand bd-abo9m23f).🤖 Generated with Claude Code