Keep the already-parsed list of terms in custom property values so that we don't...
[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/WTFString.h>
29
30 namespace WebCore {
31
32 class CSSValue;
33 class QualifiedName;
34
35 // This can't be a StringView for 2 reasons:
36 // 1. lower() clobbers the data we point to.
37 // 2. We are an element of a union (in CSSParserValue) so we need to have a trivial destructor.
38 struct CSSParserString {
39     void init(LChar* characters, unsigned length)
40     {
41         m_data.characters8 = characters;
42         m_length = length;
43         m_is8Bit = true;
44     }
45
46     void init(UChar* characters, unsigned length)
47     {
48         m_data.characters16 = characters;
49         m_length = length;
50         m_is8Bit = false;
51     }
52
53     void init(const String& string)
54     {
55         m_length = string.length();
56         if (!m_length || string.is8Bit()) {
57             m_data.characters8 = const_cast<LChar*>(string.characters8());
58             m_is8Bit = true;
59         } else {
60             m_data.characters16 = const_cast<UChar*>(string.characters16());
61             m_is8Bit = false;
62         }
63     }
64
65     void clear()
66     {
67         m_data.characters8 = 0;
68         m_length = 0;
69         m_is8Bit = true;
70     }
71
72     bool is8Bit() const { return m_is8Bit; }
73     LChar* characters8() const { ASSERT(is8Bit()); return m_data.characters8; }
74     UChar* characters16() const { ASSERT(!is8Bit()); return m_data.characters16; }
75     template <typename CharacterType>
76     CharacterType* characters() const;
77
78     unsigned length() const { return m_length; }
79     void setLength(unsigned length) { m_length = length; }
80
81     void lower();
82
83     UChar operator[](unsigned i) const
84     {
85         ASSERT_WITH_SECURITY_IMPLICATION(i < m_length);
86         if (is8Bit())
87             return m_data.characters8[i];
88         return m_data.characters16[i];
89     }
90
91     bool equalIgnoringCase(const char* str) const
92     {
93         if (is8Bit())
94             return WTF::equalIgnoringCase(str, characters8(), length());
95         return WTF::equalIgnoringCase(str, characters16(), length());
96     }
97
98     operator String() const { return is8Bit() ? String(m_data.characters8, m_length) : String(m_data.characters16, m_length); }
99     operator AtomicString() const { return is8Bit() ? AtomicString(m_data.characters8, m_length) : AtomicString(m_data.characters16, m_length); }
100
101     union {
102         LChar* characters8;
103         UChar* characters16;
104     } m_data;
105     unsigned m_length;
106     bool m_is8Bit;
107 };
108
109 struct CSSParserFunction;
110
111 struct CSSParserValue {
112     CSSValueID id;
113     bool isInt;
114     union {
115         double fValue;
116         int iValue;
117         CSSParserString string;
118         CSSParserFunction* function;
119         CSSParserValueList* valueList;
120     };
121     enum {
122         Operator  = 0x100000,
123         Function  = 0x100001,
124         ValueList = 0x100002,
125         Q_EMS     = 0x100003,
126     };
127     int unit;
128
129     void setFromValueList(std::unique_ptr<CSSParserValueList>);
130
131     PassRefPtr<CSSValue> createCSSValue();
132 };
133
134 void destroy(const CSSParserValue&);
135
136 class CSSParserValueList {
137     WTF_MAKE_FAST_ALLOCATED;
138 public:
139     CSSParserValueList()
140         : m_current(0)
141     {
142     }
143     ~CSSParserValueList();
144
145     void addValue(const CSSParserValue&);
146     void insertValueAt(unsigned, const CSSParserValue&);
147     void deleteValueAt(unsigned);
148     void extend(CSSParserValueList&);
149
150     unsigned size() const { return m_values.size(); }
151     unsigned currentIndex() { return m_current; }
152     CSSParserValue* current() { return m_current < m_values.size() ? &m_values[m_current] : 0; }
153     CSSParserValue* next() { ++m_current; return current(); }
154     CSSParserValue* previous()
155     {
156         if (!m_current)
157             return 0;
158         --m_current;
159         return current();
160     }
161     void setCurrentIndex(unsigned index)
162     {
163         ASSERT(index < m_values.size());
164         if (index < m_values.size())
165             m_current = index;
166     }
167
168     CSSParserValue* valueAt(unsigned i) { return i < m_values.size() ? &m_values[i] : 0; }
169
170     void clear() { m_values.clear(); }
171     
172     String toString();
173
174 private:
175     unsigned m_current;
176     Vector<CSSParserValue, 4> m_values;
177 };
178
179 struct CSSParserFunction {
180     WTF_MAKE_FAST_ALLOCATED;
181 public:
182     CSSParserString name;
183     std::unique_ptr<CSSParserValueList> args;
184 };
185
186 enum class CSSParserSelectorCombinator {
187     Child,
188     DescendantSpace,
189 #if ENABLE(CSS_SELECTORS_LEVEL4)
190     DescendantDoubleChild,
191 #endif
192     DirectAdjacent,
193     IndirectAdjacent
194 };
195
196 class CSSParserSelector {
197     WTF_MAKE_FAST_ALLOCATED;
198 public:
199     static CSSParserSelector* parsePagePseudoSelector(const CSSParserString& pseudoTypeString);
200     static CSSParserSelector* parsePseudoElementSelector(CSSParserString& pseudoTypeString);
201     static CSSParserSelector* parsePseudoElementCueFunctionSelector(const CSSParserString& functionIdentifier, Vector<std::unique_ptr<CSSParserSelector>>* selectorVector);
202     static CSSParserSelector* parsePseudoClassAndCompatibilityElementSelector(CSSParserString& pseudoTypeString);
203
204     CSSParserSelector();
205     explicit CSSParserSelector(const QualifiedName&);
206     ~CSSParserSelector();
207
208     std::unique_ptr<CSSSelector> releaseSelector() { return WTF::move(m_selector); }
209
210     void setValue(const AtomicString& value) { m_selector->setValue(value); }
211     void setAttribute(const QualifiedName& value, bool isCaseInsensitive) { m_selector->setAttribute(value, isCaseInsensitive); }
212     void setArgument(const AtomicString& value) { m_selector->setArgument(value); }
213     void setAttributeValueMatchingIsCaseInsensitive(bool isCaseInsensitive) { m_selector->setAttributeValueMatchingIsCaseInsensitive(isCaseInsensitive); }
214     void setMatch(CSSSelector::Match value) { m_selector->setMatch(value); }
215     void setRelation(CSSSelector::Relation value) { m_selector->setRelation(value); }
216     void setForPage() { m_selector->setForPage(); }
217
218     void adoptSelectorVector(Vector<std::unique_ptr<CSSParserSelector>>& selectorVector);
219     void setLangArgumentList(const Vector<CSSParserString>& stringVector);
220
221     void setPseudoClassValue(const CSSParserString& pseudoClassString);
222     CSSSelector::PseudoClassType pseudoClassType() const { return m_selector->pseudoClassType(); }
223     bool isCustomPseudoElement() const { return m_selector->isCustomPseudoElement(); }
224
225     bool isPseudoElementCueFunction() const
226     {
227 #if ENABLE(VIDEO_TRACK)
228         return m_selector->match() == CSSSelector::PseudoElement && m_selector->pseudoElementType() == CSSSelector::PseudoElementCue;
229 #else
230         return false;
231 #endif
232     }
233
234     bool hasShadowDescendant() const;
235     bool matchesPseudoElement() const;
236
237     CSSParserSelector* tagHistory() const { return m_tagHistory.get(); }
238     void setTagHistory(std::unique_ptr<CSSParserSelector> selector) { m_tagHistory = WTF::move(selector); }
239     void clearTagHistory() { m_tagHistory.reset(); }
240     void insertTagHistory(CSSSelector::Relation before, std::unique_ptr<CSSParserSelector>, CSSSelector::Relation after);
241     void appendTagHistory(CSSSelector::Relation, std::unique_ptr<CSSParserSelector>);
242     void appendTagHistory(CSSParserSelectorCombinator, std::unique_ptr<CSSParserSelector>);
243     void prependTagSelector(const QualifiedName&, bool tagIsForNamespaceRule = false);
244
245 private:
246 #if ENABLE(CSS_SELECTORS_LEVEL4)
247     void setDescendantUseDoubleChildSyntax() { m_selector->setDescendantUseDoubleChildSyntax(); }
248 #endif
249
250     std::unique_ptr<CSSSelector> m_selector;
251     std::unique_ptr<CSSParserSelector> m_tagHistory;
252 };
253
254 inline bool CSSParserSelector::hasShadowDescendant() const
255 {
256     return m_selector->relation() == CSSSelector::ShadowDescendant;
257 }
258
259 inline void CSSParserValue::setFromValueList(std::unique_ptr<CSSParserValueList> valueList)
260 {
261     id = CSSValueInvalid;
262     this->valueList = valueList.release();
263     unit = ValueList;
264 }
265 }
266
267 #endif