1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
|
// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_DOM_TRAVERSAL_RANGE_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_DOM_TRAVERSAL_RANGE_H_
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
namespace blink {
class Node;
template <class Iterator>
class TraversalRange {
STACK_ALLOCATED();
public:
using StartNodeType = typename Iterator::StartNodeType;
explicit TraversalRange(const StartNodeType* start) : start_(start) {}
Iterator begin() { return Iterator(start_); }
Iterator end() { return Iterator::End(); }
private:
const StartNodeType* start_;
};
template <class Traversal>
class TraversalIteratorBase {
STACK_ALLOCATED();
public:
using NodeType = typename Traversal::TraversalNodeType;
NodeType& operator*() { return *current_; }
bool operator!=(const TraversalIteratorBase& rval) const {
return current_ != rval.current_;
}
protected:
explicit TraversalIteratorBase(NodeType* current) : current_(current) {}
NodeType* current_;
};
template <class Traversal>
class TraversalIterator : public TraversalIteratorBase<Traversal> {
STACK_ALLOCATED();
public:
using StartNodeType = typename Traversal::TraversalNodeType;
using TraversalIteratorBase<Traversal>::current_;
explicit TraversalIterator(const StartNodeType* start)
: TraversalIteratorBase<Traversal>(const_cast<StartNodeType*>(start)) {}
void operator++() { current_ = Traversal::Next(*current_); }
static TraversalIterator End() { return TraversalIterator(); }
private:
TraversalIterator() : TraversalIteratorBase<Traversal>(nullptr) {}
};
template <class Traversal>
class TraversalDescendantIterator : public TraversalIteratorBase<Traversal> {
STACK_ALLOCATED();
public:
using StartNodeType = Node;
using TraversalIteratorBase<Traversal>::current_;
explicit TraversalDescendantIterator(const StartNodeType* start)
: TraversalIteratorBase<Traversal>(start ? Traversal::FirstWithin(*start)
: nullptr),
root_(start) {}
void operator++() { current_ = Traversal::Next(*current_, root_); }
static TraversalDescendantIterator End() {
return TraversalDescendantIterator();
}
private:
TraversalDescendantIterator() : TraversalIteratorBase<Traversal>(nullptr) {}
const StartNodeType* root_ = nullptr;
};
template <class Traversal>
class TraversalInclusiveDescendantIterator
: public TraversalIteratorBase<Traversal> {
STACK_ALLOCATED();
public:
using StartNodeType = typename Traversal::TraversalNodeType;
using TraversalIteratorBase<Traversal>::current_;
explicit TraversalInclusiveDescendantIterator(const StartNodeType* start)
: TraversalIteratorBase<Traversal>(const_cast<StartNodeType*>(start)),
root_(start) {}
void operator++() { current_ = Traversal::Next(*current_, root_); }
static TraversalInclusiveDescendantIterator End() {
return TraversalInclusiveDescendantIterator(nullptr);
}
private:
const StartNodeType* root_;
};
template <class Traversal>
class TraversalParent {
public:
using TraversalNodeType = typename Traversal::TraversalNodeType;
static TraversalNodeType* Next(const TraversalNodeType& node) {
return Traversal::Parent(node);
}
};
template <class Traversal>
class TraversalSibling {
public:
using TraversalNodeType = typename Traversal::TraversalNodeType;
static TraversalNodeType* Next(const TraversalNodeType& node) {
return Traversal::NextSibling(node);
}
};
template <class T>
using TraversalNextRange = TraversalRange<TraversalIterator<T>>;
template <class T>
using TraversalAncestorRange =
TraversalRange<TraversalIterator<TraversalParent<T>>>;
template <class T>
using TraversalSiblingRange =
TraversalRange<TraversalIterator<TraversalSibling<T>>>;
template <class T>
using TraversalDescendantRange = TraversalRange<TraversalDescendantIterator<T>>;
template <class T>
using TraversalInclusiveDescendantRange =
TraversalRange<TraversalInclusiveDescendantIterator<T>>;
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_DOM_TRAVERSAL_RANGE_H_
|