81f49c431752326fc7a33cf34623bb58a70716f9
[WebKit-https.git] / Source / WebCore / css / CSSValue.cpp
1 /*
2  * Copyright (C) 2011 Andreas Kling (kling@webkit.org)
3  * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  *
26  */
27
28 #include "config.h"
29 #include "CSSValue.h"
30
31 #include "CSSAnimationTriggerScrollValue.h"
32 #include "CSSAspectRatioValue.h"
33 #include "CSSBorderImageSliceValue.h"
34 #include "CSSCalculationValue.h"
35 #include "CSSCanvasValue.h"
36 #include "CSSContentDistributionValue.h"
37 #include "CSSCrossfadeValue.h"
38 #include "CSSCursorImageValue.h"
39 #include "CSSCustomIdentValue.h"
40 #include "CSSCustomPropertyValue.h"
41 #include "CSSFilterImageValue.h"
42 #include "CSSFontFaceSrcValue.h"
43 #include "CSSFontFeatureValue.h"
44 #include "CSSFontValue.h"
45 #include "CSSFontVariationValue.h"
46 #include "CSSFunctionValue.h"
47 #include "CSSGradientValue.h"
48 #include "CSSImageSetValue.h"
49 #include "CSSImageValue.h"
50 #include "CSSInheritedValue.h"
51 #include "CSSInitialValue.h"
52 #include "CSSLineBoxContainValue.h"
53 #include "CSSNamedImageValue.h"
54 #include "CSSPendingSubstitutionValue.h"
55 #include "CSSPrimitiveValue.h"
56 #include "CSSProperty.h"
57 #include "CSSReflectValue.h"
58 #include "CSSShadowValue.h"
59 #include "CSSTimingFunctionValue.h"
60 #include "CSSUnicodeRangeValue.h"
61 #include "CSSUnsetValue.h"
62 #include "CSSValueList.h"
63 #include "CSSVariableReferenceValue.h"
64
65 #if ENABLE(CSS_GRID_LAYOUT)
66 #include "CSSGridAutoRepeatValue.h"
67 #include "CSSGridLineNamesValue.h"
68 #include "CSSGridTemplateAreasValue.h"
69 #endif
70
71 #include "DeprecatedCSSOMPrimitiveValue.h"
72 #include "DeprecatedCSSOMValueList.h"
73
74 namespace WebCore {
75
76 struct SameSizeAsCSSValue : public RefCounted<SameSizeAsCSSValue> {
77     uint32_t bitfields;
78 };
79
80 COMPILE_ASSERT(sizeof(CSSValue) == sizeof(SameSizeAsCSSValue), CSS_value_should_stay_small);
81
82 bool CSSValue::isImplicitInitialValue() const
83 {
84     return m_classType == InitialClass && downcast<CSSInitialValue>(*this).isImplicit();
85 }
86
87 CSSValue::Type CSSValue::cssValueType() const
88 {
89     if (isInheritedValue())
90         return CSS_INHERIT;
91     if (isPrimitiveValue())
92         return CSS_PRIMITIVE_VALUE;
93     if (isValueList())
94         return CSS_VALUE_LIST;
95     if (isInitialValue())
96         return CSS_INITIAL;
97     if (isUnsetValue())
98         return CSS_UNSET;
99     if (isRevertValue())
100         return CSS_REVERT;
101     return CSS_CUSTOM;
102 }
103
104 bool CSSValue::traverseSubresources(const std::function<bool (const CachedResource&)>& handler) const
105 {
106     if (is<CSSValueList>(*this))
107         return downcast<CSSValueList>(*this).traverseSubresources(handler);
108     if (is<CSSFontFaceSrcValue>(*this))
109         return downcast<CSSFontFaceSrcValue>(*this).traverseSubresources(handler);
110     if (is<CSSImageValue>(*this))
111         return downcast<CSSImageValue>(*this).traverseSubresources(handler);
112     if (is<CSSCrossfadeValue>(*this))
113         return downcast<CSSCrossfadeValue>(*this).traverseSubresources(handler);
114     if (is<CSSFilterImageValue>(*this))
115         return downcast<CSSFilterImageValue>(*this).traverseSubresources(handler);
116     if (is<CSSImageSetValue>(*this))
117         return downcast<CSSImageSetValue>(*this).traverseSubresources(handler);
118     return false;
119 }
120
121 template<class ChildClassType>
122 inline static bool compareCSSValues(const CSSValue& first, const CSSValue& second)
123 {
124     return static_cast<const ChildClassType&>(first).equals(static_cast<const ChildClassType&>(second));
125 }
126
127 bool CSSValue::equals(const CSSValue& other) const
128 {
129     if (m_classType == other.m_classType) {
130         switch (m_classType) {
131         case AspectRatioClass:
132             return compareCSSValues<CSSAspectRatioValue>(*this, other);
133         case BorderImageSliceClass:
134             return compareCSSValues<CSSBorderImageSliceValue>(*this, other);
135         case CanvasClass:
136             return compareCSSValues<CSSCanvasValue>(*this, other);
137         case NamedImageClass:
138             return compareCSSValues<CSSNamedImageValue>(*this, other);
139         case CursorImageClass:
140             return compareCSSValues<CSSCursorImageValue>(*this, other);
141         case FilterImageClass:
142             return compareCSSValues<CSSFilterImageValue>(*this, other);
143         case FontClass:
144             return compareCSSValues<CSSFontValue>(*this, other);
145         case FontFaceSrcClass:
146             return compareCSSValues<CSSFontFaceSrcValue>(*this, other);
147         case FontFeatureClass:
148             return compareCSSValues<CSSFontFeatureValue>(*this, other);
149 #if ENABLE(VARIATION_FONTS)
150         case FontVariationClass:
151             return compareCSSValues<CSSFontVariationValue>(*this, other);
152 #endif
153         case FunctionClass:
154             return compareCSSValues<CSSFunctionValue>(*this, other);
155         case LinearGradientClass:
156             return compareCSSValues<CSSLinearGradientValue>(*this, other);
157         case RadialGradientClass:
158             return compareCSSValues<CSSRadialGradientValue>(*this, other);
159         case CrossfadeClass:
160             return compareCSSValues<CSSCrossfadeValue>(*this, other);
161         case ImageClass:
162             return compareCSSValues<CSSImageValue>(*this, other);
163         case InheritedClass:
164             return compareCSSValues<CSSInheritedValue>(*this, other);
165         case InitialClass:
166             return compareCSSValues<CSSInitialValue>(*this, other);
167         case UnsetClass:
168             return compareCSSValues<CSSUnsetValue>(*this, other);
169         case RevertClass:
170             return compareCSSValues<CSSRevertValue>(*this, other);
171 #if ENABLE(CSS_GRID_LAYOUT)
172         case GridAutoRepeatClass:
173             return compareCSSValues<CSSGridAutoRepeatValue>(*this, other);
174         case GridLineNamesClass:
175             return compareCSSValues<CSSGridLineNamesValue>(*this, other);
176         case GridTemplateAreasClass:
177             return compareCSSValues<CSSGridTemplateAreasValue>(*this, other);
178 #endif
179         case PrimitiveClass:
180             return compareCSSValues<CSSPrimitiveValue>(*this, other);
181         case ReflectClass:
182             return compareCSSValues<CSSReflectValue>(*this, other);
183         case ShadowClass:
184             return compareCSSValues<CSSShadowValue>(*this, other);
185         case CubicBezierTimingFunctionClass:
186             return compareCSSValues<CSSCubicBezierTimingFunctionValue>(*this, other);
187         case StepsTimingFunctionClass:
188             return compareCSSValues<CSSStepsTimingFunctionValue>(*this, other);
189         case SpringTimingFunctionClass:
190             return compareCSSValues<CSSSpringTimingFunctionValue>(*this, other);
191         case UnicodeRangeClass:
192             return compareCSSValues<CSSUnicodeRangeValue>(*this, other);
193         case ValueListClass:
194             return compareCSSValues<CSSValueList>(*this, other);
195         case LineBoxContainClass:
196             return compareCSSValues<CSSLineBoxContainValue>(*this, other);
197         case CalculationClass:
198             return compareCSSValues<CSSCalcValue>(*this, other);
199         case ImageSetClass:
200             return compareCSSValues<CSSImageSetValue>(*this, other);
201 #if ENABLE(CSS_ANIMATIONS_LEVEL_2)
202         case AnimationTriggerScrollClass:
203             return compareCSSValues<CSSAnimationTriggerScrollValue>(*this, other);
204 #endif
205         case CSSContentDistributionClass:
206             return compareCSSValues<CSSContentDistributionValue>(*this, other);
207         case CustomPropertyClass:
208             return compareCSSValues<CSSCustomPropertyValue>(*this, other);
209         case VariableReferenceClass:
210             return compareCSSValues<CSSVariableReferenceValue>(*this, other);
211         case PendingSubstitutionValueClass:
212             return compareCSSValues<CSSPendingSubstitutionValue>(*this, other);
213         default:
214             ASSERT_NOT_REACHED();
215             return false;
216         }
217     } else if (is<CSSValueList>(*this) && !is<CSSValueList>(other))
218         return downcast<CSSValueList>(*this).equals(other);
219     else if (!is<CSSValueList>(*this) && is<CSSValueList>(other))
220         return static_cast<const CSSValueList&>(other).equals(*this);
221     return false;
222 }
223
224 String CSSValue::cssText() const
225 {
226     switch (classType()) {
227     case AspectRatioClass:
228         return downcast<CSSAspectRatioValue>(*this).customCSSText();
229     case BorderImageSliceClass:
230         return downcast<CSSBorderImageSliceValue>(*this).customCSSText();
231     case CanvasClass:
232         return downcast<CSSCanvasValue>(*this).customCSSText();
233     case NamedImageClass:
234         return downcast<CSSNamedImageValue>(*this).customCSSText();
235     case CursorImageClass:
236         return downcast<CSSCursorImageValue>(*this).customCSSText();
237     case FilterImageClass:
238         return downcast<CSSFilterImageValue>(*this).customCSSText();
239     case FontClass:
240         return downcast<CSSFontValue>(*this).customCSSText();
241     case FontFaceSrcClass:
242         return downcast<CSSFontFaceSrcValue>(*this).customCSSText();
243     case FontFeatureClass:
244         return downcast<CSSFontFeatureValue>(*this).customCSSText();
245 #if ENABLE(VARIATION_FONTS)
246     case FontVariationClass:
247         return downcast<CSSFontVariationValue>(*this).customCSSText();
248 #endif
249     case FunctionClass:
250         return downcast<CSSFunctionValue>(*this).customCSSText();
251     case LinearGradientClass:
252         return downcast<CSSLinearGradientValue>(*this).customCSSText();
253     case RadialGradientClass:
254         return downcast<CSSRadialGradientValue>(*this).customCSSText();
255     case CrossfadeClass:
256         return downcast<CSSCrossfadeValue>(*this).customCSSText();
257     case ImageClass:
258         return downcast<CSSImageValue>(*this).customCSSText();
259     case InheritedClass:
260         return downcast<CSSInheritedValue>(*this).customCSSText();
261     case InitialClass:
262         return downcast<CSSInitialValue>(*this).customCSSText();
263     case UnsetClass:
264         return downcast<CSSUnsetValue>(*this).customCSSText();
265     case RevertClass:
266         return downcast<CSSRevertValue>(*this).customCSSText();
267 #if ENABLE(CSS_GRID_LAYOUT)
268     case GridAutoRepeatClass:
269         return downcast<CSSGridAutoRepeatValue>(*this).customCSSText();
270     case GridLineNamesClass:
271         return downcast<CSSGridLineNamesValue>(*this).customCSSText();
272     case GridTemplateAreasClass:
273         return downcast<CSSGridTemplateAreasValue>(*this).customCSSText();
274 #endif
275     case PrimitiveClass:
276         return downcast<CSSPrimitiveValue>(*this).customCSSText();
277     case ReflectClass:
278         return downcast<CSSReflectValue>(*this).customCSSText();
279     case ShadowClass:
280         return downcast<CSSShadowValue>(*this).customCSSText();
281     case CubicBezierTimingFunctionClass:
282         return downcast<CSSCubicBezierTimingFunctionValue>(*this).customCSSText();
283     case StepsTimingFunctionClass:
284         return downcast<CSSStepsTimingFunctionValue>(*this).customCSSText();
285     case SpringTimingFunctionClass:
286         return downcast<CSSSpringTimingFunctionValue>(*this).customCSSText();
287     case UnicodeRangeClass:
288         return downcast<CSSUnicodeRangeValue>(*this).customCSSText();
289     case ValueListClass:
290         return downcast<CSSValueList>(*this).customCSSText();
291     case LineBoxContainClass:
292         return downcast<CSSLineBoxContainValue>(*this).customCSSText();
293     case CalculationClass:
294         return downcast<CSSCalcValue>(*this).customCSSText();
295     case ImageSetClass:
296         return downcast<CSSImageSetValue>(*this).customCSSText();
297 #if ENABLE(CSS_ANIMATIONS_LEVEL_2)
298     case AnimationTriggerScrollClass:
299         return downcast<CSSAnimationTriggerScrollValue>(*this).customCSSText();
300 #endif
301     case CSSContentDistributionClass:
302         return downcast<CSSContentDistributionValue>(*this).customCSSText();
303     case CustomPropertyClass:
304         return downcast<CSSCustomPropertyValue>(*this).customCSSText();
305     case CustomIdentClass:
306         return downcast<CSSCustomIdentValue>(*this).customCSSText();
307     case VariableReferenceClass:
308         return downcast<CSSVariableReferenceValue>(*this).customCSSText();
309     case PendingSubstitutionValueClass:
310         return downcast<CSSPendingSubstitutionValue>(*this).customCSSText();
311     }
312
313     ASSERT_NOT_REACHED();
314     return String();
315 }
316
317 void CSSValue::destroy()
318 {
319     switch (classType()) {
320     case AspectRatioClass:
321         delete downcast<CSSAspectRatioValue>(this);
322         return;
323     case BorderImageSliceClass:
324         delete downcast<CSSBorderImageSliceValue>(this);
325         return;
326     case CanvasClass:
327         delete downcast<CSSCanvasValue>(this);
328         return;
329     case NamedImageClass:
330         delete downcast<CSSNamedImageValue>(this);
331         return;
332     case CursorImageClass:
333         delete downcast<CSSCursorImageValue>(this);
334         return;
335     case FontClass:
336         delete downcast<CSSFontValue>(this);
337         return;
338     case FontFaceSrcClass:
339         delete downcast<CSSFontFaceSrcValue>(this);
340         return;
341     case FontFeatureClass:
342         delete downcast<CSSFontFeatureValue>(this);
343         return;
344 #if ENABLE(VARIATION_FONTS)
345     case FontVariationClass:
346         delete downcast<CSSFontVariationValue>(this);
347         return;
348 #endif
349     case FunctionClass:
350         delete downcast<CSSFunctionValue>(this);
351         return;
352     case LinearGradientClass:
353         delete downcast<CSSLinearGradientValue>(this);
354         return;
355     case RadialGradientClass:
356         delete downcast<CSSRadialGradientValue>(this);
357         return;
358     case CrossfadeClass:
359         delete downcast<CSSCrossfadeValue>(this);
360         return;
361     case ImageClass:
362         delete downcast<CSSImageValue>(this);
363         return;
364     case InheritedClass:
365         delete downcast<CSSInheritedValue>(this);
366         return;
367     case InitialClass:
368         delete downcast<CSSInitialValue>(this);
369         return;
370     case UnsetClass:
371         delete downcast<CSSUnsetValue>(this);
372         return;
373     case RevertClass:
374         delete downcast<CSSRevertValue>(this);
375         return;
376 #if ENABLE(CSS_GRID_LAYOUT)
377     case GridAutoRepeatClass:
378         delete downcast<CSSGridAutoRepeatValue>(this);
379         return;
380     case GridLineNamesClass:
381         delete downcast<CSSGridLineNamesValue>(this);
382         return;
383     case GridTemplateAreasClass:
384         delete downcast<CSSGridTemplateAreasValue>(this);
385         return;
386 #endif
387     case PrimitiveClass:
388         delete downcast<CSSPrimitiveValue>(this);
389         return;
390     case ReflectClass:
391         delete downcast<CSSReflectValue>(this);
392         return;
393     case ShadowClass:
394         delete downcast<CSSShadowValue>(this);
395         return;
396     case CubicBezierTimingFunctionClass:
397         delete downcast<CSSCubicBezierTimingFunctionValue>(this);
398         return;
399     case StepsTimingFunctionClass:
400         delete downcast<CSSStepsTimingFunctionValue>(this);
401         return;
402     case SpringTimingFunctionClass:
403         delete downcast<CSSSpringTimingFunctionValue>(this);
404         return;
405     case UnicodeRangeClass:
406         delete downcast<CSSUnicodeRangeValue>(this);
407         return;
408     case ValueListClass:
409         delete downcast<CSSValueList>(this);
410         return;
411     case LineBoxContainClass:
412         delete downcast<CSSLineBoxContainValue>(this);
413         return;
414     case CalculationClass:
415         delete downcast<CSSCalcValue>(this);
416         return;
417     case ImageSetClass:
418         delete downcast<CSSImageSetValue>(this);
419         return;
420     case FilterImageClass:
421         delete downcast<CSSFilterImageValue>(this);
422         return;
423 #if ENABLE(CSS_ANIMATIONS_LEVEL_2)
424     case AnimationTriggerScrollClass:
425         delete downcast<CSSAnimationTriggerScrollValue>(this);
426         return;
427 #endif
428     case CSSContentDistributionClass:
429         delete downcast<CSSContentDistributionValue>(this);
430         return;
431     case CustomPropertyClass:
432         delete downcast<CSSCustomPropertyValue>(this);
433         return;
434     case CustomIdentClass:
435         delete downcast<CSSCustomIdentValue>(this);
436         return;
437     case VariableReferenceClass:
438         delete downcast<CSSVariableReferenceValue>(this);
439         return;
440     case PendingSubstitutionValueClass:
441         delete downcast<CSSPendingSubstitutionValue>(this);
442         return;
443     }
444     ASSERT_NOT_REACHED();
445 }
446
447 Ref<DeprecatedCSSOMValue> CSSValue::createDeprecatedCSSOMWrapper() const
448 {
449     if (isImageValue() || isCursorImageValue())
450         return downcast<CSSImageValue>(this)->createDeprecatedCSSOMWrapper();
451     if (isPrimitiveValue())
452         return DeprecatedCSSOMPrimitiveValue::create(downcast<CSSPrimitiveValue>(*this));
453     if (isValueList())
454         return DeprecatedCSSOMValueList::create(downcast<CSSValueList>(*this));
455     return DeprecatedCSSOMComplexValue::create(*this);
456 }
457
458 bool CSSValue::treatAsInheritedValue(CSSPropertyID propertyID) const
459 {
460     return classType() == InheritedClass || (classType() == UnsetClass && CSSProperty::isInheritedProperty(propertyID));
461 }
462
463 bool CSSValue::treatAsInitialValue(CSSPropertyID propertyID) const
464 {
465     return classType() == InitialClass || (classType() == UnsetClass && !CSSProperty::isInheritedProperty(propertyID));
466 }
467
468 }