[css-grid] Add parsing support for <auto-repeat> syntax
[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 "CSSCustomPropertyValue.h"
40 #include "CSSFilterImageValue.h"
41 #include "CSSFontFaceSrcValue.h"
42 #include "CSSFontFeatureValue.h"
43 #include "CSSFontValue.h"
44 #include "CSSFunctionValue.h"
45 #include "CSSGradientValue.h"
46 #include "CSSImageSetValue.h"
47 #include "CSSImageValue.h"
48 #include "CSSInheritedValue.h"
49 #include "CSSInitialValue.h"
50 #include "CSSLineBoxContainValue.h"
51 #include "CSSNamedImageValue.h"
52 #include "CSSPrimitiveValue.h"
53 #include "CSSProperty.h"
54 #include "CSSReflectValue.h"
55 #include "CSSShadowValue.h"
56 #include "CSSTimingFunctionValue.h"
57 #include "CSSUnicodeRangeValue.h"
58 #include "CSSUnsetValue.h"
59 #include "CSSValueList.h"
60 #include "CSSVariableDependentValue.h"
61 #include "CSSVariableValue.h"
62 #include "SVGColor.h"
63 #include "SVGPaint.h"
64 #include "WebKitCSSFilterValue.h"
65 #include "WebKitCSSTransformValue.h"
66
67 #if ENABLE(CSS_GRID_LAYOUT)
68 #include "CSSGridAutoRepeatValue.h"
69 #include "CSSGridLineNamesValue.h"
70 #include "CSSGridTemplateAreasValue.h"
71 #endif
72
73 namespace WebCore {
74
75 struct SameSizeAsCSSValue : public RefCounted<SameSizeAsCSSValue> {
76     uint32_t bitfields;
77 };
78
79 COMPILE_ASSERT(sizeof(CSSValue) == sizeof(SameSizeAsCSSValue), CSS_value_should_stay_small);
80
81 class TextCloneCSSValue : public CSSValue {
82 public:
83     static Ref<TextCloneCSSValue> create(ClassType classType, const String& text)
84     {
85         return adoptRef(*new TextCloneCSSValue(classType, text));
86     }
87
88     String cssText() const { return m_cssText; }
89
90 private:
91     TextCloneCSSValue(ClassType classType, const String& text) 
92         : CSSValue(classType, /*isCSSOMSafe*/ true)
93         , m_cssText(text)
94     {
95         m_isTextClone = true;
96     }
97
98     String m_cssText;
99 };
100
101 bool CSSValue::isImplicitInitialValue() const
102 {
103     return m_classType == InitialClass && downcast<CSSInitialValue>(*this).isImplicit();
104 }
105
106 CSSValue::Type CSSValue::cssValueType() const
107 {
108     if (isInheritedValue())
109         return CSS_INHERIT;
110     if (isPrimitiveValue())
111         return CSS_PRIMITIVE_VALUE;
112     if (isValueList())
113         return CSS_VALUE_LIST;
114     if (isInitialValue())
115         return CSS_INITIAL;
116     if (isUnsetValue())
117         return CSS_UNSET;
118     if (isRevertValue())
119         return CSS_REVERT;
120     return CSS_CUSTOM;
121 }
122
123 void CSSValue::addSubresourceStyleURLs(ListHashSet<URL>& urls, const StyleSheetContents* styleSheet) const
124 {
125     // This should get called for internal instances only.
126     ASSERT(!isCSSOMSafe());
127
128     if (is<CSSPrimitiveValue>(*this))
129         downcast<CSSPrimitiveValue>(*this).addSubresourceStyleURLs(urls, styleSheet);
130     else if (is<CSSValueList>(*this))
131         downcast<CSSValueList>(*this).addSubresourceStyleURLs(urls, styleSheet);
132     else if (is<CSSFontFaceSrcValue>(*this))
133         downcast<CSSFontFaceSrcValue>(*this).addSubresourceStyleURLs(urls, styleSheet);
134     else if (is<CSSReflectValue>(*this))
135         downcast<CSSReflectValue>(*this).addSubresourceStyleURLs(urls, styleSheet);
136 }
137
138 bool CSSValue::traverseSubresources(const std::function<bool (const CachedResource&)>& handler) const
139 {
140     // This should get called for internal instances only.
141     ASSERT(!isCSSOMSafe());
142
143     if (is<CSSValueList>(*this))
144         return downcast<CSSValueList>(*this).traverseSubresources(handler);
145     if (is<CSSFontFaceSrcValue>(*this))
146         return downcast<CSSFontFaceSrcValue>(*this).traverseSubresources(handler);
147     if (is<CSSImageValue>(*this))
148         return downcast<CSSImageValue>(*this).traverseSubresources(handler);
149     if (is<CSSCrossfadeValue>(*this))
150         return downcast<CSSCrossfadeValue>(*this).traverseSubresources(handler);
151     if (is<CSSFilterImageValue>(*this))
152         return downcast<CSSFilterImageValue>(*this).traverseSubresources(handler);
153 #if ENABLE(CSS_IMAGE_SET)
154     if (is<CSSImageSetValue>(*this))
155         return downcast<CSSImageSetValue>(*this).traverseSubresources(handler);
156 #endif
157     return false;
158 }
159
160 template<class ChildClassType>
161 inline static bool compareCSSValues(const CSSValue& first, const CSSValue& second)
162 {
163     return static_cast<const ChildClassType&>(first).equals(static_cast<const ChildClassType&>(second));
164 }
165
166 bool CSSValue::equals(const CSSValue& other) const
167 {
168     if (m_isTextClone) {
169         ASSERT(isCSSOMSafe());
170         return static_cast<const TextCloneCSSValue*>(this)->cssText() == other.cssText();
171     }
172
173     if (m_classType == other.m_classType) {
174         switch (m_classType) {
175         case AspectRatioClass:
176             return compareCSSValues<CSSAspectRatioValue>(*this, other);
177         case BorderImageSliceClass:
178             return compareCSSValues<CSSBorderImageSliceValue>(*this, other);
179         case CanvasClass:
180             return compareCSSValues<CSSCanvasValue>(*this, other);
181         case NamedImageClass:
182             return compareCSSValues<CSSNamedImageValue>(*this, other);
183         case CursorImageClass:
184             return compareCSSValues<CSSCursorImageValue>(*this, other);
185         case FilterImageClass:
186             return compareCSSValues<CSSFilterImageValue>(*this, other);
187         case FontClass:
188             return compareCSSValues<CSSFontValue>(*this, other);
189         case FontFaceSrcClass:
190             return compareCSSValues<CSSFontFaceSrcValue>(*this, other);
191         case FontFeatureClass:
192             return compareCSSValues<CSSFontFeatureValue>(*this, other);
193         case FunctionClass:
194             return compareCSSValues<CSSFunctionValue>(*this, other);
195         case LinearGradientClass:
196             return compareCSSValues<CSSLinearGradientValue>(*this, other);
197         case RadialGradientClass:
198             return compareCSSValues<CSSRadialGradientValue>(*this, other);
199         case CrossfadeClass:
200             return compareCSSValues<CSSCrossfadeValue>(*this, other);
201         case ImageClass:
202             return compareCSSValues<CSSImageValue>(*this, other);
203         case InheritedClass:
204             return compareCSSValues<CSSInheritedValue>(*this, other);
205         case InitialClass:
206             return compareCSSValues<CSSInitialValue>(*this, other);
207         case UnsetClass:
208             return compareCSSValues<CSSUnsetValue>(*this, other);
209         case RevertClass:
210             return compareCSSValues<CSSRevertValue>(*this, other);
211 #if ENABLE(CSS_GRID_LAYOUT)
212         case GridAutoRepeatClass:
213             return compareCSSValues<CSSGridAutoRepeatValue>(*this, other);
214         case GridLineNamesClass:
215             return compareCSSValues<CSSGridLineNamesValue>(*this, other);
216         case GridTemplateAreasClass:
217             return compareCSSValues<CSSGridTemplateAreasValue>(*this, other);
218 #endif
219         case PrimitiveClass:
220             return compareCSSValues<CSSPrimitiveValue>(*this, other);
221         case ReflectClass:
222             return compareCSSValues<CSSReflectValue>(*this, other);
223         case ShadowClass:
224             return compareCSSValues<CSSShadowValue>(*this, other);
225         case CubicBezierTimingFunctionClass:
226             return compareCSSValues<CSSCubicBezierTimingFunctionValue>(*this, other);
227         case StepsTimingFunctionClass:
228             return compareCSSValues<CSSStepsTimingFunctionValue>(*this, other);
229         case UnicodeRangeClass:
230             return compareCSSValues<CSSUnicodeRangeValue>(*this, other);
231         case ValueListClass:
232             return compareCSSValues<CSSValueList>(*this, other);
233         case WebKitCSSTransformClass:
234             return compareCSSValues<WebKitCSSTransformValue>(*this, other);
235         case LineBoxContainClass:
236             return compareCSSValues<CSSLineBoxContainValue>(*this, other);
237         case CalculationClass:
238             return compareCSSValues<CSSCalcValue>(*this, other);
239 #if ENABLE(CSS_IMAGE_SET)
240         case ImageSetClass:
241             return compareCSSValues<CSSImageSetValue>(*this, other);
242 #endif
243         case WebKitCSSFilterClass:
244             return compareCSSValues<WebKitCSSFilterValue>(*this, other);
245         case SVGColorClass:
246             return compareCSSValues<SVGColor>(*this, other);
247         case SVGPaintClass:
248             return compareCSSValues<SVGPaint>(*this, other);
249 #if ENABLE(CSS_ANIMATIONS_LEVEL_2)
250         case AnimationTriggerScrollClass:
251             return compareCSSValues<CSSAnimationTriggerScrollValue>(*this, other);
252 #endif
253         case CSSContentDistributionClass:
254             return compareCSSValues<CSSContentDistributionValue>(*this, other);
255         case CustomPropertyClass:
256             return compareCSSValues<CSSCustomPropertyValue>(*this, other);
257         case VariableDependentClass:
258             return compareCSSValues<CSSVariableDependentValue>(*this, other);
259         case VariableClass:
260             return compareCSSValues<CSSVariableValue>(*this, other);
261         default:
262             ASSERT_NOT_REACHED();
263             return false;
264         }
265     } else if (is<CSSValueList>(*this) && !is<CSSValueList>(other))
266         return downcast<CSSValueList>(*this).equals(other);
267     else if (!is<CSSValueList>(*this) && is<CSSValueList>(other))
268         return static_cast<const CSSValueList&>(other).equals(*this);
269     return false;
270 }
271
272 String CSSValue::cssText() const
273 {
274     if (m_isTextClone) {
275          ASSERT(isCSSOMSafe());
276         return static_cast<const TextCloneCSSValue*>(this)->cssText();
277     }
278     ASSERT(!isCSSOMSafe() || isSubtypeExposedToCSSOM());
279
280     switch (classType()) {
281     case AspectRatioClass:
282         return downcast<CSSAspectRatioValue>(*this).customCSSText();
283     case BorderImageSliceClass:
284         return downcast<CSSBorderImageSliceValue>(*this).customCSSText();
285     case CanvasClass:
286         return downcast<CSSCanvasValue>(*this).customCSSText();
287     case NamedImageClass:
288         return downcast<CSSNamedImageValue>(*this).customCSSText();
289     case CursorImageClass:
290         return downcast<CSSCursorImageValue>(*this).customCSSText();
291     case FilterImageClass:
292         return downcast<CSSFilterImageValue>(*this).customCSSText();
293     case FontClass:
294         return downcast<CSSFontValue>(*this).customCSSText();
295     case FontFaceSrcClass:
296         return downcast<CSSFontFaceSrcValue>(*this).customCSSText();
297     case FontFeatureClass:
298         return downcast<CSSFontFeatureValue>(*this).customCSSText();
299     case FunctionClass:
300         return downcast<CSSFunctionValue>(*this).customCSSText();
301     case LinearGradientClass:
302         return downcast<CSSLinearGradientValue>(*this).customCSSText();
303     case RadialGradientClass:
304         return downcast<CSSRadialGradientValue>(*this).customCSSText();
305     case CrossfadeClass:
306         return downcast<CSSCrossfadeValue>(*this).customCSSText();
307     case ImageClass:
308         return downcast<CSSImageValue>(*this).customCSSText();
309     case InheritedClass:
310         return downcast<CSSInheritedValue>(*this).customCSSText();
311     case InitialClass:
312         return downcast<CSSInitialValue>(*this).customCSSText();
313     case UnsetClass:
314         return downcast<CSSUnsetValue>(*this).customCSSText();
315     case RevertClass:
316         return downcast<CSSRevertValue>(*this).customCSSText();
317 #if ENABLE(CSS_GRID_LAYOUT)
318     case GridAutoRepeatClass:
319         return downcast<CSSGridAutoRepeatValue>(*this).customCSSText();
320     case GridLineNamesClass:
321         return downcast<CSSGridLineNamesValue>(*this).customCSSText();
322     case GridTemplateAreasClass:
323         return downcast<CSSGridTemplateAreasValue>(*this).customCSSText();
324 #endif
325     case PrimitiveClass:
326         return downcast<CSSPrimitiveValue>(*this).customCSSText();
327     case ReflectClass:
328         return downcast<CSSReflectValue>(*this).customCSSText();
329     case ShadowClass:
330         return downcast<CSSShadowValue>(*this).customCSSText();
331     case CubicBezierTimingFunctionClass:
332         return downcast<CSSCubicBezierTimingFunctionValue>(*this).customCSSText();
333     case StepsTimingFunctionClass:
334         return downcast<CSSStepsTimingFunctionValue>(*this).customCSSText();
335     case UnicodeRangeClass:
336         return downcast<CSSUnicodeRangeValue>(*this).customCSSText();
337     case ValueListClass:
338         return downcast<CSSValueList>(*this).customCSSText();
339     case WebKitCSSTransformClass:
340         return downcast<WebKitCSSTransformValue>(*this).customCSSText();
341     case LineBoxContainClass:
342         return downcast<CSSLineBoxContainValue>(*this).customCSSText();
343     case CalculationClass:
344         return downcast<CSSCalcValue>(*this).customCSSText();
345 #if ENABLE(CSS_IMAGE_SET)
346     case ImageSetClass:
347         return downcast<CSSImageSetValue>(*this).customCSSText();
348 #endif
349     case WebKitCSSFilterClass:
350         return downcast<WebKitCSSFilterValue>(*this).customCSSText();
351     case SVGColorClass:
352         return downcast<SVGColor>(*this).customCSSText();
353     case SVGPaintClass:
354         return downcast<SVGPaint>(*this).customCSSText();
355 #if ENABLE(CSS_ANIMATIONS_LEVEL_2)
356     case AnimationTriggerScrollClass:
357         return downcast<CSSAnimationTriggerScrollValue>(*this).customCSSText();
358 #endif
359     case CSSContentDistributionClass:
360         return downcast<CSSContentDistributionValue>(*this).customCSSText();
361     case CustomPropertyClass:
362         return downcast<CSSCustomPropertyValue>(*this).customCSSText();
363     case VariableDependentClass:
364         return downcast<CSSVariableDependentValue>(*this).customCSSText();
365     case VariableClass:
366         return downcast<CSSVariableValue>(*this).customCSSText();
367     }
368
369     ASSERT_NOT_REACHED();
370     return String();
371 }
372
373 void CSSValue::destroy()
374 {
375     if (m_isTextClone) {
376         ASSERT(isCSSOMSafe());
377         delete static_cast<TextCloneCSSValue*>(this);
378         return;
379     }
380     ASSERT(!isCSSOMSafe() || isSubtypeExposedToCSSOM());
381
382     switch (classType()) {
383     case AspectRatioClass:
384         delete downcast<CSSAspectRatioValue>(this);
385         return;
386     case BorderImageSliceClass:
387         delete downcast<CSSBorderImageSliceValue>(this);
388         return;
389     case CanvasClass:
390         delete downcast<CSSCanvasValue>(this);
391         return;
392     case NamedImageClass:
393         delete downcast<CSSNamedImageValue>(this);
394         return;
395     case CursorImageClass:
396         delete downcast<CSSCursorImageValue>(this);
397         return;
398     case FontClass:
399         delete downcast<CSSFontValue>(this);
400         return;
401     case FontFaceSrcClass:
402         delete downcast<CSSFontFaceSrcValue>(this);
403         return;
404     case FontFeatureClass:
405         delete downcast<CSSFontFeatureValue>(this);
406         return;
407     case FunctionClass:
408         delete downcast<CSSFunctionValue>(this);
409         return;
410     case LinearGradientClass:
411         delete downcast<CSSLinearGradientValue>(this);
412         return;
413     case RadialGradientClass:
414         delete downcast<CSSRadialGradientValue>(this);
415         return;
416     case CrossfadeClass:
417         delete downcast<CSSCrossfadeValue>(this);
418         return;
419     case ImageClass:
420         delete downcast<CSSImageValue>(this);
421         return;
422     case InheritedClass:
423         delete downcast<CSSInheritedValue>(this);
424         return;
425     case InitialClass:
426         delete downcast<CSSInitialValue>(this);
427         return;
428     case UnsetClass:
429         delete downcast<CSSUnsetValue>(this);
430         return;
431     case RevertClass:
432         delete downcast<CSSRevertValue>(this);
433         return;
434 #if ENABLE(CSS_GRID_LAYOUT)
435     case GridAutoRepeatClass:
436         delete downcast<CSSGridAutoRepeatValue>(this);
437         return;
438     case GridLineNamesClass:
439         delete downcast<CSSGridLineNamesValue>(this);
440         return;
441     case GridTemplateAreasClass:
442         delete downcast<CSSGridTemplateAreasValue>(this);
443         return;
444 #endif
445     case PrimitiveClass:
446         delete downcast<CSSPrimitiveValue>(this);
447         return;
448     case ReflectClass:
449         delete downcast<CSSReflectValue>(this);
450         return;
451     case ShadowClass:
452         delete downcast<CSSShadowValue>(this);
453         return;
454     case CubicBezierTimingFunctionClass:
455         delete downcast<CSSCubicBezierTimingFunctionValue>(this);
456         return;
457     case StepsTimingFunctionClass:
458         delete downcast<CSSStepsTimingFunctionValue>(this);
459         return;
460     case UnicodeRangeClass:
461         delete downcast<CSSUnicodeRangeValue>(this);
462         return;
463     case ValueListClass:
464         delete downcast<CSSValueList>(this);
465         return;
466     case WebKitCSSTransformClass:
467         delete downcast<WebKitCSSTransformValue>(this);
468         return;
469     case LineBoxContainClass:
470         delete downcast<CSSLineBoxContainValue>(this);
471         return;
472     case CalculationClass:
473         delete downcast<CSSCalcValue>(this);
474         return;
475 #if ENABLE(CSS_IMAGE_SET)
476     case ImageSetClass:
477         delete downcast<CSSImageSetValue>(this);
478         return;
479 #endif
480     case FilterImageClass:
481         delete downcast<CSSFilterImageValue>(this);
482         return;
483     case WebKitCSSFilterClass:
484         delete downcast<WebKitCSSFilterValue>(this);
485         return;
486     case SVGColorClass:
487         delete downcast<SVGColor>(this);
488         return;
489     case SVGPaintClass:
490         delete downcast<SVGPaint>(this);
491         return;
492 #if ENABLE(CSS_ANIMATIONS_LEVEL_2)
493     case AnimationTriggerScrollClass:
494         delete downcast<CSSAnimationTriggerScrollValue>(this);
495         return;
496 #endif
497     case CSSContentDistributionClass:
498         delete downcast<CSSContentDistributionValue>(this);
499         return;
500     case CustomPropertyClass:
501         delete downcast<CSSCustomPropertyValue>(this);
502         return;
503     case VariableDependentClass:
504         delete downcast<CSSVariableDependentValue>(this);
505         return;
506     case VariableClass:
507         delete downcast<CSSVariableValue>(this);
508         return;
509     }
510     ASSERT_NOT_REACHED();
511 }
512
513 RefPtr<CSSValue> CSSValue::cloneForCSSOM() const
514 {
515     switch (classType()) {
516     case PrimitiveClass:
517         return downcast<CSSPrimitiveValue>(*this).cloneForCSSOM();
518     case ValueListClass:
519         return downcast<CSSValueList>(*this).cloneForCSSOM();
520     case ImageClass:
521     case CursorImageClass:
522         return downcast<CSSImageValue>(*this).cloneForCSSOM();
523     case WebKitCSSFilterClass:
524         return downcast<WebKitCSSFilterValue>(*this).cloneForCSSOM();
525     case WebKitCSSTransformClass:
526         return downcast<WebKitCSSTransformValue>(*this).cloneForCSSOM();
527 #if ENABLE(CSS_IMAGE_SET)
528     case ImageSetClass:
529         return downcast<CSSImageSetValue>(*this).cloneForCSSOM();
530 #endif
531     case SVGColorClass:
532         return downcast<SVGColor>(*this).cloneForCSSOM();
533     case SVGPaintClass:
534         return downcast<SVGPaint>(*this).cloneForCSSOM();
535     default:
536         ASSERT(!isSubtypeExposedToCSSOM());
537         return TextCloneCSSValue::create(classType(), cssText());
538     }
539 }
540
541 bool CSSValue::isInvalidCustomPropertyValue() const
542 {
543     return isCustomPropertyValue() && downcast<CSSCustomPropertyValue>(*this).isInvalid();
544 }
545
546 bool CSSValue::treatAsInheritedValue(CSSPropertyID propertyID) const
547 {
548     return classType() == InheritedClass || (classType() == UnsetClass && CSSProperty::isInheritedProperty(propertyID));
549 }
550
551 bool CSSValue::treatAsInitialValue(CSSPropertyID propertyID) const
552 {
553     return classType() == InitialClass || (classType() == UnsetClass && !CSSProperty::isInheritedProperty(propertyID));
554 }
555
556 }