• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 Andreas Kling (kling@webkit.org)
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  *
25  */
26 
27 #include "config.h"
28 #include "core/css/CSSValue.h"
29 
30 #include "core/css/CSSArrayFunctionValue.h"
31 #include "core/css/CSSAspectRatioValue.h"
32 #include "core/css/CSSBorderImageSliceValue.h"
33 #include "core/css/CSSCalculationValue.h"
34 #include "core/css/CSSCanvasValue.h"
35 #include "core/css/CSSCrossfadeValue.h"
36 #include "core/css/CSSCursorImageValue.h"
37 #include "core/css/CSSFilterValue.h"
38 #include "core/css/CSSFontFaceSrcValue.h"
39 #include "core/css/CSSFontFeatureValue.h"
40 #include "core/css/CSSFontValue.h"
41 #include "core/css/CSSFunctionValue.h"
42 #include "core/css/CSSGradientValue.h"
43 #include "core/css/CSSGridLineNamesValue.h"
44 #include "core/css/CSSGridTemplateValue.h"
45 #include "core/css/CSSImageSetValue.h"
46 #include "core/css/CSSImageValue.h"
47 #include "core/css/CSSInheritedValue.h"
48 #include "core/css/CSSInitialValue.h"
49 #include "core/css/CSSLineBoxContainValue.h"
50 #include "core/css/CSSMixFunctionValue.h"
51 #include "core/css/CSSPrimitiveValue.h"
52 #include "core/css/CSSReflectValue.h"
53 #include "core/css/CSSSVGDocumentValue.h"
54 #include "core/css/CSSShaderValue.h"
55 #include "core/css/CSSShadowValue.h"
56 #include "core/css/CSSTimingFunctionValue.h"
57 #include "core/css/CSSTransformValue.h"
58 #include "core/css/CSSUnicodeRangeValue.h"
59 #include "core/css/CSSValueList.h"
60 #include "core/css/CSSVariableValue.h"
61 #include "core/svg/SVGColor.h"
62 #include "core/svg/SVGPaint.h"
63 
64 namespace WebCore {
65 
66 struct SameSizeAsCSSValue : public RefCounted<SameSizeAsCSSValue> {
67     uint32_t bitfields;
68 };
69 
70 COMPILE_ASSERT(sizeof(CSSValue) <= sizeof(SameSizeAsCSSValue), CSS_value_should_stay_small);
71 
72 class TextCloneCSSValue : public CSSValue {
73 public:
create(ClassType classType,const String & text)74     static PassRefPtr<TextCloneCSSValue> create(ClassType classType, const String& text) { return adoptRef(new TextCloneCSSValue(classType, text)); }
75 
cssText() const76     String cssText() const { return m_cssText; }
77 
78 private:
TextCloneCSSValue(ClassType classType,const String & text)79     TextCloneCSSValue(ClassType classType, const String& text)
80         : CSSValue(classType, /*isCSSOMSafe*/ true)
81         , m_cssText(text)
82     {
83         m_isTextClone = true;
84     }
85 
86     String m_cssText;
87 };
88 
89 DEFINE_CSS_VALUE_TYPE_CASTS(TextCloneCSSValue, isTextCloneCSSValue());
90 
isImplicitInitialValue() const91 bool CSSValue::isImplicitInitialValue() const
92 {
93     return m_classType == InitialClass && toCSSInitialValue(this)->isImplicit();
94 }
95 
cssValueType() const96 CSSValue::Type CSSValue::cssValueType() const
97 {
98     if (isInheritedValue())
99         return CSS_INHERIT;
100     if (isPrimitiveValue())
101         return CSS_PRIMITIVE_VALUE;
102     if (isValueList())
103         return CSS_VALUE_LIST;
104     if (isInitialValue())
105         return CSS_INITIAL;
106     return CSS_CUSTOM;
107 }
108 
addSubresourceStyleURLs(ListHashSet<KURL> & urls,const StyleSheetContents * styleSheet) const109 void CSSValue::addSubresourceStyleURLs(ListHashSet<KURL>& urls, const StyleSheetContents* styleSheet) const
110 {
111     // This should get called for internal instances only.
112     ASSERT(!isCSSOMSafe());
113 
114     if (isPrimitiveValue())
115         toCSSPrimitiveValue(this)->addSubresourceStyleURLs(urls, styleSheet);
116     else if (isValueList())
117         toCSSValueList(this)->addSubresourceStyleURLs(urls, styleSheet);
118     else if (classType() == FontFaceSrcClass)
119         toCSSFontFaceSrcValue(this)->addSubresourceStyleURLs(urls, styleSheet);
120     else if (classType() == ReflectClass)
121         toCSSReflectValue(this)->addSubresourceStyleURLs(urls, styleSheet);
122 }
123 
hasFailedOrCanceledSubresources() const124 bool CSSValue::hasFailedOrCanceledSubresources() const
125 {
126     // This should get called for internal instances only.
127     ASSERT(!isCSSOMSafe());
128 
129     if (isValueList())
130         return toCSSValueList(this)->hasFailedOrCanceledSubresources();
131     if (classType() == FontFaceSrcClass)
132         return toCSSFontFaceSrcValue(this)->hasFailedOrCanceledSubresources();
133     if (classType() == ImageClass)
134         return toCSSImageValue(this)->hasFailedOrCanceledSubresources();
135     if (classType() == CrossfadeClass)
136         return toCSSCrossfadeValue(this)->hasFailedOrCanceledSubresources();
137     if (classType() == ImageSetClass)
138         return toCSSImageSetValue(this)->hasFailedOrCanceledSubresources();
139 
140     return false;
141 }
142 
143 template<class ChildClassType>
compareCSSValues(const CSSValue & first,const CSSValue & second)144 inline static bool compareCSSValues(const CSSValue& first, const CSSValue& second)
145 {
146     return static_cast<const ChildClassType&>(first).equals(static_cast<const ChildClassType&>(second));
147 }
148 
equals(const CSSValue & other) const149 bool CSSValue::equals(const CSSValue& other) const
150 {
151     if (m_isTextClone) {
152         ASSERT(isCSSOMSafe());
153         return toTextCloneCSSValue(this)->cssText() == other.cssText();
154     }
155 
156     if (m_classType == other.m_classType) {
157         switch (m_classType) {
158         case AspectRatioClass:
159             return compareCSSValues<CSSAspectRatioValue>(*this, other);
160         case BorderImageSliceClass:
161             return compareCSSValues<CSSBorderImageSliceValue>(*this, other);
162         case CanvasClass:
163             return compareCSSValues<CSSCanvasValue>(*this, other);
164         case CursorImageClass:
165             return compareCSSValues<CSSCursorImageValue>(*this, other);
166         case FontClass:
167             return compareCSSValues<CSSFontValue>(*this, other);
168         case FontFaceSrcClass:
169             return compareCSSValues<CSSFontFaceSrcValue>(*this, other);
170         case FontFeatureClass:
171             return compareCSSValues<CSSFontFeatureValue>(*this, other);
172         case FunctionClass:
173             return compareCSSValues<CSSFunctionValue>(*this, other);
174         case LinearGradientClass:
175             return compareCSSValues<CSSLinearGradientValue>(*this, other);
176         case RadialGradientClass:
177             return compareCSSValues<CSSRadialGradientValue>(*this, other);
178         case CrossfadeClass:
179             return compareCSSValues<CSSCrossfadeValue>(*this, other);
180         case ImageClass:
181             return compareCSSValues<CSSImageValue>(*this, other);
182         case InheritedClass:
183             return compareCSSValues<CSSInheritedValue>(*this, other);
184         case InitialClass:
185             return compareCSSValues<CSSInitialValue>(*this, other);
186         case GridLineNamesClass:
187             return compareCSSValues<CSSGridLineNamesValue>(*this, other);
188         case GridTemplateClass:
189             return compareCSSValues<CSSGridTemplateValue>(*this, other);
190         case PrimitiveClass:
191             return compareCSSValues<CSSPrimitiveValue>(*this, other);
192         case ReflectClass:
193             return compareCSSValues<CSSReflectValue>(*this, other);
194         case ShadowClass:
195             return compareCSSValues<CSSShadowValue>(*this, other);
196         case CubicBezierTimingFunctionClass:
197             return compareCSSValues<CSSCubicBezierTimingFunctionValue>(*this, other);
198         case StepsTimingFunctionClass:
199             return compareCSSValues<CSSStepsTimingFunctionValue>(*this, other);
200         case UnicodeRangeClass:
201             return compareCSSValues<CSSUnicodeRangeValue>(*this, other);
202         case ValueListClass:
203             return compareCSSValues<CSSValueList>(*this, other);
204         case CSSTransformClass:
205             return compareCSSValues<CSSTransformValue>(*this, other);
206         case LineBoxContainClass:
207             return compareCSSValues<CSSLineBoxContainValue>(*this, other);
208         case CalculationClass:
209             return compareCSSValues<CSSCalcValue>(*this, other);
210         case ImageSetClass:
211             return compareCSSValues<CSSImageSetValue>(*this, other);
212         case CSSFilterClass:
213             return compareCSSValues<CSSFilterValue>(*this, other);
214         case CSSArrayFunctionValueClass:
215             return compareCSSValues<CSSArrayFunctionValue>(*this, other);
216         case CSSMixFunctionValueClass:
217             return compareCSSValues<CSSMixFunctionValue>(*this, other);
218         case CSSShaderClass:
219             return compareCSSValues<CSSShaderValue>(*this, other);
220         case VariableClass:
221             return compareCSSValues<CSSVariableValue>(*this, other);
222         case SVGColorClass:
223             return compareCSSValues<SVGColor>(*this, other);
224         case SVGPaintClass:
225             return compareCSSValues<SVGPaint>(*this, other);
226         case CSSSVGDocumentClass:
227             return compareCSSValues<CSSSVGDocumentValue>(*this, other);
228         default:
229             ASSERT_NOT_REACHED();
230             return false;
231         }
232     } else if (m_classType == ValueListClass && other.m_classType != ValueListClass)
233         return toCSSValueList(this)->equals(other);
234     else if (m_classType != ValueListClass && other.m_classType == ValueListClass)
235         return static_cast<const CSSValueList&>(other).equals(*this);
236     return false;
237 }
238 
cssText() const239 String CSSValue::cssText() const
240 {
241     if (m_isTextClone) {
242          ASSERT(isCSSOMSafe());
243         return toTextCloneCSSValue(this)->cssText();
244     }
245     ASSERT(!isCSSOMSafe() || isSubtypeExposedToCSSOM());
246 
247     switch (classType()) {
248     case AspectRatioClass:
249         return toCSSAspectRatioValue(this)->customCSSText();
250     case BorderImageSliceClass:
251         return toCSSBorderImageSliceValue(this)->customCSSText();
252     case CanvasClass:
253         return toCSSCanvasValue(this)->customCSSText();
254     case CursorImageClass:
255         return toCSSCursorImageValue(this)->customCSSText();
256     case FontClass:
257         return toCSSFontValue(this)->customCSSText();
258     case FontFaceSrcClass:
259         return toCSSFontFaceSrcValue(this)->customCSSText();
260     case FontFeatureClass:
261         return toCSSFontFeatureValue(this)->customCSSText();
262     case FunctionClass:
263         return toCSSFunctionValue(this)->customCSSText();
264     case LinearGradientClass:
265         return toCSSLinearGradientValue(this)->customCSSText();
266     case RadialGradientClass:
267         return toCSSRadialGradientValue(this)->customCSSText();
268     case CrossfadeClass:
269         return toCSSCrossfadeValue(this)->customCSSText();
270     case ImageClass:
271         return toCSSImageValue(this)->customCSSText();
272     case InheritedClass:
273         return toCSSInheritedValue(this)->customCSSText();
274     case InitialClass:
275         return toCSSInitialValue(this)->customCSSText();
276     case GridLineNamesClass:
277         return toCSSGridLineNamesValue(this)->customCSSText();
278     case GridTemplateClass:
279         return toCSSGridTemplateValue(this)->customCSSText();
280     case PrimitiveClass:
281         return toCSSPrimitiveValue(this)->customCSSText();
282     case ReflectClass:
283         return toCSSReflectValue(this)->customCSSText();
284     case ShadowClass:
285         return toCSSShadowValue(this)->customCSSText();
286     case CubicBezierTimingFunctionClass:
287         return toCSSCubicBezierTimingFunctionValue(this)->customCSSText();
288     case StepsTimingFunctionClass:
289         return toCSSStepsTimingFunctionValue(this)->customCSSText();
290     case UnicodeRangeClass:
291         return toCSSUnicodeRangeValue(this)->customCSSText();
292     case ValueListClass:
293         return toCSSValueList(this)->customCSSText();
294     case CSSTransformClass:
295         return toCSSTransformValue(this)->customCSSText();
296     case LineBoxContainClass:
297         return toCSSLineBoxContainValue(this)->customCSSText();
298     case CalculationClass:
299         return toCSSCalcValue(this)->customCSSText();
300     case ImageSetClass:
301         return toCSSImageSetValue(this)->customCSSText();
302     case CSSFilterClass:
303         return toCSSFilterValue(this)->customCSSText();
304     case CSSArrayFunctionValueClass:
305         return toCSSArrayFunctionValue(this)->customCSSText();
306     case CSSMixFunctionValueClass:
307         return toCSSMixFunctionValue(this)->customCSSText();
308     case CSSShaderClass:
309         return toCSSShaderValue(this)->customCSSText();
310     case VariableClass:
311         return toCSSVariableValue(this)->value();
312     case SVGColorClass:
313         return toSVGColor(this)->customCSSText();
314     case SVGPaintClass:
315         return toSVGPaint(this)->customCSSText();
316     case CSSSVGDocumentClass:
317         return toCSSSVGDocumentValue(this)->customCSSText();
318     }
319     ASSERT_NOT_REACHED();
320     return String();
321 }
322 
serializeResolvingVariables(const HashMap<AtomicString,String> & variables) const323 String CSSValue::serializeResolvingVariables(const HashMap<AtomicString, String>& variables) const
324 {
325     switch (classType()) {
326     case PrimitiveClass:
327         return toCSSPrimitiveValue(this)->customSerializeResolvingVariables(variables);
328     case ReflectClass:
329         return toCSSReflectValue(this)->customSerializeResolvingVariables(variables);
330     case ValueListClass:
331         return toCSSValueList(this)->customSerializeResolvingVariables(variables);
332     case CSSTransformClass:
333         return toCSSTransformValue(this)->customSerializeResolvingVariables(variables);
334     default:
335         return cssText();
336     }
337 }
338 
destroy()339 void CSSValue::destroy()
340 {
341     if (m_isTextClone) {
342         ASSERT(isCSSOMSafe());
343         delete toTextCloneCSSValue(this);
344         return;
345     }
346     ASSERT(!isCSSOMSafe() || isSubtypeExposedToCSSOM());
347 
348     switch (classType()) {
349     case AspectRatioClass:
350         delete toCSSAspectRatioValue(this);
351         return;
352     case BorderImageSliceClass:
353         delete toCSSBorderImageSliceValue(this);
354         return;
355     case CanvasClass:
356         delete toCSSCanvasValue(this);
357         return;
358     case CursorImageClass:
359         delete toCSSCursorImageValue(this);
360         return;
361     case FontClass:
362         delete toCSSFontValue(this);
363         return;
364     case FontFaceSrcClass:
365         delete toCSSFontFaceSrcValue(this);
366         return;
367     case FontFeatureClass:
368         delete toCSSFontFeatureValue(this);
369         return;
370     case FunctionClass:
371         delete toCSSFunctionValue(this);
372         return;
373     case LinearGradientClass:
374         delete toCSSLinearGradientValue(this);
375         return;
376     case RadialGradientClass:
377         delete toCSSRadialGradientValue(this);
378         return;
379     case CrossfadeClass:
380         delete toCSSCrossfadeValue(this);
381         return;
382     case ImageClass:
383         delete toCSSImageValue(this);
384         return;
385     case InheritedClass:
386         delete toCSSInheritedValue(this);
387         return;
388     case InitialClass:
389         delete toCSSInitialValue(this);
390         return;
391     case GridLineNamesClass:
392         delete toCSSGridLineNamesValue(this);
393         return;
394     case GridTemplateClass:
395         delete toCSSGridTemplateValue(this);
396         return;
397     case PrimitiveClass:
398         delete toCSSPrimitiveValue(this);
399         return;
400     case ReflectClass:
401         delete toCSSReflectValue(this);
402         return;
403     case ShadowClass:
404         delete toCSSShadowValue(this);
405         return;
406     case CubicBezierTimingFunctionClass:
407         delete toCSSCubicBezierTimingFunctionValue(this);
408         return;
409     case StepsTimingFunctionClass:
410         delete toCSSStepsTimingFunctionValue(this);
411         return;
412     case UnicodeRangeClass:
413         delete toCSSUnicodeRangeValue(this);
414         return;
415     case ValueListClass:
416         delete toCSSValueList(this);
417         return;
418     case CSSTransformClass:
419         delete toCSSTransformValue(this);
420         return;
421     case LineBoxContainClass:
422         delete toCSSLineBoxContainValue(this);
423         return;
424     case CalculationClass:
425         delete toCSSCalcValue(this);
426         return;
427     case ImageSetClass:
428         delete toCSSImageSetValue(this);
429         return;
430     case CSSFilterClass:
431         delete toCSSFilterValue(this);
432         return;
433     case CSSArrayFunctionValueClass:
434         delete toCSSArrayFunctionValue(this);
435         return;
436     case CSSMixFunctionValueClass:
437         delete toCSSMixFunctionValue(this);
438         return;
439     case CSSShaderClass:
440         delete toCSSShaderValue(this);
441         return;
442     case VariableClass:
443         delete toCSSVariableValue(this);
444         return;
445     case SVGColorClass:
446         delete toSVGColor(this);
447         return;
448     case SVGPaintClass:
449         delete toSVGPaint(this);
450         return;
451     case CSSSVGDocumentClass:
452         delete toCSSSVGDocumentValue(this);
453         return;
454     }
455     ASSERT_NOT_REACHED();
456 }
457 
cloneForCSSOM() const458 PassRefPtr<CSSValue> CSSValue::cloneForCSSOM() const
459 {
460     switch (classType()) {
461     case PrimitiveClass:
462         return toCSSPrimitiveValue(this)->cloneForCSSOM();
463     case ValueListClass:
464         return toCSSValueList(this)->cloneForCSSOM();
465     case ImageClass:
466     case CursorImageClass:
467         return toCSSImageValue(this)->cloneForCSSOM();
468     case CSSFilterClass:
469         return toCSSFilterValue(this)->cloneForCSSOM();
470     case CSSArrayFunctionValueClass:
471         return toCSSArrayFunctionValue(this)->cloneForCSSOM();
472     case CSSMixFunctionValueClass:
473         return toCSSMixFunctionValue(this)->cloneForCSSOM();
474     case CSSTransformClass:
475         return toCSSTransformValue(this)->cloneForCSSOM();
476     case ImageSetClass:
477         return toCSSImageSetValue(this)->cloneForCSSOM();
478     case SVGColorClass:
479         return toSVGColor(this)->cloneForCSSOM();
480     case SVGPaintClass:
481         return toSVGPaint(this)->cloneForCSSOM();
482     default:
483         ASSERT(!isSubtypeExposedToCSSOM());
484         return TextCloneCSSValue::create(classType(), cssText());
485     }
486 }
487 
488 }
489