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