I’m working on integrating MathLive as inline atomic nodes in ProseMirror and running into a selection/caret placement conflict that I’d love some guidance on.
Problem I have mathField nodes defined as inline atomic nodes that render interactive math expressions using MathLive. Users should be able to:
- Click on a mathField to enter edit mode and place the caret at the exact click position within the math expression
- Select mathField nodes as part of text selections (drag selection across text that includes math nodes)
- Have reliable selection behavior even when mathFields are at the start of paragraphs
The Selection Challenge
Without draggable: true, I get inconsistent selection behavior, especially problematic when mathFields are positioned at the beginning of paragraphs, where selections simply can’t be made from left-to-right and the mathField wouldn’t be included if the selection is from right-to-left.
Demo:
However, when I add draggable: true to the node spec:
mathField: {
group: "inline",
inline: true,
atom: true,
selectable: true,
draggable: true, // This fixes selection but breaks
// ...
}
The selection behavior becomes much more reliable and predictable. mathFields properly participate in drag selections and behave consistently regardless of their position in the paragraph.
But, draggable: true breaks MathLive’s ability to place the caret at the click position. I think this is because the default behavior is to “select” the entire atom on click. I tried to fix this programmatically, but was not able to let MathLive position the caret where they clicked.
What I’ve Tried
- Selection plugins: Built plugins to manually handle drag selection expansion and mathField inclusion, but they’re fragile and don’t handle all edge cases as well as draggable=true.
- Event handler manipulation: Tried preventing draggable’s default on
mousedown,ondragetc events, never got it to totally work. - CSS “hacks”: I tried following Tiptap’s recommendation of adding a zero-width space to the mathField’s ::after, didn’t really help.
- At one time I thought the problem was with the caret not being placed at index 1 when the mathField sits at the start, but the problem was with drag handling it seems.
My Hypothesis
I suspect this is related to how browsers handle dragging? The browser’s native selection mechanism may get blocked by the contenteditable=false mathField node. When you try to drag from position 1 rightward, the selection simply can’t move past the mathField boundary, so it stays stuck at position 1. And somehow draggable=true fixes this?
Are there alternatives to draggable: true that can provide reliable selection behavior for atomic nodes? Maybe something that gives me draggable’s patches for selection handling but nothing else?
Thanks :>!