/* * Copyright (C) 2011 Andreas Kling (kling@webkit.org) * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #include "sky/engine/core/css/CSSValue.h" #include "sky/engine/core/css/CSSAspectRatioValue.h" #include "sky/engine/core/css/CSSCalculationValue.h" #include "sky/engine/core/css/CSSFilterValue.h" #include "sky/engine/core/css/CSSFontFeatureValue.h" #include "sky/engine/core/css/CSSFontValue.h" #include "sky/engine/core/css/CSSFunctionValue.h" #include "sky/engine/core/css/CSSGradientValue.h" #include "sky/engine/core/css/CSSInheritedValue.h" #include "sky/engine/core/css/CSSInitialValue.h" #include "sky/engine/core/css/CSSLineBoxContainValue.h" #include "sky/engine/core/css/CSSPrimitiveValue.h" #include "sky/engine/core/css/CSSShadowValue.h" #include "sky/engine/core/css/CSSTransformValue.h" #include "sky/engine/core/css/CSSUnicodeRangeValue.h" #include "sky/engine/core/css/CSSValueList.h" namespace blink { struct SameSizeAsCSSValue : public RefCounted { uint32_t bitfields; }; COMPILE_ASSERT(sizeof(CSSValue) <= sizeof(SameSizeAsCSSValue), CSS_value_should_stay_small); class TextCloneCSSValue : public CSSValue { public: static PassRefPtr create(ClassType classType, const String& text) { return adoptRef(new TextCloneCSSValue(classType, text)); } String cssText() const { return m_cssText; } private: TextCloneCSSValue(ClassType classType, const String& text) : CSSValue(classType, /*isCSSOMSafe*/ true) , m_cssText(text) { m_isTextClone = true; } String m_cssText; }; DEFINE_CSS_VALUE_TYPE_CASTS(TextCloneCSSValue, isTextCloneCSSValue()); bool CSSValue::isImplicitInitialValue() const { return m_classType == InitialClass && toCSSInitialValue(this)->isImplicit(); } CSSValue::Type CSSValue::cssValueType() const { if (isInheritedValue()) return CSS_INHERIT; if (isPrimitiveValue()) return CSS_PRIMITIVE_VALUE; if (isValueList()) return CSS_VALUE_LIST; if (isInitialValue()) return CSS_INITIAL; return CSS_CUSTOM; } template inline static bool compareCSSValues(const CSSValue& first, const CSSValue& second) { return static_cast(first).equals(static_cast(second)); } bool CSSValue::equals(const CSSValue& other) const { if (m_isTextClone) { ASSERT(isCSSOMSafe()); return toTextCloneCSSValue(this)->cssText() == other.cssText(); } if (m_classType == other.m_classType) { switch (m_classType) { case AspectRatioClass: return compareCSSValues(*this, other); case FontClass: return compareCSSValues(*this, other); case FontFeatureClass: return compareCSSValues(*this, other); case FunctionClass: return compareCSSValues(*this, other); case LinearGradientClass: return compareCSSValues(*this, other); case RadialGradientClass: return compareCSSValues(*this, other); case InheritedClass: return compareCSSValues(*this, other); case InitialClass: return compareCSSValues(*this, other); case PrimitiveClass: return compareCSSValues(*this, other); case ShadowClass: return compareCSSValues(*this, other); case UnicodeRangeClass: return compareCSSValues(*this, other); case ValueListClass: return compareCSSValues(*this, other); case CSSTransformClass: return compareCSSValues(*this, other); case LineBoxContainClass: return compareCSSValues(*this, other); case CalculationClass: return compareCSSValues(*this, other); case CSSFilterClass: return compareCSSValues(*this, other); default: ASSERT_NOT_REACHED(); return false; } } else if (m_classType == ValueListClass && other.m_classType != ValueListClass) return toCSSValueList(this)->equals(other); else if (m_classType != ValueListClass && other.m_classType == ValueListClass) return static_cast(other).equals(*this); return false; } String CSSValue::cssText() const { if (m_isTextClone) { ASSERT(isCSSOMSafe()); return toTextCloneCSSValue(this)->cssText(); } ASSERT(!isCSSOMSafe() || isSubtypeExposedToCSSOM()); switch (classType()) { case AspectRatioClass: return toCSSAspectRatioValue(this)->customCSSText(); case FontClass: return toCSSFontValue(this)->customCSSText(); case FontFeatureClass: return toCSSFontFeatureValue(this)->customCSSText(); case FunctionClass: return toCSSFunctionValue(this)->customCSSText(); case LinearGradientClass: return toCSSLinearGradientValue(this)->customCSSText(); case RadialGradientClass: return toCSSRadialGradientValue(this)->customCSSText(); case InheritedClass: return toCSSInheritedValue(this)->customCSSText(); case InitialClass: return toCSSInitialValue(this)->customCSSText(); case PrimitiveClass: return toCSSPrimitiveValue(this)->customCSSText(); case ShadowClass: return toCSSShadowValue(this)->customCSSText(); case UnicodeRangeClass: return toCSSUnicodeRangeValue(this)->customCSSText(); case ValueListClass: return toCSSValueList(this)->customCSSText(); case CSSTransformClass: return toCSSTransformValue(this)->customCSSText(); case LineBoxContainClass: return toCSSLineBoxContainValue(this)->customCSSText(); case CalculationClass: return toCSSCalcValue(this)->customCSSText(); case CSSFilterClass: return toCSSFilterValue(this)->customCSSText(); } ASSERT_NOT_REACHED(); return String(); } void CSSValue::destroy() { if (m_isTextClone) { ASSERT(isCSSOMSafe()); delete toTextCloneCSSValue(this); return; } ASSERT(!isCSSOMSafe() || isSubtypeExposedToCSSOM()); switch (classType()) { case AspectRatioClass: delete toCSSAspectRatioValue(this); return; case FontClass: delete toCSSFontValue(this); return; case FontFeatureClass: delete toCSSFontFeatureValue(this); return; case FunctionClass: delete toCSSFunctionValue(this); return; case LinearGradientClass: delete toCSSLinearGradientValue(this); return; case RadialGradientClass: delete toCSSRadialGradientValue(this); return; case InheritedClass: delete toCSSInheritedValue(this); return; case InitialClass: delete toCSSInitialValue(this); return; case PrimitiveClass: delete toCSSPrimitiveValue(this); return; case ShadowClass: delete toCSSShadowValue(this); return; case UnicodeRangeClass: delete toCSSUnicodeRangeValue(this); return; case ValueListClass: delete toCSSValueList(this); return; case CSSTransformClass: delete toCSSTransformValue(this); return; case LineBoxContainClass: delete toCSSLineBoxContainValue(this); return; case CalculationClass: delete toCSSCalcValue(this); return; case CSSFilterClass: delete toCSSFilterValue(this); return; } ASSERT_NOT_REACHED(); } PassRefPtr CSSValue::cloneForCSSOM() const { switch (classType()) { case PrimitiveClass: return toCSSPrimitiveValue(this)->cloneForCSSOM(); case ValueListClass: return toCSSValueList(this)->cloneForCSSOM(); case CSSFilterClass: return toCSSFilterValue(this)->cloneForCSSOM(); case CSSTransformClass: return toCSSTransformValue(this)->cloneForCSSOM(); default: ASSERT(!isSubtypeExposedToCSSOM()); return TextCloneCSSValue::create(classType(), cssText()); } } }