| /* |
| * 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 "config.h" |
| #include "core/css/CSSValue.h" |
| |
| #include "core/css/CSSArrayFunctionValue.h" |
| #include "core/css/CSSAspectRatioValue.h" |
| #include "core/css/CSSBorderImageSliceValue.h" |
| #include "core/css/CSSCalculationValue.h" |
| #include "core/css/CSSCanvasValue.h" |
| #include "core/css/CSSCrossfadeValue.h" |
| #include "core/css/CSSCursorImageValue.h" |
| #include "core/css/CSSFilterValue.h" |
| #include "core/css/CSSFontFaceSrcValue.h" |
| #include "core/css/CSSFontFeatureValue.h" |
| #include "core/css/CSSFontValue.h" |
| #include "core/css/CSSFunctionValue.h" |
| #include "core/css/CSSGradientValue.h" |
| #include "core/css/CSSGridTemplateValue.h" |
| #include "core/css/CSSImageSetValue.h" |
| #include "core/css/CSSImageValue.h" |
| #include "core/css/CSSInheritedValue.h" |
| #include "core/css/CSSInitialValue.h" |
| #include "core/css/CSSLineBoxContainValue.h" |
| #include "core/css/CSSMixFunctionValue.h" |
| #include "core/css/CSSPrimitiveValue.h" |
| #include "core/css/CSSReflectValue.h" |
| #include "core/css/CSSSVGDocumentValue.h" |
| #include "core/css/CSSShaderValue.h" |
| #include "core/css/CSSShadowValue.h" |
| #include "core/css/CSSTimingFunctionValue.h" |
| #include "core/css/CSSTransformValue.h" |
| #include "core/css/CSSUnicodeRangeValue.h" |
| #include "core/css/CSSValueList.h" |
| #include "core/css/CSSVariableValue.h" |
| #include "core/svg/SVGColor.h" |
| #include "core/svg/SVGPaint.h" |
| |
| namespace WebCore { |
| |
| struct SameSizeAsCSSValue : public RefCounted<SameSizeAsCSSValue> { |
| uint32_t bitfields; |
| }; |
| |
| COMPILE_ASSERT(sizeof(CSSValue) <= sizeof(SameSizeAsCSSValue), CSS_value_should_stay_small); |
| |
| class TextCloneCSSValue : public CSSValue { |
| public: |
| static PassRefPtr<TextCloneCSSValue> 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; |
| } |
| |
| void CSSValue::addSubresourceStyleURLs(ListHashSet<KURL>& urls, const StyleSheetContents* styleSheet) const |
| { |
| // This should get called for internal instances only. |
| ASSERT(!isCSSOMSafe()); |
| |
| if (isPrimitiveValue()) |
| toCSSPrimitiveValue(this)->addSubresourceStyleURLs(urls, styleSheet); |
| else if (isValueList()) |
| toCSSValueList(this)->addSubresourceStyleURLs(urls, styleSheet); |
| else if (classType() == FontFaceSrcClass) |
| toCSSFontFaceSrcValue(this)->addSubresourceStyleURLs(urls, styleSheet); |
| else if (classType() == ReflectClass) |
| toCSSReflectValue(this)->addSubresourceStyleURLs(urls, styleSheet); |
| } |
| |
| bool CSSValue::hasFailedOrCanceledSubresources() const |
| { |
| // This should get called for internal instances only. |
| ASSERT(!isCSSOMSafe()); |
| |
| if (isValueList()) |
| return toCSSValueList(this)->hasFailedOrCanceledSubresources(); |
| if (classType() == FontFaceSrcClass) |
| return toCSSFontFaceSrcValue(this)->hasFailedOrCanceledSubresources(); |
| if (classType() == ImageClass) |
| return toCSSImageValue(this)->hasFailedOrCanceledSubresources(); |
| if (classType() == CrossfadeClass) |
| return toCSSCrossfadeValue(this)->hasFailedOrCanceledSubresources(); |
| if (classType() == ImageSetClass) |
| return toCSSImageSetValue(this)->hasFailedOrCanceledSubresources(); |
| |
| return false; |
| } |
| |
| template<class ChildClassType> |
| inline static bool compareCSSValues(const CSSValue& first, const CSSValue& second) |
| { |
| return static_cast<const ChildClassType&>(first).equals(static_cast<const ChildClassType&>(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<CSSAspectRatioValue>(*this, other); |
| case BorderImageSliceClass: |
| return compareCSSValues<CSSBorderImageSliceValue>(*this, other); |
| case CanvasClass: |
| return compareCSSValues<CSSCanvasValue>(*this, other); |
| case CursorImageClass: |
| return compareCSSValues<CSSCursorImageValue>(*this, other); |
| case FontClass: |
| return compareCSSValues<CSSFontValue>(*this, other); |
| case FontFaceSrcClass: |
| return compareCSSValues<CSSFontFaceSrcValue>(*this, other); |
| case FontFeatureClass: |
| return compareCSSValues<CSSFontFeatureValue>(*this, other); |
| case FunctionClass: |
| return compareCSSValues<CSSFunctionValue>(*this, other); |
| case LinearGradientClass: |
| return compareCSSValues<CSSLinearGradientValue>(*this, other); |
| case RadialGradientClass: |
| return compareCSSValues<CSSRadialGradientValue>(*this, other); |
| case CrossfadeClass: |
| return compareCSSValues<CSSCrossfadeValue>(*this, other); |
| case ImageClass: |
| return compareCSSValues<CSSImageValue>(*this, other); |
| case InheritedClass: |
| return compareCSSValues<CSSInheritedValue>(*this, other); |
| case InitialClass: |
| return compareCSSValues<CSSInitialValue>(*this, other); |
| case GridTemplateClass: |
| return compareCSSValues<CSSGridTemplateValue>(*this, other); |
| case PrimitiveClass: |
| return compareCSSValues<CSSPrimitiveValue>(*this, other); |
| case ReflectClass: |
| return compareCSSValues<CSSReflectValue>(*this, other); |
| case ShadowClass: |
| return compareCSSValues<CSSShadowValue>(*this, other); |
| case CubicBezierTimingFunctionClass: |
| return compareCSSValues<CSSCubicBezierTimingFunctionValue>(*this, other); |
| case StepsTimingFunctionClass: |
| return compareCSSValues<CSSStepsTimingFunctionValue>(*this, other); |
| case UnicodeRangeClass: |
| return compareCSSValues<CSSUnicodeRangeValue>(*this, other); |
| case ValueListClass: |
| return compareCSSValues<CSSValueList>(*this, other); |
| case CSSTransformClass: |
| return compareCSSValues<CSSTransformValue>(*this, other); |
| case LineBoxContainClass: |
| return compareCSSValues<CSSLineBoxContainValue>(*this, other); |
| case CalculationClass: |
| return compareCSSValues<CSSCalcValue>(*this, other); |
| case ImageSetClass: |
| return compareCSSValues<CSSImageSetValue>(*this, other); |
| case CSSFilterClass: |
| return compareCSSValues<CSSFilterValue>(*this, other); |
| case CSSArrayFunctionValueClass: |
| return compareCSSValues<CSSArrayFunctionValue>(*this, other); |
| case CSSMixFunctionValueClass: |
| return compareCSSValues<CSSMixFunctionValue>(*this, other); |
| case CSSShaderClass: |
| return compareCSSValues<CSSShaderValue>(*this, other); |
| case VariableClass: |
| return compareCSSValues<CSSVariableValue>(*this, other); |
| case SVGColorClass: |
| return compareCSSValues<SVGColor>(*this, other); |
| case SVGPaintClass: |
| return compareCSSValues<SVGPaint>(*this, other); |
| case CSSSVGDocumentClass: |
| return compareCSSValues<CSSSVGDocumentValue>(*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<const CSSValueList&>(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 BorderImageSliceClass: |
| return toCSSBorderImageSliceValue(this)->customCSSText(); |
| case CanvasClass: |
| return toCSSCanvasValue(this)->customCSSText(); |
| case CursorImageClass: |
| return toCSSCursorImageValue(this)->customCSSText(); |
| case FontClass: |
| return toCSSFontValue(this)->customCSSText(); |
| case FontFaceSrcClass: |
| return toCSSFontFaceSrcValue(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 CrossfadeClass: |
| return toCSSCrossfadeValue(this)->customCSSText(); |
| case ImageClass: |
| return toCSSImageValue(this)->customCSSText(); |
| case InheritedClass: |
| return toCSSInheritedValue(this)->customCSSText(); |
| case InitialClass: |
| return toCSSInitialValue(this)->customCSSText(); |
| case GridTemplateClass: |
| return toCSSGridTemplateValue(this)->customCSSText(); |
| case PrimitiveClass: |
| return toCSSPrimitiveValue(this)->customCSSText(); |
| case ReflectClass: |
| return toCSSReflectValue(this)->customCSSText(); |
| case ShadowClass: |
| return toCSSShadowValue(this)->customCSSText(); |
| case CubicBezierTimingFunctionClass: |
| return toCSSCubicBezierTimingFunctionValue(this)->customCSSText(); |
| case StepsTimingFunctionClass: |
| return toCSSStepsTimingFunctionValue(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 ImageSetClass: |
| return toCSSImageSetValue(this)->customCSSText(); |
| case CSSFilterClass: |
| return toCSSFilterValue(this)->customCSSText(); |
| case CSSArrayFunctionValueClass: |
| return toCSSArrayFunctionValue(this)->customCSSText(); |
| case CSSMixFunctionValueClass: |
| return toCSSMixFunctionValue(this)->customCSSText(); |
| case CSSShaderClass: |
| return toCSSShaderValue(this)->customCSSText(); |
| case VariableClass: |
| return toCSSVariableValue(this)->value(); |
| case SVGColorClass: |
| return toSVGColor(this)->customCSSText(); |
| case SVGPaintClass: |
| return toSVGPaint(this)->customCSSText(); |
| case CSSSVGDocumentClass: |
| return toCSSSVGDocumentValue(this)->customCSSText(); |
| } |
| ASSERT_NOT_REACHED(); |
| return String(); |
| } |
| |
| String CSSValue::serializeResolvingVariables(const HashMap<AtomicString, String>& variables) const |
| { |
| switch (classType()) { |
| case PrimitiveClass: |
| return toCSSPrimitiveValue(this)->customSerializeResolvingVariables(variables); |
| case ReflectClass: |
| return toCSSReflectValue(this)->customSerializeResolvingVariables(variables); |
| case ValueListClass: |
| return toCSSValueList(this)->customSerializeResolvingVariables(variables); |
| case CSSTransformClass: |
| return toCSSTransformValue(this)->customSerializeResolvingVariables(variables); |
| default: |
| return cssText(); |
| } |
| } |
| |
| void CSSValue::destroy() |
| { |
| if (m_isTextClone) { |
| ASSERT(isCSSOMSafe()); |
| delete toTextCloneCSSValue(this); |
| return; |
| } |
| ASSERT(!isCSSOMSafe() || isSubtypeExposedToCSSOM()); |
| |
| switch (classType()) { |
| case AspectRatioClass: |
| delete toCSSAspectRatioValue(this); |
| return; |
| case BorderImageSliceClass: |
| delete toCSSBorderImageSliceValue(this); |
| return; |
| case CanvasClass: |
| delete toCSSCanvasValue(this); |
| return; |
| case CursorImageClass: |
| delete toCSSCursorImageValue(this); |
| return; |
| case FontClass: |
| delete toCSSFontValue(this); |
| return; |
| case FontFaceSrcClass: |
| delete toCSSFontFaceSrcValue(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 CrossfadeClass: |
| delete toCSSCrossfadeValue(this); |
| return; |
| case ImageClass: |
| delete toCSSImageValue(this); |
| return; |
| case InheritedClass: |
| delete toCSSInheritedValue(this); |
| return; |
| case InitialClass: |
| delete toCSSInitialValue(this); |
| return; |
| case GridTemplateClass: |
| delete toCSSGridTemplateValue(this); |
| return; |
| case PrimitiveClass: |
| delete toCSSPrimitiveValue(this); |
| return; |
| case ReflectClass: |
| delete toCSSReflectValue(this); |
| return; |
| case ShadowClass: |
| delete toCSSShadowValue(this); |
| return; |
| case CubicBezierTimingFunctionClass: |
| delete toCSSCubicBezierTimingFunctionValue(this); |
| return; |
| case StepsTimingFunctionClass: |
| delete toCSSStepsTimingFunctionValue(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 ImageSetClass: |
| delete toCSSImageSetValue(this); |
| return; |
| case CSSFilterClass: |
| delete toCSSFilterValue(this); |
| return; |
| case CSSArrayFunctionValueClass: |
| delete toCSSArrayFunctionValue(this); |
| return; |
| case CSSMixFunctionValueClass: |
| delete toCSSMixFunctionValue(this); |
| return; |
| case CSSShaderClass: |
| delete toCSSShaderValue(this); |
| return; |
| case VariableClass: |
| delete toCSSVariableValue(this); |
| return; |
| case SVGColorClass: |
| delete toSVGColor(this); |
| return; |
| case SVGPaintClass: |
| delete toSVGPaint(this); |
| return; |
| case CSSSVGDocumentClass: |
| delete toCSSSVGDocumentValue(this); |
| return; |
| } |
| ASSERT_NOT_REACHED(); |
| } |
| |
| PassRefPtr<CSSValue> CSSValue::cloneForCSSOM() const |
| { |
| switch (classType()) { |
| case PrimitiveClass: |
| return toCSSPrimitiveValue(this)->cloneForCSSOM(); |
| case ValueListClass: |
| return toCSSValueList(this)->cloneForCSSOM(); |
| case ImageClass: |
| case CursorImageClass: |
| return toCSSImageValue(this)->cloneForCSSOM(); |
| case CSSFilterClass: |
| return toCSSFilterValue(this)->cloneForCSSOM(); |
| case CSSArrayFunctionValueClass: |
| return toCSSArrayFunctionValue(this)->cloneForCSSOM(); |
| case CSSMixFunctionValueClass: |
| return toCSSMixFunctionValue(this)->cloneForCSSOM(); |
| case CSSTransformClass: |
| return toCSSTransformValue(this)->cloneForCSSOM(); |
| case ImageSetClass: |
| return toCSSImageSetValue(this)->cloneForCSSOM(); |
| case SVGColorClass: |
| return toSVGColor(this)->cloneForCSSOM(); |
| case SVGPaintClass: |
| return toSVGPaint(this)->cloneForCSSOM(); |
| default: |
| ASSERT(!isSubtypeExposedToCSSOM()); |
| return TextCloneCSSValue::create(classType(), cssText()); |
| } |
| } |
| |
| } |