| Index: Source/core/dom/NodeTraversal.h
|
| diff --git a/Source/core/dom/NodeTraversal.h b/Source/core/dom/NodeTraversal.h
|
| index fafabc8e2de7d3fc1872b805ef837d167c8916eb..21a88311aaeddc1e6632c01207fa7c416a5400de 100644
|
| --- a/Source/core/dom/NodeTraversal.h
|
| +++ b/Source/core/dom/NodeTraversal.h
|
| @@ -31,8 +31,15 @@
|
|
|
| namespace blink {
|
|
|
| +template <class Iterator> class TraversalRange;
|
| +template <class TraversalNext> class TraversalChildrenIterator;
|
| +template <class TraversalNext> class TraversalDescendantIterator;
|
| +template <class TraversalNext> class TraversalInclusiveDescendantIterator;
|
| +template <class TraversalNext> class TraversalNextIterator;
|
| +
|
| class NodeTraversal {
|
| public:
|
| + using TraversalNodeType = Node;
|
| // Does a pre-order traversal of the tree to find the next node after this one.
|
| // This uses the same order that tags appear in the source file. If the stayWithin
|
| // argument is non-null, the traversal will stop once the specified node is reached.
|
| @@ -46,6 +53,8 @@ public:
|
| static Node* nextSkippingChildren(const Node&);
|
| static Node* nextSkippingChildren(const Node&, const Node* stayWithin);
|
|
|
| + static Node* firstWithin(const Node& current) { return current.firstChild(); }
|
| +
|
| static Node* lastWithin(const ContainerNode&);
|
| static Node& lastWithinOrSelf(Node&);
|
|
|
| @@ -74,6 +83,13 @@ public:
|
| static Node* childAt(const Node& parent, unsigned index) { return childAtTemplate(parent, index); }
|
| static Node* childAt(const ContainerNode& parent, unsigned index) { return childAtTemplate(parent, index); }
|
|
|
| + static Node* nextSibling(const Node& node) { return node.nextSibling(); }
|
| +
|
| + static TraversalRange<TraversalChildrenIterator<NodeTraversal>> childrenOf(const Node&);
|
| + static TraversalRange<TraversalDescendantIterator<NodeTraversal>> descendantsOf(const Node&);
|
| + static TraversalRange<TraversalInclusiveDescendantIterator<NodeTraversal>> inclusiveDescendantsOf(const Node&);
|
| + static TraversalRange<TraversalNextIterator<NodeTraversal>> fromNext(const Node&);
|
| +
|
| private:
|
| template <class NodeType>
|
| static Node* traverseNextTemplate(NodeType&);
|
| @@ -83,6 +99,99 @@ private:
|
| static Node* childAtTemplate(NodeType&, unsigned);
|
| };
|
|
|
| +template <class Iterator>
|
| +class TraversalRange {
|
| +public:
|
| + using StartNodeType = typename Iterator::StartNodeType;
|
| + explicit TraversalRange(const StartNodeType& start) : m_start(start) { }
|
| + Iterator begin() { return Iterator(m_start); }
|
| + Iterator end() { return Iterator::end(); }
|
| +private:
|
| + const StartNodeType& m_start;
|
| +};
|
| +
|
| +template <class TraversalNext>
|
| +class TraversalIteratorBase {
|
| +public:
|
| + using NodeType = typename TraversalNext::TraversalNodeType;
|
| + NodeType& operator*() { return *m_current; }
|
| + bool operator!=(const TraversalIteratorBase& rval) const { return m_current != rval.m_current ; }
|
| +protected:
|
| + explicit TraversalIteratorBase(NodeType* current) : m_current(current) { };
|
| + NodeType* m_current;
|
| +};
|
| +
|
| +template <class TraversalNext>
|
| +class TraversalChildrenIterator : public TraversalIteratorBase<TraversalNext> {
|
| +public:
|
| + using StartNodeType = Node;
|
| + using TraversalIteratorBase<TraversalNext>::m_current;
|
| + explicit TraversalChildrenIterator(const StartNodeType& start) : TraversalIteratorBase<TraversalNext>(TraversalNext::firstWithin(start)) { };
|
| + void operator++() { m_current = TraversalNext::nextSibling(*m_current); };
|
| + static TraversalChildrenIterator end() { return TraversalChildrenIterator(); };
|
| +private:
|
| + TraversalChildrenIterator() : TraversalIteratorBase<TraversalNext>(nullptr) { };
|
| +};
|
| +
|
| +template <class TraversalNext>
|
| +class TraversalNextIterator : public TraversalIteratorBase<TraversalNext> {
|
| +public:
|
| + using StartNodeType = Node;
|
| + using TraversalIteratorBase<TraversalNext>::m_current;
|
| + explicit TraversalNextIterator(const StartNodeType& start) : TraversalIteratorBase<TraversalNext>(TraversalNext::next(start)) { };
|
| + void operator++() { m_current = TraversalNext::next(*m_current); }
|
| + static TraversalNextIterator end() { return TraversalNextIterator(); };
|
| +private:
|
| + TraversalNextIterator() : TraversalIteratorBase<TraversalNext>(nullptr) { };
|
| +};
|
| +
|
| +template <class TraversalNext>
|
| +class TraversalDescendantIterator : public TraversalIteratorBase<TraversalNext> {
|
| +public:
|
| + using StartNodeType = Node;
|
| + using TraversalIteratorBase<TraversalNext>::m_current;
|
| + explicit TraversalDescendantIterator(const StartNodeType& start) : TraversalIteratorBase<TraversalNext>(TraversalNext::firstWithin(start)), m_root(&start) { };
|
| + void operator++() { m_current = TraversalNext::next(*m_current, m_root); }
|
| + static TraversalDescendantIterator end() { return TraversalDescendantIterator(); };
|
| +private:
|
| + TraversalDescendantIterator() : TraversalIteratorBase<TraversalNext>(nullptr), m_root(nullptr) { };
|
| + const Node* m_root;
|
| +};
|
| +
|
| +template <class TraversalNext>
|
| +class TraversalInclusiveDescendantIterator : public TraversalIteratorBase<TraversalNext> {
|
| +public:
|
| + using StartNodeType = typename TraversalNext::TraversalNodeType;
|
| + using NodeType = typename TraversalNext::TraversalNodeType;
|
| + using TraversalIteratorBase<TraversalNext>::m_current;
|
| + explicit TraversalInclusiveDescendantIterator(const StartNodeType& start) : TraversalIteratorBase<TraversalNext>(const_cast<NodeType*>(&start)), m_root(&start) { };
|
| + void operator++() { m_current = TraversalNext::next(*m_current, m_root); }
|
| + static TraversalInclusiveDescendantIterator end() { return TraversalInclusiveDescendantIterator(); };
|
| +private:
|
| + TraversalInclusiveDescendantIterator() : TraversalIteratorBase<TraversalNext>(nullptr), m_root(nullptr) { };
|
| + const StartNodeType* m_root;
|
| +};
|
| +
|
| +inline TraversalRange<TraversalChildrenIterator<NodeTraversal>> NodeTraversal::childrenOf(const Node& parent)
|
| +{
|
| + return TraversalRange<TraversalChildrenIterator<NodeTraversal>>(parent);
|
| +}
|
| +
|
| +inline TraversalRange<TraversalDescendantIterator<NodeTraversal>> NodeTraversal::descendantsOf(const Node& root)
|
| +{
|
| + return TraversalRange<TraversalDescendantIterator<NodeTraversal>>(root);
|
| +}
|
| +
|
| +inline TraversalRange<TraversalInclusiveDescendantIterator<NodeTraversal>> NodeTraversal::inclusiveDescendantsOf(const Node& root)
|
| +{
|
| + return TraversalRange<TraversalInclusiveDescendantIterator<NodeTraversal>>(root);
|
| +}
|
| +
|
| +inline TraversalRange<TraversalNextIterator<NodeTraversal>> NodeTraversal::fromNext(const Node& start)
|
| +{
|
| + return TraversalRange<TraversalNextIterator<NodeTraversal>>(start);
|
| +};
|
| +
|
| template <class NodeType>
|
| inline Node* NodeTraversal::traverseNextTemplate(NodeType& current)
|
| {
|
|
|