Move URL from WebCore to WTF
[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 "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 isGridTemplateAreasValue() const { return m_classType == GridTemplateAreasClass; }
115     bool isGridLineNamesValue() const { return m_classType == GridLineNamesClass; }
116     bool isUnicodeRangeValue() const { return m_classType == UnicodeRangeClass; }
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     // What properties does this value rely on (eg, font-size for em units)
129     void collectDirectComputationalDependencies(HashSet<CSSPropertyID>&) const;
130     // What properties in the root element does this value rely on (eg. font-size for rem units)
131     void collectDirectRootComputationalDependencies(HashSet<CSSPropertyID>&) const;
132
133     bool equals(const CSSValue&) const;
134     bool operator==(const CSSValue& other) const { return equals(other); }
135
136 protected:
137
138     static const size_t ClassTypeBits = 6;
139     enum ClassType {
140         PrimitiveClass,
141
142         // Image classes.
143         ImageClass,
144         CursorImageClass,
145
146         // Image generator classes.
147         CanvasClass,
148 #if ENABLE(CSS_PAINTING_API)
149         PaintImageClass,
150 #endif
151         NamedImageClass,
152         CrossfadeClass,
153         FilterImageClass,
154         LinearGradientClass,
155         RadialGradientClass,
156         ConicGradientClass,
157
158         // Timing function classes.
159         CubicBezierTimingFunctionClass,
160         StepsTimingFunctionClass,
161         SpringTimingFunctionClass,
162
163         // Other class types.
164         AspectRatioClass,
165         BorderImageSliceClass,
166         FontFeatureClass,
167 #if ENABLE(VARIATION_FONTS)
168         FontVariationClass,
169 #endif
170         FontClass,
171         FontStyleClass,
172         FontStyleRangeClass,
173         FontFaceSrcClass,
174         FunctionClass,
175
176         InheritedClass,
177         InitialClass,
178         UnsetClass,
179         RevertClass,
180
181         ReflectClass,
182         ShadowClass,
183         UnicodeRangeClass,
184         LineBoxContainClass,
185         CalculationClass,
186         GridTemplateAreasClass,
187
188         CSSContentDistributionClass,
189
190         CustomIdentClass,
191
192         CustomPropertyClass,
193         VariableReferenceClass,
194         PendingSubstitutionValueClass,
195
196         // List class types must appear after ValueListClass. Note CSSFunctionValue
197         // is deliberately excluded, since we don't want it exposed to the CSS OM
198         // as a list.
199         ValueListClass,
200         ImageSetClass,
201         GridLineNamesClass,
202         GridAutoRepeatClass,
203         // Do not append non-list class types here.
204     };
205
206 public:
207     static const size_t ValueListSeparatorBits = 2;
208     enum ValueListSeparator {
209         SpaceSeparator,
210         CommaSeparator,
211         SlashSeparator
212     };
213
214 protected:
215     ClassType classType() const { return static_cast<ClassType>(m_classType); }
216
217     explicit CSSValue(ClassType classType)
218         : m_primitiveUnitType(0)
219         , m_hasCachedCSSText(false)
220         , m_isQuirkValue(false)
221         , m_valueListSeparator(SpaceSeparator)
222         , m_classType(classType)
223     {
224     }
225
226     // NOTE: This class is non-virtual for memory and performance reasons.
227     // Don't go making it virtual again unless you know exactly what you're doing!
228
229     ~CSSValue() = default;
230
231 private:
232     WEBCORE_EXPORT void destroy();
233
234 protected:
235     // The bits in this section are only used by specific subclasses but kept here
236     // to maximize struct packing.
237
238     // CSSPrimitiveValue bits:
239     unsigned m_primitiveUnitType : 7; // CSSPrimitiveValue::UnitType
240     mutable unsigned m_hasCachedCSSText : 1;
241     unsigned m_isQuirkValue : 1;
242
243     unsigned m_valueListSeparator : ValueListSeparatorBits;
244
245 private:
246     unsigned m_classType : ClassTypeBits; // ClassType
247     
248 friend class CSSValueList;
249 };
250
251 template<typename CSSValueType>
252 inline bool compareCSSValueVector(const Vector<Ref<CSSValueType>>& firstVector, const Vector<Ref<CSSValueType>>& secondVector)
253 {
254     size_t size = firstVector.size();
255     if (size != secondVector.size())
256         return false;
257
258     for (size_t i = 0; i < size; ++i) {
259         auto& firstPtr = firstVector[i];
260         auto& secondPtr = secondVector[i];
261         if (firstPtr.ptr() == secondPtr.ptr() || firstPtr->equals(secondPtr))
262             continue;
263         return false;
264     }
265     return true;
266 }
267
268 template<typename CSSValueType>
269 inline bool compareCSSValuePtr(const RefPtr<CSSValueType>& first, const RefPtr<CSSValueType>& second)
270 {
271     return first ? second && first->equals(*second) : !second;
272 }
273
274 template<typename CSSValueType>
275 inline bool compareCSSValue(const Ref<CSSValueType>& first, const Ref<CSSValueType>& second)
276 {
277     return first.get().equals(second);
278 }
279
280 typedef HashMap<AtomicString, RefPtr<CSSCustomPropertyValue>> CustomPropertyValueMap;
281
282 } // namespace WebCore
283
284 #define SPECIALIZE_TYPE_TRAITS_CSS_VALUE(ToValueTypeName, predicate) \
285 SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::ToValueTypeName) \
286     static bool isType(const WebCore::CSSValue& value) { return value.predicate; } \
287 SPECIALIZE_TYPE_TRAITS_END()