-
-
Notifications
You must be signed in to change notification settings - Fork 344
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Composition text replacement in Safari removes empty nodes during text composition text deletion #934
Comments
I can't quite parse this. What do you mean by honoring the element removal? The website example editor should be using the latest version. What are you not seeing in it? |
Sorry for the confusion, I had misunderstood something on the example editor and thought it was pointing to an older version. What I mean by "honoring the element removal" is that when the empty elements are removed, the model itself shouldn't be updated and the dom should revert to the expected structure. So even though the ul, li, and div get deleted, they are each restored when the mutation observer picks up the changes. I can try to track down the actual filed bug in Safari, but my guess as to why I don't see it in the example editor is due to the "div". It might trigger this element removal if the text has a div wrapped around it. We saw this behavior in our old editor in both lists (where we have a div inside of the li) and in tables (where we had a div inside of a td). I think if the toDOM method of the list schema included a div inside of the list item, then it would happen in the example editor. Do you have any suggestions on creating a reproducible example? |
You could adjust the basic schema to render paragraphs as divs. It is well possible that the changes in 1.9.0 made this harder to work around (they make the DOM reading more eager). |
So after a lot of struggle, it turns out that this happens when the list and list item are both position relative. I created a working example here https://glitch.com/edit/#!/geode-shame?path=index.js:241:16. No idea why this is the case, but that plugin fix still seems to do the trick. |
I just had the same problem. |
Example to reproduce the issue: https://peaceful-luminous-provelone.glitch.me. Just added |
For the record, we improved upon the original solution and instead now use a decoration with an empty span instead of a ZWS. We basically just detect the bad browser state in beforeinput, update our input plugin state to toggle a flag for composition text being deleted, render the empty span decoration on Safari when that flag is true, then unset in the input event. Using state and decorations helped to better trace what is happening and allowed us to better guarantee that the hack element gets removed. Edit: Forgot that we actually put a ZWS inside of the span in our decoration. |
Thanks for the reply, decoration is indeed a better implementation and has no effect on the data. |
Safari, in general, is a disaster with contenteditable. Last I checked, this happens in a plain contenteditable element without Prosemirror. The root of the issue is that the webkit contenteditable code is bad 🤷🏻 |
It was true, and it is still the same(at least in Safari 14.1). Thank you for your patience, to be honest, Safari really surprised me. There's still a lot to learn 🆙 |
For my case, remove the css( I also made a test in the official example. Add css @marijnh Do you know why? |
@percy507 Safari is trash at contenteditable. That is why. It isn't a Prosemirror specific issue. |
I created an NPM package prosemirror-safari-ime-span as a workaround for this Safari bug, based on @jljorgenson18's idea. |
I tried to use this plugin, but it doesn't seem to work in the table。This issue may be the same |
Issue details
This is a Safari issue that we've dealt with in the past and it looks like this is happening in Prosemirror as well. Let's say you have a structure that looks like this
and the cursor is inside of the "div" tag. If you start typing with a composition based IME (like Japanese) and then attempt to finish a composition, Safari fires an input event with an inputType of
deleteCompositionText
. This deletes the text before it inserts the final composition text. Now, what Safari does during the delete step is that any nodes that ended up as "empty" that were wrapped around the text that was just replaced are removed. In the example above, this means that if you started typing in the div tag, then the div would be removed, then the li, then the ul. Here it is in actionThe workaround we currently have in place is trick Safari into thinking that the element is not empty. We have a plugin that looks like this.
I would expect the domObserver not to honor the element removal, but I'm wondering if the recent composition changes broke this behavior as I'm not seeing it occur on the example editor.
The text was updated successfully, but these errors were encountered: