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.
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.
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.
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.
26 #ifndef ElementTraversal_h
27 #define ElementTraversal_h
29 #include "core/dom/Element.h"
30 #include "core/dom/NodeTraversal.h"
34 template <class ElementType>
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); }
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); }
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); }
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); }
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); }
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);
76 // Utility function to traverse only the element and pseudo-element siblings of a node.
77 static ElementType* pseudoAwarePreviousSibling(const Node&);
79 // Previous / Next sibling.
80 static ElementType* previousSibling(const Node&);
81 static ElementType* nextSibling(const Node&);
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);
108 typedef Traversal<Element> ElementTraversal;
110 // Specialized for pure Element to exploit the fact that Elements parent is always either another Element or the root.
112 template <class NodeType>
113 inline Element* Traversal<Element>::firstWithinTemplate(NodeType& current)
115 return firstChildTemplate(current);
119 template <class NodeType>
120 inline Element* Traversal<Element>::lastWithinTemplate(NodeType& current)
122 Node* node = NodeTraversal::lastWithin(current);
123 while (node && !node->isElementNode())
124 node = NodeTraversal::previous(*node, ¤t);
125 return toElement(node);
129 template <class NodeType>
130 inline Element* Traversal<Element>::nextTemplate(NodeType& current)
132 Node* node = NodeTraversal::next(current);
133 while (node && !node->isElementNode())
134 node = NodeTraversal::nextSkippingChildren(*node);
135 return toElement(node);
139 template <class NodeType>
140 inline Element* Traversal<Element>::nextTemplate(NodeType& current, const Node* stayWithin)
142 Node* node = NodeTraversal::next(current, stayWithin);
143 while (node && !node->isElementNode())
144 node = NodeTraversal::nextSkippingChildren(*node, stayWithin);
145 return toElement(node);
149 template <class NodeType>
150 inline Element* Traversal<Element>::previousTemplate(NodeType& current)
152 Node* node = NodeTraversal::previous(current);
153 while (node && !node->isElementNode())
154 node = NodeTraversal::previous(*node);
155 return toElement(node);
159 template <class NodeType>
160 inline Element* Traversal<Element>::previousTemplate(NodeType& current, const Node* stayWithin)
162 Node* node = NodeTraversal::previous(current, stayWithin);
163 while (node && !node->isElementNode())
164 node = NodeTraversal::previous(*node, stayWithin);
165 return toElement(node);
169 template <class ElementType>
170 template <class NodeType>
171 inline ElementType* Traversal<ElementType>::firstChildTemplate(NodeType& current)
173 Node* node = current.firstChild();
174 while (node && !isElementOfType<const ElementType>(*node))
175 node = node->nextSibling();
176 return toElement<ElementType>(node);
179 template <class ElementType>
180 inline ElementType* Traversal<ElementType>::firstAncestor(const Node& current)
182 ContainerNode* ancestor = current.parentNode();
183 while (ancestor && !isElementOfType<const ElementType>(*ancestor))
184 ancestor = ancestor->parentNode();
185 return toElement<ElementType>(ancestor);
188 template <class ElementType>
189 template <class NodeType>
190 inline ElementType* Traversal<ElementType>::firstAncestorOrSelfTemplate(NodeType& current)
192 if (isElementOfType<const ElementType>(current))
193 return &toElement<ElementType>(current);
194 return firstAncestor(current);
197 template <class ElementType>
198 template <class NodeType>
199 inline ElementType* Traversal<ElementType>::lastChildTemplate(NodeType& current)
201 Node* node = current.lastChild();
202 while (node && !isElementOfType<const ElementType>(*node))
203 node = node->previousSibling();
204 return toElement<ElementType>(node);
207 template <class ElementType>
208 template <class NodeType>
209 inline ElementType* Traversal<ElementType>::firstWithinTemplate(NodeType& current)
211 Element* element = Traversal<Element>::firstWithin(current);
212 while (element && !isElementOfType<const ElementType>(*element))
213 element = Traversal<Element>::next(*element, ¤t);
214 return toElement<ElementType>(element);
217 template <class ElementType>
218 template <class NodeType>
219 inline ElementType* Traversal<ElementType>::lastWithinTemplate(NodeType& current)
221 Element* element = Traversal<Element>::lastWithin(current);
222 while (element && !isElementOfType<const ElementType>(*element))
223 element = Traversal<Element>::previous(element, ¤t);
224 return toElement<ElementType>(element);
227 template <class ElementType>
228 template <class NodeType>
229 inline ElementType* Traversal<ElementType>::nextTemplate(NodeType& current)
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);
237 template <class ElementType>
238 template <class NodeType>
239 inline ElementType* Traversal<ElementType>::nextTemplate(NodeType& current, const Node* stayWithin)
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);
247 template <class ElementType>
248 template <class NodeType>
249 inline ElementType* Traversal<ElementType>::previousTemplate(NodeType& current)
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);
257 template <class ElementType>
258 template <class NodeType>
259 inline ElementType* Traversal<ElementType>::previousTemplate(NodeType& current, const Node* stayWithin)
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);
267 template <class ElementType>
268 template <class NodeType>
269 inline ElementType* Traversal<ElementType>::nextSkippingChildrenTemplate(NodeType& current)
271 Node* node = NodeTraversal::nextSkippingChildren(current);
272 while (node && !isElementOfType<const ElementType>(*node))
273 node = NodeTraversal::nextSkippingChildren(*node);
274 return toElement<ElementType>(node);
277 template <class ElementType>
278 template <class NodeType>
279 inline ElementType* Traversal<ElementType>::nextSkippingChildrenTemplate(NodeType& current, const Node* stayWithin)
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);
287 template <class ElementType>
288 inline ElementType* Traversal<ElementType>::previousIncludingPseudo(const Node& current, const Node* stayWithin)
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);
296 template <class ElementType>
297 inline ElementType* Traversal<ElementType>::nextIncludingPseudo(const Node& current, const Node* stayWithin)
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);
305 template <class ElementType>
306 inline ElementType* Traversal<ElementType>::nextIncludingPseudoSkippingChildren(const Node& current, const Node* stayWithin)
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);
314 template <class ElementType>
315 inline ElementType* Traversal<ElementType>::pseudoAwarePreviousSibling(const Node& current)
317 Node* node = current.pseudoAwarePreviousSibling();
318 while (node && !isElementOfType<const ElementType>(*node))
319 node = node->pseudoAwarePreviousSibling();
320 return toElement<ElementType>(node);
323 template <class ElementType>
324 inline ElementType* Traversal<ElementType>::previousSibling(const Node& current)
326 Node* node = current.previousSibling();
327 while (node && !isElementOfType<const ElementType>(*node))
328 node = node->previousSibling();
329 return toElement<ElementType>(node);
332 template <class ElementType>
333 inline ElementType* Traversal<ElementType>::nextSibling(const Node& current)
335 Node* node = current.nextSibling();
336 while (node && !isElementOfType<const ElementType>(*node))
337 node = node->nextSibling();
338 return toElement<ElementType>(node);
341 } // namespace WebCore