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