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