2 * Copyright (C) 2011 Andreas Kling (kling@webkit.org)
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
28 #include "core/css/CSSValue.h"
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/CSSGridTemplateAreasValue.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/CSSPrimitiveValue.h"
51 #include "core/css/CSSReflectValue.h"
52 #include "core/css/CSSSVGDocumentValue.h"
53 #include "core/css/CSSShadowValue.h"
54 #include "core/css/CSSTimingFunctionValue.h"
55 #include "core/css/CSSTransformValue.h"
56 #include "core/css/CSSUnicodeRangeValue.h"
57 #include "core/css/CSSValueList.h"
58 #include "core/svg/SVGColor.h"
59 #include "core/svg/SVGPaint.h"
63 DEFINE_GC_INFO(CSSValue);
65 struct SameSizeAsCSSValue : public RefCountedWillBeRefCountedGarbageCollected<SameSizeAsCSSValue> {
69 COMPILE_ASSERT(sizeof(CSSValue) <= sizeof(SameSizeAsCSSValue), CSS_value_should_stay_small);
71 class TextCloneCSSValue : public CSSValue {
73 static PassRefPtr<TextCloneCSSValue> create(ClassType classType, const String& text) { return adoptRef(new TextCloneCSSValue(classType, text)); }
75 String cssText() const { return m_cssText; }
77 void traceAfterDispatch(Visitor* visitor) { CSSValue::traceAfterDispatch(visitor); }
80 TextCloneCSSValue(ClassType classType, const String& text)
81 : CSSValue(classType, /*isCSSOMSafe*/ true)
90 DEFINE_CSS_VALUE_TYPE_CASTS(TextCloneCSSValue, isTextCloneCSSValue());
92 bool CSSValue::isImplicitInitialValue() const
94 return m_classType == InitialClass && toCSSInitialValue(this)->isImplicit();
97 CSSValue::Type CSSValue::cssValueType() const
99 if (isInheritedValue())
101 if (isPrimitiveValue())
102 return CSS_PRIMITIVE_VALUE;
104 return CSS_VALUE_LIST;
105 if (isInitialValue())
110 bool CSSValue::hasFailedOrCanceledSubresources() const
112 // This should get called for internal instances only.
113 ASSERT(!isCSSOMSafe());
116 return toCSSValueList(this)->hasFailedOrCanceledSubresources();
117 if (classType() == FontFaceSrcClass)
118 return toCSSFontFaceSrcValue(this)->hasFailedOrCanceledSubresources();
119 if (classType() == ImageClass)
120 return toCSSImageValue(this)->hasFailedOrCanceledSubresources();
121 if (classType() == CrossfadeClass)
122 return toCSSCrossfadeValue(this)->hasFailedOrCanceledSubresources();
123 if (classType() == ImageSetClass)
124 return toCSSImageSetValue(this)->hasFailedOrCanceledSubresources();
129 template<class ChildClassType>
130 inline static bool compareCSSValues(const CSSValue& first, const CSSValue& second)
132 return static_cast<const ChildClassType&>(first).equals(static_cast<const ChildClassType&>(second));
135 bool CSSValue::equals(const CSSValue& other) const
138 ASSERT(isCSSOMSafe());
139 return toTextCloneCSSValue(this)->cssText() == other.cssText();
142 if (m_classType == other.m_classType) {
143 switch (m_classType) {
144 case AspectRatioClass:
145 return compareCSSValues<CSSAspectRatioValue>(*this, other);
146 case BorderImageSliceClass:
147 return compareCSSValues<CSSBorderImageSliceValue>(*this, other);
149 return compareCSSValues<CSSCanvasValue>(*this, other);
150 case CursorImageClass:
151 return compareCSSValues<CSSCursorImageValue>(*this, other);
153 return compareCSSValues<CSSFontValue>(*this, other);
154 case FontFaceSrcClass:
155 return compareCSSValues<CSSFontFaceSrcValue>(*this, other);
156 case FontFeatureClass:
157 return compareCSSValues<CSSFontFeatureValue>(*this, other);
159 return compareCSSValues<CSSFunctionValue>(*this, other);
160 case LinearGradientClass:
161 return compareCSSValues<CSSLinearGradientValue>(*this, other);
162 case RadialGradientClass:
163 return compareCSSValues<CSSRadialGradientValue>(*this, other);
165 return compareCSSValues<CSSCrossfadeValue>(*this, other);
167 return compareCSSValues<CSSImageValue>(*this, other);
169 return compareCSSValues<CSSInheritedValue>(*this, other);
171 return compareCSSValues<CSSInitialValue>(*this, other);
172 case GridLineNamesClass:
173 return compareCSSValues<CSSGridLineNamesValue>(*this, other);
174 case GridTemplateAreasClass:
175 return compareCSSValues<CSSGridTemplateAreasValue>(*this, other);
177 return compareCSSValues<CSSPrimitiveValue>(*this, other);
179 return compareCSSValues<CSSReflectValue>(*this, other);
181 return compareCSSValues<CSSShadowValue>(*this, other);
182 case CubicBezierTimingFunctionClass:
183 return compareCSSValues<CSSCubicBezierTimingFunctionValue>(*this, other);
184 case StepsTimingFunctionClass:
185 return compareCSSValues<CSSStepsTimingFunctionValue>(*this, other);
186 case UnicodeRangeClass:
187 return compareCSSValues<CSSUnicodeRangeValue>(*this, other);
189 return compareCSSValues<CSSValueList>(*this, other);
190 case CSSTransformClass:
191 return compareCSSValues<CSSTransformValue>(*this, other);
192 case LineBoxContainClass:
193 return compareCSSValues<CSSLineBoxContainValue>(*this, other);
194 case CalculationClass:
195 return compareCSSValues<CSSCalcValue>(*this, other);
197 return compareCSSValues<CSSImageSetValue>(*this, other);
199 return compareCSSValues<CSSFilterValue>(*this, other);
200 case CSSArrayFunctionValueClass:
201 return compareCSSValues<CSSArrayFunctionValue>(*this, other);
203 return compareCSSValues<SVGColor>(*this, other);
205 return compareCSSValues<SVGPaint>(*this, other);
206 case CSSSVGDocumentClass:
207 return compareCSSValues<CSSSVGDocumentValue>(*this, other);
209 ASSERT_NOT_REACHED();
212 } else if (m_classType == ValueListClass && other.m_classType != ValueListClass)
213 return toCSSValueList(this)->equals(other);
214 else if (m_classType != ValueListClass && other.m_classType == ValueListClass)
215 return static_cast<const CSSValueList&>(other).equals(*this);
219 String CSSValue::cssText() const
222 ASSERT(isCSSOMSafe());
223 return toTextCloneCSSValue(this)->cssText();
225 ASSERT(!isCSSOMSafe() || isSubtypeExposedToCSSOM());
227 switch (classType()) {
228 case AspectRatioClass:
229 return toCSSAspectRatioValue(this)->customCSSText();
230 case BorderImageSliceClass:
231 return toCSSBorderImageSliceValue(this)->customCSSText();
233 return toCSSCanvasValue(this)->customCSSText();
234 case CursorImageClass:
235 return toCSSCursorImageValue(this)->customCSSText();
237 return toCSSFontValue(this)->customCSSText();
238 case FontFaceSrcClass:
239 return toCSSFontFaceSrcValue(this)->customCSSText();
240 case FontFeatureClass:
241 return toCSSFontFeatureValue(this)->customCSSText();
243 return toCSSFunctionValue(this)->customCSSText();
244 case LinearGradientClass:
245 return toCSSLinearGradientValue(this)->customCSSText();
246 case RadialGradientClass:
247 return toCSSRadialGradientValue(this)->customCSSText();
249 return toCSSCrossfadeValue(this)->customCSSText();
251 return toCSSImageValue(this)->customCSSText();
253 return toCSSInheritedValue(this)->customCSSText();
255 return toCSSInitialValue(this)->customCSSText();
256 case GridLineNamesClass:
257 return toCSSGridLineNamesValue(this)->customCSSText();
258 case GridTemplateAreasClass:
259 return toCSSGridTemplateAreasValue(this)->customCSSText();
261 return toCSSPrimitiveValue(this)->customCSSText();
263 return toCSSReflectValue(this)->customCSSText();
265 return toCSSShadowValue(this)->customCSSText();
266 case CubicBezierTimingFunctionClass:
267 return toCSSCubicBezierTimingFunctionValue(this)->customCSSText();
268 case StepsTimingFunctionClass:
269 return toCSSStepsTimingFunctionValue(this)->customCSSText();
270 case UnicodeRangeClass:
271 return toCSSUnicodeRangeValue(this)->customCSSText();
273 return toCSSValueList(this)->customCSSText();
274 case CSSTransformClass:
275 return toCSSTransformValue(this)->customCSSText();
276 case LineBoxContainClass:
277 return toCSSLineBoxContainValue(this)->customCSSText();
278 case CalculationClass:
279 return toCSSCalcValue(this)->customCSSText();
281 return toCSSImageSetValue(this)->customCSSText();
283 return toCSSFilterValue(this)->customCSSText();
284 case CSSArrayFunctionValueClass:
285 return toCSSArrayFunctionValue(this)->customCSSText();
287 return toSVGColor(this)->customCSSText();
289 return toSVGPaint(this)->customCSSText();
290 case CSSSVGDocumentClass:
291 return toCSSSVGDocumentValue(this)->customCSSText();
293 ASSERT_NOT_REACHED();
297 void CSSValue::destroy()
300 ASSERT(isCSSOMSafe());
301 delete toTextCloneCSSValue(this);
304 ASSERT(!isCSSOMSafe() || isSubtypeExposedToCSSOM());
306 switch (classType()) {
307 case AspectRatioClass:
308 delete toCSSAspectRatioValue(this);
310 case BorderImageSliceClass:
311 delete toCSSBorderImageSliceValue(this);
314 delete toCSSCanvasValue(this);
316 case CursorImageClass:
317 delete toCSSCursorImageValue(this);
320 delete toCSSFontValue(this);
322 case FontFaceSrcClass:
323 delete toCSSFontFaceSrcValue(this);
325 case FontFeatureClass:
326 delete toCSSFontFeatureValue(this);
329 delete toCSSFunctionValue(this);
331 case LinearGradientClass:
332 delete toCSSLinearGradientValue(this);
334 case RadialGradientClass:
335 delete toCSSRadialGradientValue(this);
338 delete toCSSCrossfadeValue(this);
341 delete toCSSImageValue(this);
344 delete toCSSInheritedValue(this);
347 delete toCSSInitialValue(this);
349 case GridLineNamesClass:
350 delete toCSSGridLineNamesValue(this);
352 case GridTemplateAreasClass:
353 delete toCSSGridTemplateAreasValue(this);
356 delete toCSSPrimitiveValue(this);
359 delete toCSSReflectValue(this);
362 delete toCSSShadowValue(this);
364 case CubicBezierTimingFunctionClass:
365 delete toCSSCubicBezierTimingFunctionValue(this);
367 case StepsTimingFunctionClass:
368 delete toCSSStepsTimingFunctionValue(this);
370 case UnicodeRangeClass:
371 delete toCSSUnicodeRangeValue(this);
374 delete toCSSValueList(this);
376 case CSSTransformClass:
377 delete toCSSTransformValue(this);
379 case LineBoxContainClass:
380 delete toCSSLineBoxContainValue(this);
382 case CalculationClass:
383 delete toCSSCalcValue(this);
386 delete toCSSImageSetValue(this);
389 delete toCSSFilterValue(this);
391 case CSSArrayFunctionValueClass:
392 delete toCSSArrayFunctionValue(this);
395 delete toSVGColor(this);
398 delete toSVGPaint(this);
400 case CSSSVGDocumentClass:
401 delete toCSSSVGDocumentValue(this);
404 ASSERT_NOT_REACHED();
407 void CSSValue::finalize()
410 ASSERT(isCSSOMSafe());
411 static_cast<TextCloneCSSValue*>(this)->~TextCloneCSSValue();
414 ASSERT(!isCSSOMSafe() || isSubtypeExposedToCSSOM());
416 switch (classType()) {
417 case AspectRatioClass:
418 static_cast<CSSAspectRatioValue*>(this)->~CSSAspectRatioValue();
420 case BorderImageSliceClass:
421 static_cast<CSSBorderImageSliceValue*>(this)->~CSSBorderImageSliceValue();
424 static_cast<CSSCanvasValue*>(this)->~CSSCanvasValue();
426 case CursorImageClass:
427 static_cast<CSSCursorImageValue*>(this)->~CSSCursorImageValue();
430 static_cast<CSSFontValue*>(this)->~CSSFontValue();
432 case FontFaceSrcClass:
433 static_cast<CSSFontFaceSrcValue*>(this)->~CSSFontFaceSrcValue();
435 case FontFeatureClass:
436 static_cast<CSSFontFeatureValue*>(this)->~CSSFontFeatureValue();
439 static_cast<CSSFunctionValue*>(this)->~CSSFunctionValue();
441 case LinearGradientClass:
442 static_cast<CSSLinearGradientValue*>(this)->~CSSLinearGradientValue();
444 case RadialGradientClass:
445 static_cast<CSSRadialGradientValue*>(this)->~CSSRadialGradientValue();
448 static_cast<CSSCrossfadeValue*>(this)->~CSSCrossfadeValue();
451 static_cast<CSSImageValue*>(this)->~CSSImageValue();
454 static_cast<CSSInheritedValue*>(this)->~CSSInheritedValue();
457 static_cast<CSSInitialValue*>(this)->~CSSInitialValue();
459 case GridLineNamesClass:
460 static_cast<CSSGridLineNamesValue*>(this)->~CSSGridLineNamesValue();
462 case GridTemplateAreasClass:
463 static_cast<CSSGridTemplateAreasValue*>(this)->~CSSGridTemplateAreasValue();
466 static_cast<CSSPrimitiveValue*>(this)->~CSSPrimitiveValue();
469 static_cast<CSSReflectValue*>(this)->~CSSReflectValue();
472 static_cast<CSSShadowValue*>(this)->~CSSShadowValue();
474 case CubicBezierTimingFunctionClass:
475 static_cast<CSSCubicBezierTimingFunctionValue*>(this)->~CSSCubicBezierTimingFunctionValue();
477 case StepsTimingFunctionClass:
478 static_cast<CSSStepsTimingFunctionValue*>(this)->~CSSStepsTimingFunctionValue();
480 case UnicodeRangeClass:
481 static_cast<CSSUnicodeRangeValue*>(this)->~CSSUnicodeRangeValue();
484 static_cast<CSSValueList*>(this)->~CSSValueList();
486 case CSSTransformClass:
487 static_cast<CSSTransformValue*>(this)->~CSSTransformValue();
489 case LineBoxContainClass:
490 static_cast<CSSLineBoxContainValue*>(this)->~CSSLineBoxContainValue();
492 case CalculationClass:
493 static_cast<CSSCalcValue*>(this)->~CSSCalcValue();
496 static_cast<CSSImageSetValue*>(this)->~CSSImageSetValue();
499 static_cast<CSSFilterValue*>(this)->~CSSFilterValue();
501 case CSSArrayFunctionValueClass:
502 static_cast<CSSArrayFunctionValue*>(this)->~CSSArrayFunctionValue();
505 static_cast<SVGColor*>(this)->~SVGColor();
508 static_cast<SVGPaint*>(this)->~SVGPaint();
510 case CSSSVGDocumentClass:
511 static_cast<CSSSVGDocumentValue*>(this)->~CSSSVGDocumentValue();
514 ASSERT_NOT_REACHED();
517 void CSSValue::trace(Visitor* visitor)
520 ASSERT(isCSSOMSafe());
521 static_cast<TextCloneCSSValue*>(this)->traceAfterDispatch(visitor);
524 ASSERT(!isCSSOMSafe() || isSubtypeExposedToCSSOM());
526 switch (classType()) {
527 case AspectRatioClass:
528 static_cast<CSSAspectRatioValue*>(this)->traceAfterDispatch(visitor);
530 case BorderImageSliceClass:
531 static_cast<CSSBorderImageSliceValue*>(this)->traceAfterDispatch(visitor);
534 static_cast<CSSCanvasValue*>(this)->traceAfterDispatch(visitor);
536 case CursorImageClass:
537 static_cast<CSSCursorImageValue*>(this)->traceAfterDispatch(visitor);
540 static_cast<CSSFontValue*>(this)->traceAfterDispatch(visitor);
542 case FontFaceSrcClass:
543 static_cast<CSSFontFaceSrcValue*>(this)->traceAfterDispatch(visitor);
545 case FontFeatureClass:
546 static_cast<CSSFontFeatureValue*>(this)->traceAfterDispatch(visitor);
549 static_cast<CSSFunctionValue*>(this)->traceAfterDispatch(visitor);
551 case LinearGradientClass:
552 static_cast<CSSLinearGradientValue*>(this)->traceAfterDispatch(visitor);
554 case RadialGradientClass:
555 static_cast<CSSRadialGradientValue*>(this)->traceAfterDispatch(visitor);
558 static_cast<CSSCrossfadeValue*>(this)->traceAfterDispatch(visitor);
561 static_cast<CSSImageValue*>(this)->traceAfterDispatch(visitor);
564 static_cast<CSSInheritedValue*>(this)->traceAfterDispatch(visitor);
567 static_cast<CSSInitialValue*>(this)->traceAfterDispatch(visitor);
569 case GridLineNamesClass:
570 static_cast<CSSGridLineNamesValue*>(this)->traceAfterDispatch(visitor);
572 case GridTemplateAreasClass:
573 static_cast<CSSGridTemplateAreasValue*>(this)->traceAfterDispatch(visitor);
576 static_cast<CSSPrimitiveValue*>(this)->traceAfterDispatch(visitor);
579 static_cast<CSSReflectValue*>(this)->traceAfterDispatch(visitor);
582 static_cast<CSSShadowValue*>(this)->traceAfterDispatch(visitor);
584 case CubicBezierTimingFunctionClass:
585 static_cast<CSSCubicBezierTimingFunctionValue*>(this)->traceAfterDispatch(visitor);
587 case StepsTimingFunctionClass:
588 static_cast<CSSStepsTimingFunctionValue*>(this)->traceAfterDispatch(visitor);
590 case UnicodeRangeClass:
591 static_cast<CSSUnicodeRangeValue*>(this)->traceAfterDispatch(visitor);
594 static_cast<CSSValueList*>(this)->traceAfterDispatch(visitor);
596 case CSSTransformClass:
597 static_cast<CSSTransformValue*>(this)->traceAfterDispatch(visitor);
599 case LineBoxContainClass:
600 static_cast<CSSLineBoxContainValue*>(this)->traceAfterDispatch(visitor);
602 case CalculationClass:
603 static_cast<CSSCalcValue*>(this)->traceAfterDispatch(visitor);
606 static_cast<CSSImageSetValue*>(this)->traceAfterDispatch(visitor);
609 static_cast<CSSFilterValue*>(this)->traceAfterDispatch(visitor);
611 case CSSArrayFunctionValueClass:
612 static_cast<CSSArrayFunctionValue*>(this)->traceAfterDispatch(visitor);
615 static_cast<SVGColor*>(this)->traceAfterDispatch(visitor);
618 static_cast<SVGPaint*>(this)->traceAfterDispatch(visitor);
620 case CSSSVGDocumentClass:
621 static_cast<CSSSVGDocumentValue*>(this)->traceAfterDispatch(visitor);
624 ASSERT_NOT_REACHED();
627 PassRefPtr<CSSValue> CSSValue::cloneForCSSOM() const
629 switch (classType()) {
631 return toCSSPrimitiveValue(this)->cloneForCSSOM();
633 return toCSSValueList(this)->cloneForCSSOM();
635 case CursorImageClass:
636 return toCSSImageValue(this)->cloneForCSSOM();
638 return toCSSFilterValue(this)->cloneForCSSOM();
639 case CSSArrayFunctionValueClass:
640 return toCSSArrayFunctionValue(this)->cloneForCSSOM();
641 case CSSTransformClass:
642 return toCSSTransformValue(this)->cloneForCSSOM();
644 return toCSSImageSetValue(this)->cloneForCSSOM();
646 return toSVGColor(this)->cloneForCSSOM();
648 return toSVGPaint(this)->cloneForCSSOM();
650 ASSERT(!isSubtypeExposedToCSSOM());
651 return TextCloneCSSValue::create(classType(), cssText());