fix(web): bind the composer's caret to its glyphs with one scrollport
The composer paints its draft in two layers — the textarea owns the value, the selection and the caret, the backdrop paints every visible glyph — and they had one scroll offset each, kept equal by a `scroll` listener. That holds at rest and not in motion: a wheel gesture scrolls the textarea on the compositor, the listener runs afterwards, and for those frames the caret sits at the new offset with the words at the old one. Measured on a harness of the same geometry, a 200px offset change separates caret from glyphs by ~200px (chromium 203, firefox 202, WebKit 203) until a later frame — the caret flying out of its own text when a user swipes a long draft quickly. Both layers now ride one scrollport: `[data-input-scroll]` carries the 14-line cap, the auto-grow stack inside it is as tall as the whole draft, and the textarea holds no scrollable overflow of its own. The browser applies one offset to both layers in the same frame, so the coupling is structural rather than maintained. The backdrop's trailing-line sentinel and the cross-engine wrap-width premise go with the mirror: the layers now share a containing block, which closes the WebKit 768-against-776 gap by construction.
This commit is contained in:
@@ -1,25 +1,25 @@
|
||||
# Composer draft scrolling (14-line cap, two text layers)
|
||||
# Composer draft scrolling (14-line cap, two text layers, one scrollport)
|
||||
|
||||
## At the start of the draft
|
||||
|
||||
- draft overflows the capped box: true
|
||||
- visible lines: 14
|
||||
- both layers share one scroll extent: true
|
||||
- the textarea holds no scroll offset of its own: true
|
||||
- all three layers wrap at one width: true
|
||||
- textarea scroll offset: 0px
|
||||
- glyph layer tracks it: true
|
||||
- scroll offset: 0px
|
||||
- caret and glyphs stay level when the offset changes: true
|
||||
- first draft line is on screen: true
|
||||
- last draft line is on screen: false
|
||||
|
||||
## Scrolled to the end of the draft
|
||||
|
||||
- textarea moved: true
|
||||
- glyph layer tracks it: true
|
||||
- offset moved: true
|
||||
- caret sits on its own glyphs: true
|
||||
- caret and glyphs stay level when the offset changes: true
|
||||
- first draft line has scrolled out above: true
|
||||
- last draft line is on screen: true
|
||||
|
||||
## Draft ending in a newline, scrolled to the end
|
||||
|
||||
- both layers share one scroll extent: true
|
||||
- glyph layer tracks the caret: true
|
||||
- last draft line is on screen: true
|
||||
- caret sits on its own glyphs: true
|
||||
- the draft's own last line is on screen: true
|
||||
|
||||
Reference in New Issue
Block a user