Add element ancestor iterator
[WebKit-https.git] / Source / WebCore / dom / ElementIterator.h
1 /*
2  * Copyright (C) 2013 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #ifndef ElementIterator_h
27 #define ElementIterator_h
28
29 #include "ElementTraversal.h"
30
31 #if !ASSERT_DISABLED
32 #include "ElementIteratorAssertions.h"
33 #endif
34
35 namespace WebCore {
36
37 template <typename ElementType>
38 class ElementIterator {
39 public:
40     ElementIterator(const ContainerNode* root);
41     ElementIterator(const ContainerNode* root, ElementType* current);
42
43     ElementType& operator*();
44     ElementType* operator->();
45
46     bool operator==(const ElementIterator& other) const;
47     bool operator!=(const ElementIterator& other) const;
48
49     ElementIterator& traverseNext();
50     ElementIterator& traversePrevious();
51     ElementIterator& traverseNextSibling();
52     ElementIterator& traversePreviousSibling();
53     ElementIterator& traverseAncestor();
54
55 private:
56     const ContainerNode* m_root;
57     ElementType* m_current;
58
59 #if !ASSERT_DISABLED
60     ElementIteratorAssertions m_assertions;
61 #endif
62 };
63
64 template <typename ElementType>
65 class ElementConstIterator {
66 public:
67     ElementConstIterator(const ContainerNode* root);
68     ElementConstIterator(const ContainerNode* root, const ElementType* current);
69
70     const ElementType& operator*() const;
71     const ElementType* operator->() const;
72
73     bool operator==(const ElementConstIterator& other) const;
74     bool operator!=(const ElementConstIterator& other) const;
75
76     ElementConstIterator& traverseNext();
77     ElementConstIterator& traversePrevious();
78     ElementConstIterator& traverseNextSibling();
79     ElementConstIterator& traversePreviousSibling();
80     ElementConstIterator& traverseAncestor();
81
82 private:
83     const ContainerNode* m_root;
84     const ElementType* m_current;
85
86 #if !ASSERT_DISABLED
87     ElementIteratorAssertions m_assertions;
88 #endif
89 };
90
91 // ElementIterator
92
93 template <typename ElementType>
94 inline ElementIterator<ElementType>::ElementIterator(const ContainerNode* root)
95     : m_root(root)
96     , m_current(nullptr)
97 {
98 }
99
100 template <typename ElementType>
101 inline ElementIterator<ElementType>::ElementIterator(const ContainerNode* root, ElementType* current)
102     : m_root(root)
103     , m_current(current)
104 #if !ASSERT_DISABLED
105     , m_assertions(current)
106 #endif
107 {
108 }
109
110 template <typename ElementType>
111 inline ElementIterator<ElementType>& ElementIterator<ElementType>::traverseNext()
112 {
113     ASSERT(m_current);
114     ASSERT(!m_assertions.domTreeHasMutated());
115     m_current = Traversal<ElementType>::next(m_current, m_root);
116 #if !ASSERT_DISABLED
117     // Drop the assertion when the iterator reaches the end.
118     if (!m_current)
119         m_assertions.dropEventDispatchAssertion();
120 #endif
121     return *this;
122 }
123
124 template <typename ElementType>
125 inline ElementIterator<ElementType>& ElementIterator<ElementType>::traversePrevious()
126 {
127     ASSERT(m_current);
128     ASSERT(!m_assertions.domTreeHasMutated());
129     m_current = Traversal<ElementType>::previous(m_current, m_root);
130 #if !ASSERT_DISABLED
131     // Drop the assertion when the iterator reaches the end.
132     if (!m_current)
133         m_assertions.dropEventDispatchAssertion();
134 #endif
135     return *this;
136 }
137
138 template <typename ElementType>
139 inline ElementIterator<ElementType>& ElementIterator<ElementType>::traverseNextSibling()
140 {
141     ASSERT(m_current);
142     ASSERT(!m_assertions.domTreeHasMutated());
143     m_current = Traversal<ElementType>::nextSibling(m_current);
144 #if !ASSERT_DISABLED
145     // Drop the assertion when the iterator reaches the end.
146     if (!m_current)
147         m_assertions.dropEventDispatchAssertion();
148 #endif
149     return *this;
150 }
151
152 template <typename ElementType>
153 inline ElementIterator<ElementType>& ElementIterator<ElementType>::traversePreviousSibling()
154 {
155     ASSERT(m_current);
156     ASSERT(!m_assertions.domTreeHasMutated());
157     m_current = Traversal<ElementType>::previousSibling(m_current);
158 #if !ASSERT_DISABLED
159     // Drop the assertion when the iterator reaches the end.
160     if (!m_current)
161         m_assertions.dropEventDispatchAssertion();
162 #endif
163     return *this;
164 }
165
166 template <typename ElementTypeWithConst>
167 inline ElementTypeWithConst* findElementAncestorOfType(const Element& current)
168 {
169     ContainerNode* ancestor = current.parentNode();
170     while (ancestor && ancestor->isElementNode()) {
171         // Non-root containers are always Elements.
172         Element* element = toElement(ancestor);
173         if (isElementOfType<ElementTypeWithConst>(element))
174             return static_cast<ElementTypeWithConst*>(element);
175         ancestor = ancestor->parentNode();
176     }
177     return nullptr;
178 }
179
180 template <typename ElementType>
181 inline ElementIterator<ElementType>& ElementIterator<ElementType>::traverseAncestor()
182 {
183     ASSERT(m_current);
184     ASSERT(m_current != m_root);
185     ASSERT(!m_assertions.domTreeHasMutated());
186
187     m_current = findElementAncestorOfType<ElementType>(*m_current);
188
189 #if !ASSERT_DISABLED
190     // Drop the assertion when the iterator reaches the end.
191     if (!m_current)
192         m_assertions.dropEventDispatchAssertion();
193 #endif
194     return *this;
195 }
196
197 template <typename ElementType>
198 inline ElementType& ElementIterator<ElementType>::operator*()
199 {
200     ASSERT(m_current);
201     ASSERT(!m_assertions.domTreeHasMutated());
202     return *m_current;
203 }
204
205 template <typename ElementType>
206 inline ElementType* ElementIterator<ElementType>::operator->()
207 {
208     ASSERT(m_current);
209     ASSERT(!m_assertions.domTreeHasMutated());
210     return m_current;
211 }
212
213 template <typename ElementType>
214 inline bool ElementIterator<ElementType>::operator==(const ElementIterator& other) const
215 {
216     ASSERT(m_root == other.m_root);
217     ASSERT(!m_assertions.domTreeHasMutated());
218     return m_current == other.m_current;
219 }
220
221 template <typename ElementType>
222 inline bool ElementIterator<ElementType>::operator!=(const ElementIterator& other) const
223 {
224     return !(*this == other);
225 }
226
227 // ElementConstIterator
228
229 template <typename ElementType>
230 inline ElementConstIterator<ElementType>::ElementConstIterator(const ContainerNode* root)
231     : m_root(root)
232     , m_current(nullptr)
233 {
234 }
235
236 template <typename ElementType>
237 inline ElementConstIterator<ElementType>::ElementConstIterator(const ContainerNode* root, const ElementType* current)
238     : m_root(root)
239     , m_current(current)
240 #if !ASSERT_DISABLED
241     , m_assertions(current)
242 #endif
243 {
244 }
245
246 template <typename ElementType>
247 inline ElementConstIterator<ElementType>& ElementConstIterator<ElementType>::traverseNext()
248 {
249     ASSERT(m_current);
250     ASSERT(!m_assertions.domTreeHasMutated());
251     m_current = Traversal<ElementType>::next(m_current, m_root);
252 #if !ASSERT_DISABLED
253     // Drop the assertion when the iterator reaches the end.
254     if (!m_current)
255         m_assertions.dropEventDispatchAssertion();
256 #endif
257     return *this;
258 }
259
260 template <typename ElementType>
261 inline ElementConstIterator<ElementType>& ElementConstIterator<ElementType>::traversePrevious()
262 {
263     ASSERT(m_current);
264     ASSERT(!m_assertions.domTreeHasMutated());
265     m_current = Traversal<ElementType>::previous(m_current, m_root);
266 #if !ASSERT_DISABLED
267     // Drop the assertion when the iterator reaches the end.
268     if (!m_current)
269         m_assertions.dropEventDispatchAssertion();
270 #endif
271     return *this;
272 }
273
274 template <typename ElementType>
275 inline ElementConstIterator<ElementType>& ElementConstIterator<ElementType>::traverseNextSibling()
276 {
277     ASSERT(m_current);
278     ASSERT(!m_assertions.domTreeHasMutated());
279     m_current = Traversal<ElementType>::nextSibling(m_current);
280 #if !ASSERT_DISABLED
281     // Drop the assertion when the iterator reaches the end.
282     if (!m_current)
283         m_assertions.dropEventDispatchAssertion();
284 #endif
285     return *this;
286 }
287
288 template <typename ElementType>
289 inline ElementConstIterator<ElementType>& ElementConstIterator<ElementType>::traversePreviousSibling()
290 {
291     ASSERT(m_current);
292     ASSERT(!m_assertions.domTreeHasMutated());
293     m_current = Traversal<ElementType>::previousSibling(m_current);
294 #if !ASSERT_DISABLED
295     // Drop the assertion when the iterator reaches the end.
296     if (!m_current)
297         m_assertions.dropEventDispatchAssertion();
298 #endif
299     return *this;
300 }
301
302 template <typename ElementType>
303 inline ElementConstIterator<ElementType>& ElementConstIterator<ElementType>::traverseAncestor()
304 {
305     ASSERT(m_current);
306     ASSERT(m_current != m_root);
307     ASSERT(!m_assertions.domTreeHasMutated());
308
309     m_current = findElementAncestorOfType<const ElementType>(*m_current);
310
311 #if !ASSERT_DISABLED
312     // Drop the assertion when the iterator reaches the end.
313     if (!m_current)
314         m_assertions.dropEventDispatchAssertion();
315 #endif
316     return *this;
317 }
318
319 template <typename ElementType>
320 inline const ElementType& ElementConstIterator<ElementType>::operator*() const
321 {
322     ASSERT(m_current);
323     ASSERT(!m_assertions.domTreeHasMutated());
324     return *m_current;
325 }
326
327 template <typename ElementType>
328 inline const ElementType* ElementConstIterator<ElementType>::operator->() const
329 {
330     ASSERT(m_current);
331     ASSERT(!m_assertions.domTreeHasMutated());
332     return m_current;
333 }
334
335 template <typename ElementType>
336 inline bool ElementConstIterator<ElementType>::operator==(const ElementConstIterator& other) const
337 {
338     ASSERT(m_root == other.m_root);
339     ASSERT(!m_assertions.domTreeHasMutated());
340     return m_current == other.m_current;
341 }
342
343 template <typename ElementType>
344 inline bool ElementConstIterator<ElementType>::operator!=(const ElementConstIterator& other) const
345 {
346     return !(*this == other);
347 }
348
349 }
350
351 #include "ElementAncestorIterator.h"
352 #include "ElementChildIterator.h"
353 #include "ElementDescendantIterator.h"
354
355 #endif