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#pragma once
27
28#include "ElementIterator.h"
29
30namespace WebCore {
31
32template <typename ElementType>
33class ElementAncestorIterator : public ElementIterator<ElementType> {
34public:
35 ElementAncestorIterator();
36 explicit ElementAncestorIterator(ElementType* current);
37 ElementAncestorIterator& operator++();
38};
39
40template <typename ElementType>
41class ElementAncestorConstIterator : public ElementConstIterator<ElementType> {
42public:
43 ElementAncestorConstIterator();
44 explicit ElementAncestorConstIterator(const ElementType* current);
45 ElementAncestorConstIterator& operator++();
46};
47
48template <typename ElementType>
49class ElementAncestorIteratorAdapter {
50public:
51 explicit ElementAncestorIteratorAdapter(ElementType* first);
52 ElementAncestorIterator<ElementType> begin();
53 ElementAncestorIterator<ElementType> end();
54 ElementType* first() { return m_first; }
55
56private:
57 ElementType* m_first;
58};
59
60template <typename ElementType>
61class ElementAncestorConstIteratorAdapter {
62public:
63 explicit ElementAncestorConstIteratorAdapter(const ElementType* first);
64 ElementAncestorConstIterator<ElementType> begin() const;
65 ElementAncestorConstIterator<ElementType> end() const;
66 const ElementType* first() const { return m_first; }
67
68private:
69 const ElementType* m_first;
70};
71
72ElementAncestorIteratorAdapter<Element> elementLineage(Element* first);
73ElementAncestorConstIteratorAdapter<Element> elementLineage(const Element* first);
74ElementAncestorIteratorAdapter<Element> elementAncestors(Element* descendant);
75ElementAncestorConstIteratorAdapter<Element> elementAncestors(const Element* descendant);
76template <typename ElementType> ElementAncestorIteratorAdapter<ElementType> lineageOfType(Element& first);
77template <typename ElementType> ElementAncestorConstIteratorAdapter<ElementType> lineageOfType(const Element& first);
78template <typename ElementType> ElementAncestorIteratorAdapter<ElementType> ancestorsOfType(Node& descendant);
79template <typename ElementType> ElementAncestorConstIteratorAdapter<ElementType> ancestorsOfType(const Node& descendant);
80
81// ElementAncestorIterator
82
83template <typename ElementType>
84inline ElementAncestorIterator<ElementType>::ElementAncestorIterator()
85 : ElementIterator<ElementType>(nullptr)
86{
87}
88
89template <typename ElementType>
90inline ElementAncestorIterator<ElementType>::ElementAncestorIterator(ElementType* current)
91 : ElementIterator<ElementType>(nullptr, current)
92{
93}
94
95template <typename ElementType>
96inline ElementAncestorIterator<ElementType>& ElementAncestorIterator<ElementType>::operator++()
97{
98 return static_cast<ElementAncestorIterator<ElementType>&>(ElementIterator<ElementType>::traverseAncestor());
99}
100
101// ElementAncestorConstIterator
102
103template <typename ElementType>
104inline ElementAncestorConstIterator<ElementType>::ElementAncestorConstIterator()
105 : ElementConstIterator<ElementType>(nullptr)
106{
107}
108
109template <typename ElementType>
110inline ElementAncestorConstIterator<ElementType>::ElementAncestorConstIterator(const ElementType* current)
111 : ElementConstIterator<ElementType>(nullptr, current)
112{
113}
114
115template <typename ElementType>
116inline ElementAncestorConstIterator<ElementType>& ElementAncestorConstIterator<ElementType>::operator++()
117{
118 return static_cast<ElementAncestorConstIterator<ElementType>&>(ElementConstIterator<ElementType>::traverseAncestor());
119}
120
121// ElementAncestorIteratorAdapter
122
123template <typename ElementType>
124inline ElementAncestorIteratorAdapter<ElementType>::ElementAncestorIteratorAdapter(ElementType* first)
125 : m_first(first)
126{
127}
128
129template <typename ElementType>
130inline ElementAncestorIterator<ElementType> ElementAncestorIteratorAdapter<ElementType>::begin()
131{
132 return ElementAncestorIterator<ElementType>(m_first);
133}
134
135template <typename ElementType>
136inline ElementAncestorIterator<ElementType> ElementAncestorIteratorAdapter<ElementType>::end()
137{
138 return ElementAncestorIterator<ElementType>();
139}
140
141// ElementAncestorConstIteratorAdapter
142
143template <typename ElementType>
144inline ElementAncestorConstIteratorAdapter<ElementType>::ElementAncestorConstIteratorAdapter(const ElementType* first)
145 : m_first(first)
146{
147}
148
149template <typename ElementType>
150inline ElementAncestorConstIterator<ElementType> ElementAncestorConstIteratorAdapter<ElementType>::begin() const
151{
152 return ElementAncestorConstIterator<ElementType>(m_first);
153}
154
155template <typename ElementType>
156inline ElementAncestorConstIterator<ElementType> ElementAncestorConstIteratorAdapter<ElementType>::end() const
157{
158 return ElementAncestorConstIterator<ElementType>();
159}
160
161// Standalone functions
162
163inline ElementAncestorIteratorAdapter<Element> elementLineage(Element* first)
164{
165 return ElementAncestorIteratorAdapter<Element>(first);
166}
167
168inline ElementAncestorConstIteratorAdapter<Element> elementLineage(const Element* first)
169{
170 return ElementAncestorConstIteratorAdapter<Element>(first);
171}
172
173inline ElementAncestorIteratorAdapter<Element> elementAncestors(Element* descendant)
174{
175 return ElementAncestorIteratorAdapter<Element>(descendant->parentElement());
176}
177
178inline ElementAncestorConstIteratorAdapter<Element> elementAncestors(const Element* descendant)
179{
180 return ElementAncestorConstIteratorAdapter<Element>(descendant->parentElement());
181}
182
183template <typename ElementType>
184inline ElementAncestorIteratorAdapter<ElementType> lineageOfType(Element& first)
185{
186 if (is<ElementType>(first))
187 return ElementAncestorIteratorAdapter<ElementType>(static_cast<ElementType*>(&first));
188 return ancestorsOfType<ElementType>(first);
189}
190
191template <typename ElementType>
192inline ElementAncestorConstIteratorAdapter<ElementType> lineageOfType(const Element& first)
193{
194 if (is<ElementType>(first))
195 return ElementAncestorConstIteratorAdapter<ElementType>(static_cast<const ElementType*>(&first));
196 return ancestorsOfType<ElementType>(first);
197}
198
199template <typename ElementType>
200inline ElementAncestorIteratorAdapter<ElementType> ancestorsOfType(Node& descendant)
201{
202 ElementType* first = findElementAncestorOfType<ElementType>(descendant);
203 return ElementAncestorIteratorAdapter<ElementType>(first);
204}
205
206template <typename ElementType>
207inline ElementAncestorConstIteratorAdapter<ElementType> ancestorsOfType(const Node& descendant)
208{
209 const ElementType* first = findElementAncestorOfType<const ElementType>(descendant);
210 return ElementAncestorConstIteratorAdapter<ElementType>(first);
211}
212
213} // namespace WebCore
214