W3C home > Mailing lists > Public > www-dom@w3.org > January to March 2000

RE: DocumentTraversal

From: Keith W. Boone <kboone@ebt.com>
Date: Mon, 6 Mar 2000 16:02:46 -0500
To: <keshlam@us.ibm.com>
Cc: <www-dom@w3.org>
Message-ID: <000201bf87af$531d5100$767770c6@ebt.com>

As you said, your mileage may vary.  Mine still does, so perhaps I can make
more convincing arguments:

> -----Original Message-----
> From: www-dom-request@w3.org
> [mailto:www-dom-request@w3.org]On Behalf Of
> keshlam@us.ibm.com
> Sent: Monday, March 06, 2000 1:08 PM
> To: w
> Cc: www-dom@w3.org
> Subject: Re: DocumentTraversal
> >First: The DocumentTraversal methods appears to be an
> >extension of the Node Interface, rather than an additional interface
> >that may be supported by the Document.
> Interesting thought.
> We designed these to live on the Document with the other
> factory methods, and to be passed their root node as an argument...
> but we _could_ have instead designed them so the factory was invoked
> on the root node itself, and had that association be implicit.  I agree
> that the latter is prettier architecturally.
> But consider the recent comment "You mean I have to cast to
> get access to the DocumentTraversal methods? Yuck!" -- If these live
> on the Document object, you may be able to cast once and hang onto the
> DocumentTraversal through repeated operations on that document. If they
> live on individual Nodes you'd have to cast each root node, probably every
> unless you're  repeatedly iterating over a single subtree.
> Unless the factory continues to take the root node as a
> parameter... in which case I'm not sure the difference between this
> and status quo is large enough to make much difference.
> I don't have a hugely strong opinion on this either way.

One way to avoid this would be to just put the two factory operations on
Node, removing the factory altogether.  Then take the approach that a Node
(c.f. "supports()") the traversal API would return a non-null
from the createTreeWalker/createIterator methods, whereas one that doesn't
it simply returns null.  This eliminates the need for the cast (and the
Factory) completely.  OK, so now you have to check the result everytime you
createTreeWalker ..., perhaps not as nice as a factory which always returns
a TreeWalker
or Iterator.

Yup, it breaks existing implementations, but you've already required
implementations to modify node anyway.  Those that don't care to support the
methods can add a few lines of code and they are done.

Finally, I would hope that the largest users of the API would be developers,
not implementors.  That would mean to me that making it easier for
should take priority.  Making it easier to access these from Node does make
easier for developers.

NOTE:  I cannot make the same argument for Range, as that really should be
available from Document.  Although if you do decide to put the factory
methods in
Document, you should take the same approach with the RangeFactory methods in

> >Secondly, the expandEntityReferences flag on the factory method should
> >really just be another constant that can be passed into whatToShow:
> It could be another bit in that mask, true. I'm not sure this is a net
> gain, though; it's conflating two seperate operations. Given that the
> factory call is a relatively rare operation compared to actually using the
> traversal objects, I'm not convinced that saving a parameter really gains
> us anything. Especially as bits are a scarce resource; I don't expect us
> need more than 31 nodeTypes, and there's the workaround of moving the
> nodeType test into a filter, but I'd rather not establish a precedent of
> nibbling from both ends toward the middle.
> And thinking about how I'd implement it, the first thing I'd be inclined
> do inside the factory would be to break SHOW_ENTITY_REFERENCE_EXPANSION
> into a separate boolean so it could be tested conveniently, and clear that
> bit in the mask so I didn't have to special-case it when deciding how to
> handle the rest. So saving a parameter might increase computation.
> I think this winds up being a matter of style as much as
> anything else. My instincts say to leave it as is. Your milage may vary.

The spec says that "whatToShow" specifies which node types may appear in the
logical view of the tree presented by the iterator.  As far as I'm
that is the operation being referenced, so I don't consider the two
to be 'conflated'.

Sure, you've made it easy to implement it as:

	if ((whatToShow & ( 1 << node.getNodeType()) != 0)

	if (expandEntityReferences && node.getNodeType() == Node.ENTITY_REFERENCE)

But that's syntactic sugar unless you make the above implementation part of
the specification.  [i.e., indicate that the flags will always be
specified that way].  BTW:  The easy implementation shown above wouldn't
muster in our organization.  It's a cute trick, but it isn't obvious what
code does, and it relies on some details that could change in a subsequent

Furthermore, if you want the same "simplicity" you can handle it just as
easily using
a static array, which is independant of where you put the actual flag

	if ((whatToShow & showMasks[node.getNodeType()]) != 0)

	if ((whatToShow && expandMasks[node.getNodeType()]) != 0)

The second implementation seems preferable, especially when you consider
TreeWalker and NodeIterator may be used to walk/iterate over DocumentTypes
in DOM3, in
which case you might have more flags like expandEntityReference.

If you are going to stick with the two separate arguments, could you at
least make
the second one another mask, and define a constant for entity references.
That way
it is extensible enough so that if DOM3 wants to, it can expand into the

Received on Monday, 6 March 2000 16:03:46 GMT

This archive was generated by hypermail 2.2.0+W3C-0.50 : Friday, 22 June 2012 06:13:47 GMT