explanatory note: preventDefault, IME & keyboard input

Hey,
there seem to recently been have some confusion about IME and whether
allowing preventDefault on IME-based beforeInput events would mainly be
used to disable IME-input.

*What is the current situation?*

Let me exemplify with ICE -- the track changes plugin that is
contentEditable based [1]. I contributed a great deal on getting it to work
on Chrome a few years ago. It listens to keypress/keyup/keydown events and
preventDefaults these under certain circumstances [2]. But why?

Say you have a normal non-tracked text:

"Hello this is a te|t text"

| = caret


There is an 's' missing where the caret is, and the user wants to insert
it. If we don't preventDefault anything, it will turn into:

"Hello, this is a test text"

but because we track changes, we need to turn it into:

"Hello, this is a te<ins>s</ins>t text." (simplified)

We can't really create the <ins>-element before the user actually hits a
key, because unless the user actually enters a letter, we cannot just add a
random element there just because the caret is there.


*What will the situation look like with our spec?*

Once our beforeEdit/beforeInput command is available, for keyboard input we
will listen to that instead of the keypress event. The above example will
therefore work almost the same.


How about if the s came from IME-input? The current state of negotiations
is that the beforeInput event can be cancelled for every event EXCEPT those
based on IME-input. Additionally, the discussion in the uievents thread
show that we are not even allowed to sandbox IME input.


The problem at hand would be that it would immediately enter the s without
us being able to stop it:

"Hello, this is a test text"

We would then need to have saved a previous version of the DOM and a diff
finding function on the two versions, find out that the difference is the
"s" and then create an <ins>-element in it's place and exchange the current
text for:

"Hello, this is a te<ins>s</ins>t text."


And this is just the first problem. The way Android/iOS handle what they
see as "words" probably means that they will randomly remove <ins>-elements
entirely or put entire words inside of <ins>-elements.

*So what am I proposing?*

I am proposing that also IME-based beforeInput events should be
preventDefaultable, as a first step to making it easier to handle them.

Additionally, if IMEs work on more than just simple text nodes, we probably
both need a way to tell the browser what it should consider an entire word,
and preferably also a way to sandbox them (which btw is really easy for
keyboard-based input).

I recognize Ryosuke's answer that the JS then also need to tell the browser
after a browser handled text insertion what range it should consider as
having been input by the user in order to both

a) Continue IME-composition , underlining everything correctly.

b) Let the browser know which parts of the text are still in need of spell
checking/autofixing and which parts should be considered as having been
edited by the user.



------

Did that make it clearer?

------

[1] https://github.com/NYTimes/ice/
[2] https://github.com/NYTimes/ice/blob/master/src/ice.js#L1633
-- 
Johannes Wilm
Fidus Writer
http://www.fiduswriter.org

Received on Friday, 16 October 2015 07:09:53 UTC