Click-accurate cursor positioning in the note preview #16
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/click-accurate-cursor-position"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Clicking into a note's rendered markdown preview now enters edit mode with the cursor placed at the end of the clicked line, instead of always jumping to the end of the note. Two deliberate exceptions keep exact (not line-end) positioning:
).Both are resolved directly from the clicked DOM element's position (
event.target), the same pattern already used for checkboxes and the code-block copy button - not throughcaretRangeFromPoint, which is unreliable for a void element like<img>.History
This PR went through a design pivot mid-session: it originally tried to place the cursor at the closest character to the click (proportional interpolation through markdown syntax), but that was abandoned - the interpolation was frequently a few characters off and felt unpredictable. The current design (always end of line, with the two exceptions above) is simpler and fully deterministic.
Testing
npm run check(0 errors/warnings),npm run test(150 tests passing).PENDING_CROSS_PLATFORM_TESTS.md. The PR's original Linux confirmation was for the abandoned "closest position" design and no longer applies to the current code.Two real bugs found and fixed during manual testing:
domRangeToTextOffset's whitespace filter rejected any whitespace-only text node to skip marked's decorative "\n" padding between block tags, but that same filter also silently dropped meaningful inline spaces - e.g. between twohighlight.js<span>s in a syntax-highlighted code block, or a checkbox's donated leading space before a bold-starting label. Each dropped space desynced every offset after it by one character from the token-based model, occasionally landing several lines early.🤖 Generated with Claude Code
Found via a temporary on-screen debug overlay and the user's exact note content, since every synthetic repro attempt had resolved correctly - the actual bug only showed up with syntax-highlighted code blocks present earlier in the note. domRangeToTextOffset's text-node walk rejected any whitespace-only text node ("if trimmed empty, skip") to filter out marked's decorative "\n" padding between sibling block tags (e.g. between <li>s). But that same filter also caught two other cases that are NOT decorative: - highlight.js wraps each recognized keyword of a syntax-highlighted code block in its own <span>, leaving the space between adjacent keywords ("public", "void") as its own standalone, non-newline whitespace-only text node. - a task-list checkbox's donated leading space, when the item's label starts with a formatted span (bold/italic/link) rather than plain text - the space can't merge into the same text node as "**bold**" the way it merges into plain "toto". Each dropped space silently undercounted the DOM-measured rendered text by one character relative to the token-based model in the rest of this module, desyncing every offset after it. With several such spaces before a given click, the resulting drift could land several tokens early - in the reported case, two items back in a following list. Narrowed the filter to only reject text nodes that are entirely "\n", matching what marked actually inserts for pretty-printing, and no longer swallowing a real inline space just because it happens to sit alone in its own node. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>WIP: Click-accurate cursor positioning in the note previewto Click-accurate cursor positioning in the note preview