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