[CSS Parser] Add CSS Variable Parsing support
[WebKit-https.git] / Source / WebCore / css / CSSValue.h
1 /*
2  * (C) 1999-2003 Lars Knoll (knoll@kde.org)
3  * Copyright (C) 2004, 2005, 2006, 2007, 2008 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 "ExceptionCode.h"
24 #include "URLHash.h"
25 #include <wtf/HashMap.h>
26 #include <wtf/ListHashSet.h>
27 #include <wtf/RefCounted.h>
28 #include <wtf/RefPtr.h>
29 #include <wtf/TypeCasts.h>
30
31 namespace WebCore {
32
33 class CachedResource;
34 class StyleSheetContents;
35
36 enum CSSPropertyID : uint16_t;
37
38 // FIXME: The current CSSValue and subclasses should be turned into internal types (StyleValue).
39 // The few subtypes that are actually exposed in CSSOM can be seen in the cloneForCSSOM() function.
40 // They should be handled by separate wrapper classes.
41
42 // Please don't expose more CSSValue types to the web.
43 class CSSValue : public RefCounted<CSSValue> {
44 public:
45     enum Type {
46         CSS_INHERIT = 0,
47         CSS_PRIMITIVE_VALUE = 1,
48         CSS_VALUE_LIST = 2,
49         CSS_CUSTOM = 3,
50         CSS_INITIAL = 4,
51         CSS_UNSET = 5,
52         CSS_REVERT = 6
53     };
54
55     // Override RefCounted's deref() to ensure operator delete is called on
56     // the appropriate subclass type.
57     void deref()
58     {
59         if (derefBase())
60             destroy();
61     }
62
63     WEBCORE_EXPORT Type cssValueType() const;
64
65     WEBCORE_EXPORT String cssText() const;
66
67     void setCssText(const String&, ExceptionCode&) { } // FIXME: Not implemented.
68
69     bool isPrimitiveValue() const { return m_classType == PrimitiveClass; }
70     bool isValueList() const { return m_classType >= ValueListClass; }
71     
72     bool isBaseValueList() const { return m_classType == ValueListClass; }
73         
74
75     bool isAspectRatioValue() const { return m_classType == AspectRatioClass; }
76     bool isBorderImageSliceValue() const { return m_classType == BorderImageSliceClass; }
77     bool isCanvasValue() const { return m_classType == CanvasClass; }
78     bool isCrossfadeValue() const { return m_classType == CrossfadeClass; }
79     bool isCursorImageValue() const { return m_classType == CursorImageClass; }
80     bool isCustomPropertyValue() const { return m_classType == CustomPropertyClass; }
81     bool isInvalidCustomPropertyValue() const;
82     bool isVariableDependentValue() const { return m_classType == VariableDependentClass; }
83     bool isVariableValue() const { return m_classType == VariableClass; }
84     bool isFunctionValue() const { return m_classType == FunctionClass; }
85     bool isFontFeatureValue() const { return m_classType == FontFeatureClass; }
86     bool isFontFaceSrcValue() const { return m_classType == FontFaceSrcClass; }
87     bool isFontValue() const { return m_classType == FontClass; }
88     bool isImageGeneratorValue() const { return m_classType >= CanvasClass && m_classType <= RadialGradientClass; }
89     bool isGradientValue() const { return m_classType >= LinearGradientClass && m_classType <= RadialGradientClass; }
90     bool isNamedImageValue() const { return m_classType == NamedImageClass; }
91     bool isImageSetValue() const { return m_classType == ImageSetClass; }
92     bool isImageValue() const { return m_classType == ImageClass; }
93     bool isImplicitInitialValue() const;
94     bool isInheritedValue() const { return m_classType == InheritedClass; }
95     bool isInitialValue() const { return m_classType == InitialClass; }
96     bool isUnsetValue() const { return m_classType == UnsetClass; }
97     bool isRevertValue() const { return m_classType == RevertClass; }
98     bool treatAsInitialValue(CSSPropertyID) const;
99     bool treatAsInheritedValue(CSSPropertyID) const;
100     bool isLinearGradientValue() const { return m_classType == LinearGradientClass; }
101     bool isRadialGradientValue() const { return m_classType == RadialGradientClass; }
102     bool isReflectValue() const { return m_classType == ReflectClass; }
103     bool isShadowValue() const { return m_classType == ShadowClass; }
104     bool isCubicBezierTimingFunctionValue() const { return m_classType == CubicBezierTimingFunctionClass; }
105     bool isStepsTimingFunctionValue() const { return m_classType == StepsTimingFunctionClass; }
106     bool isSpringTimingFunctionValue() const { return m_classType == SpringTimingFunctionClass; }
107     bool isWebKitCSSTransformValue() const { return m_classType == WebKitCSSTransformClass; }
108     bool isLineBoxContainValue() const { return m_classType == LineBoxContainClass; }
109     bool isCalcValue() const {return m_classType == CalculationClass; }
110     bool isFilterImageValue() const { return m_classType == FilterImageClass; }
111     bool isWebKitCSSFilterValue() const { return m_classType == WebKitCSSFilterClass; }
112     bool isContentDistributionValue() const { return m_classType == CSSContentDistributionClass; }
113 #if ENABLE(CSS_GRID_LAYOUT)
114     bool isGridAutoRepeatValue() const { return m_classType == GridAutoRepeatClass; }
115     bool isGridTemplateAreasValue() const { return m_classType == GridTemplateAreasClass; }
116     bool isGridLineNamesValue() const { return m_classType == GridLineNamesClass; }
117 #endif
118     bool isSVGColor() const { return m_classType == SVGColorClass || m_classType == SVGPaintClass; }
119     bool isSVGPaint() const { return m_classType == SVGPaintClass; }
120     bool isUnicodeRangeValue() const { return m_classType == UnicodeRangeClass; }
121
122 #if ENABLE(CSS_ANIMATIONS_LEVEL_2)
123     bool isAnimationTriggerScrollValue() const { return m_classType == AnimationTriggerScrollClass; }
124 #endif
125
126     bool isCustomPropertyDeclaration() const { return m_classType == CustomPropertyDeclarationClass; }
127     bool isCustomIdentValue() const { return m_classType == CustomIdentClass; }
128     bool isVariableReferenceValue() const { return m_classType == VariableReferenceClass; }
129
130     bool isCSSOMSafe() const { return m_isCSSOMSafe; }
131     bool isSubtypeExposedToCSSOM() const
132     { 
133         return isPrimitiveValue() 
134             || isSVGColor()
135             || isValueList();
136     }
137
138     RefPtr<CSSValue> cloneForCSSOM() const;
139
140     void addSubresourceStyleURLs(ListHashSet<URL>&, const StyleSheetContents*) const;
141
142     bool traverseSubresources(const std::function<bool (const CachedResource&)>& handler) const;
143
144     bool equals(const CSSValue&) const;
145     bool operator==(const CSSValue& other) const { return equals(other); }
146
147 protected:
148
149     static const size_t ClassTypeBits = 6;
150     enum ClassType {
151         PrimitiveClass,
152
153         // Image classes.
154         ImageClass,
155         CursorImageClass,
156
157         // Image generator classes.
158         CanvasClass,
159         NamedImageClass,
160         CrossfadeClass,
161         FilterImageClass,
162         LinearGradientClass,
163         RadialGradientClass,
164
165         // Timing function classes.
166         CubicBezierTimingFunctionClass,
167         StepsTimingFunctionClass,
168         SpringTimingFunctionClass,
169
170         // Other class types.
171         AspectRatioClass,
172         BorderImageSliceClass,
173         FontFeatureClass,
174         FontClass,
175         FontFaceSrcClass,
176         FunctionClass,
177
178         InheritedClass,
179         InitialClass,
180         UnsetClass,
181         RevertClass,
182
183         ReflectClass,
184         ShadowClass,
185         UnicodeRangeClass,
186         LineBoxContainClass,
187         CalculationClass,
188 #if ENABLE(CSS_GRID_LAYOUT)
189         GridTemplateAreasClass,
190 #endif
191         SVGColorClass,
192         SVGPaintClass,
193
194 #if ENABLE(CSS_ANIMATIONS_LEVEL_2)
195         AnimationTriggerScrollClass,
196 #endif
197
198         CSSContentDistributionClass,
199         
200         // FIXME-NEWPARSER: Remove in favor of new variables implementation.
201         CustomPropertyClass,
202         VariableDependentClass,
203         VariableClass,
204
205         // New variables implementation.
206         CustomPropertyDeclarationClass,
207         CustomIdentClass,
208         VariableReferenceClass,
209
210         // List class types must appear after ValueListClass.
211         ValueListClass,
212         ImageSetClass,
213         WebKitCSSFilterClass,
214         WebKitCSSTransformClass,
215 #if ENABLE(CSS_GRID_LAYOUT)
216         GridLineNamesClass,
217         GridAutoRepeatClass,
218 #endif
219         // Do not append non-list class types here.
220     };
221
222     static const size_t ValueListSeparatorBits = 2;
223     enum ValueListSeparator {
224         SpaceSeparator,
225         CommaSeparator,
226         SlashSeparator
227     };
228
229     ClassType classType() const { return static_cast<ClassType>(m_classType); }
230
231     explicit CSSValue(ClassType classType, bool isCSSOMSafe = false)
232         : m_isCSSOMSafe(isCSSOMSafe)
233         , m_isTextClone(false)
234         , m_primitiveUnitType(0)
235         , m_hasCachedCSSText(false)
236         , m_isQuirkValue(false)
237         , m_valueListSeparator(SpaceSeparator)
238         , m_classType(classType)
239     {
240     }
241
242     // NOTE: This class is non-virtual for memory and performance reasons.
243     // Don't go making it virtual again unless you know exactly what you're doing!
244
245     ~CSSValue() { }
246
247 private:
248     WEBCORE_EXPORT void destroy();
249
250 protected:
251     unsigned m_isCSSOMSafe : 1;
252     unsigned m_isTextClone : 1;
253     // The bits in this section are only used by specific subclasses but kept here
254     // to maximize struct packing.
255
256     // CSSPrimitiveValue bits:
257     unsigned m_primitiveUnitType : 7; // CSSPrimitiveValue::UnitTypes
258     mutable unsigned m_hasCachedCSSText : 1;
259     unsigned m_isQuirkValue : 1;
260
261     unsigned m_valueListSeparator : ValueListSeparatorBits;
262
263 private:
264     unsigned m_classType : ClassTypeBits; // ClassType
265     
266 friend class CSSValueList;
267 };
268
269 template<typename CSSValueType>
270 inline bool compareCSSValueVector(const Vector<Ref<CSSValueType>>& firstVector, const Vector<Ref<CSSValueType>>& secondVector)
271 {
272     size_t size = firstVector.size();
273     if (size != secondVector.size())
274         return false;
275
276     for (size_t i = 0; i < size; ++i) {
277         auto& firstPtr = firstVector[i];
278         auto& secondPtr = secondVector[i];
279         if (firstPtr.ptr() == secondPtr.ptr() || firstPtr->equals(secondPtr))
280             continue;
281         return false;
282     }
283     return true;
284 }
285
286 template<typename CSSValueType>
287 inline bool compareCSSValuePtr(const RefPtr<CSSValueType>& first, const RefPtr<CSSValueType>& second)
288 {
289     return first ? second && first->equals(*second) : !second;
290 }
291
292 template<typename CSSValueType>
293 inline bool compareCSSValue(const Ref<CSSValueType>& first, const Ref<CSSValueType>& second)
294 {
295     return first.get().equals(second);
296 }
297
298 typedef HashMap<AtomicString, RefPtr<CSSValue>> CustomPropertyValueMap;
299
300 } // namespace WebCore
301
302 #define SPECIALIZE_TYPE_TRAITS_CSS_VALUE(ToValueTypeName, predicate) \
303 SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::ToValueTypeName) \
304     static bool isType(const WebCore::CSSValue& value) { return value.predicate; } \
305 SPECIALIZE_TYPE_TRAITS_END()