fix: use TextSelection.between for list item cursor placement - #2422
Conversation
Fall back to the nearest valid selection when the resolved anchor/head no longer sit inside a textblock, instead of constructing a possibly invalid TextSelection directly.
|
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Pull request overview
This PR hardens cursor restoration for the list-item block NodeView by using ProseMirror’s safer selection factory when restoring a deferred selection in a requestAnimationFrame callback, preventing invalid selections if the document structure changes between frames.
Changes:
- Replace
new TextSelection($anchor, $head)withTextSelection.between($anchor, $head)to safely fall back to a valid selection when resolved positions are no longer inside a textblock. - Add an inline comment documenting the rationale for using
between.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
@milkdown/components
@milkdown/core
@milkdown/crepe
@milkdown/ctx
@milkdown/exception
@milkdown/kit
@milkdown/prose
@milkdown/transformer
@milkdown/utils
@milkdown/react
@milkdown/vue
@milkdown/plugin-automd
@milkdown/plugin-block
@milkdown/plugin-clipboard
@milkdown/plugin-collab
@milkdown/plugin-cursor
@milkdown/plugin-diff
@milkdown/plugin-emoji
@milkdown/plugin-highlight
@milkdown/plugin-history
@milkdown/plugin-indent
@milkdown/plugin-listener
@milkdown/plugin-prism
@milkdown/plugin-slash
@milkdown/plugin-streaming
@milkdown/plugin-tooltip
@milkdown/plugin-trailing
@milkdown/plugin-upload
@milkdown/preset-commonmark
@milkdown/preset-gfm
@milkdown/theme-nord
commit: |
Summary
Follow-up hardening for the list item block cursor placement fixed in #2412.
When the deferred
requestAnimationFramecallback restores the saved selection, it resolves the capturedanchor/headoffsets against the current document and builds aTextSelectionfrom them. Constructingnew TextSelection($anchor, $head)assumes both resolved positions still sit inside a textblock. If the document shifted between mount and the next frame so that a position no longer lands in inline content, that assumption breaks and we can produce an invalid selection.This PR swaps
new TextSelection(...)forTextSelection.between(...), ProseMirror's recommended factory:No changeset is added — it is generated by the release tooling.
How did you test this change?
pnpm --filter @milkdown/components test— 22 passedtsc --noEmiton@milkdown/components— no type errorspnpm test:lint(oxlint) — 0 warnings / 0 errors