Don't reuse cached stylesheet with failed or canceled resource loads
[WebKit-https.git] / Source / WebCore / css / CSSValue.cpp
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 "CSSValue.h"
29
30 #include "CSSAspectRatioValue.h"
31 #include "CSSBorderImageSliceValue.h"
32 #include "CSSCalculationValue.h"
33 #include "CSSCanvasValue.h"
34 #include "CSSCrossfadeValue.h"
35 #include "CSSCursorImageValue.h"
36 #include "CSSFontFaceSrcValue.h"
37 #include "CSSFunctionValue.h"
38 #include "CSSGradientValue.h"
39 #include "CSSImageGeneratorValue.h"
40 #include "CSSImageSetValue.h"
41 #include "CSSImageValue.h"
42 #include "CSSInheritedValue.h"
43 #include "CSSInitialValue.h"
44 #include "CSSLineBoxContainValue.h"
45 #include "CSSPrimitiveValue.h"
46 #include "CSSReflectValue.h"
47 #include "CSSTimingFunctionValue.h"
48 #include "CSSUnicodeRangeValue.h"
49 #include "CSSValueList.h"
50 #if ENABLE(CSS_VARIABLES)
51 #include "CSSVariableValue.h"
52 #endif
53 #include "FontValue.h"
54 #include "FontFeatureValue.h"
55 #include "ShadowValue.h"
56 #include "SVGColor.h"
57 #include "SVGPaint.h"
58 #include "WebKitCSSFilterValue.h"
59 #include "WebKitCSSShaderValue.h"
60 #include "WebKitCSSTransformValue.h"
61
62 #if ENABLE(SVG)
63 #include "WebKitCSSSVGDocumentValue.h"
64 #endif
65
66 namespace WebCore {
67
68 struct SameSizeAsCSSValue : public RefCounted<SameSizeAsCSSValue> {
69     uint32_t bitfields;
70 };
71
72 COMPILE_ASSERT(sizeof(CSSValue) == sizeof(SameSizeAsCSSValue), CSS_value_should_stay_small);
73     
74 class TextCloneCSSValue : public CSSValue {
75 public:
76     static PassRefPtr<TextCloneCSSValue> create(ClassType classType, const String& text) { return adoptRef(new TextCloneCSSValue(classType, text)); }
77
78     String cssText() const { return m_cssText; }
79
80 private:
81     TextCloneCSSValue(ClassType classType, const String& text) 
82         : CSSValue(classType, /*isCSSOMSafe*/ true)
83         , m_cssText(text)
84     {
85         m_isTextClone = true;
86     }
87
88     String m_cssText;
89 };
90
91 bool CSSValue::isImplicitInitialValue() const
92 {
93     return m_classType == InitialClass && static_cast<const CSSInitialValue*>(this)->isImplicit();
94 }
95
96 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
109 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         static_cast<const CSSPrimitiveValue*>(this)->addSubresourceStyleURLs(urls, styleSheet);
116     else if (isValueList())
117         static_cast<const CSSValueList*>(this)->addSubresourceStyleURLs(urls, styleSheet);
118     else if (classType() == FontFaceSrcClass)
119         static_cast<const CSSFontFaceSrcValue*>(this)->addSubresourceStyleURLs(urls, styleSheet);
120     else if (classType() == ReflectClass)
121         static_cast<const CSSReflectValue*>(this)->addSubresourceStyleURLs(urls, styleSheet);
122 }
123
124 bool CSSValue::hasFailedOrCanceledSubresources() const
125 {
126     // This should get called for internal instances only.
127     ASSERT(!isCSSOMSafe());
128
129     if (isValueList())
130         return static_cast<const CSSValueList*>(this)->hasFailedOrCanceledSubresources();
131     if (classType() == FontFaceSrcClass)
132         return static_cast<const CSSFontFaceSrcValue*>(this)->hasFailedOrCanceledSubresources();
133     if (classType() == ImageClass)
134         return static_cast<const CSSImageValue*>(this)->hasFailedOrCanceledSubresources();
135     if (classType() == CrossfadeClass)
136         return static_cast<const CSSCrossfadeValue*>(this)->hasFailedOrCanceledSubresources();
137 #if ENABLE(CSS_IMAGE_SET)
138     if (classType() == ImageSetClass)
139         return static_cast<const CSSImageSetValue*>(this)->hasFailedOrCanceledSubresources();
140 #endif
141     return false;
142 }
143
144 String CSSValue::cssText() const
145 {
146     if (m_isTextClone) {
147          ASSERT(isCSSOMSafe());
148         return static_cast<const TextCloneCSSValue*>(this)->cssText();
149     }
150     ASSERT(!isCSSOMSafe() || isSubtypeExposedToCSSOM());
151
152     switch (classType()) {
153     case AspectRatioClass:
154         return static_cast<const CSSAspectRatioValue*>(this)->customCssText();
155     case BorderImageSliceClass:
156         return static_cast<const CSSBorderImageSliceValue*>(this)->customCssText();
157     case CanvasClass:
158         return static_cast<const CSSCanvasValue*>(this)->customCssText();
159     case CursorImageClass:
160         return static_cast<const CSSCursorImageValue*>(this)->customCssText();
161     case FontClass:
162         return static_cast<const FontValue*>(this)->customCssText();
163     case FontFaceSrcClass:
164         return static_cast<const CSSFontFaceSrcValue*>(this)->customCssText();
165     case FontFeatureClass:
166         return static_cast<const FontFeatureValue*>(this)->customCssText();
167     case FunctionClass:
168         return static_cast<const CSSFunctionValue*>(this)->customCssText();
169     case LinearGradientClass:
170         return static_cast<const CSSLinearGradientValue*>(this)->customCssText();
171     case RadialGradientClass:
172         return static_cast<const CSSRadialGradientValue*>(this)->customCssText();
173     case CrossfadeClass:
174         return static_cast<const CSSCrossfadeValue*>(this)->customCssText();
175     case ImageClass:
176         return static_cast<const CSSImageValue*>(this)->customCssText();
177     case InheritedClass:
178         return static_cast<const CSSInheritedValue*>(this)->customCssText();
179     case InitialClass:
180         return static_cast<const CSSInitialValue*>(this)->customCssText();
181     case PrimitiveClass:
182         return static_cast<const CSSPrimitiveValue*>(this)->customCssText();
183     case ReflectClass:
184         return static_cast<const CSSReflectValue*>(this)->customCssText();
185     case ShadowClass:
186         return static_cast<const ShadowValue*>(this)->customCssText();
187     case LinearTimingFunctionClass:
188         return static_cast<const CSSLinearTimingFunctionValue*>(this)->customCssText();
189     case CubicBezierTimingFunctionClass:
190         return static_cast<const CSSCubicBezierTimingFunctionValue*>(this)->customCssText();
191     case StepsTimingFunctionClass:
192         return static_cast<const CSSStepsTimingFunctionValue*>(this)->customCssText();
193     case UnicodeRangeClass:
194         return static_cast<const CSSUnicodeRangeValue*>(this)->customCssText();
195     case ValueListClass:
196         return static_cast<const CSSValueList*>(this)->customCssText();
197     case WebKitCSSTransformClass:
198         return static_cast<const WebKitCSSTransformValue*>(this)->customCssText();
199     case LineBoxContainClass:
200         return static_cast<const CSSLineBoxContainValue*>(this)->customCssText();
201     case CalculationClass:
202         return static_cast<const CSSCalcValue*>(this)->customCssText();
203 #if ENABLE(CSS_IMAGE_SET)
204     case ImageSetClass:
205         return static_cast<const CSSImageSetValue*>(this)->customCssText();
206 #endif
207 #if ENABLE(CSS_FILTERS)
208     case WebKitCSSFilterClass:
209         return static_cast<const WebKitCSSFilterValue*>(this)->customCssText();
210 #if ENABLE(CSS_SHADERS)
211     case WebKitCSSShaderClass:
212         return static_cast<const WebKitCSSShaderValue*>(this)->customCssText();
213 #endif
214 #endif
215 #if ENABLE(CSS_VARIABLES)
216     case VariableClass:
217         return static_cast<const CSSVariableValue*>(this)->value();
218 #endif
219 #if ENABLE(SVG)
220     case SVGColorClass:
221         return static_cast<const SVGColor*>(this)->customCssText();
222     case SVGPaintClass:
223         return static_cast<const SVGPaint*>(this)->customCssText();
224     case WebKitCSSSVGDocumentClass:
225         return static_cast<const WebKitCSSSVGDocumentValue*>(this)->customCssText();
226 #endif
227     }
228     ASSERT_NOT_REACHED();
229     return String();
230 }
231
232 #if ENABLE(CSS_VARIABLES)
233 String CSSValue::serializeResolvingVariables(const HashMap<AtomicString, String>& variables) const
234 {
235     switch (classType()) {
236     case PrimitiveClass:
237         return static_cast<const CSSPrimitiveValue*>(this)->customSerializeResolvingVariables(variables);
238     case ValueListClass:
239         return static_cast<const CSSValueList*>(this)->customSerializeResolvingVariables(variables);
240     case WebKitCSSTransformClass:
241         return static_cast<const WebKitCSSTransformValue*>(this)->customSerializeResolvingVariables(variables);
242     default:
243         return cssText();
244     }
245 }
246 #endif
247
248 void CSSValue::destroy()
249 {
250     if (m_isTextClone) {
251         ASSERT(isCSSOMSafe());
252         delete static_cast<TextCloneCSSValue*>(this);
253         return;
254     }
255     ASSERT(!isCSSOMSafe() || isSubtypeExposedToCSSOM());
256
257     switch (classType()) {
258     case AspectRatioClass:
259         delete static_cast<CSSAspectRatioValue*>(this);
260         return;
261     case BorderImageSliceClass:
262         delete static_cast<CSSBorderImageSliceValue*>(this);
263         return;
264     case CanvasClass:
265         delete static_cast<CSSCanvasValue*>(this);
266         return;
267     case CursorImageClass:
268         delete static_cast<CSSCursorImageValue*>(this);
269         return;
270     case FontClass:
271         delete static_cast<FontValue*>(this);
272         return;
273     case FontFaceSrcClass:
274         delete static_cast<CSSFontFaceSrcValue*>(this);
275         return;
276     case FontFeatureClass:
277         delete static_cast<FontFeatureValue*>(this);
278         return;
279     case FunctionClass:
280         delete static_cast<CSSFunctionValue*>(this);
281         return;
282     case LinearGradientClass:
283         delete static_cast<CSSLinearGradientValue*>(this);
284         return;
285     case RadialGradientClass:
286         delete static_cast<CSSRadialGradientValue*>(this);
287         return;
288     case CrossfadeClass:
289         delete static_cast<CSSCrossfadeValue*>(this);
290         return;
291     case ImageClass:
292         delete static_cast<CSSImageValue*>(this);
293         return;
294     case InheritedClass:
295         delete static_cast<CSSInheritedValue*>(this);
296         return;
297     case InitialClass:
298         delete static_cast<CSSInitialValue*>(this);
299         return;
300     case PrimitiveClass:
301         delete static_cast<CSSPrimitiveValue*>(this);
302         return;
303     case ReflectClass:
304         delete static_cast<CSSReflectValue*>(this);
305         return;
306     case ShadowClass:
307         delete static_cast<ShadowValue*>(this);
308         return;
309     case LinearTimingFunctionClass:
310         delete static_cast<CSSLinearTimingFunctionValue*>(this);
311         return;
312     case CubicBezierTimingFunctionClass:
313         delete static_cast<CSSCubicBezierTimingFunctionValue*>(this);
314         return;
315     case StepsTimingFunctionClass:
316         delete static_cast<CSSStepsTimingFunctionValue*>(this);
317         return;
318     case UnicodeRangeClass:
319         delete static_cast<CSSUnicodeRangeValue*>(this);
320         return;
321     case ValueListClass:
322         delete static_cast<CSSValueList*>(this);
323         return;
324     case WebKitCSSTransformClass:
325         delete static_cast<WebKitCSSTransformValue*>(this);
326         return;
327     case LineBoxContainClass:
328         delete static_cast<CSSLineBoxContainValue*>(this);
329         return;
330     case CalculationClass:
331         delete static_cast<CSSCalcValue*>(this);
332         return;
333 #if ENABLE(CSS_IMAGE_SET)
334     case ImageSetClass:
335         delete static_cast<CSSImageSetValue*>(this);
336         return;
337 #endif
338 #if ENABLE(CSS_FILTERS)
339     case WebKitCSSFilterClass:
340         delete static_cast<WebKitCSSFilterValue*>(this);
341         return;
342 #if ENABLE(CSS_SHADERS)
343     case WebKitCSSShaderClass:
344         delete static_cast<WebKitCSSShaderValue*>(this);
345         return;
346 #endif
347 #endif
348 #if ENABLE(CSS_VARIABLES)
349     case VariableClass:
350         delete static_cast<CSSVariableValue*>(this);
351         return;
352 #endif
353 #if ENABLE(SVG)
354     case SVGColorClass:
355         delete static_cast<SVGColor*>(this);
356         return;
357     case SVGPaintClass:
358         delete static_cast<SVGPaint*>(this);
359         return;
360     case WebKitCSSSVGDocumentClass:
361         delete static_cast<WebKitCSSSVGDocumentValue*>(this);
362         return;
363 #endif
364     }
365     ASSERT_NOT_REACHED();
366 }
367
368 PassRefPtr<CSSValue> CSSValue::cloneForCSSOM() const
369 {
370     switch (classType()) {
371     case PrimitiveClass:
372         return static_cast<const CSSPrimitiveValue*>(this)->cloneForCSSOM();
373     case ValueListClass:
374         return static_cast<const CSSValueList*>(this)->cloneForCSSOM();
375     case ImageClass:
376     case CursorImageClass:
377         return static_cast<const CSSImageValue*>(this)->cloneForCSSOM();
378 #if ENABLE(CSS_FILTERS)
379     case WebKitCSSFilterClass:
380         return static_cast<const WebKitCSSFilterValue*>(this)->cloneForCSSOM();
381 #endif
382     case WebKitCSSTransformClass:
383         return static_cast<const WebKitCSSTransformValue*>(this)->cloneForCSSOM();
384 #if ENABLE(CSS_IMAGE_SET)
385     case ImageSetClass:
386         return static_cast<const CSSImageSetValue*>(this)->cloneForCSSOM();
387 #endif
388 #if ENABLE(SVG)
389     case SVGColorClass:
390         return static_cast<const SVGColor*>(this)->cloneForCSSOM();
391     case SVGPaintClass:
392         return static_cast<const SVGPaint*>(this)->cloneForCSSOM();
393 #endif
394     default:
395         ASSERT(!isSubtypeExposedToCSSOM());
396         return TextCloneCSSValue::create(classType(), cssText());
397     }
398 }
399
400 }