Add support for the frames() timing function
[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 "CSSFontStyleRangeValue.h"
45 #include "CSSFontStyleValue.h"
46 #include "CSSFontValue.h"
47 #include "CSSFontVariationValue.h"
48 #include "CSSFunctionValue.h"
49 #include "CSSGradientValue.h"
50 #include "CSSImageSetValue.h"
51 #include "CSSImageValue.h"
52 #include "CSSInheritedValue.h"
53 #include "CSSInitialValue.h"
54 #include "CSSLineBoxContainValue.h"
55 #include "CSSNamedImageValue.h"
56 #include "CSSPendingSubstitutionValue.h"
57 #include "CSSPrimitiveValue.h"
58 #include "CSSProperty.h"
59 #include "CSSReflectValue.h"
60 #include "CSSShadowValue.h"
61 #include "CSSTimingFunctionValue.h"
62 #include "CSSUnicodeRangeValue.h"
63 #include "CSSUnsetValue.h"
64 #include "CSSValueList.h"
65 #include "CSSVariableReferenceValue.h"
66
67 #include "CSSGridAutoRepeatValue.h"
68 #include "CSSGridLineNamesValue.h"
69 #include "CSSGridTemplateAreasValue.h"
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 WTF::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 ConicGradientClass:
160             return compareCSSValues<CSSConicGradientValue>(*this, other);
161         case CrossfadeClass:
162             return compareCSSValues<CSSCrossfadeValue>(*this, other);
163         case ImageClass:
164             return compareCSSValues<CSSImageValue>(*this, other);
165         case InheritedClass:
166             return compareCSSValues<CSSInheritedValue>(*this, other);
167         case InitialClass:
168             return compareCSSValues<CSSInitialValue>(*this, other);
169         case UnsetClass:
170             return compareCSSValues<CSSUnsetValue>(*this, other);
171         case RevertClass:
172             return compareCSSValues<CSSRevertValue>(*this, other);
173         case GridAutoRepeatClass:
174             return compareCSSValues<CSSGridAutoRepeatValue>(*this, other);
175         case GridLineNamesClass:
176             return compareCSSValues<CSSGridLineNamesValue>(*this, other);
177         case GridTemplateAreasClass:
178             return compareCSSValues<CSSGridTemplateAreasValue>(*this, other);
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 FramesTimingFunctionClass:
190             return compareCSSValues<CSSFramesTimingFunctionValue>(*this, other);
191         case SpringTimingFunctionClass:
192             return compareCSSValues<CSSSpringTimingFunctionValue>(*this, other);
193         case UnicodeRangeClass:
194             return compareCSSValues<CSSUnicodeRangeValue>(*this, other);
195         case ValueListClass:
196             return compareCSSValues<CSSValueList>(*this, other);
197         case LineBoxContainClass:
198             return compareCSSValues<CSSLineBoxContainValue>(*this, other);
199         case CalculationClass:
200             return compareCSSValues<CSSCalcValue>(*this, other);
201         case ImageSetClass:
202             return compareCSSValues<CSSImageSetValue>(*this, other);
203 #if ENABLE(CSS_ANIMATIONS_LEVEL_2)
204         case AnimationTriggerScrollClass:
205             return compareCSSValues<CSSAnimationTriggerScrollValue>(*this, other);
206 #endif
207         case CSSContentDistributionClass:
208             return compareCSSValues<CSSContentDistributionValue>(*this, other);
209         case CustomPropertyClass:
210             return compareCSSValues<CSSCustomPropertyValue>(*this, other);
211         case VariableReferenceClass:
212             return compareCSSValues<CSSVariableReferenceValue>(*this, other);
213         case PendingSubstitutionValueClass:
214             return compareCSSValues<CSSPendingSubstitutionValue>(*this, other);
215         case FontStyleClass:
216             return compareCSSValues<CSSFontStyleValue>(*this, other);
217         case FontStyleRangeClass:
218             return compareCSSValues<CSSFontStyleRangeValue>(*this, other);
219         default:
220             ASSERT_NOT_REACHED();
221             return false;
222         }
223     } else if (is<CSSValueList>(*this) && !is<CSSValueList>(other))
224         return downcast<CSSValueList>(*this).equals(other);
225     else if (!is<CSSValueList>(*this) && is<CSSValueList>(other))
226         return static_cast<const CSSValueList&>(other).equals(*this);
227     return false;
228 }
229
230 String CSSValue::cssText() const
231 {
232     switch (classType()) {
233     case AspectRatioClass:
234         return downcast<CSSAspectRatioValue>(*this).customCSSText();
235     case BorderImageSliceClass:
236         return downcast<CSSBorderImageSliceValue>(*this).customCSSText();
237     case CanvasClass:
238         return downcast<CSSCanvasValue>(*this).customCSSText();
239     case NamedImageClass:
240         return downcast<CSSNamedImageValue>(*this).customCSSText();
241     case CursorImageClass:
242         return downcast<CSSCursorImageValue>(*this).customCSSText();
243     case FilterImageClass:
244         return downcast<CSSFilterImageValue>(*this).customCSSText();
245     case FontClass:
246         return downcast<CSSFontValue>(*this).customCSSText();
247     case FontFaceSrcClass:
248         return downcast<CSSFontFaceSrcValue>(*this).customCSSText();
249     case FontFeatureClass:
250         return downcast<CSSFontFeatureValue>(*this).customCSSText();
251 #if ENABLE(VARIATION_FONTS)
252     case FontVariationClass:
253         return downcast<CSSFontVariationValue>(*this).customCSSText();
254 #endif
255     case FunctionClass:
256         return downcast<CSSFunctionValue>(*this).customCSSText();
257     case LinearGradientClass:
258         return downcast<CSSLinearGradientValue>(*this).customCSSText();
259     case RadialGradientClass:
260         return downcast<CSSRadialGradientValue>(*this).customCSSText();
261     case ConicGradientClass:
262         return downcast<CSSConicGradientValue>(*this).customCSSText();
263     case CrossfadeClass:
264         return downcast<CSSCrossfadeValue>(*this).customCSSText();
265     case ImageClass:
266         return downcast<CSSImageValue>(*this).customCSSText();
267     case InheritedClass:
268         return downcast<CSSInheritedValue>(*this).customCSSText();
269     case InitialClass:
270         return downcast<CSSInitialValue>(*this).customCSSText();
271     case UnsetClass:
272         return downcast<CSSUnsetValue>(*this).customCSSText();
273     case RevertClass:
274         return downcast<CSSRevertValue>(*this).customCSSText();
275     case GridAutoRepeatClass:
276         return downcast<CSSGridAutoRepeatValue>(*this).customCSSText();
277     case GridLineNamesClass:
278         return downcast<CSSGridLineNamesValue>(*this).customCSSText();
279     case GridTemplateAreasClass:
280         return downcast<CSSGridTemplateAreasValue>(*this).customCSSText();
281     case PrimitiveClass:
282         return downcast<CSSPrimitiveValue>(*this).customCSSText();
283     case ReflectClass:
284         return downcast<CSSReflectValue>(*this).customCSSText();
285     case ShadowClass:
286         return downcast<CSSShadowValue>(*this).customCSSText();
287     case CubicBezierTimingFunctionClass:
288         return downcast<CSSCubicBezierTimingFunctionValue>(*this).customCSSText();
289     case StepsTimingFunctionClass:
290         return downcast<CSSStepsTimingFunctionValue>(*this).customCSSText();
291     case FramesTimingFunctionClass:
292         return downcast<CSSFramesTimingFunctionValue>(*this).customCSSText();
293     case SpringTimingFunctionClass:
294         return downcast<CSSSpringTimingFunctionValue>(*this).customCSSText();
295     case UnicodeRangeClass:
296         return downcast<CSSUnicodeRangeValue>(*this).customCSSText();
297     case ValueListClass:
298         return downcast<CSSValueList>(*this).customCSSText();
299     case LineBoxContainClass:
300         return downcast<CSSLineBoxContainValue>(*this).customCSSText();
301     case CalculationClass:
302         return downcast<CSSCalcValue>(*this).customCSSText();
303     case ImageSetClass:
304         return downcast<CSSImageSetValue>(*this).customCSSText();
305 #if ENABLE(CSS_ANIMATIONS_LEVEL_2)
306     case AnimationTriggerScrollClass:
307         return downcast<CSSAnimationTriggerScrollValue>(*this).customCSSText();
308 #endif
309     case CSSContentDistributionClass:
310         return downcast<CSSContentDistributionValue>(*this).customCSSText();
311     case CustomPropertyClass:
312         return downcast<CSSCustomPropertyValue>(*this).customCSSText();
313     case CustomIdentClass:
314         return downcast<CSSCustomIdentValue>(*this).customCSSText();
315     case VariableReferenceClass:
316         return downcast<CSSVariableReferenceValue>(*this).customCSSText();
317     case PendingSubstitutionValueClass:
318         return downcast<CSSPendingSubstitutionValue>(*this).customCSSText();
319     case FontStyleClass:
320         return downcast<CSSFontStyleValue>(*this).customCSSText();
321     case FontStyleRangeClass:
322         return downcast<CSSFontStyleRangeValue>(*this).customCSSText();
323     }
324
325     ASSERT_NOT_REACHED();
326     return String();
327 }
328
329 void CSSValue::destroy()
330 {
331     switch (classType()) {
332     case AspectRatioClass:
333         delete downcast<CSSAspectRatioValue>(this);
334         return;
335     case BorderImageSliceClass:
336         delete downcast<CSSBorderImageSliceValue>(this);
337         return;
338     case CanvasClass:
339         delete downcast<CSSCanvasValue>(this);
340         return;
341     case NamedImageClass:
342         delete downcast<CSSNamedImageValue>(this);
343         return;
344     case CursorImageClass:
345         delete downcast<CSSCursorImageValue>(this);
346         return;
347     case FontClass:
348         delete downcast<CSSFontValue>(this);
349         return;
350     case FontFaceSrcClass:
351         delete downcast<CSSFontFaceSrcValue>(this);
352         return;
353     case FontFeatureClass:
354         delete downcast<CSSFontFeatureValue>(this);
355         return;
356 #if ENABLE(VARIATION_FONTS)
357     case FontVariationClass:
358         delete downcast<CSSFontVariationValue>(this);
359         return;
360 #endif
361     case FunctionClass:
362         delete downcast<CSSFunctionValue>(this);
363         return;
364     case LinearGradientClass:
365         delete downcast<CSSLinearGradientValue>(this);
366         return;
367     case RadialGradientClass:
368         delete downcast<CSSRadialGradientValue>(this);
369         return;
370     case ConicGradientClass:
371         delete downcast<CSSConicGradientValue>(this);
372         return;
373     case CrossfadeClass:
374         delete downcast<CSSCrossfadeValue>(this);
375         return;
376     case ImageClass:
377         delete downcast<CSSImageValue>(this);
378         return;
379     case InheritedClass:
380         delete downcast<CSSInheritedValue>(this);
381         return;
382     case InitialClass:
383         delete downcast<CSSInitialValue>(this);
384         return;
385     case UnsetClass:
386         delete downcast<CSSUnsetValue>(this);
387         return;
388     case RevertClass:
389         delete downcast<CSSRevertValue>(this);
390         return;
391     case GridAutoRepeatClass:
392         delete downcast<CSSGridAutoRepeatValue>(this);
393         return;
394     case GridLineNamesClass:
395         delete downcast<CSSGridLineNamesValue>(this);
396         return;
397     case GridTemplateAreasClass:
398         delete downcast<CSSGridTemplateAreasValue>(this);
399         return;
400     case PrimitiveClass:
401         delete downcast<CSSPrimitiveValue>(this);
402         return;
403     case ReflectClass:
404         delete downcast<CSSReflectValue>(this);
405         return;
406     case ShadowClass:
407         delete downcast<CSSShadowValue>(this);
408         return;
409     case CubicBezierTimingFunctionClass:
410         delete downcast<CSSCubicBezierTimingFunctionValue>(this);
411         return;
412     case StepsTimingFunctionClass:
413         delete downcast<CSSStepsTimingFunctionValue>(this);
414         return;
415     case FramesTimingFunctionClass:
416         delete downcast<CSSFramesTimingFunctionValue>(this);
417         return;
418     case SpringTimingFunctionClass:
419         delete downcast<CSSSpringTimingFunctionValue>(this);
420         return;
421     case UnicodeRangeClass:
422         delete downcast<CSSUnicodeRangeValue>(this);
423         return;
424     case ValueListClass:
425         delete downcast<CSSValueList>(this);
426         return;
427     case LineBoxContainClass:
428         delete downcast<CSSLineBoxContainValue>(this);
429         return;
430     case CalculationClass:
431         delete downcast<CSSCalcValue>(this);
432         return;
433     case ImageSetClass:
434         delete downcast<CSSImageSetValue>(this);
435         return;
436     case FilterImageClass:
437         delete downcast<CSSFilterImageValue>(this);
438         return;
439 #if ENABLE(CSS_ANIMATIONS_LEVEL_2)
440     case AnimationTriggerScrollClass:
441         delete downcast<CSSAnimationTriggerScrollValue>(this);
442         return;
443 #endif
444     case CSSContentDistributionClass:
445         delete downcast<CSSContentDistributionValue>(this);
446         return;
447     case CustomPropertyClass:
448         delete downcast<CSSCustomPropertyValue>(this);
449         return;
450     case CustomIdentClass:
451         delete downcast<CSSCustomIdentValue>(this);
452         return;
453     case VariableReferenceClass:
454         delete downcast<CSSVariableReferenceValue>(this);
455         return;
456     case PendingSubstitutionValueClass:
457         delete downcast<CSSPendingSubstitutionValue>(this);
458         return;
459     case FontStyleClass:
460         delete downcast<CSSFontStyleValue>(this);
461         return;
462     case FontStyleRangeClass:
463         delete downcast<CSSFontStyleRangeValue>(this);
464         return;
465     }
466     ASSERT_NOT_REACHED();
467 }
468
469 Ref<DeprecatedCSSOMValue> CSSValue::createDeprecatedCSSOMWrapper(CSSStyleDeclaration& styleDeclaration) const
470 {
471     if (isImageValue() || isCursorImageValue())
472         return downcast<CSSImageValue>(this)->createDeprecatedCSSOMWrapper(styleDeclaration);
473     if (isPrimitiveValue())
474         return DeprecatedCSSOMPrimitiveValue::create(downcast<CSSPrimitiveValue>(*this), styleDeclaration);
475     if (isValueList())
476         return DeprecatedCSSOMValueList::create(downcast<CSSValueList>(*this), styleDeclaration);
477     return DeprecatedCSSOMComplexValue::create(*this, styleDeclaration);
478 }
479
480 bool CSSValue::treatAsInheritedValue(CSSPropertyID propertyID) const
481 {
482     return classType() == InheritedClass || (classType() == UnsetClass && CSSProperty::isInheritedProperty(propertyID));
483 }
484
485 bool CSSValue::treatAsInitialValue(CSSPropertyID propertyID) const
486 {
487     return classType() == InitialClass || (classType() == UnsetClass && !CSSProperty::isInheritedProperty(propertyID));
488 }
489
490 }