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