Home | History | Annotate | Download | only in css
      1 /*
      2  * Copyright (C) 2011 Andreas Kling (kling (at) 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 "core/css/CSSValue.h"
     29 
     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/CSSGridTemplateValue.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/CSSMixFunctionValue.h"
     51 #include "core/css/CSSPrimitiveValue.h"
     52 #include "core/css/CSSReflectValue.h"
     53 #include "core/css/CSSSVGDocumentValue.h"
     54 #include "core/css/CSSShaderValue.h"
     55 #include "core/css/CSSShadowValue.h"
     56 #include "core/css/CSSTimingFunctionValue.h"
     57 #include "core/css/CSSTransformValue.h"
     58 #include "core/css/CSSUnicodeRangeValue.h"
     59 #include "core/css/CSSValueList.h"
     60 #include "core/css/CSSVariableValue.h"
     61 #include "core/svg/SVGColor.h"
     62 #include "core/svg/SVGPaint.h"
     63 
     64 namespace WebCore {
     65 
     66 struct SameSizeAsCSSValue : public RefCounted<SameSizeAsCSSValue> {
     67     uint32_t bitfields;
     68 };
     69 
     70 COMPILE_ASSERT(sizeof(CSSValue) <= sizeof(SameSizeAsCSSValue), CSS_value_should_stay_small);
     71 
     72 class TextCloneCSSValue : public CSSValue {
     73 public:
     74     static PassRefPtr<TextCloneCSSValue> create(ClassType classType, const String& text) { return adoptRef(new TextCloneCSSValue(classType, text)); }
     75 
     76     String cssText() const { return m_cssText; }
     77 
     78 private:
     79     TextCloneCSSValue(ClassType classType, const String& text)
     80         : CSSValue(classType, /*isCSSOMSafe*/ true)
     81         , m_cssText(text)
     82     {
     83         m_isTextClone = true;
     84     }
     85 
     86     String m_cssText;
     87 };
     88 
     89 DEFINE_CSS_VALUE_TYPE_CASTS(TextCloneCSSValue, isTextCloneCSSValue());
     90 
     91 bool CSSValue::isImplicitInitialValue() const
     92 {
     93     return m_classType == InitialClass && toCSSInitialValue(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         toCSSPrimitiveValue(this)->addSubresourceStyleURLs(urls, styleSheet);
    116     else if (isValueList())
    117         toCSSValueList(this)->addSubresourceStyleURLs(urls, styleSheet);
    118     else if (classType() == FontFaceSrcClass)
    119         toCSSFontFaceSrcValue(this)->addSubresourceStyleURLs(urls, styleSheet);
    120     else if (classType() == ReflectClass)
    121         toCSSReflectValue(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 toCSSValueList(this)->hasFailedOrCanceledSubresources();
    131     if (classType() == FontFaceSrcClass)
    132         return toCSSFontFaceSrcValue(this)->hasFailedOrCanceledSubresources();
    133     if (classType() == ImageClass)
    134         return toCSSImageValue(this)->hasFailedOrCanceledSubresources();
    135     if (classType() == CrossfadeClass)
    136         return toCSSCrossfadeValue(this)->hasFailedOrCanceledSubresources();
    137     if (classType() == ImageSetClass)
    138         return toCSSImageSetValue(this)->hasFailedOrCanceledSubresources();
    139 
    140     return false;
    141 }
    142 
    143 template<class ChildClassType>
    144 inline static bool compareCSSValues(const CSSValue& first, const CSSValue& second)
    145 {
    146     return static_cast<const ChildClassType&>(first).equals(static_cast<const ChildClassType&>(second));
    147 }
    148 
    149 bool CSSValue::equals(const CSSValue& other) const
    150 {
    151     if (m_isTextClone) {
    152         ASSERT(isCSSOMSafe());
    153         return toTextCloneCSSValue(this)->cssText() == other.cssText();
    154     }
    155 
    156     if (m_classType == other.m_classType) {
    157         switch (m_classType) {
    158         case AspectRatioClass:
    159             return compareCSSValues<CSSAspectRatioValue>(*this, other);
    160         case BorderImageSliceClass:
    161             return compareCSSValues<CSSBorderImageSliceValue>(*this, other);
    162         case CanvasClass:
    163             return compareCSSValues<CSSCanvasValue>(*this, other);
    164         case CursorImageClass:
    165             return compareCSSValues<CSSCursorImageValue>(*this, other);
    166         case FontClass:
    167             return compareCSSValues<CSSFontValue>(*this, other);
    168         case FontFaceSrcClass:
    169             return compareCSSValues<CSSFontFaceSrcValue>(*this, other);
    170         case FontFeatureClass:
    171             return compareCSSValues<CSSFontFeatureValue>(*this, other);
    172         case FunctionClass:
    173             return compareCSSValues<CSSFunctionValue>(*this, other);
    174         case LinearGradientClass:
    175             return compareCSSValues<CSSLinearGradientValue>(*this, other);
    176         case RadialGradientClass:
    177             return compareCSSValues<CSSRadialGradientValue>(*this, other);
    178         case CrossfadeClass:
    179             return compareCSSValues<CSSCrossfadeValue>(*this, other);
    180         case ImageClass:
    181             return compareCSSValues<CSSImageValue>(*this, other);
    182         case InheritedClass:
    183             return compareCSSValues<CSSInheritedValue>(*this, other);
    184         case InitialClass:
    185             return compareCSSValues<CSSInitialValue>(*this, other);
    186         case GridLineNamesClass:
    187             return compareCSSValues<CSSGridLineNamesValue>(*this, other);
    188         case GridTemplateClass:
    189             return compareCSSValues<CSSGridTemplateValue>(*this, other);
    190         case PrimitiveClass:
    191             return compareCSSValues<CSSPrimitiveValue>(*this, other);
    192         case ReflectClass:
    193             return compareCSSValues<CSSReflectValue>(*this, other);
    194         case ShadowClass:
    195             return compareCSSValues<CSSShadowValue>(*this, other);
    196         case CubicBezierTimingFunctionClass:
    197             return compareCSSValues<CSSCubicBezierTimingFunctionValue>(*this, other);
    198         case StepsTimingFunctionClass:
    199             return compareCSSValues<CSSStepsTimingFunctionValue>(*this, other);
    200         case UnicodeRangeClass:
    201             return compareCSSValues<CSSUnicodeRangeValue>(*this, other);
    202         case ValueListClass:
    203             return compareCSSValues<CSSValueList>(*this, other);
    204         case CSSTransformClass:
    205             return compareCSSValues<CSSTransformValue>(*this, other);
    206         case LineBoxContainClass:
    207             return compareCSSValues<CSSLineBoxContainValue>(*this, other);
    208         case CalculationClass:
    209             return compareCSSValues<CSSCalcValue>(*this, other);
    210         case ImageSetClass:
    211             return compareCSSValues<CSSImageSetValue>(*this, other);
    212         case CSSFilterClass:
    213             return compareCSSValues<CSSFilterValue>(*this, other);
    214         case CSSArrayFunctionValueClass:
    215             return compareCSSValues<CSSArrayFunctionValue>(*this, other);
    216         case CSSMixFunctionValueClass:
    217             return compareCSSValues<CSSMixFunctionValue>(*this, other);
    218         case CSSShaderClass:
    219             return compareCSSValues<CSSShaderValue>(*this, other);
    220         case VariableClass:
    221             return compareCSSValues<CSSVariableValue>(*this, other);
    222         case SVGColorClass:
    223             return compareCSSValues<SVGColor>(*this, other);
    224         case SVGPaintClass:
    225             return compareCSSValues<SVGPaint>(*this, other);
    226         case CSSSVGDocumentClass:
    227             return compareCSSValues<CSSSVGDocumentValue>(*this, other);
    228         default:
    229             ASSERT_NOT_REACHED();
    230             return false;
    231         }
    232     } else if (m_classType == ValueListClass && other.m_classType != ValueListClass)
    233         return toCSSValueList(this)->equals(other);
    234     else if (m_classType != ValueListClass && other.m_classType == ValueListClass)
    235         return static_cast<const CSSValueList&>(other).equals(*this);
    236     return false;
    237 }
    238 
    239 String CSSValue::cssText() const
    240 {
    241     if (m_isTextClone) {
    242          ASSERT(isCSSOMSafe());
    243         return toTextCloneCSSValue(this)->cssText();
    244     }
    245     ASSERT(!isCSSOMSafe() || isSubtypeExposedToCSSOM());
    246 
    247     switch (classType()) {
    248     case AspectRatioClass:
    249         return toCSSAspectRatioValue(this)->customCSSText();
    250     case BorderImageSliceClass:
    251         return toCSSBorderImageSliceValue(this)->customCSSText();
    252     case CanvasClass:
    253         return toCSSCanvasValue(this)->customCSSText();
    254     case CursorImageClass:
    255         return toCSSCursorImageValue(this)->customCSSText();
    256     case FontClass:
    257         return toCSSFontValue(this)->customCSSText();
    258     case FontFaceSrcClass:
    259         return toCSSFontFaceSrcValue(this)->customCSSText();
    260     case FontFeatureClass:
    261         return toCSSFontFeatureValue(this)->customCSSText();
    262     case FunctionClass:
    263         return toCSSFunctionValue(this)->customCSSText();
    264     case LinearGradientClass:
    265         return toCSSLinearGradientValue(this)->customCSSText();
    266     case RadialGradientClass:
    267         return toCSSRadialGradientValue(this)->customCSSText();
    268     case CrossfadeClass:
    269         return toCSSCrossfadeValue(this)->customCSSText();
    270     case ImageClass:
    271         return toCSSImageValue(this)->customCSSText();
    272     case InheritedClass:
    273         return toCSSInheritedValue(this)->customCSSText();
    274     case InitialClass:
    275         return toCSSInitialValue(this)->customCSSText();
    276     case GridLineNamesClass:
    277         return toCSSGridLineNamesValue(this)->customCSSText();
    278     case GridTemplateClass:
    279         return toCSSGridTemplateValue(this)->customCSSText();
    280     case PrimitiveClass:
    281         return toCSSPrimitiveValue(this)->customCSSText();
    282     case ReflectClass:
    283         return toCSSReflectValue(this)->customCSSText();
    284     case ShadowClass:
    285         return toCSSShadowValue(this)->customCSSText();
    286     case CubicBezierTimingFunctionClass:
    287         return toCSSCubicBezierTimingFunctionValue(this)->customCSSText();
    288     case StepsTimingFunctionClass:
    289         return toCSSStepsTimingFunctionValue(this)->customCSSText();
    290     case UnicodeRangeClass:
    291         return toCSSUnicodeRangeValue(this)->customCSSText();
    292     case ValueListClass:
    293         return toCSSValueList(this)->customCSSText();
    294     case CSSTransformClass:
    295         return toCSSTransformValue(this)->customCSSText();
    296     case LineBoxContainClass:
    297         return toCSSLineBoxContainValue(this)->customCSSText();
    298     case CalculationClass:
    299         return toCSSCalcValue(this)->customCSSText();
    300     case ImageSetClass:
    301         return toCSSImageSetValue(this)->customCSSText();
    302     case CSSFilterClass:
    303         return toCSSFilterValue(this)->customCSSText();
    304     case CSSArrayFunctionValueClass:
    305         return toCSSArrayFunctionValue(this)->customCSSText();
    306     case CSSMixFunctionValueClass:
    307         return toCSSMixFunctionValue(this)->customCSSText();
    308     case CSSShaderClass:
    309         return toCSSShaderValue(this)->customCSSText();
    310     case VariableClass:
    311         return toCSSVariableValue(this)->value();
    312     case SVGColorClass:
    313         return toSVGColor(this)->customCSSText();
    314     case SVGPaintClass:
    315         return toSVGPaint(this)->customCSSText();
    316     case CSSSVGDocumentClass:
    317         return toCSSSVGDocumentValue(this)->customCSSText();
    318     }
    319     ASSERT_NOT_REACHED();
    320     return String();
    321 }
    322 
    323 String CSSValue::serializeResolvingVariables(const HashMap<AtomicString, String>& variables) const
    324 {
    325     switch (classType()) {
    326     case PrimitiveClass:
    327         return toCSSPrimitiveValue(this)->customSerializeResolvingVariables(variables);
    328     case ReflectClass:
    329         return toCSSReflectValue(this)->customSerializeResolvingVariables(variables);
    330     case ValueListClass:
    331         return toCSSValueList(this)->customSerializeResolvingVariables(variables);
    332     case CSSTransformClass:
    333         return toCSSTransformValue(this)->customSerializeResolvingVariables(variables);
    334     default:
    335         return cssText();
    336     }
    337 }
    338 
    339 void CSSValue::destroy()
    340 {
    341     if (m_isTextClone) {
    342         ASSERT(isCSSOMSafe());
    343         delete toTextCloneCSSValue(this);
    344         return;
    345     }
    346     ASSERT(!isCSSOMSafe() || isSubtypeExposedToCSSOM());
    347 
    348     switch (classType()) {
    349     case AspectRatioClass:
    350         delete toCSSAspectRatioValue(this);
    351         return;
    352     case BorderImageSliceClass:
    353         delete toCSSBorderImageSliceValue(this);
    354         return;
    355     case CanvasClass:
    356         delete toCSSCanvasValue(this);
    357         return;
    358     case CursorImageClass:
    359         delete toCSSCursorImageValue(this);
    360         return;
    361     case FontClass:
    362         delete toCSSFontValue(this);
    363         return;
    364     case FontFaceSrcClass:
    365         delete toCSSFontFaceSrcValue(this);
    366         return;
    367     case FontFeatureClass:
    368         delete toCSSFontFeatureValue(this);
    369         return;
    370     case FunctionClass:
    371         delete toCSSFunctionValue(this);
    372         return;
    373     case LinearGradientClass:
    374         delete toCSSLinearGradientValue(this);
    375         return;
    376     case RadialGradientClass:
    377         delete toCSSRadialGradientValue(this);
    378         return;
    379     case CrossfadeClass:
    380         delete toCSSCrossfadeValue(this);
    381         return;
    382     case ImageClass:
    383         delete toCSSImageValue(this);
    384         return;
    385     case InheritedClass:
    386         delete toCSSInheritedValue(this);
    387         return;
    388     case InitialClass:
    389         delete toCSSInitialValue(this);
    390         return;
    391     case GridLineNamesClass:
    392         delete toCSSGridLineNamesValue(this);
    393         return;
    394     case GridTemplateClass:
    395         delete toCSSGridTemplateValue(this);
    396         return;
    397     case PrimitiveClass:
    398         delete toCSSPrimitiveValue(this);
    399         return;
    400     case ReflectClass:
    401         delete toCSSReflectValue(this);
    402         return;
    403     case ShadowClass:
    404         delete toCSSShadowValue(this);
    405         return;
    406     case CubicBezierTimingFunctionClass:
    407         delete toCSSCubicBezierTimingFunctionValue(this);
    408         return;
    409     case StepsTimingFunctionClass:
    410         delete toCSSStepsTimingFunctionValue(this);
    411         return;
    412     case UnicodeRangeClass:
    413         delete toCSSUnicodeRangeValue(this);
    414         return;
    415     case ValueListClass:
    416         delete toCSSValueList(this);
    417         return;
    418     case CSSTransformClass:
    419         delete toCSSTransformValue(this);
    420         return;
    421     case LineBoxContainClass:
    422         delete toCSSLineBoxContainValue(this);
    423         return;
    424     case CalculationClass:
    425         delete toCSSCalcValue(this);
    426         return;
    427     case ImageSetClass:
    428         delete toCSSImageSetValue(this);
    429         return;
    430     case CSSFilterClass:
    431         delete toCSSFilterValue(this);
    432         return;
    433     case CSSArrayFunctionValueClass:
    434         delete toCSSArrayFunctionValue(this);
    435         return;
    436     case CSSMixFunctionValueClass:
    437         delete toCSSMixFunctionValue(this);
    438         return;
    439     case CSSShaderClass:
    440         delete toCSSShaderValue(this);
    441         return;
    442     case VariableClass:
    443         delete toCSSVariableValue(this);
    444         return;
    445     case SVGColorClass:
    446         delete toSVGColor(this);
    447         return;
    448     case SVGPaintClass:
    449         delete toSVGPaint(this);
    450         return;
    451     case CSSSVGDocumentClass:
    452         delete toCSSSVGDocumentValue(this);
    453         return;
    454     }
    455     ASSERT_NOT_REACHED();
    456 }
    457 
    458 PassRefPtr<CSSValue> CSSValue::cloneForCSSOM() const
    459 {
    460     switch (classType()) {
    461     case PrimitiveClass:
    462         return toCSSPrimitiveValue(this)->cloneForCSSOM();
    463     case ValueListClass:
    464         return toCSSValueList(this)->cloneForCSSOM();
    465     case ImageClass:
    466     case CursorImageClass:
    467         return toCSSImageValue(this)->cloneForCSSOM();
    468     case CSSFilterClass:
    469         return toCSSFilterValue(this)->cloneForCSSOM();
    470     case CSSArrayFunctionValueClass:
    471         return toCSSArrayFunctionValue(this)->cloneForCSSOM();
    472     case CSSMixFunctionValueClass:
    473         return toCSSMixFunctionValue(this)->cloneForCSSOM();
    474     case CSSTransformClass:
    475         return toCSSTransformValue(this)->cloneForCSSOM();
    476     case ImageSetClass:
    477         return toCSSImageSetValue(this)->cloneForCSSOM();
    478     case SVGColorClass:
    479         return toSVGColor(this)->cloneForCSSOM();
    480     case SVGPaintClass:
    481         return toSVGPaint(this)->cloneForCSSOM();
    482     default:
    483         ASSERT(!isSubtypeExposedToCSSOM());
    484         return TextCloneCSSValue::create(classType(), cssText());
    485     }
    486 }
    487 
    488 }
    489