parseHTMLInteger() should take a StringView in parameter
[WebKit-https.git] / Source / WebCore / css / parser / 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 #pragma once
22
23 #include "CSSSelector.h"
24 #include "CSSValueKeywords.h"
25 #include "CSSValueList.h"
26 #include <wtf/text/AtomicString.h>
27 #include <wtf/text/AtomicStringHash.h>
28 #include <wtf/text/WTFString.h>
29
30 namespace WebCore {
31
32 class CSSValue;
33 class QualifiedName;
34
35 // This should be a StringView but currently it can't because it's used as an element of a union in CSSParserValue.
36 struct CSSParserString {
37     void init(LChar* characters, unsigned length)
38     {
39         m_data.characters8 = characters;
40         m_length = length;
41         m_is8Bit = true;
42     }
43
44     void init(UChar* characters, unsigned length)
45     {
46         m_data.characters16 = characters;
47         m_length = length;
48         m_is8Bit = false;
49     }
50
51     void init(const String& string)
52     {
53         m_length = string.length();
54         if (!m_length || string.is8Bit()) {
55             m_data.characters8 = const_cast<LChar*>(string.characters8());
56             m_is8Bit = true;
57         } else {
58             m_data.characters16 = const_cast<UChar*>(string.characters16());
59             m_is8Bit = false;
60         }
61     }
62
63     void clear()
64     {
65         m_data.characters8 = 0;
66         m_length = 0;
67         m_is8Bit = true;
68     }
69
70     bool is8Bit() const { return m_is8Bit; }
71     LChar* characters8() const { ASSERT(is8Bit()); return m_data.characters8; }
72     UChar* characters16() const { ASSERT(!is8Bit()); return m_data.characters16; }
73     template<typename CharacterType> CharacterType* characters() const;
74
75     unsigned length() const { return m_length; }
76     void setLength(unsigned length) { m_length = length; }
77
78     void convertToASCIILowercaseInPlace();
79
80     UChar operator[](unsigned i) const
81     {
82         ASSERT_WITH_SECURITY_IMPLICATION(i < m_length);
83         if (is8Bit())
84             return m_data.characters8[i];
85         return m_data.characters16[i];
86     }
87
88     operator String() const { return is8Bit() ? String(m_data.characters8, m_length) : String(m_data.characters16, m_length); }
89     operator AtomicString() const { return is8Bit() ? AtomicString(m_data.characters8, m_length) : AtomicString(m_data.characters16, m_length); }
90     StringView toStringView() const { return is8Bit() ? StringView(m_data.characters8, m_length) : StringView(m_data.characters16, m_length); }
91
92     union {
93         LChar* characters8;
94         UChar* characters16;
95     } m_data;
96     unsigned m_length;
97     bool m_is8Bit;
98 };
99
100 template<unsigned length> bool equalLettersIgnoringASCIICase(const CSSParserString&, const char (&lowercaseLetters)[length]);
101
102 struct CSSParserFunction;
103 struct CSSParserVariable;
104
105 struct CSSParserValue {
106     CSSValueID id;
107     bool isInt;
108     union {
109         double fValue;
110         int iValue;
111         CSSParserString string;
112         CSSParserFunction* function;
113         CSSParserVariable* variable;
114         CSSParserValueList* valueList;
115     };
116     enum {
117         Operator  = 0x100000,
118         Function  = 0x100001,
119         ValueList = 0x100002,
120         Q_EMS     = 0x100003,
121         Variable  = 0x100004
122     };
123     int unit;
124
125     void setFromValueList(std::unique_ptr<CSSParserValueList>);
126
127     RefPtr<CSSValue> createCSSValue();
128 };
129
130 void destroy(const CSSParserValue&);
131
132 class CSSParserValueList {
133     WTF_MAKE_FAST_ALLOCATED;
134 public:
135     CSSParserValueList()
136         : m_current(0)
137     {
138     }
139     ~CSSParserValueList();
140
141     void addValue(const CSSParserValue&);
142     void insertValueAt(unsigned, const CSSParserValue&);
143     void extend(CSSParserValueList&);
144
145     unsigned size() const { return m_values.size(); }
146     unsigned currentIndex() { return m_current; }
147     CSSParserValue* current() { return m_current < m_values.size() ? &m_values[m_current] : 0; }
148     CSSParserValue* next() { ++m_current; return current(); }
149     CSSParserValue* previous()
150     {
151         if (!m_current)
152             return 0;
153         --m_current;
154         return current();
155     }
156     void setCurrentIndex(unsigned index)
157     {
158         ASSERT(index < m_values.size());
159         if (index < m_values.size())
160             m_current = index;
161     }
162
163     CSSParserValue* valueAt(unsigned i) { return i < m_values.size() ? &m_values[i] : 0; }
164
165     void clear() { m_values.clear(); }
166     
167     String toString();
168     
169     bool containsVariables() const;
170
171 private:
172     unsigned m_current;
173     Vector<CSSParserValue, 4> m_values;
174 };
175
176 struct CSSParserFunction {
177     WTF_MAKE_FAST_ALLOCATED;
178 public:
179     CSSParserString name;
180     std::unique_ptr<CSSParserValueList> args;
181 };
182
183 struct CSSParserVariable {
184     WTF_MAKE_FAST_ALLOCATED;
185 public:
186     CSSParserString name; // The custom property name
187     std::unique_ptr<CSSParserValueList> args; // The fallback args
188 };
189
190 enum class CSSParserSelectorCombinator {
191     Child,
192     DescendantSpace,
193 #if ENABLE(CSS_SELECTORS_LEVEL4)
194     DescendantDoubleChild,
195 #endif
196     DirectAdjacent,
197     IndirectAdjacent,
198     ShadowPseudo, // Special case of shadow DOM pseudo elements / shadow pseudo element
199     ShadowDeep, // /deep/ combinator
200     ShadowSlot // slotted to <slot> e
201 };
202
203 class CSSParserSelector {
204     WTF_MAKE_FAST_ALLOCATED;
205 public:
206     static CSSParserSelector* parsePagePseudoSelector(const CSSParserString& pseudoTypeString);
207     static CSSParserSelector* parsePseudoElementSelector(CSSParserString& pseudoTypeString);
208     static CSSParserSelector* parsePseudoElementCueFunctionSelector(const CSSParserString& functionIdentifier, Vector<std::unique_ptr<CSSParserSelector>>*);
209     static CSSParserSelector* parsePseudoElementSlottedFunctionSelector(const CSSParserString& functionIdentifier, CSSParserSelector*);
210     static CSSParserSelector* parsePseudoClassHostFunctionSelector(const CSSParserString& functionIdentifier, CSSParserSelector*);
211     static CSSParserSelector* parsePseudoClassAndCompatibilityElementSelector(CSSParserString& pseudoTypeString);
212
213     static CSSParserSelector* parsePseudoClassSelectorFromStringView(StringView&);
214     static CSSParserSelector* parsePseudoElementSelectorFromStringView(StringView&);
215     
216     CSSParserSelector();
217     explicit CSSParserSelector(const QualifiedName&);
218     ~CSSParserSelector();
219
220     std::unique_ptr<CSSSelector> releaseSelector() { return WTFMove(m_selector); }
221
222     void setValue(const AtomicString& value) { m_selector->setValue(value); }
223     void setAttribute(const QualifiedName& value, bool isCaseInsensitive) { m_selector->setAttribute(value, isCaseInsensitive); }
224     void setArgument(const AtomicString& value) { m_selector->setArgument(value); }
225     void setAttributeValueMatchingIsCaseInsensitive(bool isCaseInsensitive) { m_selector->setAttributeValueMatchingIsCaseInsensitive(isCaseInsensitive); }
226     void setMatch(CSSSelector::Match value) { m_selector->setMatch(value); }
227     void setRelation(CSSSelector::Relation value) { m_selector->setRelation(value); }
228     void setForPage() { m_selector->setForPage(); }
229
230     CSSSelector::Match match() const { return m_selector->match(); }
231     CSSSelector::PseudoElementType pseudoElementType() const { return m_selector->pseudoElementType(); }
232     const CSSSelectorList* selectorList() const { return m_selector->selectorList(); }
233
234     void adoptSelectorVector(Vector<std::unique_ptr<CSSParserSelector>>& selectorVector);
235     void setLangArgumentList(const Vector<CSSParserString>& stringVector);
236     void setSelectorList(std::unique_ptr<CSSSelectorList>);
237
238     void setPseudoClassValue(const CSSParserString& pseudoClassString);
239     CSSSelector::PseudoClassType pseudoClassType() const { return m_selector->pseudoClassType(); }
240     bool isCustomPseudoElement() const { return m_selector->isCustomPseudoElement(); }
241
242     bool isPseudoElementCueFunction() const
243     {
244 #if ENABLE(VIDEO_TRACK)
245         return m_selector->match() == CSSSelector::PseudoElement && m_selector->pseudoElementType() == CSSSelector::PseudoElementCue;
246 #else
247         return false;
248 #endif
249     }
250
251     bool hasShadowDescendant() const;
252     bool matchesPseudoElement() const;
253
254     bool isHostPseudoSelector() const;
255
256     // FIXME-NEWPARSER: Missing "shadow"
257     bool needsImplicitShadowCombinatorForMatching() const { return pseudoElementType() == CSSSelector::PseudoElementWebKitCustom || pseudoElementType() == CSSSelector::PseudoElementUserAgentCustom || pseudoElementType() == CSSSelector::PseudoElementWebKitCustomLegacyPrefixed || pseudoElementType() == CSSSelector::PseudoElementCue || pseudoElementType() == CSSSelector::PseudoElementSlotted; }
258
259     CSSParserSelector* tagHistory() const { return m_tagHistory.get(); }
260     void setTagHistory(std::unique_ptr<CSSParserSelector> selector) { m_tagHistory = WTFMove(selector); }
261     void clearTagHistory() { m_tagHistory.reset(); }
262     void insertTagHistory(CSSSelector::Relation before, std::unique_ptr<CSSParserSelector>, CSSSelector::Relation after);
263     void appendTagHistory(CSSSelector::Relation, std::unique_ptr<CSSParserSelector>);
264     void appendTagHistory(CSSParserSelectorCombinator, std::unique_ptr<CSSParserSelector>);
265     void prependTagSelector(const QualifiedName&, bool tagIsForNamespaceRule = false);
266     std::unique_ptr<CSSParserSelector> releaseTagHistory();
267
268 private:
269 #if ENABLE(CSS_SELECTORS_LEVEL4)
270     void setDescendantUseDoubleChildSyntax() { m_selector->setDescendantUseDoubleChildSyntax(); }
271 #endif
272
273     std::unique_ptr<CSSSelector> m_selector;
274     std::unique_ptr<CSSParserSelector> m_tagHistory;
275 };
276
277 inline bool CSSParserSelector::hasShadowDescendant() const
278 {
279     return m_selector->relation() == CSSSelector::ShadowDescendant;
280 }
281
282 inline void CSSParserValue::setFromValueList(std::unique_ptr<CSSParserValueList> valueList)
283 {
284     id = CSSValueInvalid;
285     this->valueList = valueList.release();
286     unit = ValueList;
287 }
288
289 template<unsigned length> inline bool equalLettersIgnoringASCIICase(const CSSParserString& string, const char (&lowercaseLetters)[length])
290 {
291     return WTF::equalLettersIgnoringASCIICaseCommon(string, lowercaseLetters);
292 }
293
294 }