[Bug 25683] Document "unsafe to dispatch events" in D3E if it's possible

https://www.w3.org/Bugs/Public/show_bug.cgi?id=25683

--- Comment #4 from Travis Leithead [MSFT] <travil@microsoft.com> ---
Rather than document the concept of unsafe, I like the approach that HTML5 took
with focus management, which can be seen here:

http://www.w3.org/html/wg/drafts/html/master/single-page.html#dom-focus

The idea is that each element has a "locked for focus" flag. The flag is
checked before focus is switched (this is presumably how focusin and focusout
are made safe from the recursion--though HTML5 doesn't mention these events in
the focus update steps
(http://www.w3.org/html/wg/drafts/html/master/single-page.html#focus-update-steps). 

(Filed https://www.w3.org/Bugs/Public/show_bug.cgi?id=25877 on HTML5 to update
to include these two.)

So, for beforeinput, we could use the same tactic

1. If target of the beforeinput event is beforeinput-locked, then abort;
2. Make the target of beforeinput event "beforeinput-locked";
3. Dispatch beforeinput;
4. Clear the "beforeinput-locked" flag on the target;
4. If beforeinput was canceled, then abort;
5. Update DOM (with content as described by beforeinput event)

This algorithm basically just eliminates the recursion (rather than allowing
the event to be randomly delayed and made non-cancelable as a result).

If we allow execCommand to generate beforeinput, then the following scenario
could occur:

1. User Types "A" into input box "input"
2. (keydown event dispatched at "input" and is not cancelled)
3. beforeinput event dispatched at "input"
 3.1. Event handler for beforeinput event invoked
 3.2. Event handler calls execCommand("insertText", .. "B") (on "input")
 3.3. (see below)
 3.4. Event handler cancels the beforeinput event

In conclusion, the "input" has a value of "B".

In step 3.3., the beforeinput event might have been dispatched, but the
"beforeinput-locked" flag prevents it from firing. This is actually good
because this was a script-initiated insertion (synchronously performed) which
the developer would otherwise need to ignore in a recursively-invoked
beforeinput event handler anyway. A similar situation would arise if the
"input" target's value attribute was modified in the handler (assuming that
beforeinput fired for script-initiated changes too--which I don't think we want
to enable). I can't think of how to force a copy/paste operation (outside of
execCommand) that is synchronous, but if it can be done, this algorithm
protects that too.

Also note: the algorithm only locks one element at a time, so it's possible to
have "input transfer" scenarios, where your beforeinput handler catches the
input in order to redirect it into another input box or contenteditable.

-- 
You are receiving this mail because:
You are the QA Contact for the bug.

Received on Friday, 23 May 2014 22:19:45 UTC