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