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/CSSFunctionValue.h" 40 #include "core/css/CSSGradientValue.h" 41 #include "core/css/CSSGridTemplateValue.h" 42 #include "core/css/CSSImageSetValue.h" 43 #include "core/css/CSSImageValue.h" 44 #include "core/css/CSSInheritedValue.h" 45 #include "core/css/CSSInitialValue.h" 46 #include "core/css/CSSLineBoxContainValue.h" 47 #include "core/css/CSSMixFunctionValue.h" 48 #include "core/css/CSSPrimitiveValue.h" 49 #include "core/css/CSSReflectValue.h" 50 #include "core/css/CSSSVGDocumentValue.h" 51 #include "core/css/CSSShaderValue.h" 52 #include "core/css/CSSTimingFunctionValue.h" 53 #include "core/css/CSSTransformValue.h" 54 #include "core/css/CSSUnicodeRangeValue.h" 55 #include "core/css/CSSValueList.h" 56 #include "core/css/CSSVariableValue.h" 57 #include "core/css/FontFeatureValue.h" 58 #include "core/css/FontValue.h" 59 #include "core/css/ShadowValue.h" 60 #include "core/svg/SVGColor.h" 61 #include "core/svg/SVGPaint.h" 62 63 namespace WebCore { 64 65 struct SameSizeAsCSSValue : public RefCounted<SameSizeAsCSSValue> { 66 uint32_t bitfields; 67 }; 68 69 COMPILE_ASSERT(sizeof(CSSValue) == sizeof(SameSizeAsCSSValue), CSS_value_should_stay_small); 70 71 class TextCloneCSSValue : public CSSValue { 72 public: 73 static PassRefPtr<TextCloneCSSValue> create(ClassType classType, const String& text) { return adoptRef(new TextCloneCSSValue(classType, text)); } 74 75 String cssText() const { return m_cssText; } 76 77 private: 78 TextCloneCSSValue(ClassType classType, const String& text) 79 : CSSValue(classType, /*isCSSOMSafe*/ true) 80 , m_cssText(text) 81 { 82 m_isTextClone = true; 83 } 84 85 String m_cssText; 86 }; 87 88 bool CSSValue::isImplicitInitialValue() const 89 { 90 return m_classType == InitialClass && static_cast<const CSSInitialValue*>(this)->isImplicit(); 91 } 92 93 CSSValue::Type CSSValue::cssValueType() const 94 { 95 if (isInheritedValue()) 96 return CSS_INHERIT; 97 if (isPrimitiveValue()) 98 return CSS_PRIMITIVE_VALUE; 99 if (isValueList()) 100 return CSS_VALUE_LIST; 101 if (isInitialValue()) 102 return CSS_INITIAL; 103 return CSS_CUSTOM; 104 } 105 106 void CSSValue::addSubresourceStyleURLs(ListHashSet<KURL>& urls, const StyleSheetContents* styleSheet) const 107 { 108 // This should get called for internal instances only. 109 ASSERT(!isCSSOMSafe()); 110 111 if (isPrimitiveValue()) 112 toCSSPrimitiveValue(this)->addSubresourceStyleURLs(urls, styleSheet); 113 else if (isValueList()) 114 toCSSValueList(this)->addSubresourceStyleURLs(urls, styleSheet); 115 else if (classType() == FontFaceSrcClass) 116 static_cast<const CSSFontFaceSrcValue*>(this)->addSubresourceStyleURLs(urls, styleSheet); 117 else if (classType() == ReflectClass) 118 static_cast<const CSSReflectValue*>(this)->addSubresourceStyleURLs(urls, styleSheet); 119 } 120 121 bool CSSValue::hasFailedOrCanceledSubresources() const 122 { 123 // This should get called for internal instances only. 124 ASSERT(!isCSSOMSafe()); 125 126 if (isValueList()) 127 return toCSSValueList(this)->hasFailedOrCanceledSubresources(); 128 if (classType() == FontFaceSrcClass) 129 return static_cast<const CSSFontFaceSrcValue*>(this)->hasFailedOrCanceledSubresources(); 130 if (classType() == ImageClass) 131 return toCSSImageValue(this)->hasFailedOrCanceledSubresources(); 132 if (classType() == CrossfadeClass) 133 return static_cast<const CSSCrossfadeValue*>(this)->hasFailedOrCanceledSubresources(); 134 if (classType() == ImageSetClass) 135 return static_cast<const CSSImageSetValue*>(this)->hasFailedOrCanceledSubresources(); 136 137 return false; 138 } 139 140 template<class ChildClassType> 141 inline static bool compareCSSValues(const CSSValue& first, const CSSValue& second) 142 { 143 return static_cast<const ChildClassType&>(first).equals(static_cast<const ChildClassType&>(second)); 144 } 145 146 bool CSSValue::equals(const CSSValue& other) const 147 { 148 if (m_isTextClone) { 149 ASSERT(isCSSOMSafe()); 150 return static_cast<const TextCloneCSSValue*>(this)->cssText() == other.cssText(); 151 } 152 153 if (m_classType == other.m_classType) { 154 switch (m_classType) { 155 case AspectRatioClass: 156 return compareCSSValues<CSSAspectRatioValue>(*this, other); 157 case BorderImageSliceClass: 158 return compareCSSValues<CSSBorderImageSliceValue>(*this, other); 159 case CanvasClass: 160 return compareCSSValues<CSSCanvasValue>(*this, other); 161 case CursorImageClass: 162 return compareCSSValues<CSSCursorImageValue>(*this, other); 163 case FontClass: 164 return compareCSSValues<FontValue>(*this, other); 165 case FontFaceSrcClass: 166 return compareCSSValues<CSSFontFaceSrcValue>(*this, other); 167 case FontFeatureClass: 168 return compareCSSValues<FontFeatureValue>(*this, other); 169 case FunctionClass: 170 return compareCSSValues<CSSFunctionValue>(*this, other); 171 case LinearGradientClass: 172 return compareCSSValues<CSSLinearGradientValue>(*this, other); 173 case RadialGradientClass: 174 return compareCSSValues<CSSRadialGradientValue>(*this, other); 175 case CrossfadeClass: 176 return compareCSSValues<CSSCrossfadeValue>(*this, other); 177 case ImageClass: 178 return compareCSSValues<CSSImageValue>(*this, other); 179 case InheritedClass: 180 return compareCSSValues<CSSInheritedValue>(*this, other); 181 case InitialClass: 182 return compareCSSValues<CSSInitialValue>(*this, other); 183 case GridTemplateClass: 184 return compareCSSValues<CSSGridTemplateValue>(*this, other); 185 case PrimitiveClass: 186 return compareCSSValues<CSSPrimitiveValue>(*this, other); 187 case ReflectClass: 188 return compareCSSValues<CSSReflectValue>(*this, other); 189 case ShadowClass: 190 return compareCSSValues<ShadowValue>(*this, other); 191 case LinearTimingFunctionClass: 192 return compareCSSValues<CSSLinearTimingFunctionValue>(*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); 199 case ValueListClass: 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); 207 case ImageSetClass: 208 return compareCSSValues<CSSImageSetValue>(*this, other); 209 case CSSFilterClass: 210 return compareCSSValues<CSSFilterValue>(*this, other); 211 case CSSArrayFunctionValueClass: 212 return compareCSSValues<CSSArrayFunctionValue>(*this, other); 213 case CSSMixFunctionValueClass: 214 return compareCSSValues<CSSMixFunctionValue>(*this, other); 215 case CSSShaderClass: 216 return compareCSSValues<CSSShaderValue>(*this, other); 217 case VariableClass: 218 return compareCSSValues<CSSVariableValue>(*this, other); 219 case SVGColorClass: 220 return compareCSSValues<SVGColor>(*this, other); 221 case SVGPaintClass: 222 return compareCSSValues<SVGPaint>(*this, other); 223 case CSSSVGDocumentClass: 224 return compareCSSValues<CSSSVGDocumentValue>(*this, other); 225 default: 226 ASSERT_NOT_REACHED(); 227 return false; 228 } 229 } else if (m_classType == ValueListClass && other.m_classType != ValueListClass) 230 return toCSSValueList(this)->equals(other); 231 else if (m_classType != ValueListClass && other.m_classType == ValueListClass) 232 return static_cast<const CSSValueList&>(other).equals(*this); 233 return false; 234 } 235 236 String CSSValue::cssText() const 237 { 238 if (m_isTextClone) { 239 ASSERT(isCSSOMSafe()); 240 return static_cast<const TextCloneCSSValue*>(this)->cssText(); 241 } 242 ASSERT(!isCSSOMSafe() || isSubtypeExposedToCSSOM()); 243 244 switch (classType()) { 245 case AspectRatioClass: 246 return static_cast<const CSSAspectRatioValue*>(this)->customCssText(); 247 case BorderImageSliceClass: 248 return static_cast<const CSSBorderImageSliceValue*>(this)->customCssText(); 249 case CanvasClass: 250 return static_cast<const CSSCanvasValue*>(this)->customCssText(); 251 case CursorImageClass: 252 return static_cast<const CSSCursorImageValue*>(this)->customCssText(); 253 case FontClass: 254 return static_cast<const FontValue*>(this)->customCssText(); 255 case FontFaceSrcClass: 256 return static_cast<const CSSFontFaceSrcValue*>(this)->customCssText(); 257 case FontFeatureClass: 258 return static_cast<const FontFeatureValue*>(this)->customCssText(); 259 case FunctionClass: 260 return static_cast<const CSSFunctionValue*>(this)->customCssText(); 261 case LinearGradientClass: 262 return static_cast<const CSSLinearGradientValue*>(this)->customCssText(); 263 case RadialGradientClass: 264 return static_cast<const CSSRadialGradientValue*>(this)->customCssText(); 265 case CrossfadeClass: 266 return static_cast<const CSSCrossfadeValue*>(this)->customCssText(); 267 case ImageClass: 268 return toCSSImageValue(this)->customCssText(); 269 case InheritedClass: 270 return static_cast<const CSSInheritedValue*>(this)->customCssText(); 271 case InitialClass: 272 return static_cast<const CSSInitialValue*>(this)->customCssText(); 273 case GridTemplateClass: 274 return static_cast<const CSSGridTemplateValue*>(this)->customCssText(); 275 case PrimitiveClass: 276 return toCSSPrimitiveValue(this)->customCssText(); 277 case ReflectClass: 278 return static_cast<const CSSReflectValue*>(this)->customCssText(); 279 case ShadowClass: 280 return static_cast<const ShadowValue*>(this)->customCssText(); 281 case LinearTimingFunctionClass: 282 return static_cast<const CSSLinearTimingFunctionValue*>(this)->customCssText(); 283 case CubicBezierTimingFunctionClass: 284 return static_cast<const CSSCubicBezierTimingFunctionValue*>(this)->customCssText(); 285 case StepsTimingFunctionClass: 286 return static_cast<const CSSStepsTimingFunctionValue*>(this)->customCssText(); 287 case UnicodeRangeClass: 288 return static_cast<const CSSUnicodeRangeValue*>(this)->customCssText(); 289 case ValueListClass: 290 return toCSSValueList(this)->customCssText(); 291 case CSSTransformClass: 292 return static_cast<const CSSTransformValue*>(this)->customCssText(); 293 case LineBoxContainClass: 294 return static_cast<const CSSLineBoxContainValue*>(this)->customCssText(); 295 case CalculationClass: 296 return static_cast<const CSSCalcValue*>(this)->customCssText(); 297 case ImageSetClass: 298 return static_cast<const CSSImageSetValue*>(this)->customCssText(); 299 case CSSFilterClass: 300 return static_cast<const CSSFilterValue*>(this)->customCssText(); 301 case CSSArrayFunctionValueClass: 302 return static_cast<const CSSArrayFunctionValue*>(this)->customCssText(); 303 case CSSMixFunctionValueClass: 304 return static_cast<const CSSMixFunctionValue*>(this)->customCssText(); 305 case CSSShaderClass: 306 return static_cast<const CSSShaderValue*>(this)->customCssText(); 307 case VariableClass: 308 return toCSSVariableValue(this)->value(); 309 case SVGColorClass: 310 return static_cast<const SVGColor*>(this)->customCssText(); 311 case SVGPaintClass: 312 return static_cast<const SVGPaint*>(this)->customCssText(); 313 case CSSSVGDocumentClass: 314 return static_cast<const CSSSVGDocumentValue*>(this)->customCssText(); 315 } 316 ASSERT_NOT_REACHED(); 317 return String(); 318 } 319 320 String CSSValue::serializeResolvingVariables(const HashMap<AtomicString, String>& variables) const 321 { 322 switch (classType()) { 323 case PrimitiveClass: 324 return toCSSPrimitiveValue(this)->customSerializeResolvingVariables(variables); 325 case ReflectClass: 326 return static_cast<const CSSReflectValue*>(this)->customSerializeResolvingVariables(variables); 327 case ValueListClass: 328 return toCSSValueList(this)->customSerializeResolvingVariables(variables); 329 case CSSTransformClass: 330 return static_cast<const CSSTransformValue*>(this)->customSerializeResolvingVariables(variables); 331 default: 332 return cssText(); 333 } 334 } 335 336 void CSSValue::destroy() 337 { 338 if (m_isTextClone) { 339 ASSERT(isCSSOMSafe()); 340 delete static_cast<TextCloneCSSValue*>(this); 341 return; 342 } 343 ASSERT(!isCSSOMSafe() || isSubtypeExposedToCSSOM()); 344 345 switch (classType()) { 346 case AspectRatioClass: 347 delete static_cast<CSSAspectRatioValue*>(this); 348 return; 349 case BorderImageSliceClass: 350 delete static_cast<CSSBorderImageSliceValue*>(this); 351 return; 352 case CanvasClass: 353 delete static_cast<CSSCanvasValue*>(this); 354 return; 355 case CursorImageClass: 356 delete static_cast<CSSCursorImageValue*>(this); 357 return; 358 case FontClass: 359 delete static_cast<FontValue*>(this); 360 return; 361 case FontFaceSrcClass: 362 delete static_cast<CSSFontFaceSrcValue*>(this); 363 return; 364 case FontFeatureClass: 365 delete static_cast<FontFeatureValue*>(this); 366 return; 367 case FunctionClass: 368 delete static_cast<CSSFunctionValue*>(this); 369 return; 370 case LinearGradientClass: 371 delete static_cast<CSSLinearGradientValue*>(this); 372 return; 373 case RadialGradientClass: 374 delete static_cast<CSSRadialGradientValue*>(this); 375 return; 376 case CrossfadeClass: 377 delete static_cast<CSSCrossfadeValue*>(this); 378 return; 379 case ImageClass: 380 delete toCSSImageValue(this); 381 return; 382 case InheritedClass: 383 delete static_cast<CSSInheritedValue*>(this); 384 return; 385 case InitialClass: 386 delete static_cast<CSSInitialValue*>(this); 387 return; 388 case GridTemplateClass: 389 delete static_cast<CSSGridTemplateValue*>(this); 390 return; 391 case PrimitiveClass: 392 delete toCSSPrimitiveValue(this); 393 return; 394 case ReflectClass: 395 delete static_cast<CSSReflectValue*>(this); 396 return; 397 case ShadowClass: 398 delete static_cast<ShadowValue*>(this); 399 return; 400 case LinearTimingFunctionClass: 401 delete static_cast<CSSLinearTimingFunctionValue*>(this); 402 return; 403 case CubicBezierTimingFunctionClass: 404 delete static_cast<CSSCubicBezierTimingFunctionValue*>(this); 405 return; 406 case StepsTimingFunctionClass: 407 delete static_cast<CSSStepsTimingFunctionValue*>(this); 408 return; 409 case UnicodeRangeClass: 410 delete static_cast<CSSUnicodeRangeValue*>(this); 411 return; 412 case ValueListClass: 413 delete toCSSValueList(this); 414 return; 415 case CSSTransformClass: 416 delete static_cast<CSSTransformValue*>(this); 417 return; 418 case LineBoxContainClass: 419 delete static_cast<CSSLineBoxContainValue*>(this); 420 return; 421 case CalculationClass: 422 delete static_cast<CSSCalcValue*>(this); 423 return; 424 case ImageSetClass: 425 delete static_cast<CSSImageSetValue*>(this); 426 return; 427 case CSSFilterClass: 428 delete static_cast<CSSFilterValue*>(this); 429 return; 430 case CSSArrayFunctionValueClass: 431 delete static_cast<CSSArrayFunctionValue*>(this); 432 return; 433 case CSSMixFunctionValueClass: 434 delete static_cast<CSSMixFunctionValue*>(this); 435 return; 436 case CSSShaderClass: 437 delete static_cast<CSSShaderValue*>(this); 438 return; 439 case VariableClass: 440 delete toCSSVariableValue(this); 441 return; 442 case SVGColorClass: 443 delete static_cast<SVGColor*>(this); 444 return; 445 case SVGPaintClass: 446 delete static_cast<SVGPaint*>(this); 447 return; 448 case CSSSVGDocumentClass: 449 delete static_cast<CSSSVGDocumentValue*>(this); 450 return; 451 } 452 ASSERT_NOT_REACHED(); 453 } 454 455 PassRefPtr<CSSValue> CSSValue::cloneForCSSOM() const 456 { 457 switch (classType()) { 458 case PrimitiveClass: 459 return toCSSPrimitiveValue(this)->cloneForCSSOM(); 460 case ValueListClass: 461 return toCSSValueList(this)->cloneForCSSOM(); 462 case ImageClass: 463 case CursorImageClass: 464 return toCSSImageValue(this)->cloneForCSSOM(); 465 case CSSFilterClass: 466 return static_cast<const CSSFilterValue*>(this)->cloneForCSSOM(); 467 case CSSArrayFunctionValueClass: 468 return static_cast<const CSSArrayFunctionValue*>(this)->cloneForCSSOM(); 469 case CSSMixFunctionValueClass: 470 return static_cast<const CSSMixFunctionValue*>(this)->cloneForCSSOM(); 471 case CSSTransformClass: 472 return static_cast<const CSSTransformValue*>(this)->cloneForCSSOM(); 473 case ImageSetClass: 474 return static_cast<const CSSImageSetValue*>(this)->cloneForCSSOM(); 475 case SVGColorClass: 476 return static_cast<const SVGColor*>(this)->cloneForCSSOM(); 477 case SVGPaintClass: 478 return static_cast<const SVGPaint*>(this)->cloneForCSSOM(); 479 default: 480 ASSERT(!isSubtypeExposedToCSSOM()); 481 return TextCloneCSSValue::create(classType(), cssText()); 482 } 483 } 484 485 } 486