5c43a1dcafea6f9a407d567a4033d5cddcf1039a
[WebKit-https.git] / Source / WebCore / rendering / RenderIterator.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 RenderIterator_h
27 #define RenderIterator_h
28
29 #include "RenderElement.h"
30
31 namespace WebCore {
32
33 template <typename T>
34 class RenderIterator {
35 public:
36     RenderIterator(const RenderElement* root);
37     RenderIterator(const RenderElement* root, T* current);
38
39     T& operator*();
40     T* operator->();
41
42     bool operator==(const RenderIterator& other) const;
43     bool operator!=(const RenderIterator& other) const;
44
45     RenderIterator& traverseNext();
46     RenderIterator& traverseNextSibling();
47     RenderIterator& traversePreviousSibling();
48     RenderIterator& traverseAncestor();
49
50 private:
51     const RenderElement* m_root;
52     T* m_current;
53 };
54
55 template <typename T>
56 class RenderConstIterator {
57 public:
58     RenderConstIterator(const RenderElement* root);
59     RenderConstIterator(const RenderElement* root, const T* current);
60
61     const T& operator*() const;
62     const T* operator->() const;
63
64     bool operator==(const RenderConstIterator& other) const;
65     bool operator!=(const RenderConstIterator& other) const;
66
67     RenderConstIterator& traverseNext();
68     RenderConstIterator& traverseNextSibling();
69     RenderConstIterator& traversePreviousSibling();
70     RenderConstIterator& traverseAncestor();
71
72 private:
73     const RenderElement* m_root;
74     const T* m_current;
75 };
76
77 // Similar to WTF::is<>() but without the static_assert() making sure the check is necessary.
78 template <typename T, typename U>
79 inline bool isRendererOfType(const U& renderer) { return TypeCastTraits<const T, const U>::isOfType(renderer); }
80
81 // Traversal helpers
82
83 namespace RenderObjectTraversal {
84
85 template <typename U>
86 inline RenderObject* firstChild(U& object)
87 {
88     return object.firstChild();
89 }
90
91 inline RenderObject* firstChild(RenderObject& object)
92 {
93     return object.firstChildSlow();
94 }
95
96 inline RenderObject* firstChild(RenderText&)
97 {
98     return nullptr;
99 }
100
101 inline RenderObject* nextAncestorSibling(RenderObject& current, const RenderObject* stayWithin)
102 {
103     for (auto* ancestor = current.parent(); ancestor; ancestor = ancestor->parent()) {
104         if (ancestor == stayWithin)
105             return nullptr;
106         if (auto* sibling = ancestor->nextSibling())
107             return sibling;
108     }
109     return nullptr;
110 }
111
112 template <typename U>
113 inline RenderObject* next(U& current, const RenderObject* stayWithin)
114 {
115     if (auto* child = firstChild(current))
116         return child;
117
118     if (&current == stayWithin)
119         return nullptr;
120
121     if (auto* sibling = current.nextSibling())
122         return sibling;
123
124     return nextAncestorSibling(current, stayWithin);
125 }
126
127 inline RenderObject* nextSkippingChildren(RenderObject& current, const RenderObject* stayWithin)
128 {
129     if (&current == stayWithin)
130         return nullptr;
131
132     if (auto* sibling = current.nextSibling())
133         return sibling;
134
135     return nextAncestorSibling(current, stayWithin);
136 }
137
138 }
139
140 namespace RenderTraversal {
141
142 template <typename T, typename U>
143 inline T* firstChild(U& current)
144 {
145     RenderObject* object = RenderObjectTraversal::firstChild(current);
146     while (object && !isRendererOfType<T>(*object))
147         object = object->nextSibling();
148     return static_cast<T*>(object);
149 }
150
151 template <typename T, typename U>
152 inline T* lastChild(U& current)
153 {
154     RenderObject* object = current.lastChild();
155     while (object && !isRendererOfType<T>(*object))
156         object = object->previousSibling();
157     return static_cast<T*>(object);
158 }
159
160 template <typename T, typename U>
161 inline T* nextSibling(U& current)
162 {
163     RenderObject* object = current.nextSibling();
164     while (object && !isRendererOfType<T>(*object))
165         object = object->nextSibling();
166     return static_cast<T*>(object);
167 }
168
169 template <typename T, typename U>
170 inline T* previousSibling(U& current)
171 {
172     RenderObject* object = current.previousSibling();
173     while (object && !isRendererOfType<T>(*object))
174         object = object->previousSibling();
175     return static_cast<T*>(object);
176 }
177
178 template <typename T>
179 inline T* findAncestorOfType(const RenderObject& current)
180 {
181     for (auto* ancestor = current.parent(); ancestor; ancestor = ancestor->parent()) {
182         if (isRendererOfType<T>(*ancestor))
183             return static_cast<T*>(ancestor);
184     }
185     return nullptr;
186 }
187
188 template <typename T, typename U>
189 inline T* firstWithin(U& current)
190 {
191     auto* descendant = RenderObjectTraversal::firstChild(current);
192     while (descendant && !isRendererOfType<T>(*descendant))
193         descendant = RenderObjectTraversal::next(*descendant, &current);
194     return static_cast<T*>(descendant);
195 }
196
197 template <typename T, typename U>
198 inline T* next(U& current, const RenderObject* stayWithin)
199 {
200     auto* descendant = RenderObjectTraversal::next(current, stayWithin);
201     while (descendant && !isRendererOfType<T>(*descendant))
202         descendant = RenderObjectTraversal::next(*descendant, stayWithin);
203     return static_cast<T*>(descendant);
204 }
205
206 } // namespace WebCore::RenderTraversal
207
208 // RenderIterator
209
210 template <typename T>
211 inline RenderIterator<T>::RenderIterator(const RenderElement* root)
212     : m_root(root)
213     , m_current(nullptr)
214 {
215 }
216
217 template <typename T>
218 inline RenderIterator<T>::RenderIterator(const RenderElement* root, T* current)
219     : m_root(root)
220     , m_current(current)
221 {
222 }
223
224 template <typename T>
225 inline RenderIterator<T>& RenderIterator<T>::traverseNextSibling()
226 {
227     ASSERT(m_current);
228     m_current = RenderTraversal::nextSibling<T>(*m_current);
229     return *this;
230 }
231
232 template <typename T>
233 inline RenderIterator<T>& RenderIterator<T>::traverseNext()
234 {
235     ASSERT(m_current);
236     m_current = RenderTraversal::next<T>(*m_current, m_root);
237     return *this;
238 }
239
240 template <typename T>
241 inline RenderIterator<T>& RenderIterator<T>::traversePreviousSibling()
242 {
243     ASSERT(m_current);
244     m_current = RenderTraversal::previousSibling<T>(*m_current);
245     return *this;
246 }
247
248 template <typename T>
249 inline RenderIterator<T>& RenderIterator<T>::traverseAncestor()
250 {
251     ASSERT(m_current);
252     ASSERT(m_current != m_root);
253     m_current = RenderTraversal::findAncestorOfType<T>(*m_current);
254     return *this;
255 }
256
257 template <typename T>
258 inline T& RenderIterator<T>::operator*()
259 {
260     ASSERT(m_current);
261     return *m_current;
262 }
263
264 template <typename T>
265 inline T* RenderIterator<T>::operator->()
266 {
267     ASSERT(m_current);
268     return m_current;
269 }
270
271 template <typename T>
272 inline bool RenderIterator<T>::operator==(const RenderIterator& other) const
273 {
274     ASSERT(m_root == other.m_root);
275     return m_current == other.m_current;
276 }
277
278 template <typename T>
279 inline bool RenderIterator<T>::operator!=(const RenderIterator& other) const
280 {
281     return !(*this == other);
282 }
283
284 // RenderConstIterator
285
286 template <typename T>
287 inline RenderConstIterator<T>::RenderConstIterator(const RenderElement* root)
288     : m_root(root)
289     , m_current(nullptr)
290 {
291 }
292
293 template <typename T>
294 inline RenderConstIterator<T>::RenderConstIterator(const RenderElement* root, const T* current)
295     : m_root(root)
296     , m_current(current)
297 {
298 }
299
300 template <typename T>
301 inline RenderConstIterator<T>& RenderConstIterator<T>::traverseNextSibling()
302 {
303     ASSERT(m_current);
304     m_current = RenderTraversal::nextSibling<T>(*m_current);
305     return *this;
306 }
307
308 template <typename T>
309 inline RenderConstIterator<T>& RenderConstIterator<T>::traverseNext()
310 {
311     ASSERT(m_current);
312     m_current = RenderTraversal::next<T>(*m_current, m_root);
313     return *this;
314 }
315
316 template <typename T>
317 inline RenderConstIterator<T>& RenderConstIterator<T>::traversePreviousSibling()
318 {
319     ASSERT(m_current);
320     m_current = RenderTraversal::previousSibling<T>(m_current);
321     return *this;
322 }
323
324
325 template <typename T>
326 inline RenderConstIterator<T>& RenderConstIterator<T>::traverseAncestor()
327 {
328     ASSERT(m_current);
329     ASSERT(m_current != m_root);
330     m_current = RenderTraversal::findAncestorOfType<const T>(*m_current);
331     return *this;
332 }
333
334 template <typename T>
335 inline const T& RenderConstIterator<T>::operator*() const
336 {
337     ASSERT(m_current);
338     return *m_current;
339 }
340
341 template <typename T>
342 inline const T* RenderConstIterator<T>::operator->() const
343 {
344     ASSERT(m_current);
345     return m_current;
346 }
347
348 template <typename T>
349 inline bool RenderConstIterator<T>::operator==(const RenderConstIterator& other) const
350 {
351     ASSERT(m_root == other.m_root);
352     return m_current == other.m_current;
353 }
354
355 template <typename T>
356 inline bool RenderConstIterator<T>::operator!=(const RenderConstIterator& other) const
357 {
358     return !(*this == other);
359 }
360
361 }
362
363 #include "RenderAncestorIterator.h"
364 #include "RenderChildIterator.h"
365
366 #endif