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