Replace WTF::move with WTFMove
[WebKit-https.git] / Source / WebCore / css / CSSParserValues.h
1 /*
2  * Copyright (C) 2003 Lars Knoll (knoll@kde.org)
3  * Copyright (C) 2004, 2005, 2006, 2008, 2009, 2010, 2014 Apple Inc. All rights reserved.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public License
16  * along with this library; see the file COPYING.LIB.  If not, write to
17  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  */
20
21 #ifndef CSSParserValues_h
22 #define CSSParserValues_h
23
24 #include "CSSSelector.h"
25 #include "CSSValueKeywords.h"
26 #include "CSSValueList.h"
27 #include <wtf/text/AtomicString.h>
28 #include <wtf/text/AtomicStringHash.h>
29 #include <wtf/text/WTFString.h>
30
31 namespace WebCore {
32
33 class CSSValue;
34 class QualifiedName;
35
36 // This can't be a StringView for 2 reasons:
37 // 1. lower() clobbers the data we point to.
38 // 2. We are an element of a union (in CSSParserValue) so we need to have a trivial destructor.
39 struct CSSParserString {
40     void init(LChar* characters, unsigned length)
41     {
42         m_data.characters8 = characters;
43         m_length = length;
44         m_is8Bit = true;
45     }
46
47     void init(UChar* characters, unsigned length)
48     {
49         m_data.characters16 = characters;
50         m_length = length;
51         m_is8Bit = false;
52     }
53
54     void init(const String& string)
55     {
56         m_length = string.length();
57         if (!m_length || string.is8Bit()) {
58             m_data.characters8 = const_cast<LChar*>(string.characters8());
59             m_is8Bit = true;
60         } else {
61             m_data.characters16 = const_cast<UChar*>(string.characters16());
62             m_is8Bit = false;
63         }
64     }
65
66     void clear()
67     {
68         m_data.characters8 = 0;
69         m_length = 0;
70         m_is8Bit = true;
71     }
72
73     bool is8Bit() const { return m_is8Bit; }
74     LChar* characters8() const { ASSERT(is8Bit()); return m_data.characters8; }
75     UChar* characters16() const { ASSERT(!is8Bit()); return m_data.characters16; }
76     template <typename CharacterType>
77     CharacterType* characters() const;
78
79     unsigned length() const { return m_length; }
80     void setLength(unsigned length) { m_length = length; }
81
82     void lower();
83
84     UChar operator[](unsigned i) const
85     {
86         ASSERT_WITH_SECURITY_IMPLICATION(i < m_length);
87         if (is8Bit())
88             return m_data.characters8[i];
89         return m_data.characters16[i];
90     }
91
92     bool equalIgnoringCase(const char* str) const
93     {
94         if (is8Bit())
95             return WTF::equalIgnoringCase(str, characters8(), length());
96         return WTF::equalIgnoringCase(str, characters16(), length());
97     }
98
99     operator String() const { return is8Bit() ? String(m_data.characters8, m_length) : String(m_data.characters16, m_length); }
100     operator AtomicString() const { return is8Bit() ? AtomicString(m_data.characters8, m_length) : AtomicString(m_data.characters16, m_length); }
101
102     union {
103         LChar* characters8;
104         UChar* characters16;
105     } m_data;
106     unsigned m_length;
107     bool m_is8Bit;
108 };
109
110 struct CSSParserFunction;
111 struct CSSParserVariable;
112
113 struct CSSParserValue {
114     CSSValueID id;
115     bool isInt;
116     union {
117         double fValue;
118         int iValue;
119         CSSParserString string;
120         CSSParserFunction* function;
121         CSSParserVariable* variable;
122         CSSParserValueList* valueList;
123     };
124     enum {
125         Operator  = 0x100000,
126         Function  = 0x100001,
127         ValueList = 0x100002,
128         Q_EMS     = 0x100003,
129         Variable  = 0x100004
130     };
131     int unit;
132
133     void setFromValueList(std::unique_ptr<CSSParserValueList>);
134
135     PassRefPtr<CSSValue> createCSSValue();
136 };
137
138 void destroy(const CSSParserValue&);
139
140 class CSSParserValueList {
141     WTF_MAKE_FAST_ALLOCATED;
142 public:
143     CSSParserValueList()
144         : m_current(0)
145     {
146     }
147     ~CSSParserValueList();
148
149     void addValue(const CSSParserValue&);
150     void insertValueAt(unsigned, const CSSParserValue&);
151     void deleteValueAt(unsigned);
152     void extend(CSSParserValueList&);
153
154     unsigned size() const { return m_values.size(); }
155     unsigned currentIndex() { return m_current; }
156     CSSParserValue* current() { return m_current < m_values.size() ? &m_values[m_current] : 0; }
157     CSSParserValue* next() { ++m_current; return current(); }
158     CSSParserValue* previous()
159     {
160         if (!m_current)
161             return 0;
162         --m_current;
163         return current();
164     }
165     void setCurrentIndex(unsigned index)
166     {
167         ASSERT(index < m_values.size());
168         if (index < m_values.size())
169             m_current = index;
170     }
171
172     CSSParserValue* valueAt(unsigned i) { return i < m_values.size() ? &m_values[i] : 0; }
173
174     void clear() { m_values.clear(); }
175     
176     String toString();
177     
178     bool containsVariables() const;
179
180 private:
181     unsigned m_current;
182     Vector<CSSParserValue, 4> m_values;
183 };
184
185 struct CSSParserFunction {
186     WTF_MAKE_FAST_ALLOCATED;
187 public:
188     CSSParserString name;
189     std::unique_ptr<CSSParserValueList> args;
190 };
191
192 struct CSSParserVariable {
193     WTF_MAKE_FAST_ALLOCATED;
194 public:
195     CSSParserString name; // The custom property name
196     std::unique_ptr<CSSParserValueList> args; // The fallback args
197 };
198
199 enum class CSSParserSelectorCombinator {
200     Child,
201     DescendantSpace,
202 #if ENABLE(CSS_SELECTORS_LEVEL4)
203     DescendantDoubleChild,
204 #endif
205     DirectAdjacent,
206     IndirectAdjacent
207 };
208
209 class CSSParserSelector {
210     WTF_MAKE_FAST_ALLOCATED;
211 public:
212     static CSSParserSelector* parsePagePseudoSelector(const CSSParserString& pseudoTypeString);
213     static CSSParserSelector* parsePseudoElementSelector(CSSParserString& pseudoTypeString);
214     static CSSParserSelector* parsePseudoElementCueFunctionSelector(const CSSParserString& functionIdentifier, Vector<std::unique_ptr<CSSParserSelector>>* selectorVector);
215     static CSSParserSelector* parsePseudoClassAndCompatibilityElementSelector(CSSParserString& pseudoTypeString);
216
217     CSSParserSelector();
218     explicit CSSParserSelector(const QualifiedName&);
219     ~CSSParserSelector();
220
221     std::unique_ptr<CSSSelector> releaseSelector() { return WTFMove(m_selector); }
222
223     void setValue(const AtomicString& value) { m_selector->setValue(value); }
224     void setAttribute(const QualifiedName& value, bool isCaseInsensitive) { m_selector->setAttribute(value, isCaseInsensitive); }
225     void setArgument(const AtomicString& value) { m_selector->setArgument(value); }
226     void setAttributeValueMatchingIsCaseInsensitive(bool isCaseInsensitive) { m_selector->setAttributeValueMatchingIsCaseInsensitive(isCaseInsensitive); }
227     void setMatch(CSSSelector::Match value) { m_selector->setMatch(value); }
228     void setRelation(CSSSelector::Relation value) { m_selector->setRelation(value); }
229     void setForPage() { m_selector->setForPage(); }
230
231     void adoptSelectorVector(Vector<std::unique_ptr<CSSParserSelector>>& selectorVector);
232     void setLangArgumentList(const Vector<CSSParserString>& stringVector);
233
234     void setPseudoClassValue(const CSSParserString& pseudoClassString);
235     CSSSelector::PseudoClassType pseudoClassType() const { return m_selector->pseudoClassType(); }
236     bool isCustomPseudoElement() const { return m_selector->isCustomPseudoElement(); }
237
238     bool isPseudoElementCueFunction() const
239     {
240 #if ENABLE(VIDEO_TRACK)
241         return m_selector->match() == CSSSelector::PseudoElement && m_selector->pseudoElementType() == CSSSelector::PseudoElementCue;
242 #else
243         return false;
244 #endif
245     }
246
247     bool hasShadowDescendant() const;
248     bool matchesPseudoElement() const;
249
250     CSSParserSelector* tagHistory() const { return m_tagHistory.get(); }
251     void setTagHistory(std::unique_ptr<CSSParserSelector> selector) { m_tagHistory = WTFMove(selector); }
252     void clearTagHistory() { m_tagHistory.reset(); }
253     void insertTagHistory(CSSSelector::Relation before, std::unique_ptr<CSSParserSelector>, CSSSelector::Relation after);
254     void appendTagHistory(CSSSelector::Relation, std::unique_ptr<CSSParserSelector>);
255     void appendTagHistory(CSSParserSelectorCombinator, std::unique_ptr<CSSParserSelector>);
256     void prependTagSelector(const QualifiedName&, bool tagIsForNamespaceRule = false);
257
258 private:
259 #if ENABLE(CSS_SELECTORS_LEVEL4)
260     void setDescendantUseDoubleChildSyntax() { m_selector->setDescendantUseDoubleChildSyntax(); }
261 #endif
262
263     std::unique_ptr<CSSSelector> m_selector;
264     std::unique_ptr<CSSParserSelector> m_tagHistory;
265 };
266
267 inline bool CSSParserSelector::hasShadowDescendant() const
268 {
269     return m_selector->relation() == CSSSelector::ShadowDescendant;
270 }
271
272 inline void CSSParserValue::setFromValueList(std::unique_ptr<CSSParserValueList> valueList)
273 {
274     id = CSSValueInvalid;
275     this->valueList = valueList.release();
276     unit = ValueList;
277 }
278 }
279
280 #endif