1 | /*
|
---|
2 | * (C) 1999-2003 Lars Knoll ([email protected])
|
---|
3 | * Copyright (C) 2004-2021 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 | #include <wtf/text/ASCIILiteral.h>
|
---|
31 |
|
---|
32 | namespace WebCore {
|
---|
33 |
|
---|
34 | class CSSCustomPropertyValue;
|
---|
35 | class CSSStyleDeclaration;
|
---|
36 | class CachedResource;
|
---|
37 | class DeprecatedCSSOMValue;
|
---|
38 | class Document;
|
---|
39 | class StyleSheetContents;
|
---|
40 |
|
---|
41 | enum CSSPropertyID : uint16_t;
|
---|
42 |
|
---|
43 | DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(CSSValue);
|
---|
44 | class CSSValue {
|
---|
45 | WTF_MAKE_NONCOPYABLE(CSSValue);
|
---|
46 | WTF_MAKE_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(CSSValue);
|
---|
47 | public:
|
---|
48 | enum Type {
|
---|
49 | CSS_INHERIT = 0,
|
---|
50 | CSS_PRIMITIVE_VALUE = 1,
|
---|
51 | CSS_VALUE_LIST = 2,
|
---|
52 | CSS_CUSTOM = 3,
|
---|
53 | CSS_INITIAL = 4,
|
---|
54 | CSS_UNSET = 5,
|
---|
55 | CSS_REVERT = 6
|
---|
56 | };
|
---|
57 |
|
---|
58 | static constexpr unsigned refCountFlagIsStatic = 0x1;
|
---|
59 | static constexpr unsigned refCountIncrement = 0x2; // This allows us to ref / deref without disturbing the static CSSValue flag.
|
---|
60 | void ref() const
|
---|
61 | {
|
---|
62 | m_refCount += refCountIncrement;
|
---|
63 | }
|
---|
64 | bool hasOneRef() const { return m_refCount == refCountIncrement; }
|
---|
65 | unsigned refCount() const { return m_refCount / refCountIncrement; }
|
---|
66 | bool hasAtLeastOneRef() const { return m_refCount; }
|
---|
67 |
|
---|
68 | void deref()
|
---|
69 | {
|
---|
70 | // Customized deref() to ensure operator delete is called on
|
---|
71 | // the appropriate subclass type.
|
---|
72 | unsigned tempRefCount = m_refCount - refCountIncrement;
|
---|
73 | if (!tempRefCount) {
|
---|
74 | destroy();
|
---|
75 | return;
|
---|
76 | }
|
---|
77 | m_refCount = tempRefCount;
|
---|
78 | }
|
---|
79 |
|
---|
80 | Type cssValueType() const;
|
---|
81 | String cssText(Document* = nullptr) const;
|
---|
82 | ASCIILiteral separatorCSSText() const;
|
---|
83 |
|
---|
84 | bool isPrimitiveValue() const { return m_classType == PrimitiveClass; }
|
---|
85 | bool isValueList() const { return m_classType >= ValueListClass; }
|
---|
86 | bool isValuePair() const { return m_classType == ValuePairClass; }
|
---|
87 |
|
---|
88 | bool isBaseValueList() const { return m_classType == ValueListClass; }
|
---|
89 |
|
---|
90 |
|
---|
91 | bool isAspectRatioValue() const { return m_classType == AspectRatioClass; }
|
---|
92 | bool isBorderImageSliceValue() const { return m_classType == BorderImageSliceClass; }
|
---|
93 | bool isBorderImageWidthValue() const { return m_classType == BorderImageWidthClass; }
|
---|
94 | bool isCanvasValue() const { return m_classType == CanvasClass; }
|
---|
95 | bool isCrossfadeValue() const { return m_classType == CrossfadeClass; }
|
---|
96 | bool isCursorImageValue() const { return m_classType == CursorImageClass; }
|
---|
97 | bool isCustomPropertyValue() const { return m_classType == CustomPropertyClass; }
|
---|
98 | bool isFunctionValue() const { return m_classType == FunctionClass; }
|
---|
99 | bool isFontFeatureValue() const { return m_classType == FontFeatureClass; }
|
---|
100 | bool isFontVariationValue() const { return m_classType == FontVariationClass; }
|
---|
101 | bool isFontFaceSrcValue() const { return m_classType == FontFaceSrcClass; }
|
---|
102 | bool isFontPaletteValuesOverrideColorsValue() const { return m_classType == FontPaletteValuesOverrideColorsClass; }
|
---|
103 | bool isFontValue() const { return m_classType == FontClass; }
|
---|
104 | bool isFontStyleValue() const { return m_classType == FontStyleClass; }
|
---|
105 | bool isFontStyleRangeValue() const { return m_classType == FontStyleRangeClass; }
|
---|
106 | bool isImageGeneratorValue() const { return m_classType >= CanvasClass && m_classType <= ConicGradientClass; }
|
---|
107 | bool isGradientValue() const { return m_classType >= LinearGradientClass && m_classType <= ConicGradientClass; }
|
---|
108 | bool isNamedImageValue() const { return m_classType == NamedImageClass; }
|
---|
109 | bool isImageSetValue() const { return m_classType == ImageSetClass; }
|
---|
110 | bool isImageValue() const { return m_classType == ImageClass; }
|
---|
111 | bool isImplicitInitialValue() const;
|
---|
112 | bool isInheritValue() const;
|
---|
113 | bool isInitialValue() const;
|
---|
114 | bool isUnsetValue() const;
|
---|
115 | bool isRevertValue() const;
|
---|
116 | bool isRevertLayerValue() const;
|
---|
117 | bool isCSSWideKeyword() const;
|
---|
118 | bool treatAsInitialValue(CSSPropertyID) const;
|
---|
119 | bool treatAsInheritedValue(CSSPropertyID) const;
|
---|
120 | bool isLinearGradientValue() const { return m_classType == LinearGradientClass; }
|
---|
121 | bool isRadialGradientValue() const { return m_classType == RadialGradientClass; }
|
---|
122 | bool isConicGradientValue() const { return m_classType == ConicGradientClass; }
|
---|
123 | bool isReflectValue() const { return m_classType == ReflectClass; }
|
---|
124 | bool isShadowValue() const { return m_classType == ShadowClass; }
|
---|
125 | bool isCubicBezierTimingFunctionValue() const { return m_classType == CubicBezierTimingFunctionClass; }
|
---|
126 | bool isStepsTimingFunctionValue() const { return m_classType == StepsTimingFunctionClass; }
|
---|
127 | bool isSpringTimingFunctionValue() const { return m_classType == SpringTimingFunctionClass; }
|
---|
128 | bool isLineBoxContainValue() const { return m_classType == LineBoxContainClass; }
|
---|
129 | bool isCalcValue() const {return m_classType == CalculationClass; }
|
---|
130 | bool isFilterImageValue() const { return m_classType == FilterImageClass; }
|
---|
131 | #if ENABLE(CSS_PAINTING_API)
|
---|
132 | bool isPaintImageValue() const { return m_classType == PaintImageClass; }
|
---|
133 | #endif
|
---|
134 | bool isContentDistributionValue() const { return m_classType == CSSContentDistributionClass; }
|
---|
135 | bool isGridAutoRepeatValue() const { return m_classType == GridAutoRepeatClass; }
|
---|
136 | bool isGridIntegerRepeatValue() const { return m_classType == GridIntegerRepeatClass; }
|
---|
137 | bool isGridTemplateAreasValue() const { return m_classType == GridTemplateAreasClass; }
|
---|
138 | bool isGridLineNamesValue() const { return m_classType == GridLineNamesClass; }
|
---|
139 | bool isSubgridValue() const { return m_classType == SubgridClass; }
|
---|
140 | bool isUnicodeRangeValue() const { return m_classType == UnicodeRangeClass; }
|
---|
141 |
|
---|
142 | bool isVariableReferenceValue() const { return m_classType == VariableReferenceClass; }
|
---|
143 | bool isPendingSubstitutionValue() const { return m_classType == PendingSubstitutionValueClass; }
|
---|
144 |
|
---|
145 | bool isOffsetRotateValue() const { return m_classType == OffsetRotateClass; }
|
---|
146 | bool isRayValue() const { return m_classType == RayClass; }
|
---|
147 |
|
---|
148 | bool hasVariableReferences() const { return isVariableReferenceValue() || isPendingSubstitutionValue(); }
|
---|
149 |
|
---|
150 | Ref<DeprecatedCSSOMValue> createDeprecatedCSSOMWrapper(CSSStyleDeclaration&) const;
|
---|
151 |
|
---|
152 | bool traverseSubresources(const Function<bool(const CachedResource&)>& handler) const;
|
---|
153 |
|
---|
154 | // What properties does this value rely on (eg, font-size for em units)
|
---|
155 | void collectDirectComputationalDependencies(HashSet<CSSPropertyID>&) const;
|
---|
156 | // What properties in the root element does this value rely on (eg. font-size for rem units)
|
---|
157 | void collectDirectRootComputationalDependencies(HashSet<CSSPropertyID>&) const;
|
---|
158 |
|
---|
159 | bool equals(const CSSValue&) const;
|
---|
160 | bool operator==(const CSSValue& other) const { return equals(other); }
|
---|
161 |
|
---|
162 | // https://www.w3.org/TR/css-values-4/#local-urls
|
---|
163 | // Empty URLs and fragment-only URLs should not be resolved relative to the base URL.
|
---|
164 | static bool isCSSLocalURL(StringView relativeURL);
|
---|
165 |
|
---|
166 | protected:
|
---|
167 |
|
---|
168 | static const size_t ClassTypeBits = 6;
|
---|
169 | enum ClassType {
|
---|
170 | PrimitiveClass,
|
---|
171 |
|
---|
172 | // Image classes.
|
---|
173 | ImageClass,
|
---|
174 | CursorImageClass,
|
---|
175 |
|
---|
176 | // Image generator classes.
|
---|
177 | CanvasClass,
|
---|
178 | #if ENABLE(CSS_PAINTING_API)
|
---|
179 | PaintImageClass,
|
---|
180 | #endif
|
---|
181 | NamedImageClass,
|
---|
182 | CrossfadeClass,
|
---|
183 | FilterImageClass,
|
---|
184 | LinearGradientClass,
|
---|
185 | RadialGradientClass,
|
---|
186 | ConicGradientClass,
|
---|
187 |
|
---|
188 | // Timing function classes.
|
---|
189 | CubicBezierTimingFunctionClass,
|
---|
190 | StepsTimingFunctionClass,
|
---|
191 | SpringTimingFunctionClass,
|
---|
192 |
|
---|
193 | // Other class types.
|
---|
194 | AspectRatioClass,
|
---|
195 | BorderImageSliceClass,
|
---|
196 | BorderImageWidthClass,
|
---|
197 | FontFeatureClass,
|
---|
198 | FontVariationClass,
|
---|
199 | FontClass,
|
---|
200 | FontStyleClass,
|
---|
201 | FontStyleRangeClass,
|
---|
202 | FontFaceSrcClass,
|
---|
203 | FontPaletteValuesOverrideColorsClass,
|
---|
204 | FunctionClass,
|
---|
205 |
|
---|
206 | ReflectClass,
|
---|
207 | ShadowClass,
|
---|
208 | UnicodeRangeClass,
|
---|
209 | LineBoxContainClass,
|
---|
210 | CalculationClass,
|
---|
211 | GridTemplateAreasClass,
|
---|
212 | ValuePairClass,
|
---|
213 |
|
---|
214 | CSSContentDistributionClass,
|
---|
215 |
|
---|
216 | CustomPropertyClass,
|
---|
217 | VariableReferenceClass,
|
---|
218 | PendingSubstitutionValueClass,
|
---|
219 |
|
---|
220 | OffsetRotateClass,
|
---|
221 | RayClass,
|
---|
222 |
|
---|
223 | // List class types must appear after ValueListClass. Note CSSFunctionValue
|
---|
224 | // is deliberately excluded, since we don't want it exposed to the CSS OM
|
---|
225 | // as a list.
|
---|
226 | ValueListClass,
|
---|
227 | ImageSetClass,
|
---|
228 | GridLineNamesClass,
|
---|
229 | GridAutoRepeatClass,
|
---|
230 | GridIntegerRepeatClass,
|
---|
231 | SubgridClass,
|
---|
232 | // Do not append non-list class types here.
|
---|
233 | };
|
---|
234 |
|
---|
235 | public:
|
---|
236 | static const size_t ValueSeparatorBits = 2;
|
---|
237 | enum ValueSeparator {
|
---|
238 | SpaceSeparator,
|
---|
239 | CommaSeparator,
|
---|
240 | SlashSeparator
|
---|
241 | };
|
---|
242 | enum StaticCSSValueTag { StaticCSSValue };
|
---|
243 |
|
---|
244 | protected:
|
---|
245 | ClassType classType() const { return static_cast<ClassType>(m_classType); }
|
---|
246 |
|
---|
247 | explicit CSSValue(ClassType classType)
|
---|
248 | : m_primitiveUnitType(0)
|
---|
249 | , m_hasCachedCSSText(false)
|
---|
250 | , m_valueSeparator(SpaceSeparator)
|
---|
251 | , m_isImplicit(false)
|
---|
252 | , m_cachedCSSTextUsesLegacyPrecision(false)
|
---|
253 | , m_classType(classType)
|
---|
254 | {
|
---|
255 | }
|
---|
256 |
|
---|
257 | void makeStatic()
|
---|
258 | {
|
---|
259 | m_refCount |= refCountFlagIsStatic;
|
---|
260 | }
|
---|
261 |
|
---|
262 | // NOTE: This class is non-virtual for memory and performance reasons.
|
---|
263 | // Don't go making it virtual again unless you know exactly what you're doing!
|
---|
264 |
|
---|
265 | ~CSSValue() = default;
|
---|
266 |
|
---|
267 | private:
|
---|
268 | WEBCORE_EXPORT void destroy();
|
---|
269 |
|
---|
270 | mutable unsigned m_refCount { refCountIncrement };
|
---|
271 | protected:
|
---|
272 | // The bits in this section are only used by specific subclasses but kept here
|
---|
273 | // to maximize struct packing.
|
---|
274 | // CSSPrimitiveValue bits:
|
---|
275 | unsigned m_primitiveUnitType : 7; // CSSUnitType
|
---|
276 | mutable unsigned m_hasCachedCSSText : 1;
|
---|
277 |
|
---|
278 | unsigned m_valueSeparator : ValueSeparatorBits;
|
---|
279 | unsigned m_isImplicit : 1;
|
---|
280 | mutable unsigned m_cachedCSSTextUsesLegacyPrecision : 1;
|
---|
281 |
|
---|
282 | private:
|
---|
283 | unsigned m_classType : ClassTypeBits; // ClassType
|
---|
284 |
|
---|
285 | friend class CSSValueList;
|
---|
286 | };
|
---|
287 |
|
---|
288 | template<typename CSSValueType>
|
---|
289 | inline bool compareCSSValueVector(const Vector<Ref<CSSValueType>>& firstVector, const Vector<Ref<CSSValueType>>& secondVector)
|
---|
290 | {
|
---|
291 | size_t size = firstVector.size();
|
---|
292 | if (size != secondVector.size())
|
---|
293 | return false;
|
---|
294 |
|
---|
295 | for (size_t i = 0; i < size; ++i) {
|
---|
296 | auto& firstPtr = firstVector[i];
|
---|
297 | auto& secondPtr = secondVector[i];
|
---|
298 | if (firstPtr.ptr() == secondPtr.ptr() || firstPtr->equals(secondPtr))
|
---|
299 | continue;
|
---|
300 | return false;
|
---|
301 | }
|
---|
302 | return true;
|
---|
303 | }
|
---|
304 |
|
---|
305 | template<typename CSSValueType>
|
---|
306 | inline bool compareCSSValuePtr(const RefPtr<CSSValueType>& first, const RefPtr<CSSValueType>& second)
|
---|
307 | {
|
---|
308 | return first ? second && first->equals(*second) : !second;
|
---|
309 | }
|
---|
310 |
|
---|
311 | template<typename CSSValueType>
|
---|
312 | inline bool compareCSSValue(const Ref<CSSValueType>& first, const Ref<CSSValueType>& second)
|
---|
313 | {
|
---|
314 | return first.get().equals(second);
|
---|
315 | }
|
---|
316 |
|
---|
317 | typedef HashMap<AtomString, RefPtr<CSSCustomPropertyValue>> CustomPropertyValueMap;
|
---|
318 |
|
---|
319 | } // namespace WebCore
|
---|
320 |
|
---|
321 | #define SPECIALIZE_TYPE_TRAITS_CSS_VALUE(ToValueTypeName, predicate) \
|
---|
322 | SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::ToValueTypeName) \
|
---|
323 | static bool isType(const WebCore::CSSValue& value) { return value.predicate; } \
|
---|
324 | SPECIALIZE_TYPE_TRAITS_END()
|
---|