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