Inline decorations cause incorrect anchor/head behavior during keyboard selection (Shift + Arrow) in Safari #1560
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
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?
We implemented custom highlighting using Decoration.inline and discovered an issue with selecting text from the keyboard using
Shift + Arrowcombinations in the Safari browser.In Safari, when using keyboard selection (Shift + Arrow), the selection area can only be enlarged and cannot be reduced back. Once the selection has started to expand, it continues to expand in both directions, regardless of the direction of the arrow keys, and does not return to a smaller range.
This is probably because the anchor and head values switch places depending on the direction of the hotkey used, which leads to incorrect selection logic when using
Decoration.inline.Steps to reproduce
Shift + ArrowRightto expand the selectionShift + ArrowLeftto reduce the selectionExpected behavior
Shift + ArrowLeft, the selection shrinks back toward the original rangeActual behavior
Shift + ArrowLeft, the selection expands in the opposite direction instead of shrinkingExample
To demonstrate the problem, a minimal editor based on basic schema was prepared. A plugin using
Decoration.inlinewas added to the editor to implement custom highlighting. The example is available in CodeSandbox and reproduces the described behavior - https://codesandbox.io/p/sandbox/inline-decoration-selection-tvkfyqPlugin code
Environment
prosemirror-view: 1.41.5
prosemirror-state: 1.4.4
Safari: 26.1 (21622.2.11.11.9)
macOS: 26.1
This seems to be something weird that Safari is doing. I confirmed that the DOM selection focus side (
window.getSelection().focusNode) is still in the right place when the key event for shift-leftarrow fires, yet the native selection update that happens for that key event moves the wrong side of the selection (and inverts the DOM selection, which caused ProseMirror to then adopt that inversion for its own selection state as well).As you found, this only happens when a decoration like the one you're using is active, not generally. And other browsers don't have the issue. So I believe it is caused by some obscure misbehavior in Safari that this situation triggers. I tried some workarounds, like always resetting the DOM selection on every update, but couldn't find one that actually manages to suppress this behavior.
For various reasons, ProseMirror relies on browsers' native behavior for cursor motion (motion in bidirectional text or weirdly styled block structure is complicated and code-heavy to implement), so when that misbehaves, we're kind of thrown. It may be possible to encode an extremely specific kludge that detects precisely this situation, but that feels a bit dodgy.
@marijnh Thank you very much for your reply! I will try to find a solution.