| OLD | NEW | 
|---|
| 1 /* | 1 /* | 
| 2  * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2  * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 
| 3  *           (C) 1999 Antti Koivisto (koivisto@kde.org) | 3  *           (C) 1999 Antti Koivisto (koivisto@kde.org) | 
| 4  *           (C) 2001 Dirk Mueller (mueller@kde.org) | 4  *           (C) 2001 Dirk Mueller (mueller@kde.org) | 
| 5  * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc.
      All rights reserved. | 5  * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc.
      All rights reserved. | 
| 6  * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.t
     orchmobile.com/) | 6  * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.t
     orchmobile.com/) | 
| 7  * Copyright (C) 2014 Samsung Electronics. All rights reserved. | 7  * Copyright (C) 2014 Samsung Electronics. All rights reserved. | 
| 8  * | 8  * | 
| 9  * This library is free software; you can redistribute it and/or | 9  * This library is free software; you can redistribute it and/or | 
| 10  * modify it under the terms of the GNU Library General Public | 10  * modify it under the terms of the GNU Library General Public | 
| (...skipping 13 matching lines...) Expand all  Loading... | 
| 24  */ | 24  */ | 
| 25 | 25 | 
| 26 #ifndef NodeTraversal_h | 26 #ifndef NodeTraversal_h | 
| 27 #define NodeTraversal_h | 27 #define NodeTraversal_h | 
| 28 | 28 | 
| 29 #include "core/dom/ContainerNode.h" | 29 #include "core/dom/ContainerNode.h" | 
| 30 #include "core/dom/Node.h" | 30 #include "core/dom/Node.h" | 
| 31 | 31 | 
| 32 namespace blink { | 32 namespace blink { | 
| 33 | 33 | 
|  | 34 template <class Iterator> class TraversalRange; | 
|  | 35 template <class TraversalNext> class TraversalChildrenIterator; | 
|  | 36 template <class TraversalNext> class TraversalDescendantIterator; | 
|  | 37 template <class TraversalNext> class TraversalInclusiveDescendantIterator; | 
|  | 38 template <class TraversalNext> class TraversalNextIterator; | 
|  | 39 | 
| 34 class NodeTraversal { | 40 class NodeTraversal { | 
| 35 public: | 41 public: | 
|  | 42     using TraversalNodeType = Node; | 
| 36     // Does a pre-order traversal of the tree to find the next node after this o
     ne. | 43     // Does a pre-order traversal of the tree to find the next node after this o
     ne. | 
| 37     // This uses the same order that tags appear in the source file. If the stay
     Within | 44     // This uses the same order that tags appear in the source file. If the stay
     Within | 
| 38     // argument is non-null, the traversal will stop once the specified node is 
     reached. | 45     // argument is non-null, the traversal will stop once the specified node is 
     reached. | 
| 39     // This can be used to restrict traversal to a particular sub-tree. | 46     // This can be used to restrict traversal to a particular sub-tree. | 
| 40     static Node* next(const Node& current) { return traverseNextTemplate(current
     ); } | 47     static Node* next(const Node& current) { return traverseNextTemplate(current
     ); } | 
| 41     static Node* next(const ContainerNode& current) { return traverseNextTemplat
     e(current); } | 48     static Node* next(const ContainerNode& current) { return traverseNextTemplat
     e(current); } | 
| 42     static Node* next(const Node& current, const Node* stayWithin) { return trav
     erseNextTemplate(current, stayWithin); } | 49     static Node* next(const Node& current, const Node* stayWithin) { return trav
     erseNextTemplate(current, stayWithin); } | 
| 43     static Node* next(const ContainerNode& current, const Node* stayWithin) { re
     turn traverseNextTemplate(current, stayWithin); } | 50     static Node* next(const ContainerNode& current, const Node* stayWithin) { re
     turn traverseNextTemplate(current, stayWithin); } | 
| 44 | 51 | 
| 45     // Like next, but skips children and starts with the next sibling. | 52     // Like next, but skips children and starts with the next sibling. | 
| 46     static Node* nextSkippingChildren(const Node&); | 53     static Node* nextSkippingChildren(const Node&); | 
| 47     static Node* nextSkippingChildren(const Node&, const Node* stayWithin); | 54     static Node* nextSkippingChildren(const Node&, const Node* stayWithin); | 
| 48 | 55 | 
|  | 56     static Node* firstWithin(const Node& current) { return current.firstChild();
      } | 
|  | 57 | 
| 49     static Node* lastWithin(const ContainerNode&); | 58     static Node* lastWithin(const ContainerNode&); | 
| 50     static Node& lastWithinOrSelf(Node&); | 59     static Node& lastWithinOrSelf(Node&); | 
| 51 | 60 | 
| 52     // Does a reverse pre-order traversal to find the node that comes before the
      current one in document order | 61     // Does a reverse pre-order traversal to find the node that comes before the
      current one in document order | 
| 53     static Node* previous(const Node&, const Node* stayWithin = 0); | 62     static Node* previous(const Node&, const Node* stayWithin = 0); | 
| 54 | 63 | 
| 55     // Like previous, but skips children and starts with the next sibling. | 64     // Like previous, but skips children and starts with the next sibling. | 
| 56     static Node* previousSkippingChildren(const Node&, const Node* stayWithin = 
     0); | 65     static Node* previousSkippingChildren(const Node&, const Node* stayWithin = 
     0); | 
| 57 | 66 | 
| 58     // Like next, but visits parents after their children. | 67     // Like next, but visits parents after their children. | 
| 59     static Node* nextPostOrder(const Node&, const Node* stayWithin = 0); | 68     static Node* nextPostOrder(const Node&, const Node* stayWithin = 0); | 
| 60 | 69 | 
| 61     // Like previous, but visits parents before their children. | 70     // Like previous, but visits parents before their children. | 
| 62     static Node* previousPostOrder(const Node&, const Node* stayWithin = 0); | 71     static Node* previousPostOrder(const Node&, const Node* stayWithin = 0); | 
| 63 | 72 | 
| 64     // Pre-order traversal including the pseudo-elements. | 73     // Pre-order traversal including the pseudo-elements. | 
| 65     static Node* previousIncludingPseudo(const Node&, const Node* stayWithin = 0
     ); | 74     static Node* previousIncludingPseudo(const Node&, const Node* stayWithin = 0
     ); | 
| 66     static Node* nextIncludingPseudo(const Node&, const Node* stayWithin = 0); | 75     static Node* nextIncludingPseudo(const Node&, const Node* stayWithin = 0); | 
| 67     static Node* nextIncludingPseudoSkippingChildren(const Node&, const Node* st
     ayWithin = 0); | 76     static Node* nextIncludingPseudoSkippingChildren(const Node&, const Node* st
     ayWithin = 0); | 
| 68 | 77 | 
| 69     static Node* nextAncestorSibling(const Node&); | 78     static Node* nextAncestorSibling(const Node&); | 
| 70     static Node* nextAncestorSibling(const Node&, const Node* stayWithin); | 79     static Node* nextAncestorSibling(const Node&, const Node* stayWithin); | 
| 71     static Node& highestAncestorOrSelf(Node&); | 80     static Node& highestAncestorOrSelf(Node&); | 
| 72 | 81 | 
| 73     // Children traversal. | 82     // Children traversal. | 
| 74     static Node* childAt(const Node& parent, unsigned index) { return childAtTem
     plate(parent, index); } | 83     static Node* childAt(const Node& parent, unsigned index) { return childAtTem
     plate(parent, index); } | 
| 75     static Node* childAt(const ContainerNode& parent, unsigned index) { return c
     hildAtTemplate(parent, index); } | 84     static Node* childAt(const ContainerNode& parent, unsigned index) { return c
     hildAtTemplate(parent, index); } | 
| 76 | 85 | 
|  | 86     static Node* nextSibling(const Node& node) { return node.nextSibling(); } | 
|  | 87 | 
|  | 88     static TraversalRange<TraversalChildrenIterator<NodeTraversal>> childrenOf(c
     onst Node&); | 
|  | 89     static TraversalRange<TraversalDescendantIterator<NodeTraversal>> descendant
     sOf(const Node&); | 
|  | 90     static TraversalRange<TraversalInclusiveDescendantIterator<NodeTraversal>> i
     nclusiveDescendantsOf(const Node&); | 
|  | 91     static TraversalRange<TraversalNextIterator<NodeTraversal>> fromNext(const N
     ode&); | 
|  | 92 | 
| 77 private: | 93 private: | 
| 78     template <class NodeType> | 94     template <class NodeType> | 
| 79     static Node* traverseNextTemplate(NodeType&); | 95     static Node* traverseNextTemplate(NodeType&); | 
| 80     template <class NodeType> | 96     template <class NodeType> | 
| 81     static Node* traverseNextTemplate(NodeType&, const Node* stayWithin); | 97     static Node* traverseNextTemplate(NodeType&, const Node* stayWithin); | 
| 82     template <class NodeType> | 98     template <class NodeType> | 
| 83     static Node* childAtTemplate(NodeType&, unsigned); | 99     static Node* childAtTemplate(NodeType&, unsigned); | 
| 84 }; | 100 }; | 
| 85 | 101 | 
|  | 102 template <class Iterator> | 
|  | 103 class TraversalRange { | 
|  | 104 public: | 
|  | 105     using StartNodeType = typename Iterator::StartNodeType; | 
|  | 106     explicit TraversalRange(const StartNodeType& start) : m_start(start) { } | 
|  | 107     Iterator begin() { return Iterator(m_start); } | 
|  | 108     Iterator end() { return Iterator::end(); } | 
|  | 109 private: | 
|  | 110     const StartNodeType& m_start; | 
|  | 111 }; | 
|  | 112 | 
|  | 113 template <class TraversalNext> | 
|  | 114 class TraversalIteratorBase { | 
|  | 115 public: | 
|  | 116     using NodeType = typename TraversalNext::TraversalNodeType; | 
|  | 117     NodeType& operator*() { return *m_current; } | 
|  | 118     bool operator!=(const TraversalIteratorBase& rval) const { return m_current 
     != rval.m_current ; } | 
|  | 119 protected: | 
|  | 120     explicit TraversalIteratorBase(NodeType* current) : m_current(current) { }; | 
|  | 121     NodeType* m_current; | 
|  | 122 }; | 
|  | 123 | 
|  | 124 template <class TraversalNext> | 
|  | 125 class TraversalChildrenIterator : public TraversalIteratorBase<TraversalNext> { | 
|  | 126 public: | 
|  | 127     using StartNodeType = Node; | 
|  | 128     using TraversalIteratorBase<TraversalNext>::m_current; | 
|  | 129     explicit TraversalChildrenIterator(const StartNodeType& start) : TraversalIt
     eratorBase<TraversalNext>(TraversalNext::firstWithin(start)) { }; | 
|  | 130     void operator++() { m_current = TraversalNext::nextSibling(*m_current); }; | 
|  | 131     static TraversalChildrenIterator end() { return TraversalChildrenIterator();
      }; | 
|  | 132 private: | 
|  | 133     TraversalChildrenIterator() : TraversalIteratorBase<TraversalNext>(nullptr) 
     { }; | 
|  | 134 }; | 
|  | 135 | 
|  | 136 template <class TraversalNext> | 
|  | 137 class TraversalNextIterator : public TraversalIteratorBase<TraversalNext> { | 
|  | 138 public: | 
|  | 139     using StartNodeType = Node; | 
|  | 140     using TraversalIteratorBase<TraversalNext>::m_current; | 
|  | 141     explicit TraversalNextIterator(const StartNodeType& start) : TraversalIterat
     orBase<TraversalNext>(TraversalNext::next(start)) { }; | 
|  | 142     void operator++() { m_current = TraversalNext::next(*m_current); } | 
|  | 143     static TraversalNextIterator end() { return TraversalNextIterator(); }; | 
|  | 144 private: | 
|  | 145     TraversalNextIterator() : TraversalIteratorBase<TraversalNext>(nullptr) { }; | 
|  | 146 }; | 
|  | 147 | 
|  | 148 template <class TraversalNext> | 
|  | 149 class TraversalDescendantIterator : public TraversalIteratorBase<TraversalNext> 
     { | 
|  | 150 public: | 
|  | 151     using StartNodeType = Node; | 
|  | 152     using TraversalIteratorBase<TraversalNext>::m_current; | 
|  | 153     explicit TraversalDescendantIterator(const StartNodeType& start) : Traversal
     IteratorBase<TraversalNext>(TraversalNext::firstWithin(start)), m_root(&start) {
      }; | 
|  | 154     void operator++() { m_current = TraversalNext::next(*m_current, m_root); } | 
|  | 155     static TraversalDescendantIterator end() { return TraversalDescendantIterato
     r(); }; | 
|  | 156 private: | 
|  | 157     TraversalDescendantIterator() : TraversalIteratorBase<TraversalNext>(nullptr
     ), m_root(nullptr) { }; | 
|  | 158     const Node* m_root; | 
|  | 159 }; | 
|  | 160 | 
|  | 161 template <class TraversalNext> | 
|  | 162 class TraversalInclusiveDescendantIterator : public TraversalIteratorBase<Traver
     salNext> { | 
|  | 163 public: | 
|  | 164     using StartNodeType = typename TraversalNext::TraversalNodeType; | 
|  | 165     using NodeType = typename TraversalNext::TraversalNodeType; | 
|  | 166     using TraversalIteratorBase<TraversalNext>::m_current; | 
|  | 167     explicit TraversalInclusiveDescendantIterator(const StartNodeType& start) : 
     TraversalIteratorBase<TraversalNext>(const_cast<NodeType*>(&start)), m_root(&sta
     rt) { }; | 
|  | 168     void operator++() { m_current = TraversalNext::next(*m_current, m_root); } | 
|  | 169     static TraversalInclusiveDescendantIterator end() { return TraversalInclusiv
     eDescendantIterator(); }; | 
|  | 170 private: | 
|  | 171     TraversalInclusiveDescendantIterator() : TraversalIteratorBase<TraversalNext
     >(nullptr), m_root(nullptr) { }; | 
|  | 172     const StartNodeType* m_root; | 
|  | 173 }; | 
|  | 174 | 
|  | 175 inline TraversalRange<TraversalChildrenIterator<NodeTraversal>> NodeTraversal::c
     hildrenOf(const Node& parent) | 
|  | 176 { | 
|  | 177     return TraversalRange<TraversalChildrenIterator<NodeTraversal>>(parent); | 
|  | 178 } | 
|  | 179 | 
|  | 180 inline TraversalRange<TraversalDescendantIterator<NodeTraversal>> NodeTraversal:
     :descendantsOf(const Node& root) | 
|  | 181 { | 
|  | 182     return TraversalRange<TraversalDescendantIterator<NodeTraversal>>(root); | 
|  | 183 } | 
|  | 184 | 
|  | 185 inline TraversalRange<TraversalInclusiveDescendantIterator<NodeTraversal>> NodeT
     raversal::inclusiveDescendantsOf(const Node& root) | 
|  | 186 { | 
|  | 187     return TraversalRange<TraversalInclusiveDescendantIterator<NodeTraversal>>(r
     oot); | 
|  | 188 } | 
|  | 189 | 
|  | 190 inline TraversalRange<TraversalNextIterator<NodeTraversal>> NodeTraversal::fromN
     ext(const Node& start) | 
|  | 191 { | 
|  | 192     return TraversalRange<TraversalNextIterator<NodeTraversal>>(start); | 
|  | 193 }; | 
|  | 194 | 
| 86 template <class NodeType> | 195 template <class NodeType> | 
| 87 inline Node* NodeTraversal::traverseNextTemplate(NodeType& current) | 196 inline Node* NodeTraversal::traverseNextTemplate(NodeType& current) | 
| 88 { | 197 { | 
| 89     if (current.hasChildren()) | 198     if (current.hasChildren()) | 
| 90         return current.firstChild(); | 199         return current.firstChild(); | 
| 91     if (current.nextSibling()) | 200     if (current.nextSibling()) | 
| 92         return current.nextSibling(); | 201         return current.nextSibling(); | 
| 93     return nextAncestorSibling(current); | 202     return nextAncestorSibling(current); | 
| 94 } | 203 } | 
| 95 | 204 | 
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 134 { | 243 { | 
| 135     Node* child = parent.firstChild(); | 244     Node* child = parent.firstChild(); | 
| 136     while (child && index--) | 245     while (child && index--) | 
| 137         child = child->nextSibling(); | 246         child = child->nextSibling(); | 
| 138     return child; | 247     return child; | 
| 139 } | 248 } | 
| 140 | 249 | 
| 141 } // namespace blink | 250 } // namespace blink | 
| 142 | 251 | 
| 143 #endif | 252 #endif | 
| OLD | NEW | 
|---|