ProseMirror / prosemirror

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

Select whole content input with Pinyin Input Method caused content drop first characters #1379

Open Matrixbirds opened 1 year ago

Matrixbirds commented 1 year ago

Which demo can reproduce it?

prosemirror offical website: https://prosemirror.net/examples/dino/

What’s the bug you are facing?

Inputing characters with Pinyin Input Method the first characters will be dropped and it will not replaced content which was selected.

What browser are you using?

Chrome

Code example

https://prosemirror.net/examples/dino/

What did you expect to happen?

It should be replaced by Pinyin Input Method characters which did input as expect.

Anything to add? (optional)

Reproduce Steps: System Info: System Info Version
macOS Monterey Version 12.1
Browser Info: Google Chrome 113.0.5672.126 (Official Build) (arm64)
Revision c541687b21a73452ab403e2dced7033ddc97ee9d-refs/branch-heads/5672@{#1202}
OS macOS Version 12.1 (Build 21C52)
JavaScript V8 11.3.244.11
User agent Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36
Command Line /Applications/Google Chrome.app/Contents/MacOS/Google Chrome --flag-switches-begin --enable-experimental-web-platform-features --flag-switches-end
Executable Path /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
  1. Open https://prosemirror.net/examples/dino/
  2. set current input method as Chinese Pinyin
  3. Select the whole content by command+a
  4. Inputing any characters with Chinese Pinyin Input Method.

Expected Result:

The selection of content will be replaced by Chinese Pinyin Input Method characters.

Actually Result:

The selection of content will be replaced but the prosemirror-view don't insert correct characters in the editor dom content area. It seems something ate the characters, until typing the second characters that will be visible in editor content.

Here is the video record to reproduce

https://github.com/ProseMirror/prosemirror/assets/9990676/f3133d47-6ac5-4a77-96c5-a6c97f072a5d

Matrixbirds commented 1 year ago

My colleague find a way to break out this case, the solution is binding events on beforeinput, we can force delete the content before prosemirror-view do some procedure, but it seems will not generate save editing history.

marijnh commented 1 year ago

Composition input with a cross-block selection is really difficult to handle. The browser will do its messy and implementation-dependent DOM mangling, and then immediately start an input composition, generally in a DOM structure that doesn't correspond to what ProseMirror would have created for that action. Touching the DOM or selection during a composition will break it in unpredictable ways (sometimes you get no input, as seems to be the case for you here, sometimes Chrome will duplicate the input).

By the time compositionstart (or even beforeinput) fires, the browser has already committed to the composition, so there doesn't seem to be a way to detect this happening in advance and prepare the DOM structure either.