001package votorola.g.web.gwt; // Copyright 2012, Michael Allan.  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Votorola Software"), to deal in the Votorola Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicence, and/or sell copies of the Votorola Software, and to permit persons to whom the Votorola Software is furnished to do so, subject to the following conditions: The preceding copyright notice and this permission notice shall be included in all copies or substantial portions of the Votorola Software. THE VOTOROLA SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE VOTOROLA SOFTWARE OR THE USE OR OTHER DEALINGS IN THE VOTOROLA SOFTWARE.
002
003import com.google.gwt.dom.client.*;
004
005
006/** {@linkplain Node Node} utilities.
007  */
008public final class NodeX
009{
010
011
012    private NodeX() {}
013
014
015
016    /** Returns the next ancestor that is an element, or null if there is none.
017      */
018    public static Element nextAncestorElement( Node node )
019    {
020        for( ;; )
021        {
022            node = node.getParentNode();
023            if( node == null ) return null;
024
025            if( Element.is( node )) return node.cast();
026        }
027    }
028
029
030
031    /** Returns the next element in document order; or null if n is null, or the document
032      * has no more elements.
033      *
034      *     @param n the reference node, which may be null.
035      *     @param name the tag name to restrict the search to, or null to search for
036      *       elements of any tag name.
037      *     @param deeply whether to recurse into child nodes, if any.
038      */
039    public static Element nextElement( Node n, final String name, final boolean deeply )
040    {
041        for( ;; )
042        {
043            n = nextNode( n, deeply );
044            if( n == null ) break;
045
046            if( !Element.is( n )) continue;
047
048            if( name == null || name.equals(n.getNodeName()) ) return n.cast();
049        }
050        return null;
051    }
052
053
054
055    /** Returns the next node in document order; or null if n is null, or the document has
056      * no more nodes.
057      *
058      *     @param n the reference node, which may be null.
059      *     @param deeply whether to recurse into child nodes, if any.  Calling
060      *       <code>nextNode(n,true)</code> is equivalent to
061      *       org.w3c.dom.traversal.TreeWalker.nextNode.
062      */
063    public static Node nextNode( final Node n, final boolean deeply )
064    {
065        Node o = null; // next node
066        walk: if( n != null )
067        {
068            if( deeply )
069            {
070                o = n.getFirstChild();
071                if( o != null ) break walk;
072            }
073
074            o = n.getNextSibling();
075            if( o != null ) break walk;
076
077            o = nextNode( n.getParentNode(), /*deeply*/false );
078        }
079        return o;
080    }
081
082
083
084}