w3c / uievents

UI Events
https://w3c.github.io/uievents/
Other
147 stars 51 forks source link

specify how compositionend works if the caret has been moved to a different element #5

Open johanneswilm opened 9 years ago

johanneswilm commented 9 years ago

If one moves the caret/selection to a different element when compoisitionstart is triggered, browsers different on compositionend:

  1. Chrome/Safari trigger the compositionend event on the element where composition takes place.
  2. Firefox triggers the compositionend event on the element where the caret was at the time when the compositionstart event was triggered.

Additionally, browsers behave differently if the caret is moved to a different element when compositionend is triggered:

  1. Chrome/Safari paste the composed characters in the place where the caret is moved to.
  2. Firefox moves the caret to a different element and inserts no characters there by default. If the JS inserts the characters by means of execCommand/insertHTML, the endComposition event is triggered a second time.

The Chrome/Safari behavior is desired for the use case where one wants to have IME character insertion into the document stream be atomic -- either by doing composition somewhere else [1] or by using a Shadow DOM during composition [2].

[1] http://jsbin.com/wimuqowimu/15/edit?html,js,console,output (works in Chrome/FF) [2] http://jsbin.com/pacisugiwu/1/edit?html,js,output (only works in Chrome)

Edge behavior is close to FF behavior and Safari close to Chrome.

See also debate about this here: https://lists.w3.org/Archives/Public/www-dom/2015JulSep/0044.html

kojiishi commented 9 years ago

What use cases do you have in your mind? From the normal use cases, Chrome/Safari behavior is considered as a bug. Is it happening only when set from JS?

Consider re-conversion, that turns existing text into composition. If the composition is inserted into DOM, and if the selection was moved, the original text must be restored. In that case, moving composition text into new caret is undesirable.

johanneswilm commented 9 years ago

@kojiishi

What use cases do you have in your mind?

At a low level basically what you had proposed to do inside the browser with IME using the Shadow DOM to do IME input without changing the DOM. Only that @ojanvafai was strongly against that idea, so we found a solution whereby it should instead be possible to do things that way in JS code only [1].

At a higher level, the idea of having IME character commits come in "atomic commits" into the DOM. This would be helpful for among other things:

From the normal use cases, Chrome/Safari behavior is considered as a bug

What do you mean by "From the normal use cases"?

The part about the Chrome/Safari behavior that I cannot see anything about in the spec is that it pastes the created characters into the editing host where the caret is placed when the compositionend event is triggered. The rest of it is according to spec, as far as I can tell.

Firefox, on the other hand, does not follow the spec in several ways, AFAICT. First of all, it should not trigger the event twice. Secondly, the spec reads "Event.target: focused element processing the composition". That is what Chrome/Safari do, while for Firefox the Event.target is the element that was focused BEFORE the composition started. Unless JS moves the caret somewhere else, there will be no difference between where the caret was before composition started and during composition started, which is likely why they didn't think of this case when they wrote the code.

Is it happening only when set from JS?

I am not sure what you mean. How would you set the caret anywhere else when compositionstart is triggered without using JS?

Consider re-conversion, that turns existing text into composition.

This is something you only do in Android and that is not used anywhere else, right?

If the composition is inserted into DOM, and if the selection was moved, the original text must be restored. In that case, moving composition text into new caret is undesirable.

I don't think I understand what you are trying to say here.

In general, I don't think that this re-conversion should be a problem for the JS solution [1] possibly with some minor modifications. Could you outline what the process is exactly for re-conversion, or do you have a link?

[1] http://jsbin.com/pacisugiwu/1/edit?html,js,output

masayuki-nakano commented 9 years ago

Secondly, the spec reads "Event.target: focused element processing the composition".

It should be a bug of UI Events.

That is what Chrome/Safari do, while for Firefox the Event.target is the element that was focused BEFORE the composition started.

In these days, modern IMEs queries content information before compositionstart. Therefore, moving focus at compositionstart is too late for native IMEs.

Firefox guarantees that a set of composition events must be fired on an element. It should be better for web developers because compositionend events may not be fired if focus is lost from listening event target unexpectedly.

masayuki-nakano commented 9 years ago

Firefox moves the caret to a different element and inserts no characters there by default. If the JS inserts the characters by means of execCommand/insertHTML, the endComposition event is triggered a second time.

I think that if the focused element was <input> or <textarea>, the composition string is committed on the element at moving focus?

IIRC, if it's a contenteditable element, it doesn't work fine due to our editor's bug (and it's very difficult to fix in current design...)

johanneswilm commented 9 years ago

Secondly, the spec reads "Event.target: focused element processing the composition".

It should be a bug of UI Events.

What do you mean? Do you mean that the UI Events spec should be changed? Or that Firefox has a bug?

That is what Chrome/Safari do, while for Firefox the Event.target is the element that was focused BEFORE the composition started.

In these days, modern IMEs queries content information before compositionstart. Therefore, moving focus at compositionstart is too late for native IMEs.

What are modern IMEs for you and what are native IMEs? I tried this on Chrome on Mac OS X with one of the Mac OS X built-in IMEs, and the Chrome example still works, which means that it's no problem to move the focus somewhere else during compositionstart for Chrome on Mac OS X. Also Safari is able to move the focus during compositionstart.

If there are UAs which start composition before compositionstart and therefore cannot move the selection somewhere else, I would say that those UAs have a bug and should be fixed.

Firefox moves the caret to a different element and inserts no characters there by default. If the JS inserts the characters by means of execCommand/insertHTML, the endComposition event is triggered a second time. I think that if the focused element was or