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