summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/core/dom/traversal_range.h
blob: 38939a61e34069340b9cd2ac1aa54b544397e925 (plain)
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. All rights reserved.
// 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/heap/handle.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:
  Member<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) {}

  Member<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) {}
  Member<const StartNodeType> root_;
};

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:
  Member<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_