Inline Atomic Node Selection Issues - MathLive Integration with draggable Property Conflict

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:

  1. Click on a mathField to enter edit mode and place the caret at the exact click position within the math expression
  2. Select mathField nodes as part of text selections (drag selection across text that includes math nodes)
  3. 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

  1. 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.
  2. Event handler manipulation: Tried preventing draggable’s default on mousedown, ondrag etc events, never got it to totally work.
  3. CSS “hacks”: I tried following Tiptap’s recommendation of adding a zero-width space to the mathField’s ::after, didn’t really help.
  4. 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 :>!

Which browser are you testing with?

1 Like

Arc - so Chromium. Just tried it on Zen (a Firefox fork) and encountered the same problem :<.

I think there is a fundamental conflict around how mouse interaction should be handled on such a node—on the one hand, you want clicks to activate the node itself, focusing it and putting the selection inside of it, on the other hand, you want dragging from its start (which would technically still be on the node itself) to create a selection in the outer editor.

You could try to play with the representation to create a ‘buffer zone’ around the node’s core DOM structure. <img> tags without an src attribute can be a useful way to create something that counts as a text position but isn’t actually text (so that it doesn’t accidentally end up in the document during editing).

YESSSSS IT WORKS!!! Thank you SO MUCH!

I’ve been banging my head against this bug for like 3 straight days (definitely should’ve asked for help way sooner lol) - but now it’s FINALLY working!!

My dumb mistake was assuming anchor = 1 meant the mathField wasn’t “selected!” Anyhow that srcless img tag workaround is chef’s kiss perfect.

THANK YOUUUU again!!

1 Like