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