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 | |
31 | namespace WebCore { |
32 | |
33 | class CSSCustomPropertyValue; |
34 | class CSSStyleDeclaration; |
35 | class CachedResource; |
36 | class DeprecatedCSSOMValue; |
37 | class StyleSheetContents; |
38 | |
39 | enum CSSPropertyID : uint16_t; |
40 | |
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 | 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 | |
137 | protected: |
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 | |
208 | public: |
209 | static const size_t ValueListSeparatorBits = 2; |
210 | enum ValueListSeparator { |
211 | SpaceSeparator, |
212 | CommaSeparator, |
213 | SlashSeparator |
214 | }; |
215 | |
216 | protected: |
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 | |
233 | private: |
234 | WEBCORE_EXPORT void destroy(); |
235 | |
236 | protected: |
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 | |
247 | private: |
248 | unsigned m_classType : ClassTypeBits; // ClassType |
249 | |
250 | friend class CSSValueList; |
251 | }; |
252 | |
253 | template<typename CSSValueType> |
254 | inline 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 | |
270 | template<typename CSSValueType> |
271 | inline bool compareCSSValuePtr(const RefPtr<CSSValueType>& first, const RefPtr<CSSValueType>& second) |
272 | { |
273 | return first ? second && first->equals(*second) : !second; |
274 | } |
275 | |
276 | template<typename CSSValueType> |
277 | inline bool compareCSSValue(const Ref<CSSValueType>& first, const Ref<CSSValueType>& second) |
278 | { |
279 | return first.get().equals(second); |
280 | } |
281 | |
282 | typedef HashMap<AtomString, RefPtr<CSSCustomPropertyValue>> CustomPropertyValueMap; |
283 | |
284 | } // namespace WebCore |
285 | |
286 | #define SPECIALIZE_TYPE_TRAITS_CSS_VALUE(ToValueTypeName, predicate) \ |
287 | SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::ToValueTypeName) \ |
288 | static bool isType(const WebCore::CSSValue& value) { return value.predicate; } \ |
289 | SPECIALIZE_TYPE_TRAITS_END() |
290 | |