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