This is an archived snapshot of W3C's public bugzilla bug tracker, decommissioned in April 2019. Please see the home page for more details.
Specification: http://www.whatwg.org/specs/web-apps/current-work/multipage/common-input-element-attributes.html Multipage: http://www.whatwg.org/C#common-event-behaviors Complete: http://www.whatwg.org/c#common-event-behaviors Comment: Consider firing `oninput` for contenteditable areas as well Posted from: 91.182.194.222 by mathias@qiwi.be User agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.808.0 Safari/535.1
Example use case: http://mothereffingcssescapes.com/ `oninput` is used there, falling back to `onkeyup` in case its not available. As only WebKit fires `oninput` event handlers for contenteditable areas, theres an unnecessary delay in all other browsers.
Indeed, this is apparently one of the big reasons that people use mutation events. However something like an "input" event is much better suited for letting the page know that something was input.
input event isn't enough to replace mutation events in many cases. It is just way too high level to detect where the change happened. But sure, in some cases it might work just fine.
mass-move component to LC1
Aryeh?
I don't know how useful this would be for the typical contenteditable use-cases I've been thinking of, namely editors, but the use-case in comment 1 seems pretty reasonable. It's basically just using <div contenteditable> as a textarea that you can use custom styles for. This isn't the primary intended use of contenteditable, but it's fair enough, and an input event is as useful there as for an actual textarea or input. So I'd say it makes sense to spec this.
Your spec or mine?
I think this should probably happen in the editing spec. Please reassign to me in the "LC1 HTML5 spec" component of the HTMLWG if you disagree. Ping me on IRC if you have any questions about this, I'm happy to help.
This collides with the "aftereditaction" event that we've been talking about, right? We can probably just use that event for this purpose too.
"input" is a much simpler event, that fires whenever the contents change and provides no extra info. It's also more consistent with textarea/input. I think it's worthwhile to have in addition to before/after command events.
Are we only gong to fire the input event for user initiated editing actions? That is how it works for input/textarea, I think. In that case, we should probably differentiate between execCommands initiated by the user using keyboard shortcuts and such.
WebKit seems to fire input for execCommand() as well as user input. It doesn't fire it for every command, though: for instance, it doesn't fire for unrecognized commands, or commands like styleWithCss that never modify anything. It does fire for document.execCommand("inserttext", false, ""), but not for delete/forwardDelete in the cases where they're no-ops. Also, it fires at the appropriate editing host, not at the Document; if no editing host is focused, it doesn't fire. So I don't think this is a replacement for an aftereditcommand event. I'll still spec it, though, since it's potentially useful anyway. How aggressively should I fire it? The simplest thing would be to just fire it every time a suitable command is executed, regardless of whether it does anything. The more complicated thing would be to figure out which nodes are actually affected on a per-command basis, and fire it at their editing hosts. Which do we want? Firing it more often than necessary isn't a big problem, since it doesn't tell you what changed and is only useful for "update everything" functions anyway. So I'd err on the side of just always firing it at any possibly relevant editing host. But it's hard to tell in my spec which editing hosts will be affected.
(In reply to comment #12) > WebKit seems to fire input for execCommand() as well as user input. It doesn't > fire it for every command, though: for instance, it doesn't fire for > unrecognized commands, or commands like styleWithCss that never modify > anything. It does fire for document.execCommand("inserttext", false, ""), but > not for delete/forwardDelete in the cases where they're no-ops. Also, it fires > at the appropriate editing host, not at the Document; if no editing host is > focused, it doesn't fire. > > So I don't think this is a replacement for an aftereditcommand event. I'll > still spec it, though, since it's potentially useful anyway. I think we should change it to always fire and use beforeInput/input instead of beforeeditcommand/aftereditcommand. Firing it in cases where the DOM isn't actually modified seems fine to me. These cases are rare, they complicate the implementation and they don't really buy web developers that much. Why would we want to fire input/aftereditcommand if there's no appropriate editing host?
Relevant: https://bugzilla.mozilla.org/show_bug.cgi?id=668606#c4 > IE supports it too. However, the event target is different from WebKit. > https://developer.mozilla.org/en/DOM/DOM_event_reference/input > WebKit’s target is the editing host. However, IE’s target is the innermost element at the caret position.
(In reply to comment #13) > I think we should change it to always fire and use beforeInput/input instead of > beforeeditcommand/aftereditcommand. Sounds good to me. What extra data should we add to the events? For beforeInput I don't know what we could usefully add. For input, should we add a list of all nodes created/modified by the command? That would be quite complicated to do, but could be very useful to authors. See bug 13891 for use-cases. To start with, I think I'll spec them as exposing no new info. I can add a list of affected nodes later. > Firing it in cases where the DOM isn't actually modified seems fine to me. > These cases are rare, they complicate the implementation and they don't really > buy web developers that much. Sounds fair to me. If we include a list of affected nodes in the input event, it would be no extra complexity to not fire it if no nodes are affected -- we know anyway whether nodes were affected. But we may as well let authors check themselves. > Why would we want to fire input/aftereditcommand if there's no appropriate > editing host? What's an "appropriate editing host"? If I do document.execCommand("delete") and there's no Selection, or the Selection is entirely in non-editable content, should that behave differently from if there are no editing hosts on the page at all? (In reply to comment #14) > Relevant: https://bugzilla.mozilla.org/show_bug.cgi?id=668606#c4 > > > IE supports it too. However, the event target is different from WebKit. > > https://developer.mozilla.org/en/DOM/DOM_event_reference/input > > WebKit’s target is the editing host. However, IE’s target is the innermost element at the caret position. I think for simplicity, we want to fire the event at whatever node execCommand() was called on, usually the document (but see bug 15522). Firing it at the editing host is a problem because it can be hard to figure out what editing hosts it affects in the current spec. E.g., in the current spec, hitting Enter with <div contenteditable=true>foo<span contenteditable=true>bar[]</span>baz</div> creates <div contenteditable=true><p>foo<span contenteditable=true>bar[]</span></p><p>baz</p></div> so it modifies the outer editing host, which isn't focused. Arguably we should try to avoid this behavior, but that would add further complication. So is it okay to just fire the event at the document in most cases? If not, how should we decide which editing host(s) to fire at? I'm happy to add the events as soon as we figure out what nodes to fire them at. Firing them at the start node of the selection or such isn't great either, because that might not be editable at all.
> I think we should change it to always fire and use beforeInput/input instead of > beforeeditcommand/aftereditcommand. > > Firing it in cases where the DOM isn't actually modified seems fine to me. > These cases are rare, they complicate the implementation and they don't really > buy web developers that much. > > Why would we want to fire input/aftereditcommand if there's no appropriate > editing host? For apps like Google Docs that doesn't use contenteditable but still wants to know the user intent.
What scenarios are you thinking of? Should we fire an input event every time the user hits any key, even if there's nothing editable on the page? That seems like a very big change, and probably not a good one. E.g., if the user hits space to scroll down, should that really fire an input event for insertText? Apps like Google Docs that don't use contenteditable have to reinvent the wheel in three dozen other ways too, so I'm okay with requiring them to intercept keyup/keydown/keypress/etc. and not get input events.
(In reply to comment #17) > What scenarios are you thinking of? Should we fire an input event every time > the user hits any key, even if there's nothing editable on the page? That > seems like a very big change, and probably not a good one. E.g., if the user > hits space to scroll down, should that really fire an input event for > insertText? Yeah that doesn't sound plausible. Another problem with input event is that it's not cancelable. If input event were cancelable, then the apps could use contenteditable and easily override the action by preventing the default. Maybe we can change input event to be cancelable? But that's a substantial change and may adversely affect the existing contents.
(In reply to comment #15) > (In reply to comment #13) > > I think we should change it to always fire and use beforeInput/input instead of > > beforeeditcommand/aftereditcommand. > > Sounds good to me. What extra data should we add to the events? For > beforeInput I don't know what we could usefully add. For input, should we add > a list of all nodes created/modified by the command? That would be quite > complicated to do, but could be very useful to authors. See bug 13891 for > use-cases. I think we should piggy-back on MutationObservers for this. I'm not sure exactly how the two should play together, but the list of data you get should be the same as what you get from MutationObservers and the UA ought to be able to keep one list for both. Eventually, I think we want to expose the command name (e.g. Bold) and if the command inserts text to include a property with the text being inserted. But that should probably be a a whole different discussion. > > Why would we want to fire input/aftereditcommand if there's no appropriate > > editing host? > > What's an "appropriate editing host"? If I do document.execCommand("delete") > and there's no Selection, or the Selection is entirely in non-editable content, > should that behave differently from if there are no editing hosts on the page > at all? Yeah. I was picturing that the event wouldn't fire at all if there's no editing hosts or no selection. > I think for simplicity, we want to fire the event at whatever node > execCommand() was called on, usually the document (but see bug 15522). Firing > it at the editing host is a problem because it can be hard to figure out what > editing hosts it affects in the current spec. E.g., in the current spec, > hitting Enter with > > <div contenteditable=true>foo<span contenteditable=true>bar[]</span>baz</div> > > creates > > <div contenteditable=true><p>foo<span > contenteditable=true>bar[]</span></p><p>baz</p></div> > > so it modifies the outer editing host, which isn't focused. Arguably we should > try to avoid this behavior, but that would add further complication. > > So is it okay to just fire the event at the document in most cases? If not, > how should we decide which editing host(s) to fire at? I'm happy to add the > events as soon as we figure out what nodes to fire them at. Firing them at the > start node of the selection or such isn't great either, because that might not > be editable at all. I was picturing that we'd fire it at the root editing host (i.e. the one highest up in the tree). Are there problems with that approach? I think that's much more useful than firing on document in the same way that having execCommand on Element is much more useful. In practice, sites rarely nest editing hosts. We should make it work, but we shouldn't make non-nested editing worse for it. (In reply to comment #18) > (In reply to comment #17) > > What scenarios are you thinking of? Should we fire an input event every time > > the user hits any key, even if there's nothing editable on the page? That > > seems like a very big change, and probably not a good one. E.g., if the user > > hits space to scroll down, should that really fire an input event for > > insertText? > > Yeah that doesn't sound plausible. Another problem with input event is that > it's not cancelable. If input event were cancelable, then the apps could use > contenteditable and easily override the action by preventing the default. Maybe > we can change input event to be cancelable? But that's a substantial change and > may adversely affect the existing contents. The input event happens after the DOM has been modified, so it's necessarily not cancelable. beforeinput ought to be cancelable though.
(In reply to comment #19) > I think we should piggy-back on MutationObservers for this. I'm not sure > exactly how the two should play together, but the list of data you get should > be the same as what you get from MutationObservers and the UA ought to be able > to keep one list for both. > > Eventually, I think we want to expose the command name (e.g. Bold) and if the > command inserts text to include a property with the text being inserted. But > that should probably be a a whole different discussion. MutationObservers will return all the transient intermediate changes, though, right? I was thinking that if you have <p>fo[o<strong>bar</strong></p><p>ba]z</p> and run "bold", so you get <p>fo<b>[obar</b></p><p><b>ba]</b>z</p>, the returned nodes would be just the two new <b> tags. MutationObservers would return a whole list of events, like * "foo" text node split * "baz" text node split * "bar" text node moved to be child of first <p> tag * <strong> tag removed * <b> tag added to first <p> before "o" text node * "o" text node moved to be child of <b> * "bar" text node moved to be child of <b> * <b> tag tag added to second <p> before "ba" text node * "ba" text node moved to be child of second <b> or something equally inconvenient. In some cases we even add a node in one step and then remove it in later steps. Also, consider a case like <p><i><b>foo</b></i>[bar]</p> where we'll make it <p><b><i>foo</i>[bar]</b>. We're moving around the <i> tag here, but that's just noise -- it has nothing to do with the bolding. There are also probably cases where we create new tags unrelated to the operation being performed. > I was picturing that we'd fire it at the root editing host (i.e. the one > highest up in the tree). Are there problems with that approach? I think that's > much more useful than firing on document in the same way that having > execCommand on Element is much more useful. > > In practice, sites rarely nest editing hosts. We should make it work, but we > shouldn't make non-nested editing worse for it. I think similar problems can arise with selections spanning non-nested editing hosts, or outside of editing hosts entirely. E.g., per current spec, running "indent" on foo<div style=display:inline contenteditable=true>bar</div>[baz] will actually produce foo<div style=display:inline contenteditable=true><blockquote>bar</blockquote></div>[baz] or something, I think. This is probably just a spec bug, though! Probably block-extending the selection shouldn't cross editing hosts. So we should try to make sure that commands don't affect any editing hosts that aren't ancestors of some node that's contained or partially contained in the selection? And fire input events at every editing host that's an ancestor of some node that's contained or partially contained in the selection? Something like that?
(In reply to comment #20) > (In reply to comment #19) > > I think we should piggy-back on MutationObservers for this. I'm not sure > > exactly how the two should play together, but the list of data you get should > > be the same as what you get from MutationObservers and the UA ought to be able > > to keep one list for both. > > > > Eventually, I think we want to expose the command name (e.g. Bold) and if the > > command inserts text to include a property with the text being inserted. But > > that should probably be a a whole different discussion. > > MutationObservers will return all the transient intermediate changes, though, > right? I was thinking that if you have > <p>fo[o<strong>bar</strong></p><p>ba]z</p> > and run "bold", so you get > <p>fo<b>[obar</b></p><p><b>ba]</b>z</p>, > the returned nodes would be just the two new <b> tags. MutationObservers would > return a whole list of events, like > > * "foo" text node split > * "baz" text node split > * "bar" text node moved to be child of first <p> tag > * <strong> tag removed > * <b> tag added to first <p> before "o" text node > * "o" text node moved to be child of <b> > * "bar" text node moved to be child of <b> > * <b> tag tag added to second <p> before "ba" text node > * "ba" text node moved to be child of second <b> > > or something equally inconvenient. In some cases we even add a node in one > step and then remove it in later steps. Also, consider a case like > <p><i><b>foo</b></i>[bar]</p> > where we'll make it > <p><b><i>foo</i>[bar]</b>. > We're moving around the <i> tag here, but that's just noise -- it has nothing > to do with the bolding. There are also probably cases where we create new tags > unrelated to the operation being performed. Rafael Weinstein, one of Chromium's MutationObserver implementors is working on a JS library that takes a stream of mutation records and gives you this summarized view. I prefer that way of doing things. We might eventually want to bake the code for summarizing the mutation records into the web platform as well, but I think we want more experience with MutationObservers before pursuing that. > > I was picturing that we'd fire it at the root editing host (i.e. the one > > highest up in the tree). Are there problems with that approach? I think that's > > much more useful than firing on document in the same way that having > > execCommand on Element is much more useful. > > > > In practice, sites rarely nest editing hosts. We should make it work, but we > > shouldn't make non-nested editing worse for it. > > I think similar problems can arise with selections spanning non-nested editing > hosts, or outside of editing hosts entirely. E.g., per current spec, running > "indent" on > foo<div style=display:inline contenteditable=true>bar</div>[baz] > will actually produce > foo<div style=display:inline > contenteditable=true><blockquote>bar</blockquote></div>[baz] > or something, I think. This is probably just a spec bug, though! Probably > block-extending the selection shouldn't cross editing hosts. > > So we should try to make sure that commands don't affect any editing hosts that > aren't ancestors of some node that's contained or partially contained in the > selection? I think so. I'm not sure I understand the question. > And fire input events at every editing host that's an ancestor of > some node that's contained or partially contained in the selection? Something > like that? Oh, interesting. I guess that's the other solution is to fire input events on all editing hosts in the ancestor chain. That sounds kind of expensive to compute, so I still prefer just firing on the root editing host. I'm confused by your example. If you have *any* content selected that is not a descendant of any editing host, I would expect execCommands to all be noops.
In either case, I think we should punt the discussion of including what changed to a different bug. I'm not convinced there are use-cases that need this information that are not met by MutationObservers and I don't think this will affect when/how input events are fired.
(In reply to comment #22) > In either case, I think we should punt the discussion of including what changed > to a different bug. I'm not convinced there are use-cases that need this > information that are not met by MutationObservers and I don't think this will > affect when/how input events are fired. Sounds good to me. We can spec firing the events first, add more info to them later. (In reply to comment #21) > (In reply to comment #20) > > So we should try to make sure that commands don't affect any editing hosts that > > aren't ancestors of some node that's contained or partially contained in the > > selection? > > I think so. I'm not sure I understand the question. Probably because my spec is insane for not making sure this is the case. :) > Oh, interesting. I guess that's the other solution is to fire input events on > all editing hosts in the ancestor chain. That sounds kind of expensive to > compute, so I still prefer just firing on the root editing host. That's fine. > I'm confused by your example. If you have *any* content selected that is not a > descendant of any editing host, I would expect execCommands to all be noops. Well, not styleWithCss, right? But that probably shouldn't fire input events at all. What if you have <div contenteditable=true>foo[bar</div>baz] and the user hits delete? That shouldn't delete the word "bar"? Per spec and in Chrome 17 dev, it currently produces <div contenteditable=true>foo[]</div>baz although in Firefox 12.0a1 it's a no-op. The spec/Chrome behavior seems more correct, no? Okay, so here's a sketch of a proposed solution, together with some lingering issues I see: Before any command is executed due to a user action (not script-run execCommand()), fire a cancelable beforeInput event that will cancel the command; and after it executes, fire an input event. The events get fired at every editing host that intersects <http://dvcs.w3.org/hg/domcore/raw-file/tip/dom-core.html#dom-range-intersectsnode> the selection, which might be none or more than one. If multiple beforeInput events are fired, canceling any one of them cancels the whole command. The events will expose the command name and value, but nothing else for now. No command should ever affect the contents of editing hosts that don't intersect the selection. Issue 1: If a command is run by a script, I think we don't want to fire events. A script might run many execCommand()s before the event loop spins, so beforeInput is impossible, and input is probably useless. If scripts want to intercept execCommand(), they should overwrite the method on the prototype. Issue 2: Do we need to fire events for copy, cut, paste, redo, or undo? These have their own events already. Likewise, selectAll can use dedicated selection events, which we should spec anyway. I suggest we don't need to also fire beforeInput/input events for any of these. Issue 3: I'm ignoring styleWithCss, useCss, and similar. I assume UAs won't let users activate them, so they don't need to fire events (per issue 1). How does this sound to everyone? Ojan, Ehsan, Ryosuke, Simon? Any other interested parties? If everyone is okay with this, I'll spec it, probably sometime next week.
(In reply to comment #21) > (In reply to comment #20) > > or something equally inconvenient. In some cases we even add a node in one > > step and then remove it in later steps. Also, consider a case like > > <p><i><b>foo</b></i>[bar]</p> > > where we'll make it > > <p><b><i>foo</i>[bar]</b>. > > We're moving around the <i> tag here, but that's just noise -- it has nothing > > to do with the bolding. There are also probably cases where we create new tags > > unrelated to the operation being performed. > > Rafael Weinstein, one of Chromium's MutationObserver implementors is working on > a JS library that takes a stream of mutation records and gives you this > summarized view. I prefer that way of doing things. We might eventually want to > bake the code for summarizing the mutation records into the web platform as > well, but I think we want more experience with MutationObservers before > pursuing that. I think one drawback with using the mutation observer API will be that they fire at the end of a micro-task. So if we call multiple execCommand, for example, then observers won't be called 'til all of those execCommand finish and script exits. So correlating which list of mutations correspond to which execCommand might be tricky. To be fair, the API should work nicely for user-initiated execCommands since the UA should end a micro-task at the end of each user-initiated execCommand as far as I understand it. (In reply to comment #23) > Before any command is executed due to a user action (not script-run > execCommand()), fire a cancelable beforeInput event that will cancel the > command; and after it executes, fire an input event. The events get fired at > every editing host that intersects > <http://dvcs.w3.org/hg/domcore/raw-file/tip/dom-core.html#dom-range-intersectsnode> > the selection, which might be none or more than one. If multiple beforeInput > events are fired, canceling any one of them cancels the whole command. The > events will expose the command name and value, but nothing else for now. No > command should ever affect the contents of editing hosts that don't intersect > the selection. > > Issue 1: If a command is run by a script, I think we don't want to fire events. > A script might run many execCommand()s before the event loop spins, so > beforeInput is impossible, and input is probably useless. If scripts want to > intercept execCommand(), they should overwrite the method on the prototype. I don't understand this statement. beforeInput and input events are fired synchronously as far as I know. So I don't think this will be an issue, and I think we should fire input/beforeInput events for script-initiated execCommand as well. To be fair, not firing them would resolve the issue with mutation observer API I described above. > Issue 2: Do we need to fire events for copy, cut, paste, redo, or undo? These > have their own events already. Likewise, selectAll can use dedicated selection > events, which we should spec anyway. I suggest we don't need to also fire > beforeInput/input events for any of these. Right, I don't think we should fire events for "SelectAll". > Issue 3: I'm ignoring styleWithCss, useCss, and similar. I assume UAs won't > let users activate them, so they don't need to fire events (per issue 1). Agreed. > How does this sound to everyone? Ojan, Ehsan, Ryosuke, Simon? Any other > interested parties? If everyone is okay with this, I'll spec it, probably > sometime next week. Sounds good in general although I'd like to see us firing events for script-initiated editing commands as well.
By the way, we should make sure to expose editing action's name and the value. e.g. event.editingAction and event.editingActionValue.
Here's a WIP for people to comment on: http://aryeh.name/tmp/editing/editing.html#methods-to-query-and-execute-commands I'll commit it sometime soon (hopefully) if there are no comments, along with appropriate changes to the tests. The basic idea is * Commands that can change stuff (everything but copy/redo/selectAll/styleWithCSS/undo/useCSS) are now enabled (= queryCommandEnabled() true) only if the active range's endpoints are both editable and both in the same editing host. So if the selection spans non-nested editing hosts or one end isn't editable, most commands do nothing. * If a command is supported and enabled, a beforeinput event is fired at the deepest editing host that contains the selection. The event has .command and .value properties, bubbles, and is cancelable. If it's canceled, the command is aborted. * If the beforeinput event isn't canceled, we check again whether the command is enabled. If not, we return false and do nothing further. * After the command's action is taken, we fire an input event at the deepest editing host that contained the selection before the command's action was taken (but after the beforeinput command fired). This event has .command and .value properties, bubbles, but is not cancelable. If we get up to running the command's action, execCommand() always returns true. I was talking about this with Ojan and Ryosuke in #whatwg, and they seem to like it. If anyone else has comments, please share.
Firing the events for script generated actions sound like a reasonable requirement. A developer may decide to execute editing actions by simply simulating real user actions. This could happen when executing a wysiwyg editor feature, but can be even more useful in an automated testing environment. One could at that point create an editor plugin that reacts to input events. In the above cases, both user and script events are to be considered. Couldn't the event carry an additional property specifying the input source? (user/script)
(In reply to comment #27) > Couldn't the event carry an additional property specifying the input source? > (user/script) Events already have that (isTrusted).
(In reply to comment #28) > Events already have that (isTrusted). Perfect, that's another motivation to fire input events for script actions as well.
(In reply to comment #28) > Events already have that (isTrusted). Hmm... actually, isTrusted is true for events that are dispatched by the UA, and false for events that are dispatched by the author (with dispatchEvent()), and here it would still be dispatched by the UA. So it's not quite right.
*** Bug 13891 has been marked as a duplicate of this bug. ***
(In reply to comment #27) > A developer may decide to execute editing actions by simply simulating real > user actions. This could happen when executing a wysiwyg editor feature, but > can be even more useful in an automated testing environment. > > One could at that point create an editor plugin that reacts to input events. In > the above cases, both user and script events are to be considered. > > Couldn't the event carry an additional property specifying the input source? > (user/script) That would be possible, if there's good reason for it. Could you explain the use-cases for this in more detail? It would already be possible to do it using hackery like overwriting Document.prototype.execCommand, so the question is if we need to make it easy.
Done: http://dvcs.w3.org/hg/editing/rev/a089a5315642 Please note the test case: http://dvcs.w3.org/hg/editing/raw-file/tip/conformancetest/event.html Try using that as the basis for any implementations. Please report back any implementation comments either in this bug or in a new one. (If you make it a new one, ping me if I don't respond quickly enough, because I might accidentally archive the bug e-mail without realizing it's editing-related.)
>> Oh, interesting. I guess that's the other solution is to fire input events on >> all editing hosts in the ancestor chain. That sounds kind of expensive to >> compute, so I still prefer just firing on the root editing host. > > That's fine. I agree with that an input event is fired only on the root editing host. If UA dispatches input events multiple for an action, an event handler which is added by addEventListener() of the root editing host or its ancestors is executed multiple times. It's not good behavior.
In the current spec, documented in comment 26, commands only are enabled if both endpoints are in the same editing host. An event is only fired if the command is enabled, and in that case at most one beforeinput command is fired, and at most one input command, in both cases at the deepest editing host that contains both endpoints. Notice how the steps here that dispatch events dispatch one event each, and each is hit only once per execCommand(): http://dvcs.w3.org/hg/editing/raw-file/tip/editing.html#execcommand() So I think the current spec matches your feedback already. Thanks, though! Tell me if you have any other thoughts. By the way, I just realized that the spec as written didn't require events to be fired for user actions. I fixed that: https://dvcs.w3.org/hg/editing/rev/3776dec493c5