ProseMirror / prosemirror

The ProseMirror WYSIWYM editor
http://prosemirror.net/
MIT License
7.53k stars 334 forks source link

In Chrome, type-over an inline node contents will remove the entire node if more than one text child is present #1436

Closed sarahriouslydt closed 7 months ago

sarahriouslydt commented 7 months ago

Hi,

I encountered this issue while testing inline node behaviour. It's reproducible in Chrome but not in Firefox. To reproduce:

Example test case to reproduce: https://codesandbox.io/p/sandbox/brave-shadow-68hmfy?file=%2Fsrc%2Findex.js

This behaviour occurs in Chrome only, as far as I can tell. In firefox, the outer inline node is retained in both cases.

Demo video of this behaviour in chrome:

https://github.com/ProseMirror/prosemirror/assets/113878532/2a9204f5-0aee-4354-8074-8d884f019df1

Demo of the behaviour in firefox (expected behaviour):

https://github.com/ProseMirror/prosemirror/assets/113878532/6bf6490d-c242-4974-bf24-043ab10cebd7


I'm not sure what's going on here. I had a look at how browser mutations are processed and handled and it's true that both browsers seem to approach the mutations quite differently. I'm unsure if this is something that can be worked around in prosemirror or if it's simply not realistic to fix.

Either way, look forward to hearing your thoughts and thank you for all the work you do.

marijnh commented 7 months ago

What appears to be happening is that some logic somewhere deep in Chrome's contenteditable implementation replaces the <span class=inlineNode> with <span style="background-color: rgb(255, 255, 0);"><i>x</i></span> when you type over it—it somehow inlines the span's styles (and throws in an <i> for some reason). ProseMirror's parser won't be able to associate the resulting mess with the inline node from the schema, so you lose the node.

Since native editing operations are pretty much opaque to ProseMirror—it just observes the DOM changes and then tries to make sense of the new DOM—this may be hard to work around. You could add a parse rule that spots this kind of span and treats it as an inlineNode, but that also seems like it'd be messy and fragile.

sarahriouslydt commented 7 months ago

Thank you for digging into this - it's certainly a very niche area and some quite troublesome browser code.

We will probably document this as a known issue in our product for the time being, and if I can spare the time I'll take it up with the chromium developers.