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