Spinning off from bug 543789 because DOM3 textinput event needs some change which are not related to composition.
Seems like this implementing this would remove the need for a hidden textarea in ACE (http://mozillalabs.com/skywriter/2011/01/18/mozilla-skywriter-has-been-merged-into-ace/)
I should remove following hacky composition by replacing with textinput event.
Created attachment 562995 [details] [diff] [review]
Patch part.1 Implement DOM3 textinput event
I'll create other patches to implement dispatchers...
Created attachment 563297 [details]
Created attachment 563326 [details]
testcase (+contenteditable and +textInput for WebKit)
Hmm, if we would dispatch a textinput event from editor directly when it receives an input event, editor would make nested events. Especially, this makes problems when editor doesn't use system group event handler or the event is dispatched by content script.
For making simple code, I think that we should stop accepting untrusted key events in editor. It is impossible on other browsers to input text by dispatching untrusted key events, so, we don't need to keep it.
And also, when editor wants to change its content, editor should register a textinput event to PresShell (PostEvent() is good name?). And PresShell should dispatch the event before calling nsEventStateManager::PostHandleEvent().
Then, editor should modify its text only from the textinput handler.
Smaug, do you agree with this idea?
Additionally, I think that current delayed focus/blur event should use this approach too.
Type a character in the following <input>:
> data:text/html,<input onkeypress="event.target.blur();">
You can input a character *before* it loose focus. This is different behavior with WebKit, and I think that WebKit's behavior is better.
> And also, when editor wants to change its content, editor should register a textinput event to PresShell (PostEvent() is good name?). And PresShell should dispatch the event before calling nsEventStateManager::PostHandleEvent().
It seems that nsContentUtils::AddScriptRunner() may be useful.
rniwa, do you know the reason for webkit's rather strange behavior. Is it just a bug?
Why does webkit support untrusted events at all in this case?
If untrusted events should be supported, focus handling shouldn't change the handling.
I'm a bit confused here looking at the comments #6 through #8. What exactly is the "strange behavior"?
Oh, sorry, this bug is missing some context.
(in Webkit) Looks like if you dispatch untrusted textinput to some element inside contenteditable,
the text is added to the focused element, not to the element to which the event was dispatched.
That makes no sense from API point of view and is very unexpected to web devs: dispatch
event to element A, but actually element B gets modified.
<body contenteditable><span id="A">aaaaaaaaa</span><span id="B">bbbbbb[focus]bbbbbb</span></body>
<body><div id="A" contenteditable></div><div id="B" contentediable>[focused]</div></body>
Masayuki, please correct me if I posted wrong examples.
Because it is very much unclear how untrusted textinput event should work in contenteditable,
I propose implementations shouldn't have any default handling for untrusted textinput in any case.
At least not before its handling is specified properly.
(In reply to Olli Pettay [:smaug] from comment #10)
> (in Webkit) Looks like if you dispatch untrusted textinput to some element
> inside contenteditable,
> the text is added to the focused element, not to the element to which the
> event was dispatched.
Right, it's probably because we're triggering regular editing code to input text.
> Because it is very much unclear how untrusted textinput event should work in
> I propose implementations shouldn't have any default handling for untrusted
> textinput in any case.
> At least not before its handling is specified properly.
The problem is that WebKit has not and doesn't support Keyboard event properly, and some websites may have replied on textInput event to emulate text input by users.
Webkit's behavior is so strange that I propose that we don't copy it, unless really needed.
Also, we should get this all spec'ed somewhere... whatever defines contentEditable.
So, by default we shouldn't allow untrusted events to trigger default handling.
Hmm, about for untrusted keypress event, it was implemented intentionally at bug 303713. Can we kill the untrusted keypress event handling??
bz, neil: see comment 13.
That bug allowed untrusted keypress to work because there were pages depending on it and it had worked for years.
Does it work in other browsers?
Created attachment 570930 [details]
(In reply to Boris Zbarsky (:bz) from comment #15)
> Does it work in other browsers?
I cannot input characters by this testcase on Canary, IE9 and Opera 11.51.
Created attachment 570931 [details]
fix some nits.
Google Chrome accepts untrusted textInput event. However, other browsers refuse all untrusted events.
OK. Probably ok to nix the untrusted stuff, then, as long as the spec says the right things in the process.
Created attachment 570935 [details] [diff] [review]
Patch part.1 Implement DOM3 textinput event
Created attachment 570936 [details] [diff] [review]
Patch part.2 Implement textinput handler of editor
Created attachment 570937 [details] [diff] [review]
Patch part.3 Editor should refuse untrusted keypress event
We should probably remove support for untrusted keypress, but that is a separate bug.
And we should warn about that change first in one release and remove it in the next one.
Hmm, but as I said, implementing textinput event may cause new failures due to async modification. We need to kill it first...
Are you sure you want to implement textInput? My goal is to phase it out of WebKit. I'm not sure how realistic that is given compat concerns, but I'd like to try (we'd possibly end up aliasing textInput to beforeInput...see below).
What I would really like to see is that we implement a beforeInput event that matches the existing input event. For inputs that generate text data (e.g. where we would have fired a textInput), we put a "data" property on the beforeInput event with the text being inserted.
This makes it strictly a superset of textInput, meets more use-cases (e.g. you can detect deletes as well) and keeps the platform simpler by matching the existing input event. Getting just the text inserting events is simply an if-check on the beforeInput event.
There has already been much discussion on www-dom about this and it was shot-down not for technical objections but because it was considered too big of a change for a spec that is trying to get to CR status as soon as possible.
Even if WebKit can't kill the event due to compat issues, we'll certainly never implement most of the inputMethods (e.g. handwriting).
textinput is a useful event and it can often be used instead of key and composition events.
(input event is just a dummy notification event which happens after the 'input' has happened.)
Using both input + textinput you can easily detect additions and deletions after they have actually
happened - which is often desired.
The supported inputMethods depends ofc the context where browser runs,
and it is up to UA implementation to support or not support all the possible values.
Hmm, I guess following code becomes to fail.
inputElement.value = "foo";
Probably, the alert() doesn't show "foo" because during setting the value, we cannot dispatch textinput event. Therefore, we may not finish to modify the value at the second line. Is this OK??
I don't know why we block to dispatch a event if the code is called by another event handler even when the nested level isn't deep.
Oh, but according to D3E event spec, textinput is fired after the value is modified. This looks like same behavior as IE9. However, Chrome dispatches the events *before* actually modified. Therefore, on IE9, when I call preventDefault() of the textinput event, it doesn't prevent anything. On the other hand, on Chrome, it prevents the modification.
Which behavior should we implement?
I have been working on to implement Chrome's behavior. But it makes asynchronous modification due to script blocker. So, it's too hard for us. And it makes a lot of incompatibility with other browsers like comment 26.
textinput is for the case when the input has already happened. IE9 does the right thing.
Okay, then, should it be cancelable? D3E said that it's cancelable but default action is none.
(In reply to Olli Pettay [:smaug] from comment #25)
> textinput is a useful event and it can often be used instead of key and
> composition events.
> (input event is just a dummy notification event which happens after the
> 'input' has happened.)
> Using both input + textinput you can easily detect additions and deletions
> after they have actually
> happened - which is often desired.
I didn't realize that textInput is specced as happening after the dom has been modified. Hopefully WebKit can change that without compat problems (hopefully we can just kill the event!).
Regardless, if it fires after the dom has been modified, then does it fire before or after the input event? Couldn't you just put a "data" property on the input event that is the text inserted? Then you wouldn't need a whole other event and you get all the benefits of textInput.
If there were cases that textInput fired where input did not fire, I could buy the argument for needing a textInput event. But input + data/inputMethod properties is a strict superset of textInput.
The fewer events we fire on each keypress the better.
> The supported inputMethods depends ofc the context where browser runs,
> and it is up to UA implementation to support or not support all the possible
I don't see anything in the spec indicating that these are optional values. I'd rather we remove from the spec the values that no UA intends to implement.
Do you know the purpose of DOM_INPUT_METHOD_OPTION? When user chooses an item from autocomplete list, should we use it? And also when user chooses an item of suggested list of spellchecker?
And should we use DOM_INPUT_METHOD_UNKNOWN for inserting text from accessible, undo and redo?
# IE9 hangs up when I test undo and redo...
(In reply to Ojan Vafai from comment #31)
> I didn't realize that textInput is specced as happening after the dom has
> been modified.
Argh, I'm wrong. Per spec textinput fires between keypress and keyup, but before the default actions,
so before DOM is modified.
> Hopefully WebKit can change that without compat problems
> (hopefully we can just kill the event!).
Webkit doesn't support textinput, but older, and now removed textInput ;)
HTML spec has very buggy definition for input event. I'll file a spec bug.
(In reply to Olli Pettay [:smaug] from comment #33)
> (In reply to Ojan Vafai from comment #31)
> > I didn't realize that textInput is specced as happening after the dom has
> > been modified.
> Argh, I'm wrong. Per spec textinput fires between keypress and keyup, but
> before the default actions,
> so before DOM is modified.
Then, the asynchronous modification is back since textinput event may be fired asynchronously when it's not safe to be fired. And we need to fix bug 698949 first.
Created attachment 588374 [details]
textinput event has gone from D3E. Use HTML5 input event if you want to catch the timing of content changed. If you need to know the timing immediately before content changed, D3E or D4E should define beforeinput or something. If you need to know the input source, the input event should have the attribute.
FYI, beforeinput is specified in the html editing APIs spec.
I documented in MDN that textinput was removed from the spec.
Firefox has to implement this event or make dramatic change on compositionstart and compositionend.
textInput event is basically same as the composition event, but Firefox's implementation of composition event is basically same as the input event which is unusable.
For example, if user enter "bad" in IME, IME may show "bad" and "badly" as options, if user choose "badly", Firefox will generate following composition event:
As a programmer, how can you tell what the user entered. The correct composition event should be:
Basically, if you want make the composition event works right, you'll have to implement this event. In my opinion, textInput is better way compared with composition event, because textInput can be use no both IME or non-IME environment which is very developer friendly.
Why is it assumed that the only people who need unicode text input are writing HTML text editors? What if one simply needs unicode input events? The input event does nothing for you in that case. The composition events help, but do they cover all cases? For example, would a combination of keypress and composition events be able to handle non-latin keyboards?