Let a reader comment on a line that carries a reference - #210
Merged
Conversation
…e way Selecting a line to comment on it broke when the line carried a footnote citation or a numbered-section link: the hover card opened mid-drag, directly over the text being swept. - enter() turns away a mouseenter that arrives with a button held, and a focus that does not match :focus-visible — which is the focus Chromium fires on mousedown, but never the one a keyboard reader earns. Each entry point reads the gesture for itself, so there is no flag to strand when a drag ends without a mouseup. - The :focus-visible test runs as the card is about to open rather than inside the handler. Chrome settles that state after dispatching focus, and reading it inline turned keyboard readers away about one time in five. - follow() deliberately does NOT veto the jump when a selection is live. It cannot mean "this click is the tail of a sweep": the browser dispatches a sweep's click on the common-ancestor paragraph rather than the anchor, and refuses to start a selection from a press on a link at all. So the selection always predates the press and the click is always deliberate — and swallowing it strands the reader, because clicking a link never collapses a selection, so every retry is swallowed too. The new example pins that against a well-meant future patch. Four system specs, each verified to fail when its guard is removed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Selecting a line to comment on it was refused outright — "Anchor text doesn't match the plan content" — whenever the selection crossed a footnote citation, for two unrelated reasons. The extractor read the document with a different grammar than the renderer wrote it with: bare Commonmarker.parse against the renderer's footnotes: true. So the canonical text kept `[^label]` verbatim while the reader saw a superscript number, and no selection carrying that number could ever match. It now parses with the renderer's own EXTENSION_OPTIONS and emits the number the reader sees. The digits are sentinel-mapped, like every other synthetic character here, which also means a selection that merely ends on the marker resolves back to the prose rather than to half a citation. The second cause has nothing to do with references: a browser hands back a selection with whitespace runs collapsed to a space, since a hard-wrapped paragraph is one flowing line on screen, while the extractor keeps the source's newlines. Any selection crossing a wrapped line failed, prose or not. Both sides now fold the same way, carrying the position map so ranges still land on real source positions. Resolution and occurrence counting fold identically — they have to agree or they disagree about which copy of a repeated phrase was selected, and the highlight lands on the wrong one. Twelve examples, each verified to fail when its guard is removed. The system example drives a real drag across the citation through to a placed anchor; reverting the extractor reproduces the reported error verbatim. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
saip-block
marked this pull request as draft
September 4, 2026 14:21
saip-block
marked this pull request as ready for review
September 4, 2026 17:42
HamptonMakes
approved these changes
Sep 4, 2026
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.
Selecting a line to comment on it broke when the line carried a footnote citation. The hover card opened mid-drag, right over the text being swept — and if you got a selection out anyway, the server refused it with "Anchor text doesn't match the plan content — the comment would have nowhere to appear."
Three causes, none of them the same bug.
The preview opened mid-gesture
A held button means the reader is sweeping a selection across the line, not resting on a reference. Each entry point now reads that for itself, so there's no flag to leave stranded when a gesture ends without a mouseup — a link drag, a release outside the window.
mouseentercarries the button state, and the focus Chromium fires on mousedown answers with:focus-visible, which a press never matches but keyboard and assistive-technology focus always do. That question is asked as the card is about to open rather than while the focus event is still dispatching, because Chrome settles:focus-visibleafterwards and reading it inline intermittently turns a keyboard reader away.The extractor read the document with the wrong grammar
MarkdownTextExtractorparsed with bareCommonmarker.parsewhile the renderer parses withfootnotes: true. So the canonical text kept[^label]verbatim while the reader saw a superscript number, and no selection carrying that number could ever match. It now parses with the renderer's ownEXTENSION_OPTIONSand emits the number the reader sees.The digits are sentinel-mapped, like every other synthetic character here. That falls out nicely: a selection that merely ends on the marker resolves back to the prose before it rather than to half a citation.
Whitespace — and this one isn't about references at all
A browser hands back a selection with whitespace runs collapsed to a single space; a hard-wrapped paragraph is one flowing line on screen and the reader swept it as one. The extractor keeps the source's own newlines, so any selection crossing a wrapped line was refused, prose or not. Both sides now fold the same way, carrying the position map so ranges still land on real source positions.
Resolution and occurrence counting fold identically. They have to agree, or they disagree about which copy of a repeated phrase was selected and the highlight lands on the wrong one — nothing covered that before, so there's now an example with a repeated phrase spanning a wrap.
Verification
16 examples, each verified to fail when its guard is removed. The system example drives a real Selenium drag across the citation, through the comment form, to a placed anchor; reverting the extractor reproduces the reported error verbatim:
Full suite 1980 examples / 0 failures. RuboCop clean across 489 files. Also confirmed by hand in dev on a plan carrying both a citation and a section link.
Demos
Before
before-coplan.mov
After
after-coplan.mov