- 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