Re: [D3E] Possible Changes to Mutation Events

2008-07-21 Thread Jonas Sicking


Stewart Brodie wrote:

Maciej Stachowiak [EMAIL PROTECTED] wrote:


On Jul 16, 2008, at 5:00 PM, Stewart Brodie wrote:


Maciej Stachowiak [EMAIL PROTECTED] wrote:

On Jul 16, 2008, at 2:03 PM, Stewart Brodie wrote:


I agree with all that, but it's not the whole story, because making
this change has potentially severe consequences for memory usage if
you start moving large subtrees around within a document.  Just how
long is the event queue allowed to get?

It will only grow without bound if every mutation event handler in
turn modifies the DOM itself, or if a compound DOM operation is
unbounded.

Unbounded queueing is a real concern.  Having said that, the current
situation is that we have unbounded recursion, which is equally
unacceptable, although the recursion depth is at least defined by the
number of recursive calls made by the event listeners, whereas the queue
length is dependent on the number of nodes in the affected subtree,
which is likely to be substantially greater.

Can you describe a plausible scenario where growth of the mutation event
queue would be a significant issue? You've said repeatedly you are worried
about it but have not given an example of when this might happen. Are you
talking about the kind of programmer error that results in an infinite
loop?


[Many apologies for the delayed reply]

The worst case I can think of is Node.replaceChild() where the removed child
is a large subtree and the new child is a large subtree that's attached
somewhere else in the document.  This sort of content is easily feasible in
the sort of UI applications that we have to support (for example, a TV
electronic programme guide), and yet the memory we have available is
severely constrained.

If each subtree contains just 100 nodes, that's 303 events to be queued.
Even if the new subtree is not attached, that's still 203 events.  What
happens if we have no memory left in which to queue these events?


So how much memory are these 303 events compared to the 200 nodes that 
are involved in the mutation? I would expect it to be pretty small.


My point is that it's easy to create a scenario where most algorithms 
consume a lot of data in absolute terms. But if it requires that large 
amounts of data is already being consumed then this doesn't seem like a 
big practical problem.


I would actually argue that the problem here is that the 
DOMNodeRemovedFromDocument event is pretty insanely defined. The rest is 
just side effects from that. This is why we haven't implemented it in 
mozilla as of yet.



Concentrating on the removal side, currently, I have to queue 0 events, and
I can optimise away DOMNodeRemovedFromDocument completely, usually. However,
I have to ensure that the detached node and its parent are still valid after
the dispatch of DOMNodeRemoved.  With these changes, I could only optimise
away the events if *neither* DOMNodeRemoved or DOMNodeRemovedFromDocument
have any listeners.  Sure, the DNRFD events would get optimised out at the
point of dispatch, but I've had to store a whole load of information in the
meantime.


Hmm.. this is indeed a problem. I definitely want to be able to optimize 
away most of the mutation code if there isn't someone actually listening 
to these events.


One way to fix it would be to state that if no listeners are registered 
for an event by the time it is scheduled, an implementation is allowed 
to not fire the event at all, even if a listener got registered before 
the event would have actually fired.


It seems like it's a very odd edge case where anyone would notice a 
difference at all. It requires that one mutation event listener 
registers another listener for another event.


It'd be ugly, but I can't think of anything better really.


The alternative would be to queue a promise to generate the event for every
node in the subtree, but that promise would end up being fulfilled based on
the state of the tree after DOMNodeRemoved listeners had been executed.
However, it would reduce the likelihood of memory problems dramatically.


Yes, noone is saying that you need to actually create the actual event 
objects until it's needed.


/ Jonas



Re: [D3E] Possible Changes to Mutation Events

2008-07-18 Thread Kartikaya Gupta

On Thu, 17 Jul 2008 17:51:42 -0700, Jonas Sicking [EMAIL PROTECTED] wrote:
 
 As for when the events fire (note that this is just clarifications of 
 the spec, not changes to it):
 For events that fire after the mutation takes place I propose that we 
 add a concept of a compound operation and state that while compound 
 operations are in progress no mutation events are fired.

I was thinking about this some more, and it seems to me that a compound 
operation is more or less a lightweight transaction (transaction in the sense 
that is referred to in 1.6.4 of L2 events). It might be useful to expose this 
functionality to authors as well. If a couple of methods were added to allow 
authors to indicate the start and end of a compound operation/transaction, and 
it were guaranteed that no mutation events would be dispatched until the end of 
the compound operation, they would have to worry less about dealing with 
interference from other mutation listeners while they're doing a high-level 
compound operation.

It would be pretty trivial to implement on top of internal compound events, and 
would solve the problem of revalidating assumptions for authors as well as 
implementors. The only pitfall I can see is if authors started a compound 
operation and never ended it, causing an unbounded queue of events. We'd have 
to allow implementations to drop the queue (or some events) if it got too 
large. Thoughts?

kats



Re: [D3E] Possible Changes to Mutation Events

2008-07-18 Thread Jonas Sicking


Doug Schepers wrote:


Hi, Jonas-

Thanks for this modified proposal.  I want to hear back from those 
who've already commented as to their disposition, and to solicit 
comments from other known implementors (e.g., gtk, BitFlash, Opera, 
JSR), but I think your proposal is reasonable, and well detailed.


A few comments inline...

Jonas Sicking wrote (on 7/17/08 8:51 PM):


* Add a |readonly attribute long relatedIndex;| property to
  the MutationEvent interface.
* Add a DOMChildRemoved event which is fired on a node when one
  of its children is removed. The relatedNode property contains the
  removed child, and relatedIndex contains the index the child had
  immediately before the removal. The event is fired after the removal
  takes place.
* Add a DOMDescendantRemovedFromDocument event which is fired on a node
  when the node is in a document, but any of nodes the descendants is
  removed from the document. The event is fired after the removal takes
  place.
  The relatedNode property contains the removed descendant. The
  relatedIndex property contains the index the child had
  immediately before the removal. (Should relatedIndex be -1 when
  the node wasn't removed from its parent, but rather an ancestor was?)


What is the rationale for having both 'DOMChildRemoved' and 
'DOMDescendantRemovedFromDocument'?  Wouldn't a single one, 
'DOMDescendantRemovedFromDocument' (or, preferably, 
'DOMDescendantRemoved'), work about as well?  You already give a way to 
detect if it was a child or a descendant.


Well, I'd start by asking what the rationale is for mutation events at
all :) They seem to only solve the very simple cases where all parties
that mutate the page cooperate nicely with each other and with the
parties that listen to mutation events. But I would have expected that
in those cases the parties that mutate the DOM could instead have
notified the listening parties directly.

But I digress :)

Specifically the two new events correspond to the current DOMNodeRemoved
and DOMNodeRemovedFromDocument, so the rationale is the same as for
those old events. However I can only guess at that rationale is.

DOMNodeRemoved is useful when you want to know when a node is removed
from its parent.

DOMNodeRemovedFromDocument is useful when you want to know when a node
is no longer part of a document.

The latter seems in general more useful, for example for keeping a TOC
of headings in a page, or a list of clickable links. However the latter
seems very complicated to implement without severely regressing
performance any time there is a listener for the event. Whenever a node
is removed you have to fire an event for each and every node in the
removed subtree, presumably including attribute nodes.

Also DOMNodeRemoved can be mostly used to emulate
DOMNodeRemovedFromDocument by checking if the node you are interested in
(i.e. the link or the heading) has the removed node in its parent chain.

In mozilla we have never implemented DOMNodeRemovedFromDocument or
DOMNodeInsertedIntoDocument due to its high cost. Likewise I doubt that
we'll implement DOMDescendantRemovedFromDocument. I'm not sure what
other vendors have done about the old event or feel about the new.

I understand that having the distinction means that you could filter on 
the level of depth to fire events on, but I'm asking if this is useful 
and necessary.


I take it you are asking under the general assumption that mutation
events are useful at all? :)

I generally think that DOMDescendantRemovedFromDocument is likely easier
to use, but seems prohibitively expensive to implement correctly,
whereas DOMChildRemoved seems to cover most use cases, though with a bit 
more effort on the side of the listener.


Also note that all these events have a capture phase, so you can always 
attack your listener on an ancestor of the nodes you are interested in, 
such as the document node.



* Specify *when* the events fire (see details below).


We should do this regardless, since it is tightening up the spec, not 
changing it (though admittedly, it may force some implementations to 
change anyway... but that means more interop).




* Deprecate the DOMNodeRemoved and DOMNodeRemovedFromDocument events.
  If this means making them optional or just discouraged I don't really
  care. I'd even be ok with simply leaving them in as is. Mozilla will
  simply remove our implementation of the DOMNodeRemoved event. We've
  never supported the DOMNodeRemovedFromDocument event.


If Mozilla is determined to remove them regardless of what the spec 
says, then I would rather leave them in as specced, but deprecate them. 


Yes, given that someone pointed out that we can't really fire 
DOMNodeRemoved after the event takes place as that means that the parent 
chain is broken and so the event wouldn't reach any ancestors, I see no 
other alternative than dropping the event entirely.


Do note that there is still nothing that defines when these events 
should fire. I.e. if you do 

Re: [D3E] Possible Changes to Mutation Events

2008-07-18 Thread Jonas Sicking


Kartikaya Gupta wrote:

On Thu, 17 Jul 2008 17:51:42 -0700, Jonas Sicking [EMAIL PROTECTED] wrote:

* Add a DOMDescendantRemovedFromDocument event which is fired on a node
   when the node is in a document, but any of nodes the descendants is
   removed from the document. The event is fired after the removal takes
   place.
   The relatedNode property contains the removed descendant. The
   relatedIndex property contains the index the child had
   immediately before the removal. (Should relatedIndex be -1 when
   the node wasn't removed from its parent, but rather an ancestor was?)



From this description it seems bit ambiguous as to exactly which node is the 
target of the event, since there could be multiple nodes that satisfy the 
conditions (a) being attached to the document and (b) ancestor of the removed 
node. I assume you mean the node that satisfies the conditions that is deepest 
in the tree? And yes, I think relatedIndex should be -1 if an ancestor was the 
one that was removed, so that it's easier to distinguish between the roots of 
the removed subtrees and the non-roots.


Good point. Yes, I meant the one deepest in the tree. Another way to put 
it is that the target is always the parent old of the root of the 
subtree that was removed.




/ Jonas



Re: [D3E] Possible Changes to Mutation Events

2008-07-18 Thread Doug Schepers


Hi, Jonas-

Jonas Sicking wrote (on 7/18/08 2:51 PM):


Well, I'd start by asking what the rationale is for mutation events at
all :) They seem to only solve the very simple cases where all parties
that mutate the page cooperate nicely with each other and with the
parties that listen to mutation events. But I would have expected that
in those cases the parties that mutate the DOM could instead have
notified the listening parties directly.


I admit I've used mutation events only sparingly in my own projects, so 
I'm not the most qualified to answer.  However, many authors I've talked 
to or read from speak of them glowingly, so I will defer to the notion 
that they are useful.


I know you deal a lot with the more complex mashup cases, but are those 
really the most common case?  I suspect that even today, the very simple 
case where only one site is involved are the more common.  Or does all 
parties also mean cases where people are using script frameworks like dojo?




In mozilla we have never implemented DOMNodeRemovedFromDocument or
DOMNodeInsertedIntoDocument due to its high cost. Likewise I doubt that
we'll implement DOMDescendantRemovedFromDocument. I'm not sure what
other vendors have done about the old event or feel about the new.


I am very reluctant to specify something that browser vendors won't 
implement.  Unless other vendors feel strongly about including it, or 
Mozilla changes their mind and decides to include it, I'm not going to 
waste everyone's time by adding this.  The only reason to add a feature 
is to make sure that authors can use it interoperably, in my mind.  As 
an author, I was (and am!) always bitter and disappointed when I read 
about *exactly* the feature I need in a spec, but it's not implemented 
at all, or not implemented interoperably enough to use.  I have no 
intention of building up authors expectations like that if it will be 
futile.


If possible, I prefer to keep looking for a solution that fits the use 
cases and will be widely implemented.


But I want to resolve this soon.  This specification is at the awkward 
point where it's too established to change it much, and too unstable to 
rely on it.  That sucks for everyone.



I understand that having the distinction means that you could filter 
on the level of depth to fire events on, but I'm asking if this is 
useful and necessary.


I take it you are asking under the general assumption that mutation
events are useful at all? :)


That is the general tenor of the authors, who, along with users, are my 
chief constituents.



Do note that there is still nothing that defines when these events 
should fire. I.e. if you do foo.textContent = '', does that fire a 
DOMNodeRemoved on all elements before any of them are removed, or does 
it fire the event on each of them as they are removed.


Though it might not be needed to be defined if the events get deprecated 
anyway...


No, I intend to define that regardless of whether or not we deprecate it.



Regards-
-Doug Schepers
W3C Team Contact, WebApps, SVG, and CDF



Re: [D3E] Possible Changes to Mutation Events

2008-07-17 Thread Jonas Sicking


Kartikaya Gupta wrote:

On Thu, 17 Jul 2008 11:48:52 -0400, Boris Zbarsky [EMAIL PROTECTED] wrote:

There are countless other
implementations of MutationEvents out in the world
(http://google.com/codesearch?hl=enlr=q=DOMNodeRemoved+-mozilla+-webcoresbtn=Search).
They exist in more languages and are used in more contexts than I
care to enumerate

That's fine.  How many of those contexts have to assume that all DOM
access is malicious?


More than zero, I think. There's at least one gtk implementation that (at a 
quick glance) would have to deal with potentially malicious users.


And how well is gtk dealing with this? Has anyone done any extensive 
testing, such as fuzzing, to try to do evil things inside these mutation 
listeners?


/ Jonas



Re: [D3E] Possible Changes to Mutation Events

2008-07-17 Thread Maciej Stachowiak



On Jul 16, 2008, at 10:33 PM, Kartikaya Gupta wrote:



You could argue that this example is contrived (and it is), but I  
think it still illustrates the point. The current interleaving of  
mutations and events is bad for (some) implementations and good for  
web authors. Your proposed interleaving is good for (some)  
implementations and bad for web authors. In both cases it's for the  
same reason - being able to make assumptions simplifies code, so the  
side that gets to make those assumptions is better off, and the  
other side has to revalidate their assumptions.


That would be a valid argument if mutation events were good for Web  
developers in the first place. But they are pretty hard to use either  
way, and generally are unused by most content. Like the Mozilla  
developers who have posted on this thread, I consider them a marginal- 
value feature.


I also consider this entire problem to be more of an implementation  
detail than anything else. The current spec can pose a security risk  
if not properly implemented, but that's true of any spec. The  
security risk identified is only a problem on C/C++ implementations.  
Speaking as a Java implementor, I prefer the spec as it stands now.  
It is far easier to simpler for me to assume listeners don't mutate  
the DOM, and then catch any exceptions that get thrown when that  
assumption is violated. With the proposed changes, I would have to  
implement some complicated queuing solution that increases memory  
requirements dramatically.


There's almost certainly some cases where such an approach will lead  
to wrong behavior instead of an exception. Since your implementation  
takes the ostrich approach, I don't consider this very strong evidence  
of the spec being easy to implement in any language.


Regards,
Maciej
 



Re: [D3E] Possible Changes to Mutation Events

2008-07-17 Thread Jonas Sicking


Kartikaya Gupta wrote:

On Wed, 16 Jul 2008 16:18:39 -0500, Jonas Sicking [EMAIL PROTECTED] wrote:

Laurens Holst wrote:
I see, so the motivation for the change request to DOMNodeRemoved is 
that the second change request (throwing events at the end, after all 
operations) is be impossible to do if events are not always thrown at 
the end. And the motivation for throwing events at the end seems to be 
for a specific kind of optimisation called ‘queuing of events’. I would 
appreciate if someone could describe this optimisation.

Here is the problem we are struggling with is that the current design is
very complex to implement. Any code we have that somewhere inside the
code requires the DOM to be mutated mean that after the mutation we
recheck all invariants after each mutation. This is because during the
mutation a mutation event could have fired which has completely changed
the world under us. These changes can be as severe as totally changing
the structure of the whole DOM, navigating away to another webpage
altogether and/or closing the current window.



I understand your concerns, and while your proposed solution would
solve your problem, it pushes this exact same burden onto web authors.
Say we go ahead change the spec so that all the events are queued up
and fired at the end of a compound operation. Now listeners that
receive these events cannot be sure the DOM hasn't changed out from
under *them* as part of a compound operation.


In the case where there are multiple people listening to mutation events 
for a DOM, and occationally mutating the DOM during those listeners, 
mutation events are already useless.


There is no way you can know that by the time you get the event is 
represents reality at all. The node you just got a remove-event for 
might already be inserted in exactly the same place again.


If this isn't the case, i.e. where one person writes all listeners, or 
listeners don't mutate the DOM, then I don't see that we are pushing the 
problem onto authors. Yes, the DOM will look different by the time 
handler fires, but I don't see that it should significantly harder to 
deal with.



Consider the following
example:

htmlbody
 style.lastLink { color: red }/style
 a href=http://example.org;i want to be the last link/a
 div id=emptyMe
  a href=http://example.org;example two/a
  a class=lastLink href=http://example.org;example three/a
 /div
 script type=text/javascript
var numLinks = document.links.length;
document.addEventListener( DOMNodeRemovedFromDocument, function(e) {
if (e.target.nodeName == 'A') { // or e.relatedNode.nodeName as the 
case may be
if (--numLinks  0) {
document.links[ numLinks - 1 ].className = 'lastLink';
}
}
}, true );
 /script
/body/html


The above would be trivial to rewrite to use

document.links[document.links.length - 1].className = 'lastLink';


If you did something like document.getElementById('emptyMe').innerHTML
= '' and considered it a compound operation, the code above, which
works with current implementations, will die because numLinks will be
out of sync with document.links.length, and the array indexing will
fail. To avoid this scenario, the code has to be rewritten to re-query
document.links.length instead of assuming numLinks will always be
valid. This is exactly the same problem you're currently having - the
DOM is changing under the code unexpectedly, forcing it to recheck
assumptions.


Note that there is nothing in the spec that says that this isn't already 
the case. For example, an implementation would be totally allowed to in 
the case of


document.getElementById('emptyMe').innerHTML = '';

fire all DOMNodeRemovedFromDocument events before doing any mutations to 
the DOM. It could then do all removals while firing no events. This 
seems like it would break your code.


The fact is, it would be extremely hard to define how implementations 
should behave in all the various specs that cause mutations to occur, if 
you also have to define exactly how to behave if mutation listeners 
mutate the DOM.


If instead we instead allowed those specs to state what is a compound 
operation, it can allow the speced behavior to happen inside a compound 
operation, and then mutation listeners are dealt with afterwards.


/ Jonas




Re: [D3E] Possible Changes to Mutation Events

2008-07-17 Thread Jonas Sicking


Doug Schepers wrote:

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.


So based on the feedback so far in this thread, here is a revised 
proposal from me, with the added feature that it's backwards compatible

with DOM Events Level 2:

* Add a |readonly attribute long relatedIndex;| property to
  the MutationEvent interface.
* Add a DOMChildRemoved event which is fired on a node when one
  of its children is removed. The relatedNode property contains the
  removed child, and relatedIndex contains the index the child had
  immediately before the removal. The event is fired after the removal
  takes place.
* Add a DOMDescendantRemovedFromDocument event which is fired on a node
  when the node is in a document, but any of nodes the descendants is
  removed from the document. The event is fired after the removal takes
  place.
  The relatedNode property contains the removed descendant. The
  relatedIndex property contains the index the child had
  immediately before the removal. (Should relatedIndex be -1 when
  the node wasn't removed from its parent, but rather an ancestor was?)
* Specify *when* the events fire (see details below).
* Deprecate the DOMNodeRemoved and DOMNodeRemovedFromDocument events.
  If this means making them optional or just discouraged I don't really
  care. I'd even be ok with simply leaving them in as is. Mozilla will
  simply remove our implementation of the DOMNodeRemoved event. We've
  never supported the DOMNodeRemovedFromDocument event.


As for when the events fire (note that this is just clarifications of 
the spec, not changes to it):
For events that fire after the mutation takes place I propose that we 
add a concept of a compound operation and state that while compound 
operations are in progress no mutation events are fired. Instead the 
events are queued up. After the outermost compound operation finishes, 
but before it returns control to the caller, the queue of mutation 
events is processed.


A compound operation may itself contain several compound operations. For 
example parent.replaceChild(newChild, oldChild) can consist of a removal 
(removing newChild from its old parent) a second removal (removing 
oldChild from parent) and an insertion (inserting newChild into its new 
parent). Processing of the queue wouldn't start until after the 
outermost compound operation finishes.


One important detail here is that processing of the queue starts *after* 
the compound operation finishes. This means that if a mutation listener 
causes another mutation to happen, this is considered a new compound 
operation. So if the mutation listener causes another mutation to 
happen, then the mutation events queued up during that compound 
operation fires before that compound operation returns.


There are two ways to implement this:
Either you move the currently queued events off of the queue before 
starting to process them.


Or, when starting an outermost compound operation, remember what the 
current length of the queue is, and when finishing the operation, only 
process queued events added after that index.


The whole point of this inner queuing is to allow mutations inside 
mutation listeners to behave like mutations outside them. So if code 
inside a mutation listeners calls .replaceChild, it can count on that 
the mutation listeners for that mutation has fired by the time 
replaceChild returns.



What exactly constitutes a compound operation is left up to the specs 
that describe the operations. For example setting .innerHTML should 
likely constitute a compound operation. For DOM Core, every function 
that mutates the DOM should be considered a compound operation.



This all does sound a bit complicated. However the same would be true 
for any sufficiently detailed specification of how mutation events 
behave. As stated, the current wording of the spec allows for wildly 
different and useless firing logic.


The only thing that we could somewhat simplify would be to not use 
separate queues for mutations inside mutation listeners. However the 
simplification would be pretty marginal, and I think it would be 
confusing that mutations inside mutation listeners wouldn't cause events 
to fire until after all other pending events had fired.


/ Jonas



Re: [D3E] Possible Changes to Mutation Events

2008-07-17 Thread Doug Schepers


Hi, Jonas-

Thanks for this modified proposal.  I want to hear back from those 
who've already commented as to their disposition, and to solicit 
comments from other known implementors (e.g., gtk, BitFlash, Opera, 
JSR), but I think your proposal is reasonable, and well detailed.


A few comments inline...

Jonas Sicking wrote (on 7/17/08 8:51 PM):


* Add a |readonly attribute long relatedIndex;| property to
  the MutationEvent interface.
* Add a DOMChildRemoved event which is fired on a node when one
  of its children is removed. The relatedNode property contains the
  removed child, and relatedIndex contains the index the child had
  immediately before the removal. The event is fired after the removal
  takes place.
* Add a DOMDescendantRemovedFromDocument event which is fired on a node
  when the node is in a document, but any of nodes the descendants is
  removed from the document. The event is fired after the removal takes
  place.
  The relatedNode property contains the removed descendant. The
  relatedIndex property contains the index the child had
  immediately before the removal. (Should relatedIndex be -1 when
  the node wasn't removed from its parent, but rather an ancestor was?)


What is the rationale for having both 'DOMChildRemoved' and 
'DOMDescendantRemovedFromDocument'?  Wouldn't a single one, 
'DOMDescendantRemovedFromDocument' (or, preferably, 
'DOMDescendantRemoved'), work about as well?  You already give a way to 
detect if it was a child or a descendant.


I understand that having the distinction means that you could filter on 
the level of depth to fire events on, but I'm asking if this is useful 
and necessary.




* Specify *when* the events fire (see details below).


We should do this regardless, since it is tightening up the spec, not 
changing it (though admittedly, it may force some implementations to 
change anyway... but that means more interop).




* Deprecate the DOMNodeRemoved and DOMNodeRemovedFromDocument events.
  If this means making them optional or just discouraged I don't really
  care. I'd even be ok with simply leaving them in as is. Mozilla will
  simply remove our implementation of the DOMNodeRemoved event. We've
  never supported the DOMNodeRemovedFromDocument event.


If Mozilla is determined to remove them regardless of what the spec 
says, then I would rather leave them in as specced, but deprecate them. 
 It sounds like we will have alignment from Mozilla and Safari/WebKit, 
and I'm sure that IE would rather implement this simpler version.  I 
imagine that Opera would join in the fun.  Hopefully others would align 
as well.


Then we would have interoperable mutation events in all 4 major desktop 
browsers, decreasing the need for script library compensation.  A script 
lib could still provide DOMNodeRemoved and DOMNodeRemovedFromDocument as 
patches for older code, it seems.



As for when the events fire (note that this is just clarifications of 
the spec, not changes to it):
For events that fire after the mutation takes place I propose that we 
add a concept of a compound operation and state that while compound 
operations are in progress no mutation events are fired. Instead the 
events are queued up. After the outermost compound operation finishes, 
but before it returns control to the caller, the queue of mutation 
events is processed.


I really like the concept of the compound operation, and I will add 
that in regardless of other conclusions.  I will specify that a host 
language should indicate when an operation is a compound operation, 
and describe the precise order of operations.  (See next comment for 
details.)



A compound operation may itself contain several compound operations. For 
example parent.replaceChild(newChild, oldChild) can consist of a removal 
(removing newChild from its old parent) a second removal (removing 
oldChild from parent) and an insertion (inserting newChild into its new 
parent). Processing of the queue wouldn't start until after the 
outermost compound operation finishes.


This actually has at least 3 variant orders of operation (assuming the 
removal of newChild, which may not be in the document at all yet):


* remove newChild, remove oldChild, insert newChild
* remove newChild, insert newChild, remove oldChild
* remove oldChild, remove newChild, insert newChild

All of these are possible, and DOM3 Core doesn't indicate an order.  So 
this adds to the unpredictability of dealing with any compound 
operation, including mutation events.  Requiring a spec to state the 
order would help authors.



What exactly constitutes a compound operation is left up to the specs 
that describe the operations. For example setting .innerHTML should 
likely constitute a compound operation. For DOM Core, every function 
that mutates the DOM should be considered a compound operation.


Maybe a DOM3 Core 2nd edition, or DOM4 Core, could provide these 
stricter event orders for compound operations.



Regards-
-Doug Schepers

Re: [D3E] Possible Changes to Mutation Events

2008-07-16 Thread Laurens Holst

Hi Doug,

Doug Schepers schreef:

Sergey Ilinsky wrote (on 7/15/08 6:39 AM):

Doug Schepers wrote:
1. DOMNodeRemoved and DOMNodeRemovedFromDocument would be fired 
after the mutation rather than before
2. 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.

General concerns:
1) Clearly defined use cases seem to be missing from the proposal, 
would it be possible to bring them all to the table?


That's a reasonable request

I think that Jonas and Maciej described some of the use cases (from an 
implementor's point of view) in their discussion:

1. optimizing based on queuing of events
2. reduction of code
3. consistency and predictability of behavior
4. interoperability on the issue of when the events fire (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. [1])


I see, so the motivation for the change request to DOMNodeRemoved is 
that the second change request (throwing events at the end, after all 
operations) is be impossible to do if events are not always thrown at 
the end. And the motivation for throwing events at the end seems to be 
for a specific kind of optimisation called ‘queuing of events’. I would 
appreciate if someone could describe this optimisation.


Even ignoring the serious backwards compatibility issues that Sergey 
described, I do not think this is a good idea. By defining that all 
events have to be fired at the end of the operation, e.g. 
Document.renameNode can never be implemented by just calling existing 
DOM operations; the implementation would need to call some internal 
event-less version of the methods (e.g. removeNodeNoEvent()).


It seems to me that such a definition would possibly make 
implementations more complex if not impossible (in case the 
implementation provides no access to events-less methods), and put more 
constraints on the underlying implementation, as the implementation 
would now be required to throw the events separately from the actual 
operations (which I do not think would be good design).


To provide a more concrete example, a DOM (e.g. the Mozilla DOM) could 
never be extended with a custom document.renameNode method that performs 
the operations as described in the DOM level 3 specification, because 
the events would fire too soon. Not that Backbase implements events like 
this, by the way.


With regard to the DOMNodeRemoved change request, I do not think these 
arguments apply. It is doubtful that moving the dispatching of the event 
to another place will reduce code (2), there is a sensible reason for 
why some events fire before and some fire after the action (3), and the 
spec clearly defines how the event should work (4). I don’t really 
understand exactly what kind of optimisation (1) entails, but I think it 
would not matter for ‘event queueing’ if the event was fired before or 
after the action.


To expand a little more on item 3; I do not think the ‘consistency’ 
argument really applies here, because there are plenty of events that 
fire before the actual action takes place (e.g. all cancelable events). 
Now of all 7 mutation events, only two are fired before the action, so 
it is true the majority of events fires after. However they do this 
because it makes sense for their specific operations, not because of 
some unwritten rule that events always have to be fired after the action.


By the way, note that Backbase is also looking at this from an 
implementor’s point of view :).



It would be nice to have more use case outlined.

This knife cuts both ways, of course.  Can you cite some cases 
(preferably in use today) that rely on keeping things the way they are?


In our product we have several controls that either access the 
parentNode property (which would no longer be accessible) or have an 
event listener for DOMNodeRemoved on their parent. Also, it is fair to 
assume that there will be several customer projects expecting the 
currently defined functionality.


It is not so much that with the requested changes the desired 
functionality could not be achieved (although DOMNodeRemovedFromDocument 
would need to provide the relatedNode property, and we would have to 
attach DOMNodeRemoved event handlers to all child nodes instead of their 
parent). The objection is rather that backwards compatibility with a REC 
from 2000 is broken, for reasons that remains largely unclear. The 
defined behaviour of DOMNodeRemoved makes sense, and is useful.


2) The changes contradict with DOM-Level-2 Events where Mutation was 
initially defined (back in the year 2000) thus creating backwards 
incompatible behavior


Not necessarily.  It has the potential to create 
backwards-incompatibility, 

Re: [D3E] Possible Changes to Mutation Events

2008-07-16 Thread Doug Schepers


Hi, Grauw-

First, I want to note that I'm just collecting data here... I can see 
both sides of the argument on this particular issue, so as editor, I'm 
happy to specify this however it seems most beneficial to authors and 
implementors (in that order).  I appreciate all the good feedback 
everyone is supplying.


I realize that by relaying and summarizing Jonas' and Maciej's request, 
I may seem to have already aligned myself with a side here, but any 
defense I'm making is as an advocate for the authors and for the devil 
(not necessarily in that order).


So, I will leave it up to Jonas and Maciej to present counter-arguments.

Just a couple comments inline...

Laurens Holst wrote (on 7/16/08 9:36 AM):


To expand a little more on item 3; I do not think the ‘consistency’ 
argument really applies here, because there are plenty of events that 
fire before the actual action takes place (e.g. all cancelable events). 
Now of all 7 mutation events, only two are fired before the action, so 
it is true the majority of events fires after. However they do this 
because it makes sense for their specific operations, not because of 
some unwritten rule that events always have to be fired after the action.


The consistency and predictability I was referring to was not alignment 
with the other mutation events firing after the operation, but rather with:


a) The bit in DOM3 Events that says, 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.


b) predictability that operations will not end up with surprising 
results regarding the tree structure as a result of complex operations.


By the way, note that Backbase is also looking at this from an 
implementor’s point of view :).


Yes, it seems Backbase would be considered both an implementor and an 
author (that is, you implement the functionality of the spec, and 
provide content on top of that functionality).  It would be interesting 
so see an examination of the different needs and markets for desktop 
browser vendors, mobile browser vendors, and script library vendors, 
with regards to reliance on underlying platforms and ability to push 
changes out into deployed code.


I took a look through the Backbase demo... very impressive stuff.  Much 
of it was even accessible and navigable by keyboard control, which was 
even nicer.



Not necessarily.  It has the potential to create 
backwards-incompatibility, but only if there are scripts and 
implementations that rely on the specific details that are proposed 
for change, i.e. that depend on the DOMNodeRemoved and 
DOMNodeRemovedFromDocument events firing before removal.  If the 
script only relies on knowing that a node was removed, and doesn't 
care much when, then it's not actually a problem.


The differences are pretty big, you shouldn’t downplay them as being 
‘details’. I’m sure things will break. I think this is a very bad idea.


I didn't mean details in a pejorative sense, but rather as a contrast 
to a more drastic change, such as removing mutation events altogether. 
The point was that certain aspects of the events could possibly be 
changed without affecting existing applications or script code; you have 
evidence that this is not the case here, but without knowing the details 
of that, it was hard to judge.  The devil is in the details, after 
all... and specifications are, let's face is, all about details.




It is certain.

Some examples of what would break in our product:


Okay, thanks for the details, especially regarding what remedial steps 
you'd have to take.



I disagree with your suggestion that the event as it is currently 
specified would be “difficult to implement” or “unpredictable to use”. 


I was really trying to characterize Jonas' stance, and may not have been 
successful at it.  I invite him to provide more details.



I do not care so much about backwards compatibility with earlier 
revisions of the DOM level 3 spec (although I hope there won’t be really 
big changes :)), however this concerns compatibility with DOM level 2 
which has been a REC since 2000. As far as I know (and if Appendix B: 
Changes is not omitting anything), DOM level 3 has so far not introduced 
any backwards incompatibilities with DOM level 2. Doing this would set a 
very bad precedent.


None of the other changes currently being considered would affect 
compatibility with DOM2... most of them have to do with Key Identifiers 
and IMEs, new events (e.g. wheel, mousewheel, dblclick), event order, 
and default actions (off the top of my head).  I'm glad that you are 
paying attention, and look forward to your feedback on these other 
issues, too.



I think you should be very, very reluctant to break backwards 
compatibility with an 8-year old REC. The DOM specifications are a core 
part of XML technologies, and if those standardised core technologies 
can not be trusted to be compatible 

Re: [D3E] Possible Changes to Mutation Events

2008-07-16 Thread Boris Zbarsky


Laurens Holst wrote:
I see, so the motivation for the change request to DOMNodeRemoved is 
that the second change request (throwing events at the end, after all 
operations) is be impossible to do if events are not always thrown at 
the end. And the motivation for throwing events at the end seems to be 
for a specific kind of optimisation called ‘queuing of events’.


It's not quite an optimization.  At heart, it's a security requirement: 
untrusted script must not be run while data structures are in an 
inconsistent state.


It can be worked around by adding a lot more code to make sure things 
are in a consistent state at all times during, say, a DocumentFragment 
insertion, which is what some implementations have been doing.  But this 
greatly increases complexity and reduces performance of cases that are 
commonly used on the Web (innerHTML).


By defining that all 
events have to be fired at the end of the operation, e.g. 
Document.renameNode can never be implemented by just calling existing 
DOM operations


This is a serious concern, yes.  On the other hand, that's already the 
case in a lot of situations with the DOM because of the way ranges work. 
 You end up having to call notification-less versions of basic methods...


With regard to the DOMNodeRemoved change request, I do not think these 
arguments apply. It is doubtful that moving the dispatching of the event 
to another place will reduce code


I can guarantee you that it would reduce code and improve security in Gecko.


there is a sensible reason for why some events fire before and some fire after 
the action


Agreed, but in practice this causes some problems.  If it's possible to 
address the problems while still addressing the mutation event use 
cases, that would be great.


In our product we have several controls that either access the 
parentNode property (which would no longer be accessible)


I should note that being able to use parentNode like this assumes that 
you are the only one listening for the mutation event.  That might be a 
good assumption in your project, of course...


or have an 
event listener for DOMNodeRemoved on their parent.


Whatever we do, this case certainly needs to work, in my opinion. 
Firing DOMNodeRemoved on the node that actually got removed is not as 
important as this.  Again, in my opinion.


-Boris






Re: [D3E] Possible Changes to Mutation Events

2008-07-16 Thread Maciej Stachowiak



On Jul 16, 2008, at 6:36 AM, Laurens Holst wrote:


Hi Doug,

Doug Schepers schreef:

Sergey Ilinsky wrote (on 7/15/08 6:39 AM):

Doug Schepers wrote:
1. DOMNodeRemoved and DOMNodeRemovedFromDocument would be fired  
after the mutation rather than before
2. 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.

General concerns:
1) Clearly defined use cases seem to be missing from the proposal,  
would it be possible to bring them all to the table?


That's a reasonable request

I think that Jonas and Maciej described some of the use cases (from  
an implementor's point of view) in their discussion:

1. optimizing based on queuing of events
2. reduction of code
3. consistency and predictability of behavior
4. interoperability on the issue of when the events fire (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. [1])


I see, so the motivation for the change request to DOMNodeRemoved is  
that the second change request (throwing events at the end, after  
all operations) is be impossible to do if events are not always  
thrown at the end. And the motivation for throwing events at the end  
seems to be for a specific kind of optimisation called ‘queuing of  
events’. I would appreciate if someone could describe this  
optimisation.


The purpose is not optimization, but rather reducing code complexity  
and risk. DOM mutation events can make arbitrary changes to the DOM,  
including ones that may invalidate the rest of the operation. Let's  
say you call parent.replaceChild(old, new). If the DOMNodeRemoved  
notification is fired before the removal of old, or even between the  
removal and the insertion, it might remove old from parent and moved  
elsewhere in the document. The remove notification for new (if it  
already had a parent) could also move old, or new, or parent. There's  
no particularly valid reason to do this, but Web-facing  
implementations must be robust in the face of broken or malicious  
code. This means that at every stage of a multistep operation, the  
implementation has to recheck its assumptions. In WebKit and Gecko,  
the code for many of the basic DOM operations often is more than 50%  
code to dispatch mutation events, re-check assumptions and abort if  
needed. Dispatching mutation events at the end of a compound operation  
doesn't have this problem - there is no need to re-check assumptions  
because the operation is complete.


Even ignoring the serious backwards compatibility issues that Sergey  
described, I do not think this is a good idea. By defining that all  
events have to be fired at the end of the operation, e.g.  
Document.renameNode can never be implemented by just calling  
existing DOM operations; the implementation would need to call some  
internal event-less version of the methods (e.g. removeNodeNoEvent()).


First of all, this is not a big deal for implementations. Second, it  
seems to me this is true whether removeNode fires the event first or  
last.



It seems to me that such a definition would possibly make  
implementations more complex if not impossible (in case the  
implementation provides no access to events-less methods), and put  
more constraints on the underlying implementation, as the  
implementation would now be required to throw the events separately  
from the actual operations (which I do not think would be good  
design).


No, it would make implementations much simpler by removing all the  
code that handles the very unlikely case of the mutation event  
listener modifying the DOM in a way that invalidates the operation. I  
know for sure this is the case for WebKit's DOM implementation, and  
Mozilla folks have told me the same is true for Gecko.


[...snip...]

I do not care so much about backwards compatibility with earlier  
revisions of the DOM level 3 spec (although I hope there won’t be  
really big changes :)), however this concerns compatibility with DOM  
level 2 which has been a REC since 2000. As far as I know (and if  
Appendix B: Changes is not omitting anything), DOM level 3 has so  
far not introduced any backwards incompatibilities with DOM level 2.  
Doing this would set a very bad precedent.


If you introduce incompatible behaviour with regard to DOM level 2,  
there is no way to prevent existing applications from breaking  
either, because DOM does not provide a version mechanism that knows  
an older version is expected and could provide backwards compatible  
behaviour. And either way, I think having to branch code (or worse,  
providing different implementations) based on version is undesirable.


I think you should be very, very reluctant to break 

Re: [D3E] Possible Changes to Mutation Events

2008-07-15 Thread Sergey Ilinsky


Doug Schepers wrote:
* 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.

General concerns:
1) Clearly defined use cases seem to be missing from the proposal, would 
it be possible to bring them all to the table?
2) The changes contradict with DOM-Level-2 Events where Mutation was 
initially defined (back in the year 2000) thus creating backwards 
incompatible behavior


Specific concerns:
1) If DOMNodeRemovedFromDocument is fired after the mutation, then in 
the listener for this event there is no way to know where Node was 
removed from.
   (This does not apply to DOMNodeRemoved, since it has a relatedNode 
property pointing to node removed)
2) If DOMNodeRemoved is fired after the mutation, event won't be capable 
of bubbling


(I did not yet dig into any specific functionality that depends on the 
present behavior (and potential change) of the events in subject (for 
sure lots of stuff would break))


Tech Lead at Backbase,
Sergey Ilinsky/

P.S. Backbase Ajax Framework contains an implementation of DOM-Events 
(Level-3) module (as well as other DOM modules) and it is dependent on 
the present behavior.





Re: [D3E] Possible Changes to Mutation Events

2008-07-15 Thread Kartikaya Gupta

On Tue, 15 Jul 2008 12:39:16 +0200, Sergey Ilinsky [EMAIL PROTECTED] wrote:
 
 Specific concerns:
 1) If DOMNodeRemovedFromDocument is fired after the mutation, then in 
 the listener for this event there is no way to know where Node was 
 removed from.
 (This does not apply to DOMNodeRemoved, since it has a relatedNode 
 property pointing to node removed)
 2) If DOMNodeRemoved is fired after the mutation, event won't be capable 
 of bubbling

+1. If you make these events fire after the mutation, then they won't go 
anywhere since the target of the event (the removed node) is free-standing. In 
order to listen for these events, you'd have to register a listener on every 
single DOM node, which seems pretty silly. Even if you changed one or both of 
the events to fire on the parent node, it would still be impossible to 
determine exactly where the removed node was removed from (i.e. what was the 
removed node's .nextSibling before it was removed?)

The same problem applies to batching up mutations and firing them at the end; 
there might be operations whose mutation events get discarded because some 
other mutation happens to the tree before the event is fired.

kats



Re: [D3E] Possible Changes to Mutation Events

2008-07-15 Thread Boris Zbarsky


Sergey Ilinsky wrote:
1) Clearly defined use cases seem to be missing from the proposal, would 
it be possible to bring them all to the table?


It's more a matter of sanity of implementation than anything else, for 
what it's worth.


2) The changes contradict with DOM-Level-2 Events where Mutation was 
initially defined (back in the year 2000) thus creating backwards 
incompatible behavior


Yes.  The whole proposal is to change the Events specification.

1) If DOMNodeRemovedFromDocument is fired after the mutation, then in 
the listener for this event there is no way to know where Node was 
removed from.
   (This does not apply to DOMNodeRemoved, since it has a relatedNode 
property pointing to node removed)


Should DOMNodeRemovedFromDocument have a relatedNode too?

2) If DOMNodeRemoved is fired after the mutation, event won't be capable 
of bubbling


This is a much more serious issue.  To be honest, I think the original 
mutation event design was pretty weird.  I would have fired the event on 
the parent, with the relatedNode being the node being removed or 
added...   That would avoid this issue.  Of course that would be 
inconsistent with the way DOMNodeInserted works.


-Boris



Re: [D3E] Possible Changes to Mutation Events

2008-07-15 Thread Kartikaya Gupta

On Tue, 15 Jul 2008 11:20:17 -0400, Boris Zbarsky [EMAIL PROTECTED] wrote:
 
 Kartikaya Gupta wrote:
  The same problem applies to batching up mutations and firing them at the 
  end; there might be operations whose mutation events get discarded because 
  some other mutation happens to the tree before the event is fired.
 
 I'm not sure I follow this.  What exactly is the problem here?
 

Sorry, I misread the original thread and misunderstood the scope of the change. 
Never mind.



Re: [D3E] Possible Changes to Mutation Events

2008-07-15 Thread Sergey Ilinsky


Boris Zbarsky wrote:

1) If DOMNodeRemovedFromDocument is fired after the mutation, then in 
the listener for this event there is no way to know where Node was 
removed from.
   (This does not apply to DOMNodeRemoved, since it has a relatedNode 
property pointing to node removed)

Should DOMNodeRemovedFromDocument have a relatedNode too?
A single relatedNode property would not be enough to satisfy developer's 
curiosity on where exactly node was removed from.


2) If DOMNodeRemoved is fired after the mutation, event won't be 
capable of bubbling


This is a much more serious issue.  To be honest, I think the original 
mutation event design was pretty weird.  I would have fired the event 
on the parent, with the relatedNode being the node being removed or 
added...   That would avoid this issue.  Of course that would be 
inconsistent with the way DOMNodeInserted works.
Although I do not share negative attitude to the design of Mutation 
module, I know there are indeed use cases that are not well satisfied 
with it.


The bad part about the potential to changing something in Mutation 
Module is that it is almost not possible to say a there without having 
to say b - the design is very much tight and consistent.



-Boris


Sergey Ilinsky/




Re: [D3E] Possible Changes to Mutation Events

2008-07-15 Thread Doug Schepers


Hi, Sergey-

Thanks for your prompt and informative feedback!

Sergey Ilinsky wrote (on 7/15/08 6:39 AM):

Doug Schepers wrote:
* 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.

General concerns:
1) Clearly defined use cases seem to be missing from the proposal, would 
it be possible to bring them all to the table?


That's a reasonable request

I think that Jonas and Maciej described some of the use cases (from an 
implementor's point of view) in their discussion:

* optimizing based on queuing of events
* reduction of code
* consistency and predictability of behavior
* interoperability on the issue of when the events fire (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. [1])


It would be nice to have more use case outlined.

This knife cuts both ways, of course.  Can you cite some cases 
(preferably in use today) that rely on keeping things the way they are?



2) The changes contradict with DOM-Level-2 Events where Mutation was 
initially defined (back in the year 2000) thus creating backwards 
incompatible behavior


Not necessarily.  It has the potential to create 
backwards-incompatibility, but only if there are scripts and 
implementations that rely on the specific details that are proposed for 
change, i.e. that depend on the DOMNodeRemoved and 
DOMNodeRemovedFromDocument events firing before removal.  If the script 
only relies on knowing that a node was removed, and doesn't care much 
when, then it's not actually a problem.




Specific concerns:
1) If DOMNodeRemovedFromDocument is fired after the mutation, then in 
the listener for this event there is no way to know where Node was 
removed from.
   (This does not apply to DOMNodeRemoved, since it has a relatedNode 
property pointing to node removed)
2) If DOMNodeRemoved is fired after the mutation, event won't be capable 
of bubbling


I don't believe that is correct.  DOM3 Event states:

At the beginning of the dispatch, implementations must first determine 
the event object's propagation path. This is an ordered list of event 
targets the object may propagate to. The last item in the list is the 
event's target; the preceding items in the list are referred to as the 
target's ancestors and the immediately preceding item as the target's 
parent. Once determined, the propagation path cannot be changed. As an 
example, in the DOM event flow event listeners might change the position 
of the target node in the document while the event object is being 
dispatched; such changes do not affect the propagation path. [2]


You could simply add another event listener on the target element's 
parent (or other relevant ancestor) to find the tree context, if necessary.


A use case demonstrating that this wouldn't suffice would weigh in favor 
of not changing it.



(I did not yet dig into any specific functionality that depends on the 
present behavior (and potential change) of the events in subject (for 
sure lots of stuff would break))


Are you certain about that?  I don't want stuff to break (especially in 
an irreparable way), but neither do I want to forestall making a change 
to the spec that would be easier to implement and more predictable to 
use, based on supposition of problems.  It would be very useful if you 
could point out what would break, and how.



P.S. Backbase Ajax Framework contains an implementation of DOM-Events 
(Level-3) module (as well as other DOM modules) and it is dependent on 
the present behavior.


Can you please confirm that the behavior your implementation relies on 
would actually be negatively affected by the particular changes 
detailed?  Please consider that this may actually have a positive impact 
on your implementation's performance and maintainability.  Detailed 
comments would be helpful.


I will note that other changes are also being made to the specification, 
and while we are trying to be as backwards compatible with earlier 
revisions of the spec as possible, we also place a high priority on the 
spec meeting its use cases and requirements.  I'm sensitive that this 
spec is too long in being finished, and that implementations reasonably 
have relied on it despite its status, but it's a balancing act.


[1] 
http://www.w3.org/TR/DOM-Level-3-Events/events.html#Events-eventgroupings-mutationevents

[2] http://www.w3.org/TR/DOM-Level-3-Events/events.html#Events-flow

Regards-
-Doug Schepers
W3C Team Contact, WebApps, SVG, and CDF



Re: [D3E] Possible Changes to Mutation Events

2008-07-15 Thread Boris Zbarsky


Doug Schepers wrote:
2) If DOMNodeRemoved is fired after the mutation, event won't be 
capable of bubbling


I don't believe that is correct.  DOM3 Event states:

At the beginning of the dispatch, implementations must first determine 
the event object's propagation path.


I think Sergey's point was that if dispatch happens after the removal, 
and the target is the node being removed, this path will have nothing 
else in it.


-Boris