Re: [D3E] Possible Changes to Mutation Events

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, 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’ve done a quick survey of our controls that use the 
DOMNodeRemoved(FromDocument) events, as you can read below the majority 
would break on these ‘details’.

>> 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.

This section is talking about what happens when dispatchEvent is called. 
In Jonas’s proposal, at this time the node would no longer be attached 
to its parent node, and thus no bubbling would occur, because the 
ordered list of targets would only contain a single node.

>> (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.

It is certain.

Some examples of what would break in our product:

- Our comboBox control would no longer be registering child option 
elements getting removed from the tree.
- Our dataContextMenu control would no longer properly remove an event 
listener when it is (re)moved, leading to unpredictable behaviour. E.g. 
if it is re-attached, the event will occur twice, and when it is moved, 
it would still respond to events on the old location.
- The options property of a control extending from formList (e.g. our 
suggestBox, listBox controls) would no longer be updated properly upon 
removal of list options.
- The selected property of the listBox would no longer be updated 
properly upon removal of an option.

The list goes on. Out of 18 DOMNodeRemoved and 
DOMNodeRemovedFromDocument event handlers in our bindings alone, at 
least 12 are dependant on the current behaviour (specifically, 
‘parentNode’ being available, and the DOMNodeRemoved event bubbling).

I have not evaluated our customer and consulting projects, but I can 
predict there will be many more issues there.

I disagree with your suggestion that the event as it is currently 
specified would be “difficult to implement” or “unpredictable to use”. 
Rather, I would argue that the opposite is true, and these changes would 
make implementing Events more complicated, and would make DOMNodeRemoved 
behave very differently from DOMNodeInserted.

>> 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.

We would definitely be negatively affected by this change; compatibility 
would break, and we would have to implement ugly workarounds that are 
not consistent with DOMNodeInserted.

E.g. instead of registering one DOMNodeInserted and one DOMNodeRemoved 
handler to deal with insertion and removal of child nodes, we would need 
to register one DOMNodeInserted handler and then a DOMNodeRemoved 
handler on each child node. Also, in these handlers, we can not access 
the parentNode instead having to use relatedNode, reducing the 
probability that we can call generic methods to deal with the changes.

I do not see how we would benefit from this change, as we have currently 
implemented DOM Events without issues, and the optimisation Mozilla 
wants to make is not detailed.

> 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.  

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 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 with previous Recommendations, 
requiring application-level changes, maybe XML technologies aren’t as 
reliable as we all thought.

~Grauw

-- 
Note: New email address! Please update your address book.

~~ Ushiko-san! Kimi wa doushite, Ushiko-san nan da!! ~~
Laurens Holst, student, university of Utrecht, the Netherlands
Website: www.grauw.nl. Backbase employee; www.backbase.com

Received on Wednesday, 16 July 2008 13:36:50 UTC