- From: Ms2ger <ms2ger@gmail.com>
- Date: Sun, 12 Aug 2012 22:16:50 +0200
- To: www-dom@w3.org
Hi Leo, On 08/10/2012 09:40 AM, Leo Deng wrote: > Hello, > > According to DOM4, when an author creates a TreeWalker object, the > return value of the acceptNode() method would be one of the following > three: > > FILTER_ACCEPT the current node passes the filter (and the > descendant would still be traversed). > FILTER_REJECT the current node doesn't pass the filter, and the > descendant would not be traversed. > FILTER_SKIP the current node doesn't pass the filter, but > continue traversing the decendants. > > All three values can't describe the "the current node passes the filter, > but the descendants would not be traversed" state. In other words, > there's a missing value: > > FILTER_ACCEPT FILTER_REJECT FILTER_SKIP FILTER_? > > passes the YES NO NO YES > filter > > descendants YES NO YES NO > traversed > > > Consider a use case when an author wants to select any <div> element in > an element with id "myid" such that it's not a descendant of an element > matching ".any". With TreeWalker, the following JavaScript code can > achieve this. > > var selected = []; > var domWalker = document.createTreeWalker( > document.getElementById('myid'), > NodeFilter.SHOW_ELEMENT, > { acceptNode: function(node) { > if((node.parentNode.classList.contains('any')) { > return NodeFilter.FILTER_REJECT; > } else if(node.tagName == 'DIV') { > return NodeFilter.FILTER_ACCEPT; > } else { > return NodeFilter.FILTER_SKIP; > } > } }, > false > ); > > while(domWalker.nextNode()) { > selected.push(domWalker.currentNode); > } > > For a node matching "div.any", when UA traverses it, among all three > possible return value of acceptNode(), only FILTER_ACCEPT indicates that > this node passes the filter. However, FILTER_ACCEPT couldn't stop UA > from traversing its children, so when its children is being traversed, > the code has to determine if the parent node is matching ".any" to > determine if acceptNode() can return a FILTER_REJECT here. > > If acceptNode() can return a value representing "the current node > passeds the filter, but the descendants would not be traversed", say, > FILTER_FINISH, then when UA traverses a node that passes the filter, it > may still decide not to traverse the children of the node. Therefore, > there's no longer a need to use *the characteristics of the parent node* > to decide what the return value of acceptNode() for the current node is > (which is also prone to error. For example, the above code throws when > the element with id "myid" doesn't have a parent): > > var selected = []; > var domWalker = document.createTreeWalker( > document.getElementById('myid'), > NodeFilter.SHOW_ELEMENT, > { acceptNode: function(node) { > if((node.parentNode.classList.contains('any')) { > return node.tagName == 'DIV' ? NodeFilter.FILTER_FINISH : > NodeFilter.FILTER_REJECT; > } else { > return node.tagName == 'DIV' ? NodeFilter.FILTER_ACCEPT : > NodeFilter.FILTER_SKIP; > } > } }, > false > ); > > while(domWalker.nextNode()) { > selected.push(domWalker.currentNode); > } > > FILTER_FINISH would be equivalent to FILTER_ACCEPT when used > for a filter of a NodeIterator. To track this proposal, I filed bug 18540 [1]. I would be interested to hear if there is implementer interest in this feature. Thanks Ms2ger [1] https://www.w3.org/Bugs/Public/show_bug.cgi?id=18540
Received on Sunday, 12 August 2012 20:17:22 UTC