[D3E] Possible Changes to Mutation Events

Hi, WebApps Fans-

The subject of mutation events arose in dinner conversation during the 
WebApps F2F.  There was a short thread on it afterward, which I'm 
forwarding on with permission.

Currently, the spec says, "Many single modifications of the tree can 
cause multiple mutation events to be dispatched. Rather than attempt to 
specify the ordering of mutation events due to every possible 
modification of the tree, the ordering of these events is left to the 
implementation."

Jonas proposes two substantive changes to this:

* DOMNodeRemoved and DOMNodeRemovedFromDocument would be fired after the 
mutation rather than before
* DOM operations that perform multiple sub-operations (such as moving an 
element) would be dispatched (in order of operation) after all the 
sub-operations are complete.

I am inclined to put this in the spec, because they have identified it 
as a major pain point, and because I'm too simpleminded to find a 
pragmatic case where this would cause problems (I guess if someone was 
counting on getting the mutation event before it occurred and stopping 
it, for instance, they would be disappointed... but I wonder how 
practical that is).

I would be very interested in hard data about real-world usage (Hixie?) 
or implementation status that would countermand my changing this... so, 
if anyone has any feedback on this matter, please let us know.

Regards-
-Doug

-------- Original Message --------
Date: Mon, 07 Jul 2008 18:08:37 -0700
From: Jonas Sicking <jonas@sicking.cc>
To: Maciej Stachowiak <mjs@apple.com>
Cc: Doug Schepers <schepers@w3.org>, Ian Hickson <ian@hixie.ch>
Subject: Re: Mutation Events Pain Points
Maciej Stachowiak wrote:

> 
> On Jul 6, 2008, at 9:32 PM, Jonas Sicking wrote:
> 
>> Actually, the only strictly needed change is to change DOMNodeRemoved 
>> and DOMNodeRemovedFromDocument to say that they are fired *after* the 
>> mutation rather than before.
>>
>> However it would in general be useful to define more in detail when 
>> the events should fire. For example, when inserting a fragment 
>> containing 5 nodes using appendChild, is one mutation event fired 
>> after each individual insertion, or are 5 events fired after all nodes 
>> have been inserted. The latter is very strongly desired from an 
>> implementation point of view.
>>
>> I'd like for the spec to say that when a DOM operation is performed 
>> that cause multiple mutations to happen, all mutation events are 
>> queued up and then fired before the operation finishes. For example 
>> replaceChild can cause one removal when the old child is removed, one 
>> removal when the new child is removed from its old location, and one 
>> insertion when the new child is inserted. All of these would fire 
>> after all mutations take place, but before replaceChild returns. 
>> Similarly setting .innerHTML can cause a whole host of mutations when 
>> the old children are removed and the new inserted, all of these would 
>> fire right before the innerHTML setter returns.
>>
>> Hope that makes sense?
>>
>> Maciej, does this match what you've been wishing for?
> 
> Pretty much, yes.
> 
> The biggest implementation difficulty with the current spec is that it 
> requires (either clearly or arguably) that some mutation events be fired 
> in the middle of a compound DOM operation. Since those event listeners 
> in principle could change anything about the DOM (either nodes being 
> moved, or the target part of the tree), such compound operations have to 
> check all of their assumptions any time they insert a node. I think for 
> many DOM operations, more than half the lines of code in the WebKit and 
> Gecko implementations are to deal with mutation events, which is pretty 
> unfortunate.

Yup. Another side effect is that when we do other actions that happen to
mutate the DOM, such as some features in XBL and in the editor code, we
have to keep in mind that any DOM mutation can cause any evil JS to
execute and change the world under us.

We have a queuing mechanism that in general prevents DOM manipulations
(such as inserting a <script>) from causing JS to execute during the
mutation, however the only script execution that currently isn't
queue-able is mutation events.

> Your proposal sounds like it would solve this problem. If the mutation 
> events all happen at the end, all you need is some kind of queuing 
> mechanism.
> 
> One other thing that should be clarified - when using HTML editing 
> operations, sometimes compound DOM actions occur which are not the 
> result of any DOM call. For instance, it is clear that 
> document.execCommand("Bold") should count as a compound DOM operation. 
> However, when the user hits Cmd-B on Mac or Ctrl-B on Windows, the user 
> agent may perform the equivalent action but without actually going 
> through any DOM call as such. Perhaps since this is a user agent action 
> the UA is free to do anything with regards to event dispatch but it 
> would be nice if the spec made this clear.

Yeah, it'd be good to formulate the language such that it's allowed for
an implementation to consider a whole set of operations as a single
"operation".

/ Jonas

Received on Tuesday, 15 July 2008 09:37:33 UTC