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