c86c33e3b116980e9368e5787e2ada7b1eeb1b78
[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 "URLHash.h"
24 #include <wtf/Function.h>
25 #include <wtf/HashMap.h>
26 #include <wtf/RefCounted.h>
27 #include <wtf/RefPtr.h>
28 #include <wtf/TypeCasts.h>
29
30 namespace WebCore {
31
32 class CSSCustomPropertyValue;
33 class CSSStyleDeclaration;
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 isFontStyleValue() const { return m_classType == FontStyleClass; }
83     bool isFontStyleRangeValue() const { return m_classType == FontStyleRangeClass; }
84     bool isImageGeneratorValue() const { return m_classType >= CanvasClass && m_classType <= ConicGradientClass; }
85     bool isGradientValue() const { return m_classType >= LinearGradientClass && m_classType <= ConicGradientClass; }
86     bool isNamedImageValue() const { return m_classType == NamedImageClass; }
87     bool isImageSetValue() const { return m_classType == ImageSetClass; }
88     bool isImageValue() const { return m_classType == ImageClass; }
89     bool isImplicitInitialValue() const;
90     bool isInheritedValue() const { return m_classType == InheritedClass; }
91     bool isInitialValue() const { return m_classType == InitialClass; }
92     bool isUnsetValue() const { return m_classType == UnsetClass; }
93     bool isRevertValue() const { return m_classType == RevertClass; }
94     bool isGlobalKeyword() const { return isInheritedValue() || isInitialValue() || isUnsetValue() || isRevertValue(); }
95     bool treatAsInitialValue(CSSPropertyID) const;
96     bool treatAsInheritedValue(CSSPropertyID) const;
97     bool isLinearGradientValue() const { return m_classType == LinearGradientClass; }
98     bool isRadialGradientValue() const { return m_classType == RadialGradientClass; }
99     bool isConicGradientValue() const { return m_classType == ConicGradientClass; }
100     bool isReflectValue() const { return m_classType == ReflectClass; }
101     bool isShadowValue() const { return m_classType == ShadowClass; }
102     bool isCubicBezierTimingFunctionValue() const { return m_classType == CubicBezierTimingFunctionClass; }
103     bool isStepsTimingFunctionValue() const { return m_classType == StepsTimingFunctionClass; }
104     bool isSpringTimingFunctionValue() const { return m_classType == SpringTimingFunctionClass; }
105     bool isLineBoxContainValue() const { return m_classType == LineBoxContainClass; }
106     bool isCalcValue() const {return m_classType == CalculationClass; }
107     bool isFilterImageValue() const { return m_classType == FilterImageClass; }
108     bool isContentDistributionValue() const { return m_classType == CSSContentDistributionClass; }
109     bool isGridAutoRepeatValue() const { return m_classType == GridAutoRepeatClass; }
110     bool isGridTemplateAreasValue() const { return m_classType == GridTemplateAreasClass; }
111     bool isGridLineNamesValue() const { return m_classType == GridLineNamesClass; }
112     bool isUnicodeRangeValue() const { return m_classType == UnicodeRangeClass; }
113
114 #if ENABLE(CSS_ANIMATIONS_LEVEL_2)
115     bool isAnimationTriggerScrollValue() const { return m_classType == AnimationTriggerScrollClass; }
116 #endif
117
118     bool isCustomIdentValue() const { return m_classType == CustomIdentClass; }
119     bool isVariableReferenceValue() const { return m_classType == VariableReferenceClass; }
120     bool isPendingSubstitutionValue() const { return m_classType == PendingSubstitutionValueClass; }
121     
122     bool hasVariableReferences() const { return isVariableReferenceValue() || isPendingSubstitutionValue(); }
123
124     Ref<DeprecatedCSSOMValue> createDeprecatedCSSOMWrapper(CSSStyleDeclaration&) const;
125
126     bool traverseSubresources(const WTF::Function<bool (const CachedResource&)>& handler) const;
127
128     bool equals(const CSSValue&) const;
129     bool operator==(const CSSValue& other) const { return equals(other); }
130
131 protected:
132
133     static const size_t ClassTypeBits = 6;
134     enum ClassType {
135         PrimitiveClass,
136
137         // Image classes.
138         ImageClass,
139         CursorImageClass,
140
141         // Image generator classes.
142         CanvasClass,
143         NamedImageClass,
144         CrossfadeClass,
145         FilterImageClass,
146         LinearGradientClass,
147         RadialGradientClass,
148         ConicGradientClass,
149
150         // Timing function classes.
151         CubicBezierTimingFunctionClass,
152         StepsTimingFunctionClass,
153         SpringTimingFunctionClass,
154
155         // Other class types.
156         AspectRatioClass,
157         BorderImageSliceClass,
158         FontFeatureClass,
159 #if ENABLE(VARIATION_FONTS)
160         FontVariationClass,
161 #endif
162         FontClass,
163         FontStyleClass,
164         FontStyleRangeClass,
165         FontFaceSrcClass,
166         FunctionClass,
167
168         InheritedClass,
169         InitialClass,
170         UnsetClass,
171         RevertClass,
172
173         ReflectClass,
174         ShadowClass,
175         UnicodeRangeClass,
176         LineBoxContainClass,
177         CalculationClass,
178         GridTemplateAreasClass,
179 #if ENABLE(CSS_ANIMATIONS_LEVEL_2)
180         AnimationTriggerScrollClass,
181 #endif
182
183         CSSContentDistributionClass,
184         
185         CustomIdentClass,
186
187         CustomPropertyClass,
188         VariableReferenceClass,
189         PendingSubstitutionValueClass,
190
191         // List class types must appear after ValueListClass. Note CSSFunctionValue
192         // is deliberately excluded, since we don't want it exposed to the CSS OM
193         // as a list.
194         ValueListClass,
195         ImageSetClass,
196         GridLineNamesClass,
197         GridAutoRepeatClass,
198         // Do not append non-list class types here.
199     };
200
201 public:
202     static const size_t ValueListSeparatorBits = 2;
203     enum ValueListSeparator {
204         SpaceSeparator,
205         CommaSeparator,
206         SlashSeparator
207     };
208
209 protected:
210     ClassType classType() const { return static_cast<ClassType>(m_classType); }
211
212     explicit CSSValue(ClassType classType)
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() = default;
225
226 private:
227     WEBCORE_EXPORT void destroy();
228
229 protected:
230     // The bits in this section are only used by specific subclasses but kept here
231     // to maximize struct packing.
232
233     // CSSPrimitiveValue bits:
234     unsigned m_primitiveUnitType : 7; // CSSPrimitiveValue::UnitType
235     mutable unsigned m_hasCachedCSSText : 1;
236     unsigned m_isQuirkValue : 1;
237
238     unsigned m_valueListSeparator : ValueListSeparatorBits;
239
240 private:
241     unsigned m_classType : ClassTypeBits; // ClassType
242     
243 friend class CSSValueList;
244 };
245
246 template<typename CSSValueType>
247 inline bool compareCSSValueVector(const Vector<Ref<CSSValueType>>& firstVector, const Vector<Ref<CSSValueType>>& secondVector)
248 {
249     size_t size = firstVector.size();
250     if (size != secondVector.size())
251         return false;
252
253     for (size_t i = 0; i < size; ++i) {
254         auto& firstPtr = firstVector[i];
255         auto& secondPtr = secondVector[i];
256         if (firstPtr.ptr() == secondPtr.ptr() || firstPtr->equals(secondPtr))
257             continue;
258         return false;
259     }
260     return true;
261 }
262
263 template<typename CSSValueType>
264 inline bool compareCSSValuePtr(const RefPtr<CSSValueType>& first, const RefPtr<CSSValueType>& second)
265 {
266     return first ? second && first->equals(*second) : !second;
267 }
268
269 template<typename CSSValueType>
270 inline bool compareCSSValue(const Ref<CSSValueType>& first, const Ref<CSSValueType>& second)
271 {
272     return first.get().equals(second);
273 }
274
275 typedef HashMap<AtomicString, RefPtr<CSSCustomPropertyValue>> CustomPropertyValueMap;
276
277 } // namespace WebCore
278
279 #define SPECIALIZE_TYPE_TRAITS_CSS_VALUE(ToValueTypeName, predicate) \
280 SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::ToValueTypeName) \
281     static bool isType(const WebCore::CSSValue& value) { return value.predicate; } \
282 SPECIALIZE_TYPE_TRAITS_END()