W3C home > Mailing lists > Public > www-dom@w3.org > April to June 2009

RE: Mutation events replacement

From: Mike Wilson <mikewse@hotmail.com>
Date: Sat, 6 Jun 2009 00:51:16 +0200
Message-ID: <BAY116-DAV10DCA1292CF234F9E275D1A4480@phx.gbl>
To: "'Jonas Sicking'" <jonas@sicking.cc>
Cc: <www-dom@w3.org>
Message-ID: <08f501c9e630$2271c5b0$0a01a8c0@mikedeskxp>
Jonas Sicking wrote:
> The following methods are added to the Document, Element and
> DocumentFragment interfaces:
>   addAttributeChangedListener(NodeDataCallback);
>   addSubtreeAttributeChangedListener(NodeDataCallback);
>   addChildlistChangedListener(NodeDataCallback);
>   addSubtreeChangedListener(NodeDataCallback);
>   addTextDataChangedListener(NodeDataCallback);
>   removeAttributeChangedListener(NodeDataCallback);
>   removeSubtreeAttributeChangedListener(NodeDataCallback);
>   removeChildlistChangedListener(NodeDataCallback);
>   removeSubtreeChangedListener(NodeDataCallback);
>   removeTextDataChangedListener(NodeDataCallback);

This is a very low-level API. Like others I miss a way to ask 
for updates on a specific attribute and/or to get informed
about what attributes were actually changed.

Secondly, like (a few) others I would really like to see some 
selector based syntax for asking only for a subset of 
notifications, not having to do all filtering in user script.

Both of these issues are about filtering and could of course 
be addressed by libraries building on top of the low-level API, 
but to be able to get performance in this some native support 
f ex for reverse selector matching would be needed ("does this 
node match this selector" and so forth).

You have mentioned that your suggested API already gains 
performance by avoiding events/bubbling and by (by design) 
clustering many notifications into one. Are you certain that
doing filtering in UA implementation instead of in user 
script would risk losing performance?

> 'ChildlistChanged': Called if one or or mode children are added or
> removed to the node. So for example when innerHTML is set, replacing
> 10 existing nodes with 20 new ones, only one call is made to the
> 'ChildlistChanged' listeners on that node.

As I've understood the discussion so far, this would trigger not
only for elements but also for f ex text and comment nodes being
added or removed (but not when text data is changed in these).

> 'TextDataChanged': Called when the data in a Text, CDATASection or
> ProcessingInstruction, is changed on the node or any of its
> decendants.

Right, so if I update textNode.data below a node with this 
listener, then it gets called.

But following on, this opens up a couple of questions:

1) If I instead replace a text node with another text node through
   replaceChild or similar it seems ChildlistChanged will trigger,
   although the practical effect from a parent node's view is 
   "changed text". Maybe TextDataChanged should also fire in this 

2) Could setting textNode.data result in new text nodes being
   created? (I don't see Gecko's 4096 char text split happening for
   assigning .data, but could it happen in other implementations?) 
   Should setting textNode.data then result in ChildlistChanged?

3) Doing node.normalize() on a parent node may remove redundant
   text nodes so this should trigger ChildlistChanged. The perceived
   text is not changed, but individual text nodes' data is, so should
   TextDataChanged be triggered or not?

> The only undesirable feature is that code that mutates the DOM from
> inside a callback, say by calling setAttribute, can't rely on that by
> the time that setAttribute returns, all callbacks have been notified.
> This is unfortunately required if we want the second desirable
> property listed above.

I guess the following is an example of this? :

Considering having the following nodes and listener:
    attrListener1_1: if attr1 changed node2.setAttribute("attr2", "a")
    attrListener1_2: if attr1 changed node2.setAttribute("attr2", "b")
    attrListener2: what value of attr2 will this listener see?

and then calling:
  node1.setAttribute("attr1", "x")

would cause the following listener calls:
  attrListener1_1(node1) [attr1="x"]
  attrListener1_2(node1) [attr1="x"]
  attrListener2(node2) [attr2="b"] // expected "a"
  attrListener2(node2) [attr2="b"]

Ie, the undesirable effect is that attrListener2 is triggered twice
with the last state of node2, instead of once for each state?

Best regards
Mike Wilson
Received on Friday, 5 June 2009 22:52:33 UTC

This archive was generated by hypermail 2.3.1 : Tuesday, 20 October 2015 10:46:14 UTC