Upstream version 8.37.180.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / css / SiblingTraversalStrategies.h
1 /*
2  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3  *           (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com)
4  * Copyright (C) 2006, 2007 Nicholas Shanks (webkit@nickshanks.com)
5  * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
6  * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org>
7  * Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org>
8  * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
9  * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
10  * Copyright (C) Research In Motion Limited 2011. All rights reserved.
11  * Copyright (C) 2012, Google, Inc. All rights reserved.
12  *
13  * This library is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU Library General Public
15  * License as published by the Free Software Foundation; either
16  * version 2 of the License, or (at your option) any later version.
17  *
18  * This library is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21  * Library General Public License for more details.
22  *
23  * You should have received a copy of the GNU Library General Public License
24  * along with this library; see the file COPYING.LIB.  If not, write to
25  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
26  * Boston, MA 02110-1301, USA.
27  */
28
29 #ifndef SiblingTraversalStrategies_h
30 #define SiblingTraversalStrategies_h
31
32 #include "core/dom/Element.h"
33 #include "core/dom/ElementTraversal.h"
34 #include "core/rendering/style/RenderStyle.h"
35
36 namespace WebCore {
37
38 struct DOMSiblingTraversalStrategy {
39     bool isFirstChild(Element&) const;
40     bool isLastChild(Element&) const;
41     bool isFirstOfType(Element&, const QualifiedName&) const;
42     bool isLastOfType(Element&, const QualifiedName&) const;
43
44     int countElementsBefore(Element&) const;
45     int countElementsAfter(Element&) const;
46     int countElementsOfTypeBefore(Element&, const QualifiedName&) const;
47     int countElementsOfTypeAfter(Element&, const QualifiedName&) const;
48 };
49
50 inline bool DOMSiblingTraversalStrategy::isFirstChild(Element& element) const
51 {
52     return !ElementTraversal::previousSibling(element);
53 }
54
55 inline bool DOMSiblingTraversalStrategy::isLastChild(Element& element) const
56 {
57     return !ElementTraversal::nextSibling(element);
58 }
59
60 inline bool DOMSiblingTraversalStrategy::isFirstOfType(Element& element, const QualifiedName& type) const
61 {
62     for (const Element* sibling = ElementTraversal::previousSibling(element); sibling; sibling = ElementTraversal::previousSibling(*sibling)) {
63         if (sibling->hasTagName(type))
64             return false;
65     }
66     return true;
67 }
68
69 inline bool DOMSiblingTraversalStrategy::isLastOfType(Element& element, const QualifiedName& type) const
70 {
71     for (const Element* sibling = ElementTraversal::nextSibling(element); sibling; sibling = ElementTraversal::nextSibling(*sibling)) {
72         if (sibling->hasTagName(type))
73             return false;
74     }
75     return true;
76 }
77
78 inline int DOMSiblingTraversalStrategy::countElementsBefore(Element& element) const
79 {
80     int count = 0;
81     for (const Element* sibling = ElementTraversal::previousSibling(element); sibling; sibling = ElementTraversal::previousSibling(*sibling))
82         count++;
83
84     return count;
85 }
86
87 inline int DOMSiblingTraversalStrategy::countElementsOfTypeBefore(Element& element, const QualifiedName& type) const
88 {
89     int count = 0;
90     for (const Element* sibling = ElementTraversal::previousSibling(element); sibling; sibling = ElementTraversal::previousSibling(*sibling)) {
91         if (sibling->hasTagName(type))
92             ++count;
93     }
94
95     return count;
96 }
97
98 inline int DOMSiblingTraversalStrategy::countElementsAfter(Element& element) const
99 {
100     int count = 0;
101     for (const Element* sibling = ElementTraversal::nextSibling(element); sibling; sibling = ElementTraversal::nextSibling(*sibling))
102         ++count;
103
104     return count;
105 }
106
107 inline int DOMSiblingTraversalStrategy::countElementsOfTypeAfter(Element& element, const QualifiedName& type) const
108 {
109     int count = 0;
110     for (const Element* sibling = ElementTraversal::nextSibling(element); sibling; sibling = ElementTraversal::nextSibling(*sibling)) {
111         if (sibling->hasTagName(type))
112             ++count;
113     }
114
115     return count;
116 }
117
118 class ShadowDOMSiblingTraversalStrategy FINAL {
119     STACK_ALLOCATED();
120 public:
121     ShadowDOMSiblingTraversalStrategy(const WillBeHeapVector<RawPtrWillBeMember<Node>, 32>& siblings, int nth)
122         : m_siblings(siblings)
123         , m_nth(nth)
124     {
125     }
126
127     bool isFirstChild(Element&) const;
128     bool isLastChild(Element&) const;
129     bool isFirstOfType(Element&, const QualifiedName&) const;
130     bool isLastOfType(Element&, const QualifiedName&) const;
131
132     int countElementsBefore(Element&) const;
133     int countElementsAfter(Element&) const;
134     int countElementsOfTypeBefore(Element&, const QualifiedName&) const;
135     int countElementsOfTypeAfter(Element&, const QualifiedName&) const;
136
137 private:
138     const WillBeHeapVector<RawPtrWillBeMember<Node>, 32>& m_siblings;
139     int m_nth;
140 };
141
142 inline bool ShadowDOMSiblingTraversalStrategy::isFirstChild(Element& element) const
143 {
144     ASSERT(element == toElement(m_siblings[m_nth]));
145
146     for (int i = m_nth - 1; i >= 0; --i) {
147         if (m_siblings[i]->isElementNode())
148             return false;
149     }
150
151     return true;
152 }
153
154 inline bool ShadowDOMSiblingTraversalStrategy::isLastChild(Element& element) const
155 {
156     ASSERT(element == toElement(m_siblings[m_nth]));
157
158     for (size_t i = m_nth + 1; i < m_siblings.size(); ++i) {
159         if (m_siblings[i]->isElementNode())
160             return false;
161     }
162
163     return true;
164 }
165
166 inline bool ShadowDOMSiblingTraversalStrategy::isFirstOfType(Element& element, const QualifiedName& type) const
167 {
168     ASSERT(element == toElement(m_siblings[m_nth]));
169
170     for (int i = m_nth - 1; i >= 0; --i) {
171         if (m_siblings[i]->hasTagName(type))
172             return false;
173     }
174
175     return true;
176 }
177
178 inline bool ShadowDOMSiblingTraversalStrategy::isLastOfType(Element& element, const QualifiedName& type) const
179 {
180     ASSERT(element == toElement(m_siblings[m_nth]));
181
182     for (size_t i = m_nth + 1; i < m_siblings.size(); ++i) {
183         if (m_siblings[i]->hasTagName(type))
184             return false;
185     }
186
187     return true;
188 }
189
190 inline int ShadowDOMSiblingTraversalStrategy::countElementsBefore(Element& element) const
191 {
192     ASSERT(element == toElement(m_siblings[m_nth]));
193
194     int count = 0;
195     for (int i = m_nth - 1; i >= 0; --i) {
196         if (m_siblings[i]->isElementNode())
197             ++count;
198     }
199
200     return count;
201 }
202
203 inline int ShadowDOMSiblingTraversalStrategy::countElementsAfter(Element& element) const
204 {
205     ASSERT(element == toElement(m_siblings[m_nth]));
206
207     int count = 0;
208     for (size_t i = m_nth + 1; i < m_siblings.size(); ++i) {
209         if (m_siblings[i]->isElementNode())
210             return ++count;
211     }
212
213     return count;
214 }
215
216 inline int ShadowDOMSiblingTraversalStrategy::countElementsOfTypeBefore(Element& element, const QualifiedName& type) const
217 {
218     ASSERT(element == toElement(m_siblings[m_nth]));
219
220     int count = 0;
221     for (int i = m_nth - 1; i >= 0; --i) {
222         if (m_siblings[i]->hasTagName(type))
223             ++count;
224     }
225
226     return count;
227 }
228
229 inline int ShadowDOMSiblingTraversalStrategy::countElementsOfTypeAfter(Element& element, const QualifiedName& type) const
230 {
231     ASSERT(element == toElement(m_siblings[m_nth]));
232
233     int count = 0;
234     for (size_t i = m_nth + 1; i < m_siblings.size(); ++i) {
235         if (m_siblings[i]->hasTagName(type))
236             return ++count;
237     }
238
239     return count;
240 }
241
242 }
243
244 #endif