Build fix after r154515.
[WebKit-https.git] / Source / WebCore / dom / ElementTraversal.h
1 /*
2  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
4  *           (C) 2001 Dirk Mueller (mueller@kde.org)
5  * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights reserved.
6  * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public License
19  * along with this library; see the file COPYING.LIB.  If not, write to
20  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21  * Boston, MA 02110-1301, USA.
22  *
23  */
24
25 #ifndef ElementTraversal_h
26 #define ElementTraversal_h
27
28 #include "Element.h"
29 #include "NodeTraversal.h"
30
31 namespace WebCore {
32
33 template <typename ElementType>
34 class Traversal {
35 public:
36     // First or last ElementType child of the node.
37     static ElementType* firstChild(const Node*);
38     static ElementType* firstChild(const ContainerNode*);
39     static ElementType* lastChild(const Node*);
40     static ElementType* lastChild(const ContainerNode*);
41
42     // First or last ElementType descendant of the node. For Elements this is always the same as first/last child.
43     static ElementType* firstWithin(const Node*);
44     static ElementType* firstWithin(const ContainerNode*);
45     static ElementType* lastWithin(const Node*);
46     static ElementType* lastWithin(const ContainerNode*);
47
48     // Pre-order traversal skipping non-ElementType nodes.
49     static ElementType* next(const Node*);
50     static ElementType* next(const Node*, const Node* stayWithin);
51     static ElementType* next(const ContainerNode*);
52     static ElementType* next(const ContainerNode*, const Node* stayWithin);
53     static ElementType* previous(const Node*);
54     static ElementType* previous(const Node*, const Node* stayWithin);
55     static ElementType* previous(const ContainerNode*);
56     static ElementType* previous(const ContainerNode*, const Node* stayWithin);
57
58     // Next or previous ElementType sibling if there is one.
59     static ElementType* nextSibling(const Node*);
60     static ElementType* nextSibling(const ContainerNode*);
61     static ElementType* previousSibling(const Node*);
62     static ElementType* previousSibling(const ContainerNode*);
63
64     // Like next, but skips children.
65     static ElementType* nextSkippingChildren(const Node*);
66     static ElementType* nextSkippingChildren(const Node*, const Node* stayWithin);
67     static ElementType* nextSkippingChildren(const ContainerNode*);
68     static ElementType* nextSkippingChildren(const ContainerNode*, const Node* stayWithin);
69
70 private:
71     template <typename CurrentType> static ElementType* firstChildTemplate(CurrentType*);
72     template <typename CurrentType> static ElementType* lastChildTemplate(CurrentType*);
73     template <typename CurrentType> static ElementType* firstWithinTemplate(CurrentType*);
74     template <typename CurrentType> static ElementType* lastWithinTemplate(CurrentType*);
75     template <typename CurrentType> static ElementType* nextTemplate(CurrentType*);
76     template <typename CurrentType> static ElementType* nextTemplate(CurrentType*, const Node* stayWithin);
77     template <typename CurrentType> static ElementType* previousTemplate(CurrentType*);
78     template <typename CurrentType> static ElementType* previousTemplate(CurrentType*, const Node* stayWithin);
79     template <typename CurrentType> static ElementType* nextSiblingTemplate(CurrentType*);
80     template <typename CurrentType> static ElementType* previousSiblingTemplate(CurrentType*);
81     template <typename CurrentType> static ElementType* nextSkippingChildrenTemplate(CurrentType*);
82     template <typename CurrentType> static ElementType* nextSkippingChildrenTemplate(CurrentType*, const Node* stayWithin);
83 };
84
85 class ElementTraversal : public Traversal<Element> {
86 public:
87     // FIXME: These should go somewhere else.
88     // Pre-order traversal including the pseudo-elements.
89     static Element* previousIncludingPseudo(const Node*, const Node* = 0);
90     static Element* nextIncludingPseudo(const Node*, const Node* = 0);
91     static Element* nextIncludingPseudoSkippingChildren(const Node*, const Node* = 0);
92
93     // Utility function to traverse only the element and pseudo-element siblings of a node.
94     static Element* pseudoAwarePreviousSibling(const Node*);
95 };
96
97 // Specialized for pure Element to exploit the fact that Elements parent is always either another Element or the root.
98 template <>
99 template <typename CurrentType>
100 inline Element* Traversal<Element>::firstWithinTemplate(CurrentType* current)
101 {
102     return firstChildTemplate(current);
103 }
104
105 template <>
106 template <typename CurrentType>
107 inline Element* Traversal<Element>::lastWithinTemplate(CurrentType* current)
108 {
109     return lastChildTemplate(current);
110 }
111
112 template <>
113 template <typename CurrentType>
114 inline Element* Traversal<Element>::nextTemplate(CurrentType* current)
115 {
116     Node* node = NodeTraversal::next(current);
117     while (node && !node->isElementNode())
118         node = NodeTraversal::nextSkippingChildren(node);
119     return static_cast<Element*>(node);
120 }
121
122 template <>
123 template <typename CurrentType>
124 inline Element* Traversal<Element>::nextTemplate(CurrentType* current, const Node* stayWithin)
125 {
126     Node* node = NodeTraversal::next(current, stayWithin);
127     while (node && !node->isElementNode())
128         node = NodeTraversal::nextSkippingChildren(node, stayWithin);
129     return static_cast<Element*>(node);
130 }
131
132 template <>
133 template <typename CurrentType>
134 inline Element* Traversal<Element>::previousTemplate(CurrentType* current)
135 {
136     Node* node = NodeTraversal::previous(current);
137     while (node && !node->isElementNode())
138         node = NodeTraversal::previousSkippingChildren(node);
139     return static_cast<Element*>(node);
140 }
141
142 template <>
143 template <typename CurrentType>
144 inline Element* Traversal<Element>::previousTemplate(CurrentType* current, const Node* stayWithin)
145 {
146     Node* node = NodeTraversal::previous(current, stayWithin);
147     while (node && !node->isElementNode())
148         node = NodeTraversal::previousSkippingChildren(node, stayWithin);
149     return static_cast<Element*>(node);
150 }
151
152 // Generic versions.
153 template <typename ElementType>
154 template <typename CurrentType>
155 inline ElementType* Traversal<ElementType>::firstChildTemplate(CurrentType* current)
156 {
157     Node* node = current->firstChild();
158     while (node && !isElementOfType<ElementType>(node))
159         node = node->nextSibling();
160     return static_cast<ElementType*>(node);
161 }
162
163 template <typename ElementType>
164 template <typename CurrentType>
165 inline ElementType* Traversal<ElementType>::lastChildTemplate(CurrentType* current)
166 {
167     Node* node = current->lastChild();
168     while (node && !isElementOfType<ElementType>(node))
169         node = node->previousSibling();
170     return static_cast<ElementType*>(node);
171 }
172
173 template <typename ElementType>
174 template <typename CurrentType>
175 inline ElementType* Traversal<ElementType>::firstWithinTemplate(CurrentType* current)
176 {
177     Element* element = Traversal<Element>::firstWithin(current);
178     while (element && !isElementOfType<ElementType>(element))
179         element = Traversal<Element>::next(element, current);
180     return static_cast<ElementType*>(element);
181 }
182
183 template <typename ElementType>
184 template <typename CurrentType>
185 inline ElementType* Traversal<ElementType>::lastWithinTemplate(CurrentType* current)
186 {
187     Element* element = Traversal<Element>::lastWithin(current);
188     while (element && !isElementOfType<ElementType>(element))
189         element = Traversal<Element>::previous(element, current);
190     return static_cast<ElementType*>(element);
191 }
192
193 template <typename ElementType>
194 template <typename CurrentType>
195 inline ElementType* Traversal<ElementType>::nextTemplate(CurrentType* current)
196 {
197     Element* element = Traversal<Element>::next(current);
198     while (element && !isElementOfType<ElementType>(element))
199         element = Traversal<Element>::next(element);
200     return static_cast<ElementType*>(element);
201 }
202
203 template <typename ElementType>
204 template <typename CurrentType>
205 inline ElementType* Traversal<ElementType>::nextTemplate(CurrentType* current, const Node* stayWithin)
206 {
207     Element* element = Traversal<Element>::next(current, stayWithin);
208     while (element && !isElementOfType<ElementType>(element))
209         element = Traversal<Element>::next(element, stayWithin);
210     return static_cast<ElementType*>(element);
211 }
212
213 template <typename ElementType>
214 template <typename CurrentType>
215 inline ElementType* Traversal<ElementType>::previousTemplate(CurrentType* current)
216 {
217     Element* element = Traversal<Element>::previous(current);
218     while (element && !isElementOfType<ElementType>(element))
219         element = Traversal<Element>::previous(element);
220     return static_cast<ElementType*>(element);
221 }
222
223 template <typename ElementType>
224 template <typename CurrentType>
225 inline ElementType* Traversal<ElementType>::previousTemplate(CurrentType* current, const Node* stayWithin)
226 {
227     Element* element = Traversal<Element>::previous(current, stayWithin);
228     while (element && !isElementOfType<ElementType>(element))
229         element = Traversal<Element>::previous(element, stayWithin);
230     return static_cast<ElementType*>(element);
231 }
232
233 template <typename ElementType>
234 template <typename CurrentType>
235 inline ElementType* Traversal<ElementType>::nextSiblingTemplate(CurrentType* current)
236 {
237     Node* node = current->nextSibling();
238     while (node && !isElementOfType<ElementType>(node))
239         node = node->nextSibling();
240     return static_cast<ElementType*>(node);
241 }
242
243 template <typename ElementType>
244 template <typename CurrentType>
245 inline ElementType* Traversal<ElementType>::previousSiblingTemplate(CurrentType* current)
246 {
247     Node* node = current->previousSibling();
248     while (node && !isElementOfType<ElementType>(node))
249         node = node->previousSibling();
250     return static_cast<ElementType*>(node);
251 }
252
253 template <typename ElementType>
254 template <typename CurrentType>
255 inline ElementType* Traversal<ElementType>::nextSkippingChildrenTemplate(CurrentType* current)
256 {
257     Node* node = NodeTraversal::nextSkippingChildren(current);
258     while (node && !isElementOfType<ElementType>(node))
259         node = NodeTraversal::nextSkippingChildren(node);
260     return static_cast<ElementType*>(node);
261 }
262
263 template <typename ElementType>
264 template <typename CurrentType>
265 inline ElementType* Traversal<ElementType>::nextSkippingChildrenTemplate(CurrentType* current, const Node* stayWithin)
266 {
267     Node* node = NodeTraversal::nextSkippingChildren(current, stayWithin);
268     while (node && !isElementOfType<ElementType>(node))
269         node = NodeTraversal::nextSkippingChildren(node, stayWithin);
270     return static_cast<ElementType*>(node);
271 }
272
273 template <typename ElementType>
274 inline ElementType* Traversal<ElementType>::firstChild(const ContainerNode* current) { return firstChildTemplate(current); }
275 template <typename ElementType>
276 inline ElementType* Traversal<ElementType>::firstChild(const Node* current) { return firstChildTemplate(current); }
277 template <typename ElementType>
278
279 inline ElementType* Traversal<ElementType>::lastChild(const ContainerNode* current) { return lastChildTemplate(current); }
280 template <typename ElementType>
281 inline ElementType* Traversal<ElementType>::lastChild(const Node* current) { return lastChildTemplate(current); }
282
283 template <typename ElementType>
284 inline ElementType* Traversal<ElementType>::firstWithin(const ContainerNode* current) { return firstWithinTemplate(current); }
285 template <typename ElementType>
286 inline ElementType* Traversal<ElementType>::firstWithin(const Node* current) { return firstWithinTemplate(current); }
287 template <typename ElementType>
288
289 inline ElementType* Traversal<ElementType>::lastWithin(const ContainerNode* current) { return lastWithinTemplate(current); }
290 template <typename ElementType>
291 inline ElementType* Traversal<ElementType>::lastWithin(const Node* current) { return lastWithinTemplate(current); }
292
293 template <typename ElementType>
294 inline ElementType* Traversal<ElementType>::next(const ContainerNode* current) { return nextTemplate(current); }
295 template <typename ElementType>
296 inline ElementType* Traversal<ElementType>::next(const Node* current) { return nextTemplate(current); }
297 template <typename ElementType>
298 inline ElementType* Traversal<ElementType>::next(const ContainerNode* current, const Node* stayWithin) { return nextTemplate(current, stayWithin); }
299 template <typename ElementType>
300 inline ElementType* Traversal<ElementType>::next(const Node* current, const Node* stayWithin) { return nextTemplate(current, stayWithin); }
301
302 template <typename ElementType>
303 inline ElementType* Traversal<ElementType>::previous(const ContainerNode* current) { return previousTemplate(current); }
304 template <typename ElementType>
305 inline ElementType* Traversal<ElementType>::previous(const Node* current) { return previousTemplate(current); }
306 template <typename ElementType>
307 inline ElementType* Traversal<ElementType>::previous(const ContainerNode* current, const Node* stayWithin) { return previousTemplate(current, stayWithin); }
308 template <typename ElementType>
309 inline ElementType* Traversal<ElementType>::previous(const Node* current, const Node* stayWithin) { return previousTemplate(current, stayWithin); }
310
311 template <typename ElementType>
312 inline ElementType* Traversal<ElementType>::nextSibling(const ContainerNode* current) { return nextSiblingTemplate(current); }
313 template <typename ElementType>
314 inline ElementType* Traversal<ElementType>::nextSibling(const Node* current) { return nextSiblingTemplate(current); }
315
316 template <typename ElementType>
317 inline ElementType* Traversal<ElementType>::previousSibling(const ContainerNode* current) { return previousSiblingTemplate(current); }
318 template <typename ElementType>
319 inline ElementType* Traversal<ElementType>::previousSibling(const Node* current) { return previousSiblingTemplate(current); }
320
321 template <typename ElementType>
322 inline ElementType* Traversal<ElementType>::nextSkippingChildren(const ContainerNode* current) { return nextSkippingChildrenTemplate(current); }
323 template <typename ElementType>
324 inline ElementType* Traversal<ElementType>::nextSkippingChildren(const Node* current) { return nextSkippingChildrenTemplate(current); }
325 template <typename ElementType>
326 inline ElementType* Traversal<ElementType>::nextSkippingChildren(const ContainerNode* current, const Node* stayWithin) { return nextSkippingChildrenTemplate(current, stayWithin); }
327 template <typename ElementType>
328 inline ElementType* Traversal<ElementType>::nextSkippingChildren(const Node* current, const Node* stayWithin) { return nextSkippingChildrenTemplate(current, stayWithin); }
329
330 // FIXME: These should go somewhere else.
331 inline Element* ElementTraversal::previousIncludingPseudo(const Node* current, const Node* stayWithin)
332 {
333     Node* node = NodeTraversal::previousIncludingPseudo(current, stayWithin);
334     while (node && !node->isElementNode())
335         node = NodeTraversal::previousIncludingPseudo(node, stayWithin);
336     return toElement(node);
337 }
338
339 inline Element* ElementTraversal::nextIncludingPseudo(const Node* current, const Node* stayWithin)
340 {
341     Node* node = NodeTraversal::nextIncludingPseudo(current, stayWithin);
342     while (node && !node->isElementNode())
343         node = NodeTraversal::nextIncludingPseudo(node, stayWithin);
344     return toElement(node);
345 }
346
347 inline Element* ElementTraversal::nextIncludingPseudoSkippingChildren(const Node* current, const Node* stayWithin)
348 {
349     Node* node = NodeTraversal::nextIncludingPseudoSkippingChildren(current, stayWithin);
350     while (node && !node->isElementNode())
351         node = NodeTraversal::nextIncludingPseudoSkippingChildren(node, stayWithin);
352     return toElement(node);
353 }
354
355 inline Element* ElementTraversal::pseudoAwarePreviousSibling(const Node* current)
356 {
357     Node* node = current->pseudoAwarePreviousSibling();
358     while (node && !node->isElementNode())
359         node = node->pseudoAwarePreviousSibling();
360     return toElement(node);
361 }
362
363 }
364
365 #endif