Root cause (diagnosed on rendered DOM, this dev build): splitLines() in internal/web/static/paste-lines.js unconditionally re-split body.innerHTML on \n. When the server-rendered HTML contains no newline text nodes (blocks already adjacent), the split produces a single part and the guard-clone path rebuilt the DOM into one .codeline block containing the entire escaped markup. renumber() then ran against that stale/mismatched DOM, so with wrap ON the measure-based renumber ran against a code column whose content had been replaced, and gutter numbers drifted from the wrapped rows (reproducing the inter-block-newline phantom-row symptoms described in #205).
Fix: when body.innerHTML has no \n to split on, leave the DOM untouched — the .codeline blocks are already adjacent (the '\n' join was already removed in ec791cc/0643ca4), so renumber() measures the real blocks.
Verification (headless chromium, CDP bounding-box probes against a local build of this branch, paste with two deliberately long lines):
1400x900 wrap ON: 5 logical lines -> 7 gutter rows; numbers 1..5 on rows 1,2,4,5,7; max |number top - line top| = 0.0 px
375x812 wrap ON: 11 gutter rows; numbers on rows 1,2,6,7,11; max drift 0.0 px
Root cause (diagnosed on rendered DOM, this dev build): `splitLines()` in `internal/web/static/paste-lines.js` unconditionally re-split `body.innerHTML` on `\n`. When the server-rendered HTML contains no newline text nodes (blocks already adjacent), the split produces a single part and the guard-clone path rebuilt the DOM into one `.codeline` block containing the entire escaped markup. `renumber()` then ran against that stale/mismatched DOM, so with wrap ON the measure-based renumber ran against a code column whose content had been replaced, and gutter numbers drifted from the wrapped rows (reproducing the inter-block-newline phantom-row symptoms described in #205).
Fix: when `body.innerHTML` has no `\n` to split on, leave the DOM untouched — the `.codeline` blocks are already adjacent (the '\n' join was already removed in ec791cc/0643ca4), so renumber() measures the real blocks.
Verification (headless chromium, CDP bounding-box probes against a local build of this branch, paste with two deliberately long lines):
- 1400x900 wrap ON: 5 logical lines -> 7 gutter rows; numbers 1..5 on rows 1,2,4,5,7; max |number top - line top| = 0.0 px
- 375x812 wrap ON: 11 gutter rows; numbers on rows 1,2,6,7,11; max drift 0.0 px
- wrap OFF: `.code` horizontally scrollable (scrollWidth > clientWidth)
- No CSP console errors; go build ./... and go test ./... pass
Fixes #205
Closing as superseded: the #205 fix already merged (PR #212 / #218 line) and issue #205 is closed with QA verification. Branch fix-205-r2 removed during branch hygiene.
Closing as superseded: the #205 fix already merged (PR #212 / #218 line) and issue #205 is closed with QA verification. Branch fix-205-r2 removed during branch hygiene.
fen
removed the QA label 2026-09-10 18:21:07 +00:00
Pull request closed
This pull request cannot be reopened because the branch was deleted.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Root cause (diagnosed on rendered DOM, this dev build):
splitLines()ininternal/web/static/paste-lines.jsunconditionally re-splitbody.innerHTMLon\n. When the server-rendered HTML contains no newline text nodes (blocks already adjacent), the split produces a single part and the guard-clone path rebuilt the DOM into one.codelineblock containing the entire escaped markup.renumber()then ran against that stale/mismatched DOM, so with wrap ON the measure-based renumber ran against a code column whose content had been replaced, and gutter numbers drifted from the wrapped rows (reproducing the inter-block-newline phantom-row symptoms described in #205).Fix: when
body.innerHTMLhas no\nto split on, leave the DOM untouched — the.codelineblocks are already adjacent (the '\n' join was already removed in ec791cc/0643ca4), so renumber() measures the real blocks.Verification (headless chromium, CDP bounding-box probes against a local build of this branch, paste with two deliberately long lines):
.codehorizontally scrollable (scrollWidth > clientWidth)Fixes #205
Closing as superseded: the #205 fix already merged (PR #212 / #218 line) and issue #205 is closed with QA verification. Branch fix-205-r2 removed during branch hygiene.
Pull request closed