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