Bug: Dragging a selection past the edge of an editable CodeView collapses it, then stops it growing
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 35/100
- Issue type
- Bug
- Clarity
- Mostly clear
- Activity status
- Active
- Tech stack
- typescript
- Domain
- frontend
Research direction
Start with the tail of __syncRenderView and the #focus(position) method, which the issue says overwrites a live drag selection, and check #isContentMouseDown. Run the linked repro repo, dragging past the scroller edge in an editable CodeView, to confirm the collapse. Done means the selection keeps its anchor and grows while the button is held. The freeze part needs a design decision on who owns the held-drag selection, so settle that before coding.
Written by the indexing model from the issue text.
Description
Prerequisites
- I have searched for duplicate or closed issues
- I have read the contributing guidelines
Describe the issue
In a CodeView with edit: true, dragging a selection past the edge of the scroller doesn't work the way it does in a text editor. Click on a line and drag below the scroller and the view auto-scrolls as expected, but two things go wrong after that:
- The selection collapses to a caret at the anchor line on the next re-render, so you end up with nothing selected.
- With that fixed (patch below), the selection survives but stops growing at the row where the pointer left the scroller. The view keeps scrolling and the selection doesn't follow.
In VS Code, or in a plain textarea, the selection keeps its start at the anchor line and grows for as long as the button is held. For us this shows up when someone selects a block in a long file to copy it or comment on it: they either lose the selection or get a fraction of what they dragged over.
Seen on @pierre/[email protected], Chromium (Electron 44)
Steps
- A
CodeViewwith onediffitem,edit: true, a few hundred lines long so it is taller than the scroller - Click near the top and drag below the scroller's bottom edge
- Watch the selection as the view scrolls: it collapses to a caret. With the patch below applied, it holds but stops at the row where the pointer left the scroller
Potential cause
From the source:
- The collapse. The tail of
__syncRenderViewrestores focus with#restoreReplacementFocus()orthis.focus({ preventScroll: true })without checking#isContentMouseDown. Both reach#focus(position), which writes a collapsed selection atpositionover the live drag selection. - The freeze. Past the scroller's edge the selection is the browser's native one. The browser doesn't extend a held drag into rows that are rendered or recycled while it auto-scrolls. If the anchor's row is virtualized out mid-drag, the browser drops that end too.
Suggested fix
For the collapse, we're carrying this local patch against 1.5.2 and would be glad to drop it:
- add
&& !this.#isContentMouseDownto bothelse ifconditions at the tail of__syncRenderView; - add
if (position !== void 0 && this.#isContentMouseDown) return;afterthis.#contentHasFocus = true;in#focus.
For the freeze, could the editor own the held drag's selection? It could keep the anchor from the press in its model, hit-test the edge row on each scroll while the button is held, and write the selection from the model, the way it already restores the selection after a render. That would also fix the dropped anchor.
Reproduction
https://github.com/eamodio/pierre-diffs-drag-repro
What browser(s) are you seeing the problem on?
Chrome
What version of @pierre/diffs are you using?
1.5.2
- Dominant language
- TypeScript
- Stars
- 6.2k
- Forks
- 226
- Avg merge
- 1d 1h
- Merged PRs (30d)
- 29
Getting set up
This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from pierrecomputer/pierre
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
pierrecomputer/pierre#1187 ·
Maintainers usually reply within 1 day
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
pierrecomputer/pierre#1150 · 3 comments ·
Maintainers usually reply within 1 day
-
Difficulty 3/5 1-2 days Newbie friendliness 61/100
pierrecomputer/pierre#1198 ·
Maintainers usually reply within 1 day
-
Difficulty 4/5 3-5 days Newbie friendliness 25/100
pierrecomputer/pierre#1184 · 4 comments ·
Maintainers usually reply within 1 day
-
bug
Difficulty 3/5 1-2 days Newbie friendliness 63/100
pierrecomputer/pierre#1172 ·
Maintainers usually reply within 1 day
All issues in pierrecomputer/pierre
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
jessepollak/home#2223 ·
Maintainers usually reply within 1 day
-
grep fixture corpus test follows the corpus's loop symlink under the receipt runner (fails on main)Open
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
code-yeongyu/senpi#3756 ·
Maintainers usually reply within 1 day
-
org:external package:deepagents priority:triage topic:memory topic:middleware type:bug
Difficulty 2/5 1-3 hours Newbie friendliness 65/100
langchain-ai/deepagents#7059 ·
Maintainers usually reply within 1 day
-
Difficulty 1/5 Under an hour Newbie friendliness 92/100
osmlab/name-suggestion-index#12992 ·
Maintainers usually reply within 1 day
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 66/100
hemilabs/ui-monorepo#2506 ·
Maintainers usually reply within 1 day