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/CSSBorderImageSliceValue.h"
31 #include "core/css/CSSCalculationValue.h"
32 #include "core/css/CSSCanvasValue.h"
33 #include "core/css/CSSContentDistributionValue.h"
34 #include "core/css/CSSCrossfadeValue.h"
35 #include "core/css/CSSCursorImageValue.h"
36 #include "core/css/CSSFilterValue.h"
37 #include "core/css/CSSFontFaceSrcValue.h"
38 #include "core/css/CSSFontFeatureValue.h"
39 #include "core/css/CSSFontValue.h"
40 #include "core/css/CSSFunctionValue.h"
41 #include "core/css/CSSGradientValue.h"
42 #include "core/css/CSSGridLineNamesValue.h"
43 #include "core/css/CSSGridTemplateAreasValue.h"
44 #include "core/css/CSSImageSetValue.h"
45 #include "core/css/CSSImageValue.h"
46 #include "core/css/CSSInheritedValue.h"
47 #include "core/css/CSSInitialValue.h"
48 #include "core/css/CSSLineBoxContainValue.h"
49 #include "core/css/CSSPrimitiveValue.h"
50 #include "core/css/CSSReflectValue.h"
51 #include "core/css/CSSSVGDocumentValue.h"
52 #include "core/css/CSSShadowValue.h"
53 #include "core/css/CSSTimingFunctionValue.h"
54 #include "core/css/CSSTransformValue.h"
55 #include "core/css/CSSUnicodeRangeValue.h"
56 #include "core/css/CSSValueList.h"
60 struct SameSizeAsCSSValue : public RefCountedWillBeGarbageCollectedFinalized<SameSizeAsCSSValue>
61 // VC++ 2013 doesn't support EBCO (Empty Base Class Optimization), and having
62 // multiple empty base classes makes the size of CSSValue bloat (Note that both
63 // of GarbageCollectedFinalized and ScriptWrappableBase are empty classes).
64 // See the following article for details.
65 // http://social.msdn.microsoft.com/forums/vstudio/en-US/504c6598-6076-4acf-96b6-e6acb475d302/vc-multiple-inheritance-empty-base-classes-bloats-object-size
67 // FIXME: Remove this #if directive once VC++'s issue gets fixed.
68 // Note that we're going to split CSSValue class into two classes; CSSOMValue
69 // (assumed name) which derives ScriptWrappable and CSSValue (new one) which
70 // doesn't derive ScriptWrappable or ScriptWrappableBase. Then, we can safely
71 // remove this #if directive.
72 #if ENABLE(OILPAN) && COMPILER(MSVC)
73 , public ScriptWrappableBase
79 COMPILE_ASSERT(sizeof(CSSValue) <= sizeof(SameSizeAsCSSValue), CSS_value_should_stay_small);
81 class TextCloneCSSValue : public CSSValue {
83 static PassRefPtrWillBeRawPtr<TextCloneCSSValue> create(ClassType classType, const String& text)
85 return adoptRefWillBeNoop(new TextCloneCSSValue(classType, text));
88 String cssText() const { return m_cssText; }
90 void traceAfterDispatch(Visitor* visitor) { CSSValue::traceAfterDispatch(visitor); }
93 TextCloneCSSValue(ClassType classType, const String& text)
94 : CSSValue(classType, /*isCSSOMSafe*/ true)
103 DEFINE_CSS_VALUE_TYPE_CASTS(TextCloneCSSValue, isTextCloneCSSValue());
105 bool CSSValue::isImplicitInitialValue() const
107 return m_classType == InitialClass && toCSSInitialValue(this)->isImplicit();
110 CSSValue::Type CSSValue::cssValueType() const
112 if (isInheritedValue())
114 if (isPrimitiveValue())
115 return CSS_PRIMITIVE_VALUE;
117 return CSS_VALUE_LIST;
118 if (isInitialValue())
123 bool CSSValue::hasFailedOrCanceledSubresources() const
125 // This should get called for internal instances only.
126 ASSERT(!isCSSOMSafe());
129 return toCSSValueList(this)->hasFailedOrCanceledSubresources();
130 if (classType() == FontFaceSrcClass)
131 return toCSSFontFaceSrcValue(this)->hasFailedOrCanceledSubresources();
132 if (classType() == ImageClass)
133 return toCSSImageValue(this)->hasFailedOrCanceledSubresources();
134 if (classType() == CrossfadeClass)
135 return toCSSCrossfadeValue(this)->hasFailedOrCanceledSubresources();
136 if (classType() == ImageSetClass)
137 return toCSSImageSetValue(this)->hasFailedOrCanceledSubresources();
142 template<class ChildClassType>
143 inline static bool compareCSSValues(const CSSValue& first, const CSSValue& second)
145 return static_cast<const ChildClassType&>(first).equals(static_cast<const ChildClassType&>(second));
148 bool CSSValue::equals(const CSSValue& other) const
151 ASSERT(isCSSOMSafe());
152 return toTextCloneCSSValue(this)->cssText() == other.cssText();
155 if (m_classType == other.m_classType) {
156 switch (m_classType) {
157 case BorderImageSliceClass:
158 return compareCSSValues<CSSBorderImageSliceValue>(*this, other);
160 return compareCSSValues<CSSCanvasValue>(*this, other);
161 case CursorImageClass:
162 return compareCSSValues<CSSCursorImageValue>(*this, other);
164 return compareCSSValues<CSSFontValue>(*this, other);
165 case FontFaceSrcClass:
166 return compareCSSValues<CSSFontFaceSrcValue>(*this, other);
167 case FontFeatureClass:
168 return compareCSSValues<CSSFontFeatureValue>(*this, other);
170 return compareCSSValues<CSSFunctionValue>(*this, other);
171 case LinearGradientClass:
172 return compareCSSValues<CSSLinearGradientValue>(*this, other);
173 case RadialGradientClass:
174 return compareCSSValues<CSSRadialGradientValue>(*this, other);
176 return compareCSSValues<CSSCrossfadeValue>(*this, other);
178 return compareCSSValues<CSSImageValue>(*this, other);
180 return compareCSSValues<CSSInheritedValue>(*this, other);
182 return compareCSSValues<CSSInitialValue>(*this, other);
183 case GridLineNamesClass:
184 return compareCSSValues<CSSGridLineNamesValue>(*this, other);
185 case GridTemplateAreasClass:
186 return compareCSSValues<CSSGridTemplateAreasValue>(*this, other);
188 return compareCSSValues<CSSPrimitiveValue>(*this, other);
190 return compareCSSValues<CSSReflectValue>(*this, other);
192 return compareCSSValues<CSSShadowValue>(*this, other);
193 case CubicBezierTimingFunctionClass:
194 return compareCSSValues<CSSCubicBezierTimingFunctionValue>(*this, other);
195 case StepsTimingFunctionClass:
196 return compareCSSValues<CSSStepsTimingFunctionValue>(*this, other);
197 case UnicodeRangeClass:
198 return compareCSSValues<CSSUnicodeRangeValue>(*this, other);
200 return compareCSSValues<CSSValueList>(*this, other);
201 case CSSTransformClass:
202 return compareCSSValues<CSSTransformValue>(*this, other);
203 case LineBoxContainClass:
204 return compareCSSValues<CSSLineBoxContainValue>(*this, other);
205 case CalculationClass:
206 return compareCSSValues<CSSCalcValue>(*this, other);
208 return compareCSSValues<CSSImageSetValue>(*this, other);
210 return compareCSSValues<CSSFilterValue>(*this, other);
211 case CSSSVGDocumentClass:
212 return compareCSSValues<CSSSVGDocumentValue>(*this, other);
213 case CSSContentDistributionClass:
214 return compareCSSValues<CSSContentDistributionValue>(*this, other);
216 ASSERT_NOT_REACHED();
219 } else if (m_classType == ValueListClass && other.m_classType != ValueListClass)
220 return toCSSValueList(this)->equals(other);
221 else if (m_classType != ValueListClass && other.m_classType == ValueListClass)
222 return static_cast<const CSSValueList&>(other).equals(*this);
226 String CSSValue::cssText() const
229 ASSERT(isCSSOMSafe());
230 return toTextCloneCSSValue(this)->cssText();
232 ASSERT(!isCSSOMSafe() || isSubtypeExposedToCSSOM());
234 switch (classType()) {
235 case BorderImageSliceClass:
236 return toCSSBorderImageSliceValue(this)->customCSSText();
238 return toCSSCanvasValue(this)->customCSSText();
239 case CursorImageClass:
240 return toCSSCursorImageValue(this)->customCSSText();
242 return toCSSFontValue(this)->customCSSText();
243 case FontFaceSrcClass:
244 return toCSSFontFaceSrcValue(this)->customCSSText();
245 case FontFeatureClass:
246 return toCSSFontFeatureValue(this)->customCSSText();
248 return toCSSFunctionValue(this)->customCSSText();
249 case LinearGradientClass:
250 return toCSSLinearGradientValue(this)->customCSSText();
251 case RadialGradientClass:
252 return toCSSRadialGradientValue(this)->customCSSText();
254 return toCSSCrossfadeValue(this)->customCSSText();
256 return toCSSImageValue(this)->customCSSText();
258 return toCSSInheritedValue(this)->customCSSText();
260 return toCSSInitialValue(this)->customCSSText();
261 case GridLineNamesClass:
262 return toCSSGridLineNamesValue(this)->customCSSText();
263 case GridTemplateAreasClass:
264 return toCSSGridTemplateAreasValue(this)->customCSSText();
266 return toCSSPrimitiveValue(this)->customCSSText();
268 return toCSSReflectValue(this)->customCSSText();
270 return toCSSShadowValue(this)->customCSSText();
271 case CubicBezierTimingFunctionClass:
272 return toCSSCubicBezierTimingFunctionValue(this)->customCSSText();
273 case StepsTimingFunctionClass:
274 return toCSSStepsTimingFunctionValue(this)->customCSSText();
275 case UnicodeRangeClass:
276 return toCSSUnicodeRangeValue(this)->customCSSText();
278 return toCSSValueList(this)->customCSSText();
279 case CSSTransformClass:
280 return toCSSTransformValue(this)->customCSSText();
281 case LineBoxContainClass:
282 return toCSSLineBoxContainValue(this)->customCSSText();
283 case CalculationClass:
284 return toCSSCalcValue(this)->customCSSText();
286 return toCSSImageSetValue(this)->customCSSText();
288 return toCSSFilterValue(this)->customCSSText();
289 case CSSSVGDocumentClass:
290 return toCSSSVGDocumentValue(this)->customCSSText();
291 case CSSContentDistributionClass:
292 return toCSSContentDistributionValue(this)->customCSSText();
294 ASSERT_NOT_REACHED();
298 void CSSValue::destroy()
301 ASSERT(isCSSOMSafe());
302 delete toTextCloneCSSValue(this);
305 ASSERT(!isCSSOMSafe() || isSubtypeExposedToCSSOM());
307 switch (classType()) {
308 case BorderImageSliceClass:
309 delete toCSSBorderImageSliceValue(this);
312 delete toCSSCanvasValue(this);
314 case CursorImageClass:
315 delete toCSSCursorImageValue(this);
318 delete toCSSFontValue(this);
320 case FontFaceSrcClass:
321 delete toCSSFontFaceSrcValue(this);
323 case FontFeatureClass:
324 delete toCSSFontFeatureValue(this);
327 delete toCSSFunctionValue(this);
329 case LinearGradientClass:
330 delete toCSSLinearGradientValue(this);
332 case RadialGradientClass:
333 delete toCSSRadialGradientValue(this);
336 delete toCSSCrossfadeValue(this);
339 delete toCSSImageValue(this);
342 delete toCSSInheritedValue(this);
345 delete toCSSInitialValue(this);
347 case GridLineNamesClass:
348 delete toCSSGridLineNamesValue(this);
350 case GridTemplateAreasClass:
351 delete toCSSGridTemplateAreasValue(this);
354 delete toCSSPrimitiveValue(this);
357 delete toCSSReflectValue(this);
360 delete toCSSShadowValue(this);
362 case CubicBezierTimingFunctionClass:
363 delete toCSSCubicBezierTimingFunctionValue(this);
365 case StepsTimingFunctionClass:
366 delete toCSSStepsTimingFunctionValue(this);
368 case UnicodeRangeClass:
369 delete toCSSUnicodeRangeValue(this);
372 delete toCSSValueList(this);
374 case CSSTransformClass:
375 delete toCSSTransformValue(this);
377 case LineBoxContainClass:
378 delete toCSSLineBoxContainValue(this);
380 case CalculationClass:
381 delete toCSSCalcValue(this);
384 delete toCSSImageSetValue(this);
387 delete toCSSFilterValue(this);
389 case CSSSVGDocumentClass:
390 delete toCSSSVGDocumentValue(this);
392 case CSSContentDistributionClass:
393 delete toCSSContentDistributionValue(this);
396 ASSERT_NOT_REACHED();
399 void CSSValue::finalizeGarbageCollectedObject()
402 ASSERT(isCSSOMSafe());
403 toTextCloneCSSValue(this)->~TextCloneCSSValue();
406 ASSERT(!isCSSOMSafe() || isSubtypeExposedToCSSOM());
408 switch (classType()) {
409 case BorderImageSliceClass:
410 toCSSBorderImageSliceValue(this)->~CSSBorderImageSliceValue();
413 toCSSCanvasValue(this)->~CSSCanvasValue();
415 case CursorImageClass:
416 toCSSCursorImageValue(this)->~CSSCursorImageValue();
419 toCSSFontValue(this)->~CSSFontValue();
421 case FontFaceSrcClass:
422 toCSSFontFaceSrcValue(this)->~CSSFontFaceSrcValue();
424 case FontFeatureClass:
425 toCSSFontFeatureValue(this)->~CSSFontFeatureValue();
428 toCSSFunctionValue(this)->~CSSFunctionValue();
430 case LinearGradientClass:
431 toCSSLinearGradientValue(this)->~CSSLinearGradientValue();
433 case RadialGradientClass:
434 toCSSRadialGradientValue(this)->~CSSRadialGradientValue();
437 toCSSCrossfadeValue(this)->~CSSCrossfadeValue();
440 toCSSImageValue(this)->~CSSImageValue();
443 toCSSInheritedValue(this)->~CSSInheritedValue();
446 toCSSInitialValue(this)->~CSSInitialValue();
448 case GridLineNamesClass:
449 toCSSGridLineNamesValue(this)->~CSSGridLineNamesValue();
451 case GridTemplateAreasClass:
452 toCSSGridTemplateAreasValue(this)->~CSSGridTemplateAreasValue();
455 toCSSPrimitiveValue(this)->~CSSPrimitiveValue();
458 toCSSReflectValue(this)->~CSSReflectValue();
461 toCSSShadowValue(this)->~CSSShadowValue();
463 case CubicBezierTimingFunctionClass:
464 toCSSCubicBezierTimingFunctionValue(this)->~CSSCubicBezierTimingFunctionValue();
466 case StepsTimingFunctionClass:
467 toCSSStepsTimingFunctionValue(this)->~CSSStepsTimingFunctionValue();
469 case UnicodeRangeClass:
470 toCSSUnicodeRangeValue(this)->~CSSUnicodeRangeValue();
473 toCSSValueList(this)->~CSSValueList();
475 case CSSTransformClass:
476 toCSSTransformValue(this)->~CSSTransformValue();
478 case LineBoxContainClass:
479 toCSSLineBoxContainValue(this)->~CSSLineBoxContainValue();
481 case CalculationClass:
482 toCSSCalcValue(this)->~CSSCalcValue();
485 toCSSImageSetValue(this)->~CSSImageSetValue();
488 toCSSFilterValue(this)->~CSSFilterValue();
490 case CSSSVGDocumentClass:
491 toCSSSVGDocumentValue(this)->~CSSSVGDocumentValue();
493 case CSSContentDistributionClass:
494 toCSSContentDistributionValue(this)->~CSSContentDistributionValue();
497 ASSERT_NOT_REACHED();
500 void CSSValue::trace(Visitor* visitor)
503 ASSERT(isCSSOMSafe());
504 toTextCloneCSSValue(this)->traceAfterDispatch(visitor);
507 ASSERT(!isCSSOMSafe() || isSubtypeExposedToCSSOM());
509 switch (classType()) {
510 case BorderImageSliceClass:
511 toCSSBorderImageSliceValue(this)->traceAfterDispatch(visitor);
514 toCSSCanvasValue(this)->traceAfterDispatch(visitor);
516 case CursorImageClass:
517 toCSSCursorImageValue(this)->traceAfterDispatch(visitor);
520 toCSSFontValue(this)->traceAfterDispatch(visitor);
522 case FontFaceSrcClass:
523 toCSSFontFaceSrcValue(this)->traceAfterDispatch(visitor);
525 case FontFeatureClass:
526 toCSSFontFeatureValue(this)->traceAfterDispatch(visitor);
529 toCSSFunctionValue(this)->traceAfterDispatch(visitor);
531 case LinearGradientClass:
532 toCSSLinearGradientValue(this)->traceAfterDispatch(visitor);
534 case RadialGradientClass:
535 toCSSRadialGradientValue(this)->traceAfterDispatch(visitor);
538 toCSSCrossfadeValue(this)->traceAfterDispatch(visitor);
541 toCSSImageValue(this)->traceAfterDispatch(visitor);
544 toCSSInheritedValue(this)->traceAfterDispatch(visitor);
547 toCSSInitialValue(this)->traceAfterDispatch(visitor);
549 case GridLineNamesClass:
550 toCSSGridLineNamesValue(this)->traceAfterDispatch(visitor);
552 case GridTemplateAreasClass:
553 toCSSGridTemplateAreasValue(this)->traceAfterDispatch(visitor);
556 toCSSPrimitiveValue(this)->traceAfterDispatch(visitor);
559 toCSSReflectValue(this)->traceAfterDispatch(visitor);
562 toCSSShadowValue(this)->traceAfterDispatch(visitor);
564 case CubicBezierTimingFunctionClass:
565 toCSSCubicBezierTimingFunctionValue(this)->traceAfterDispatch(visitor);
567 case StepsTimingFunctionClass:
568 toCSSStepsTimingFunctionValue(this)->traceAfterDispatch(visitor);
570 case UnicodeRangeClass:
571 toCSSUnicodeRangeValue(this)->traceAfterDispatch(visitor);
574 toCSSValueList(this)->traceAfterDispatch(visitor);
576 case CSSTransformClass:
577 toCSSTransformValue(this)->traceAfterDispatch(visitor);
579 case LineBoxContainClass:
580 toCSSLineBoxContainValue(this)->traceAfterDispatch(visitor);
582 case CalculationClass:
583 toCSSCalcValue(this)->traceAfterDispatch(visitor);
586 toCSSImageSetValue(this)->traceAfterDispatch(visitor);
589 toCSSFilterValue(this)->traceAfterDispatch(visitor);
591 case CSSSVGDocumentClass:
592 toCSSSVGDocumentValue(this)->traceAfterDispatch(visitor);
594 case CSSContentDistributionClass:
595 toCSSContentDistributionValue(this)->traceAfterDispatch(visitor);
598 ASSERT_NOT_REACHED();
601 PassRefPtrWillBeRawPtr<CSSValue> CSSValue::cloneForCSSOM() const
603 switch (classType()) {
605 return toCSSPrimitiveValue(this)->cloneForCSSOM();
607 return toCSSValueList(this)->cloneForCSSOM();
609 case CursorImageClass:
610 return toCSSImageValue(this)->cloneForCSSOM();
612 return toCSSFilterValue(this)->cloneForCSSOM();
613 case CSSTransformClass:
614 return toCSSTransformValue(this)->cloneForCSSOM();
616 return toCSSImageSetValue(this)->cloneForCSSOM();
618 ASSERT(!isSubtypeExposedToCSSOM());
619 return TextCloneCSSValue::create(classType(), cssText());