20f067d8bc24636de2bf9e86f723b9e51f8f32c5
[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 "ExceptionOr.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 CSSCustomPropertyValue;
34 class CachedResource;
35 class DeprecatedCSSOMValue;
36 class StyleSheetContents;
37
38 enum CSSPropertyID : uint16_t;
39
40 class CSSValue : public RefCounted<CSSValue> {
41 public:
42     enum Type {
43         CSS_INHERIT = 0,
44         CSS_PRIMITIVE_VALUE = 1,
45         CSS_VALUE_LIST = 2,
46         CSS_CUSTOM = 3,
47         CSS_INITIAL = 4,
48         CSS_UNSET = 5,
49         CSS_REVERT = 6
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     String cssText() const;
62
63     bool isPrimitiveValue() const { return m_classType == PrimitiveClass; }
64     bool isValueList() const { return m_classType >= ValueListClass; }
65     
66     bool isBaseValueList() const { return m_classType == ValueListClass; }
67         
68
69     bool isAspectRatioValue() const { return m_classType == AspectRatioClass; }
70     bool isBorderImageSliceValue() const { return m_classType == BorderImageSliceClass; }
71     bool isCanvasValue() const { return m_classType == CanvasClass; }
72     bool isCrossfadeValue() const { return m_classType == CrossfadeClass; }
73     bool isCursorImageValue() const { return m_classType == CursorImageClass; }
74     bool isCustomPropertyValue() const { return m_classType == CustomPropertyClass; }
75     bool isFunctionValue() const { return m_classType == FunctionClass; }
76     bool isFontFeatureValue() const { return m_classType == FontFeatureClass; }
77 #if ENABLE(VARIATION_FONTS)
78     bool isFontVariationValue() const { return m_classType == FontVariationClass; }
79 #endif
80     bool isFontFaceSrcValue() const { return m_classType == FontFaceSrcClass; }
81     bool isFontValue() const { return m_classType == FontClass; }
82     bool isImageGeneratorValue() const { return m_classType >= CanvasClass && m_classType <= RadialGradientClass; }
83     bool isGradientValue() const { return m_classType >= LinearGradientClass && m_classType <= RadialGradientClass; }
84     bool isNamedImageValue() const { return m_classType == NamedImageClass; }
85     bool isImageSetValue() const { return m_classType == ImageSetClass; }
86     bool isImageValue() const { return m_classType == ImageClass; }
87     bool isImplicitInitialValue() const;
88     bool isInheritedValue() const { return m_classType == InheritedClass; }
89     bool isInitialValue() const { return m_classType == InitialClass; }
90     bool isUnsetValue() const { return m_classType == UnsetClass; }
91     bool isRevertValue() const { return m_classType == RevertClass; }
92     bool treatAsInitialValue(CSSPropertyID) const;
93     bool treatAsInheritedValue(CSSPropertyID) const;
94     bool isLinearGradientValue() const { return m_classType == LinearGradientClass; }
95     bool isRadialGradientValue() const { return m_classType == RadialGradientClass; }
96     bool isReflectValue() const { return m_classType == ReflectClass; }
97     bool isShadowValue() const { return m_classType == ShadowClass; }
98     bool isCubicBezierTimingFunctionValue() const { return m_classType == CubicBezierTimingFunctionClass; }
99     bool isStepsTimingFunctionValue() const { return m_classType == StepsTimingFunctionClass; }
100     bool isSpringTimingFunctionValue() const { return m_classType == SpringTimingFunctionClass; }
101     bool isLineBoxContainValue() const { return m_classType == LineBoxContainClass; }
102     bool isCalcValue() const {return m_classType == CalculationClass; }
103     bool isFilterImageValue() const { return m_classType == FilterImageClass; }
104     bool isContentDistributionValue() const { return m_classType == CSSContentDistributionClass; }
105 #if ENABLE(CSS_GRID_LAYOUT)
106     bool isGridAutoRepeatValue() const { return m_classType == GridAutoRepeatClass; }
107     bool isGridTemplateAreasValue() const { return m_classType == GridTemplateAreasClass; }
108     bool isGridLineNamesValue() const { return m_classType == GridLineNamesClass; }
109 #endif
110     bool isUnicodeRangeValue() const { return m_classType == UnicodeRangeClass; }
111
112 #if ENABLE(CSS_ANIMATIONS_LEVEL_2)
113     bool isAnimationTriggerScrollValue() const { return m_classType == AnimationTriggerScrollClass; }
114 #endif
115
116     bool isCustomIdentValue() const { return m_classType == CustomIdentClass; }
117     bool isVariableReferenceValue() const { return m_classType == VariableReferenceClass; }
118     bool isPendingSubstitutionValue() const { return m_classType == PendingSubstitutionValueClass; }
119     
120     bool hasVariableReferences() const { return isVariableReferenceValue() || isPendingSubstitutionValue(); }
121
122     Ref<DeprecatedCSSOMValue> createDeprecatedCSSOMWrapper() const;
123
124     bool traverseSubresources(const std::function<bool (const CachedResource&)>& handler) const;
125
126     bool equals(const CSSValue&) const;
127     bool operator==(const CSSValue& other) const { return equals(other); }
128
129 protected:
130
131     static const size_t ClassTypeBits = 6;
132     enum ClassType {
133         PrimitiveClass,
134
135         // Image classes.
136         ImageClass,
137         CursorImageClass,
138
139         // Image generator classes.
140         CanvasClass,
141         NamedImageClass,
142         CrossfadeClass,
143         FilterImageClass,
144         LinearGradientClass,
145         RadialGradientClass,
146
147         // Timing function classes.
148         CubicBezierTimingFunctionClass,
149         StepsTimingFunctionClass,
150         SpringTimingFunctionClass,
151
152         // Other class types.
153         AspectRatioClass,
154         BorderImageSliceClass,
155         FontFeatureClass,
156 #if ENABLE(VARIATION_FONTS)
157         FontVariationClass,
158 #endif
159         FontClass,
160         FontFaceSrcClass,
161         FunctionClass,
162
163         InheritedClass,
164         InitialClass,
165         UnsetClass,
166         RevertClass,
167
168         ReflectClass,
169         ShadowClass,
170         UnicodeRangeClass,
171         LineBoxContainClass,
172         CalculationClass,
173 #if ENABLE(CSS_GRID_LAYOUT)
174         GridTemplateAreasClass,
175 #endif
176 #if ENABLE(CSS_ANIMATIONS_LEVEL_2)
177         AnimationTriggerScrollClass,
178 #endif
179
180         CSSContentDistributionClass,
181         
182         CustomIdentClass,
183
184         CustomPropertyClass,
185         VariableReferenceClass,
186         PendingSubstitutionValueClass,
187
188         // List class types must appear after ValueListClass. Note CSSFunctionValue
189         // is deliberately excluded, since we don't want it exposed to the CSS OM
190         // as a list.
191         ValueListClass,
192         ImageSetClass,
193 #if ENABLE(CSS_GRID_LAYOUT)
194         GridLineNamesClass,
195         GridAutoRepeatClass,
196 #endif
197         // Do not append non-list class types here.
198     };
199
200 public:
201     static const size_t ValueListSeparatorBits = 2;
202     enum ValueListSeparator {
203         SpaceSeparator,
204         CommaSeparator,
205         SlashSeparator
206     };
207
208 protected:
209     ClassType classType() const { return static_cast<ClassType>(m_classType); }
210
211     explicit CSSValue(ClassType classType)
212         : m_primitiveUnitType(0)
213         , m_hasCachedCSSText(false)
214         , m_isQuirkValue(false)
215         , m_valueListSeparator(SpaceSeparator)
216         , m_classType(classType)
217     {
218     }
219
220     // NOTE: This class is non-virtual for memory and performance reasons.
221     // Don't go making it virtual again unless you know exactly what you're doing!
222
223     ~CSSValue() { }
224
225 private:
226     WEBCORE_EXPORT void destroy();
227
228 protected:
229     // The bits in this section are only used by specific subclasses but kept here
230     // to maximize struct packing.
231
232     // CSSPrimitiveValue bits:
233     unsigned m_primitiveUnitType : 7; // CSSPrimitiveValue::UnitType
234     mutable unsigned m_hasCachedCSSText : 1;
235     unsigned m_isQuirkValue : 1;
236
237     unsigned m_valueListSeparator : ValueListSeparatorBits;
238
239 private:
240     unsigned m_classType : ClassTypeBits; // ClassType
241     
242 friend class CSSValueList;
243 };
244
245 template<typename CSSValueType>
246 inline bool compareCSSValueVector(const Vector<Ref<CSSValueType>>& firstVector, const Vector<Ref<CSSValueType>>& secondVector)
247 {
248     size_t size = firstVector.size();
249     if (size != secondVector.size())
250         return false;
251
252     for (size_t i = 0; i < size; ++i) {
253         auto& firstPtr = firstVector[i];
254         auto& secondPtr = secondVector[i];
255         if (firstPtr.ptr() == secondPtr.ptr() || firstPtr->equals(secondPtr))
256             continue;
257         return false;
258     }
259     return true;
260 }
261
262 template<typename CSSValueType>
263 inline bool compareCSSValuePtr(const RefPtr<CSSValueType>& first, const RefPtr<CSSValueType>& second)
264 {
265     return first ? second && first->equals(*second) : !second;
266 }
267
268 template<typename CSSValueType>
269 inline bool compareCSSValue(const Ref<CSSValueType>& first, const Ref<CSSValueType>& second)
270 {
271     return first.get().equals(second);
272 }
273
274 typedef HashMap<AtomicString, RefPtr<CSSCustomPropertyValue>> CustomPropertyValueMap;
275
276 } // namespace WebCore
277
278 #define SPECIALIZE_TYPE_TRAITS_CSS_VALUE(ToValueTypeName, predicate) \
279 SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::ToValueTypeName) \
280     static bool isType(const WebCore::CSSValue& value) { return value.predicate; } \
281 SPECIALIZE_TYPE_TRAITS_END()