1 /* 2 * Copyright (C) 2004 Zack Rusin <zack (at) kde.org> 3 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved. 4 * Copyright (C) 2007 Alexey Proskuryakov <ap (at) webkit.org> 5 * Copyright (C) 2007 Nicholas Shanks <webkit (at) nickshanks.com> 6 * Copyright (C) 2011 Sencha, Inc. All rights reserved. 7 * 8 * This library is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU Lesser General Public 10 * License as published by the Free Software Foundation; either 11 * version 2 of the License, or (at your option) any later version. 12 * 13 * This library is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * Lesser General Public License for more details. 17 * 18 * You should have received a copy of the GNU Lesser General Public 19 * License along with this library; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 21 * 02110-1301 USA 22 */ 23 24 #include "config.h" 25 #include "core/css/CSSComputedStyleDeclaration.h" 26 27 #include "CSSPropertyNames.h" 28 #include "FontFamilyNames.h" 29 #include "RuntimeEnabledFeatures.h" 30 #include "StylePropertyShorthand.h" 31 #include "bindings/v8/ExceptionState.h" 32 #include "core/animation/DocumentAnimations.h" 33 #include "core/css/BasicShapeFunctions.h" 34 #include "core/css/CSSArrayFunctionValue.h" 35 #include "core/css/CSSAspectRatioValue.h" 36 #include "core/css/CSSBorderImage.h" 37 #include "core/css/CSSFilterValue.h" 38 #include "core/css/CSSFontFeatureValue.h" 39 #include "core/css/CSSFontValue.h" 40 #include "core/css/CSSFunctionValue.h" 41 #include "core/css/CSSGridLineNamesValue.h" 42 #include "core/css/CSSGridTemplateValue.h" 43 #include "core/css/CSSLineBoxContainValue.h" 44 #include "core/css/CSSMixFunctionValue.h" 45 #include "core/css/CSSParser.h" 46 #include "core/css/CSSPrimitiveValue.h" 47 #include "core/css/CSSPrimitiveValueMappings.h" 48 #include "core/css/CSSReflectValue.h" 49 #include "core/css/CSSSelector.h" 50 #include "core/css/CSSShadowValue.h" 51 #include "core/css/CSSTimingFunctionValue.h" 52 #include "core/css/CSSTransformValue.h" 53 #include "core/css/CSSValueList.h" 54 #include "core/css/CSSValuePool.h" 55 #include "core/css/Pair.h" 56 #include "core/css/Rect.h" 57 #include "core/css/RuntimeCSSEnabled.h" 58 #include "core/css/StylePropertySet.h" 59 #include "core/css/resolver/StyleResolver.h" 60 #include "core/dom/Document.h" 61 #include "core/dom/ExceptionCode.h" 62 #include "core/dom/PseudoElement.h" 63 #include "core/frame/animation/AnimationController.h" 64 #include "core/rendering/RenderBox.h" 65 #include "core/rendering/RenderGrid.h" 66 #include "core/rendering/RenderView.h" 67 #include "core/rendering/style/ContentData.h" 68 #include "core/rendering/style/CounterContent.h" 69 #include "core/rendering/style/CursorList.h" 70 #include "core/rendering/style/RenderStyle.h" 71 #include "core/rendering/style/ShadowList.h" 72 #include "core/rendering/style/ShapeValue.h" 73 #include "core/rendering/style/StyleCustomFilterProgram.h" 74 #include "platform/fonts/FontFeatureSettings.h" 75 #include "platform/graphics/filters/custom/CustomFilterArrayParameter.h" 76 #include "platform/graphics/filters/custom/CustomFilterNumberParameter.h" 77 #include "platform/graphics/filters/custom/CustomFilterOperation.h" 78 #include "platform/graphics/filters/custom/CustomFilterParameter.h" 79 #include "platform/graphics/filters/custom/CustomFilterTransformParameter.h" 80 #include "wtf/text/StringBuilder.h" 81 82 namespace WebCore { 83 84 // List of all properties we know how to compute, omitting shorthands. 85 // NOTE: Do not use this list, use computableProperties() instead 86 // to respect runtime enabling of CSS properties. 87 static const CSSPropertyID staticComputableProperties[] = { 88 CSSPropertyAnimationDelay, 89 CSSPropertyAnimationDirection, 90 CSSPropertyAnimationDuration, 91 CSSPropertyAnimationFillMode, 92 CSSPropertyAnimationIterationCount, 93 CSSPropertyAnimationName, 94 CSSPropertyAnimationPlayState, 95 CSSPropertyAnimationTimingFunction, 96 CSSPropertyBackgroundAttachment, 97 CSSPropertyBackgroundBlendMode, 98 CSSPropertyBackgroundClip, 99 CSSPropertyBackgroundColor, 100 CSSPropertyBackgroundImage, 101 CSSPropertyBackgroundOrigin, 102 CSSPropertyBackgroundPosition, // more-specific background-position-x/y are non-standard 103 CSSPropertyBackgroundRepeat, 104 CSSPropertyBackgroundSize, 105 CSSPropertyBorderBottomColor, 106 CSSPropertyBorderBottomLeftRadius, 107 CSSPropertyBorderBottomRightRadius, 108 CSSPropertyBorderBottomStyle, 109 CSSPropertyBorderBottomWidth, 110 CSSPropertyBorderCollapse, 111 CSSPropertyBorderImageOutset, 112 CSSPropertyBorderImageRepeat, 113 CSSPropertyBorderImageSlice, 114 CSSPropertyBorderImageSource, 115 CSSPropertyBorderImageWidth, 116 CSSPropertyBorderLeftColor, 117 CSSPropertyBorderLeftStyle, 118 CSSPropertyBorderLeftWidth, 119 CSSPropertyBorderRightColor, 120 CSSPropertyBorderRightStyle, 121 CSSPropertyBorderRightWidth, 122 CSSPropertyBorderTopColor, 123 CSSPropertyBorderTopLeftRadius, 124 CSSPropertyBorderTopRightRadius, 125 CSSPropertyBorderTopStyle, 126 CSSPropertyBorderTopWidth, 127 CSSPropertyBottom, 128 CSSPropertyBoxShadow, 129 CSSPropertyBoxSizing, 130 CSSPropertyCaptionSide, 131 CSSPropertyClear, 132 CSSPropertyClip, 133 CSSPropertyColor, 134 CSSPropertyCursor, 135 CSSPropertyDirection, 136 CSSPropertyDisplay, 137 CSSPropertyEmptyCells, 138 CSSPropertyFloat, 139 CSSPropertyFontFamily, 140 CSSPropertyFontKerning, 141 CSSPropertyFontSize, 142 CSSPropertyFontStyle, 143 CSSPropertyFontVariant, 144 CSSPropertyFontWeight, 145 CSSPropertyHeight, 146 CSSPropertyImageRendering, 147 CSSPropertyIsolation, 148 CSSPropertyLeft, 149 CSSPropertyLetterSpacing, 150 CSSPropertyLineHeight, 151 CSSPropertyListStyleImage, 152 CSSPropertyListStylePosition, 153 CSSPropertyListStyleType, 154 CSSPropertyMarginBottom, 155 CSSPropertyMarginLeft, 156 CSSPropertyMarginRight, 157 CSSPropertyMarginTop, 158 CSSPropertyMaxHeight, 159 CSSPropertyMaxWidth, 160 CSSPropertyMinHeight, 161 CSSPropertyMinWidth, 162 CSSPropertyMixBlendMode, 163 CSSPropertyObjectFit, 164 CSSPropertyObjectPosition, 165 CSSPropertyOpacity, 166 CSSPropertyOrphans, 167 CSSPropertyOutlineColor, 168 CSSPropertyOutlineOffset, 169 CSSPropertyOutlineStyle, 170 CSSPropertyOutlineWidth, 171 CSSPropertyOverflowWrap, 172 CSSPropertyOverflowX, 173 CSSPropertyOverflowY, 174 CSSPropertyPaddingBottom, 175 CSSPropertyPaddingLeft, 176 CSSPropertyPaddingRight, 177 CSSPropertyPaddingTop, 178 CSSPropertyPageBreakAfter, 179 CSSPropertyPageBreakBefore, 180 CSSPropertyPageBreakInside, 181 CSSPropertyPointerEvents, 182 CSSPropertyPosition, 183 CSSPropertyResize, 184 CSSPropertyRight, 185 CSSPropertySpeak, 186 CSSPropertyTableLayout, 187 CSSPropertyTabSize, 188 CSSPropertyTextAlign, 189 CSSPropertyTextAlignLast, 190 CSSPropertyTextDecoration, 191 CSSPropertyTextDecorationLine, 192 CSSPropertyTextDecorationStyle, 193 CSSPropertyTextDecorationColor, 194 CSSPropertyTextJustify, 195 CSSPropertyTextUnderlinePosition, 196 CSSPropertyTextIndent, 197 CSSPropertyTextRendering, 198 CSSPropertyTextShadow, 199 CSSPropertyTextOverflow, 200 CSSPropertyTextTransform, 201 CSSPropertyTop, 202 CSSPropertyTouchAction, 203 CSSPropertyTouchActionDelay, 204 CSSPropertyTransitionDelay, 205 CSSPropertyTransitionDuration, 206 CSSPropertyTransitionProperty, 207 CSSPropertyTransitionTimingFunction, 208 CSSPropertyUnicodeBidi, 209 CSSPropertyVerticalAlign, 210 CSSPropertyVisibility, 211 CSSPropertyWhiteSpace, 212 CSSPropertyWidows, 213 CSSPropertyWidth, 214 CSSPropertyWordBreak, 215 CSSPropertyWordSpacing, 216 CSSPropertyWordWrap, 217 CSSPropertyZIndex, 218 CSSPropertyZoom, 219 220 CSSPropertyWebkitAnimationDelay, 221 CSSPropertyWebkitAnimationDirection, 222 CSSPropertyWebkitAnimationDuration, 223 CSSPropertyWebkitAnimationFillMode, 224 CSSPropertyWebkitAnimationIterationCount, 225 CSSPropertyWebkitAnimationName, 226 CSSPropertyWebkitAnimationPlayState, 227 CSSPropertyWebkitAnimationTimingFunction, 228 CSSPropertyWebkitAppearance, 229 CSSPropertyWebkitBackfaceVisibility, 230 CSSPropertyWebkitBackgroundClip, 231 CSSPropertyWebkitBackgroundComposite, 232 CSSPropertyWebkitBackgroundOrigin, 233 CSSPropertyWebkitBackgroundSize, 234 CSSPropertyWebkitBorderFit, 235 CSSPropertyWebkitBorderHorizontalSpacing, 236 CSSPropertyWebkitBorderImage, 237 CSSPropertyWebkitBorderVerticalSpacing, 238 CSSPropertyWebkitBoxAlign, 239 CSSPropertyWebkitBoxDecorationBreak, 240 CSSPropertyWebkitBoxDirection, 241 CSSPropertyWebkitBoxFlex, 242 CSSPropertyWebkitBoxFlexGroup, 243 CSSPropertyWebkitBoxLines, 244 CSSPropertyWebkitBoxOrdinalGroup, 245 CSSPropertyWebkitBoxOrient, 246 CSSPropertyWebkitBoxPack, 247 CSSPropertyWebkitBoxReflect, 248 CSSPropertyWebkitBoxShadow, 249 CSSPropertyWebkitClipPath, 250 CSSPropertyWebkitColumnBreakAfter, 251 CSSPropertyWebkitColumnBreakBefore, 252 CSSPropertyWebkitColumnBreakInside, 253 CSSPropertyWebkitColumnAxis, 254 CSSPropertyWebkitColumnCount, 255 CSSPropertyWebkitColumnGap, 256 CSSPropertyWebkitColumnProgression, 257 CSSPropertyWebkitColumnRuleColor, 258 CSSPropertyWebkitColumnRuleStyle, 259 CSSPropertyWebkitColumnRuleWidth, 260 CSSPropertyWebkitColumnSpan, 261 CSSPropertyWebkitColumnWidth, 262 CSSPropertyWebkitFilter, 263 CSSPropertyAlignContent, 264 CSSPropertyAlignItems, 265 CSSPropertyAlignSelf, 266 CSSPropertyFlexBasis, 267 CSSPropertyFlexGrow, 268 CSSPropertyFlexShrink, 269 CSSPropertyFlexDirection, 270 CSSPropertyFlexWrap, 271 CSSPropertyJustifyContent, 272 CSSPropertyWebkitFontSmoothing, 273 CSSPropertyWebkitFontVariantLigatures, 274 CSSPropertyGridAutoColumns, 275 CSSPropertyGridAutoFlow, 276 CSSPropertyGridAutoRows, 277 CSSPropertyGridColumnEnd, 278 CSSPropertyGridColumnStart, 279 CSSPropertyGridDefinitionColumns, 280 CSSPropertyGridDefinitionRows, 281 CSSPropertyGridRowEnd, 282 CSSPropertyGridRowStart, 283 CSSPropertyWebkitHighlight, 284 CSSPropertyWebkitHyphenateCharacter, 285 CSSPropertyWebkitLineAlign, 286 CSSPropertyWebkitLineBoxContain, 287 CSSPropertyWebkitLineBreak, 288 CSSPropertyWebkitLineClamp, 289 CSSPropertyWebkitLineGrid, 290 CSSPropertyWebkitLineSnap, 291 CSSPropertyWebkitLocale, 292 CSSPropertyWebkitMarginBeforeCollapse, 293 CSSPropertyWebkitMarginAfterCollapse, 294 CSSPropertyWebkitMaskBoxImage, 295 CSSPropertyWebkitMaskBoxImageOutset, 296 CSSPropertyWebkitMaskBoxImageRepeat, 297 CSSPropertyWebkitMaskBoxImageSlice, 298 CSSPropertyWebkitMaskBoxImageSource, 299 CSSPropertyWebkitMaskBoxImageWidth, 300 CSSPropertyWebkitMaskClip, 301 CSSPropertyWebkitMaskComposite, 302 CSSPropertyWebkitMaskImage, 303 CSSPropertyWebkitMaskOrigin, 304 CSSPropertyWebkitMaskPosition, 305 CSSPropertyWebkitMaskRepeat, 306 CSSPropertyWebkitMaskSize, 307 CSSPropertyOrder, 308 CSSPropertyWebkitPerspective, 309 CSSPropertyWebkitPerspectiveOrigin, 310 CSSPropertyWebkitPrintColorAdjust, 311 CSSPropertyWebkitRtlOrdering, 312 CSSPropertyShapeInside, 313 CSSPropertyShapeOutside, 314 CSSPropertyShapePadding, 315 CSSPropertyShapeImageThreshold, 316 CSSPropertyShapeMargin, 317 CSSPropertyWebkitTapHighlightColor, 318 CSSPropertyWebkitTextCombine, 319 CSSPropertyWebkitTextDecorationsInEffect, 320 CSSPropertyWebkitTextEmphasisColor, 321 CSSPropertyWebkitTextEmphasisPosition, 322 CSSPropertyWebkitTextEmphasisStyle, 323 CSSPropertyWebkitTextFillColor, 324 CSSPropertyWebkitTextOrientation, 325 CSSPropertyWebkitTextSecurity, 326 CSSPropertyWebkitTextStrokeColor, 327 CSSPropertyWebkitTextStrokeWidth, 328 CSSPropertyWebkitTransform, 329 CSSPropertyWebkitTransformOrigin, 330 CSSPropertyWebkitTransformStyle, 331 CSSPropertyWebkitTransitionDelay, 332 CSSPropertyWebkitTransitionDuration, 333 CSSPropertyWebkitTransitionProperty, 334 CSSPropertyWebkitTransitionTimingFunction, 335 CSSPropertyWebkitUserDrag, 336 CSSPropertyWebkitUserModify, 337 CSSPropertyWebkitUserSelect, 338 CSSPropertyWebkitWritingMode, 339 CSSPropertyWebkitFlowInto, 340 CSSPropertyWebkitFlowFrom, 341 CSSPropertyWebkitRegionBreakAfter, 342 CSSPropertyWebkitRegionBreakBefore, 343 CSSPropertyWebkitRegionBreakInside, 344 CSSPropertyWebkitRegionFragment, 345 CSSPropertyWebkitAppRegion, 346 CSSPropertyWebkitWrapFlow, 347 CSSPropertyWebkitWrapThrough, 348 CSSPropertyBufferedRendering, 349 CSSPropertyClipPath, 350 CSSPropertyClipRule, 351 CSSPropertyMask, 352 CSSPropertyFilter, 353 CSSPropertyFloodColor, 354 CSSPropertyFloodOpacity, 355 CSSPropertyLightingColor, 356 CSSPropertyStopColor, 357 CSSPropertyStopOpacity, 358 CSSPropertyColorInterpolation, 359 CSSPropertyColorInterpolationFilters, 360 CSSPropertyColorRendering, 361 CSSPropertyFill, 362 CSSPropertyFillOpacity, 363 CSSPropertyFillRule, 364 CSSPropertyMarkerEnd, 365 CSSPropertyMarkerMid, 366 CSSPropertyMarkerStart, 367 CSSPropertyMaskType, 368 CSSPropertyMaskSourceType, 369 CSSPropertyShapeRendering, 370 CSSPropertyStroke, 371 CSSPropertyStrokeDasharray, 372 CSSPropertyStrokeDashoffset, 373 CSSPropertyStrokeLinecap, 374 CSSPropertyStrokeLinejoin, 375 CSSPropertyStrokeMiterlimit, 376 CSSPropertyStrokeOpacity, 377 CSSPropertyStrokeWidth, 378 CSSPropertyAlignmentBaseline, 379 CSSPropertyBaselineShift, 380 CSSPropertyDominantBaseline, 381 CSSPropertyKerning, 382 CSSPropertyTextAnchor, 383 CSSPropertyWritingMode, 384 CSSPropertyGlyphOrientationHorizontal, 385 CSSPropertyGlyphOrientationVertical, 386 CSSPropertyVectorEffect, 387 CSSPropertyPaintOrder 388 }; 389 390 static const Vector<CSSPropertyID>& computableProperties() 391 { 392 DEFINE_STATIC_LOCAL(Vector<CSSPropertyID>, properties, ()); 393 if (properties.isEmpty()) 394 RuntimeCSSEnabled::filterEnabledCSSPropertiesIntoVector(staticComputableProperties, WTF_ARRAY_LENGTH(staticComputableProperties), properties); 395 return properties; 396 } 397 398 static CSSValueID valueForRepeatRule(int rule) 399 { 400 switch (rule) { 401 case RepeatImageRule: 402 return CSSValueRepeat; 403 case RoundImageRule: 404 return CSSValueRound; 405 case SpaceImageRule: 406 return CSSValueSpace; 407 default: 408 return CSSValueStretch; 409 } 410 } 411 412 static PassRefPtr<CSSBorderImageSliceValue> valueForNinePieceImageSlice(const NinePieceImage& image) 413 { 414 // Create the slices. 415 RefPtr<CSSPrimitiveValue> top; 416 RefPtr<CSSPrimitiveValue> right; 417 RefPtr<CSSPrimitiveValue> bottom; 418 RefPtr<CSSPrimitiveValue> left; 419 420 if (image.imageSlices().top().isPercent()) 421 top = cssValuePool().createValue(image.imageSlices().top().value(), CSSPrimitiveValue::CSS_PERCENTAGE); 422 else 423 top = cssValuePool().createValue(image.imageSlices().top().value(), CSSPrimitiveValue::CSS_NUMBER); 424 425 if (image.imageSlices().right() == image.imageSlices().top() && image.imageSlices().bottom() == image.imageSlices().top() 426 && image.imageSlices().left() == image.imageSlices().top()) { 427 right = top; 428 bottom = top; 429 left = top; 430 } else { 431 if (image.imageSlices().right().isPercent()) 432 right = cssValuePool().createValue(image.imageSlices().right().value(), CSSPrimitiveValue::CSS_PERCENTAGE); 433 else 434 right = cssValuePool().createValue(image.imageSlices().right().value(), CSSPrimitiveValue::CSS_NUMBER); 435 436 if (image.imageSlices().bottom() == image.imageSlices().top() && image.imageSlices().right() == image.imageSlices().left()) { 437 bottom = top; 438 left = right; 439 } else { 440 if (image.imageSlices().bottom().isPercent()) 441 bottom = cssValuePool().createValue(image.imageSlices().bottom().value(), CSSPrimitiveValue::CSS_PERCENTAGE); 442 else 443 bottom = cssValuePool().createValue(image.imageSlices().bottom().value(), CSSPrimitiveValue::CSS_NUMBER); 444 445 if (image.imageSlices().left() == image.imageSlices().right()) 446 left = right; 447 else { 448 if (image.imageSlices().left().isPercent()) 449 left = cssValuePool().createValue(image.imageSlices().left().value(), CSSPrimitiveValue::CSS_PERCENTAGE); 450 else 451 left = cssValuePool().createValue(image.imageSlices().left().value(), CSSPrimitiveValue::CSS_NUMBER); 452 } 453 } 454 } 455 456 RefPtr<Quad> quad = Quad::create(); 457 quad->setTop(top); 458 quad->setRight(right); 459 quad->setBottom(bottom); 460 quad->setLeft(left); 461 462 return CSSBorderImageSliceValue::create(cssValuePool().createValue(quad.release()), image.fill()); 463 } 464 465 static PassRefPtr<CSSPrimitiveValue> valueForNinePieceImageQuad(const BorderImageLengthBox& box, const RenderStyle& style) 466 { 467 // Create the slices. 468 RefPtr<CSSPrimitiveValue> top; 469 RefPtr<CSSPrimitiveValue> right; 470 RefPtr<CSSPrimitiveValue> bottom; 471 RefPtr<CSSPrimitiveValue> left; 472 473 if (box.top().isNumber()) 474 top = cssValuePool().createValue(box.top().number(), CSSPrimitiveValue::CSS_NUMBER); 475 else 476 top = cssValuePool().createValue(box.top().length(), style); 477 478 if (box.right() == box.top() && box.bottom() == box.top() && box.left() == box.top()) { 479 right = top; 480 bottom = top; 481 left = top; 482 } else { 483 if (box.right().isNumber()) 484 right = cssValuePool().createValue(box.right().number(), CSSPrimitiveValue::CSS_NUMBER); 485 else 486 right = cssValuePool().createValue(box.right().length(), style); 487 488 if (box.bottom() == box.top() && box.right() == box.left()) { 489 bottom = top; 490 left = right; 491 } else { 492 if (box.bottom().isNumber()) 493 bottom = cssValuePool().createValue(box.bottom().number(), CSSPrimitiveValue::CSS_NUMBER); 494 else 495 bottom = cssValuePool().createValue(box.bottom().length(), style); 496 497 if (box.left() == box.right()) 498 left = right; 499 else { 500 if (box.left().isNumber()) 501 left = cssValuePool().createValue(box.left().number(), CSSPrimitiveValue::CSS_NUMBER); 502 else 503 left = cssValuePool().createValue(box.left().length(), style); 504 } 505 } 506 } 507 508 RefPtr<Quad> quad = Quad::create(); 509 quad->setTop(top); 510 quad->setRight(right); 511 quad->setBottom(bottom); 512 quad->setLeft(left); 513 514 return cssValuePool().createValue(quad.release()); 515 } 516 517 static PassRefPtr<CSSValue> valueForNinePieceImageRepeat(const NinePieceImage& image) 518 { 519 RefPtr<CSSPrimitiveValue> horizontalRepeat; 520 RefPtr<CSSPrimitiveValue> verticalRepeat; 521 522 horizontalRepeat = cssValuePool().createIdentifierValue(valueForRepeatRule(image.horizontalRule())); 523 if (image.horizontalRule() == image.verticalRule()) 524 verticalRepeat = horizontalRepeat; 525 else 526 verticalRepeat = cssValuePool().createIdentifierValue(valueForRepeatRule(image.verticalRule())); 527 return cssValuePool().createValue(Pair::create(horizontalRepeat.release(), verticalRepeat.release(), Pair::DropIdenticalValues)); 528 } 529 530 static PassRefPtr<CSSValue> valueForNinePieceImage(const NinePieceImage& image, const RenderStyle& style) 531 { 532 if (!image.hasImage()) 533 return cssValuePool().createIdentifierValue(CSSValueNone); 534 535 // Image first. 536 RefPtr<CSSValue> imageValue; 537 if (image.image()) 538 imageValue = image.image()->cssValue(); 539 540 // Create the image slice. 541 RefPtr<CSSBorderImageSliceValue> imageSlices = valueForNinePieceImageSlice(image); 542 543 // Create the border area slices. 544 RefPtr<CSSValue> borderSlices = valueForNinePieceImageQuad(image.borderSlices(), style); 545 546 // Create the border outset. 547 RefPtr<CSSValue> outset = valueForNinePieceImageQuad(image.outset(), style); 548 549 // Create the repeat rules. 550 RefPtr<CSSValue> repeat = valueForNinePieceImageRepeat(image); 551 552 return createBorderImageValue(imageValue.release(), imageSlices.release(), borderSlices.release(), outset.release(), repeat.release()); 553 } 554 555 inline static PassRefPtr<CSSPrimitiveValue> zoomAdjustedPixelValue(double value, const RenderStyle& style) 556 { 557 return cssValuePool().createValue(adjustFloatForAbsoluteZoom(value, style), CSSPrimitiveValue::CSS_PX); 558 } 559 560 inline static PassRefPtr<CSSPrimitiveValue> zoomAdjustedNumberValue(double value, const RenderStyle& style) 561 { 562 return cssValuePool().createValue(value / style.effectiveZoom(), CSSPrimitiveValue::CSS_NUMBER); 563 } 564 565 static PassRefPtr<CSSPrimitiveValue> zoomAdjustedPixelValueForLength(const Length& length, const RenderStyle& style) 566 { 567 if (length.isFixed()) 568 return zoomAdjustedPixelValue(length.value(), style); 569 return cssValuePool().createValue(length, style); 570 } 571 572 static PassRefPtr<CSSValue> valueForReflection(const StyleReflection* reflection, const RenderStyle& style) 573 { 574 if (!reflection) 575 return cssValuePool().createIdentifierValue(CSSValueNone); 576 577 RefPtr<CSSPrimitiveValue> offset; 578 if (reflection->offset().isPercent()) 579 offset = cssValuePool().createValue(reflection->offset().percent(), CSSPrimitiveValue::CSS_PERCENTAGE); 580 else 581 offset = zoomAdjustedPixelValue(reflection->offset().value(), style); 582 583 RefPtr<CSSPrimitiveValue> direction; 584 switch (reflection->direction()) { 585 case ReflectionBelow: 586 direction = cssValuePool().createIdentifierValue(CSSValueBelow); 587 break; 588 case ReflectionAbove: 589 direction = cssValuePool().createIdentifierValue(CSSValueAbove); 590 break; 591 case ReflectionLeft: 592 direction = cssValuePool().createIdentifierValue(CSSValueLeft); 593 break; 594 case ReflectionRight: 595 direction = cssValuePool().createIdentifierValue(CSSValueRight); 596 break; 597 } 598 599 return CSSReflectValue::create(direction.release(), offset.release(), valueForNinePieceImage(reflection->mask(), style)); 600 } 601 602 static PassRefPtr<CSSValueList> createPositionListForLayer(CSSPropertyID propertyID, const FillLayer* layer, const RenderStyle& style) 603 { 604 RefPtr<CSSValueList> positionList = CSSValueList::createSpaceSeparated(); 605 if (layer->isBackgroundXOriginSet()) { 606 ASSERT_UNUSED(propertyID, propertyID == CSSPropertyBackgroundPosition || propertyID == CSSPropertyWebkitMaskPosition); 607 positionList->append(cssValuePool().createValue(layer->backgroundXOrigin())); 608 } 609 positionList->append(zoomAdjustedPixelValueForLength(layer->xPosition(), style)); 610 if (layer->isBackgroundYOriginSet()) { 611 ASSERT(propertyID == CSSPropertyBackgroundPosition || propertyID == CSSPropertyWebkitMaskPosition); 612 positionList->append(cssValuePool().createValue(layer->backgroundYOrigin())); 613 } 614 positionList->append(zoomAdjustedPixelValueForLength(layer->yPosition(), style)); 615 return positionList.release(); 616 } 617 618 static PassRefPtr<CSSValue> valueForPositionOffset(RenderStyle& style, CSSPropertyID propertyID, const RenderObject* renderer, RenderView* renderView) 619 { 620 Length l; 621 switch (propertyID) { 622 case CSSPropertyLeft: 623 l = style.left(); 624 break; 625 case CSSPropertyRight: 626 l = style.right(); 627 break; 628 case CSSPropertyTop: 629 l = style.top(); 630 break; 631 case CSSPropertyBottom: 632 l = style.bottom(); 633 break; 634 default: 635 return 0; 636 } 637 638 if (l.isPercent() && renderer && renderer->isBox()) { 639 LayoutUnit containingBlockSize = (propertyID == CSSPropertyLeft || propertyID == CSSPropertyRight) ? 640 toRenderBox(renderer)->containingBlockLogicalWidthForContent() : 641 toRenderBox(renderer)->containingBlockLogicalHeightForContent(ExcludeMarginBorderPadding); 642 return zoomAdjustedPixelValue(valueForLength(l, containingBlockSize, 0), style); 643 } 644 if (l.isViewportPercentage()) 645 return zoomAdjustedPixelValue(valueForLength(l, 0, renderView), style); 646 if (l.isAuto()) { 647 // FIXME: It's not enough to simply return "auto" values for one offset if the other side is defined. 648 // In other words if left is auto and right is not auto, then left's computed value is negative right(). 649 // So we should get the opposite length unit and see if it is auto. 650 return cssValuePool().createValue(l); 651 } 652 653 return zoomAdjustedPixelValueForLength(l, style); 654 } 655 656 PassRefPtr<CSSPrimitiveValue> CSSComputedStyleDeclaration::currentColorOrValidColor(const RenderStyle& style, const Color& color) const 657 { 658 // This function does NOT look at visited information, so that computed style doesn't expose that. 659 if (!color.isValid()) 660 return cssValuePool().createColorValue(style.color().rgb()); 661 return cssValuePool().createColorValue(color.rgb()); 662 } 663 664 static PassRefPtr<CSSValueList> valuesForBorderRadiusCorner(LengthSize radius, const RenderStyle& style) 665 { 666 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); 667 if (radius.width().type() == Percent) 668 list->append(cssValuePool().createValue(radius.width().percent(), CSSPrimitiveValue::CSS_PERCENTAGE)); 669 else 670 list->append(zoomAdjustedPixelValueForLength(radius.width(), style)); 671 if (radius.height().type() == Percent) 672 list->append(cssValuePool().createValue(radius.height().percent(), CSSPrimitiveValue::CSS_PERCENTAGE)); 673 else 674 list->append(zoomAdjustedPixelValueForLength(radius.height(), style)); 675 return list.release(); 676 } 677 678 static PassRefPtr<CSSValue> valueForBorderRadiusCorner(LengthSize radius, const RenderStyle& style) 679 { 680 RefPtr<CSSValueList> list = valuesForBorderRadiusCorner(radius, style); 681 if (list->item(0)->equals(*list->item(1))) 682 return list->item(0); 683 return list.release(); 684 } 685 686 static PassRefPtr<CSSValueList> valueForBorderRadiusShorthand(const RenderStyle& style) 687 { 688 RefPtr<CSSValueList> list = CSSValueList::createSlashSeparated(); 689 690 bool showHorizontalBottomLeft = style.borderTopRightRadius().width() != style.borderBottomLeftRadius().width(); 691 bool showHorizontalBottomRight = showHorizontalBottomLeft || (style.borderBottomRightRadius().width() != style.borderTopLeftRadius().width()); 692 bool showHorizontalTopRight = showHorizontalBottomRight || (style.borderTopRightRadius().width() != style.borderTopLeftRadius().width()); 693 694 bool showVerticalBottomLeft = style.borderTopRightRadius().height() != style.borderBottomLeftRadius().height(); 695 bool showVerticalBottomRight = showVerticalBottomLeft || (style.borderBottomRightRadius().height() != style.borderTopLeftRadius().height()); 696 bool showVerticalTopRight = showVerticalBottomRight || (style.borderTopRightRadius().height() != style.borderTopLeftRadius().height()); 697 698 RefPtr<CSSValueList> topLeftRadius = valuesForBorderRadiusCorner(style.borderTopLeftRadius(), style); 699 RefPtr<CSSValueList> topRightRadius = valuesForBorderRadiusCorner(style.borderTopRightRadius(), style); 700 RefPtr<CSSValueList> bottomRightRadius = valuesForBorderRadiusCorner(style.borderBottomRightRadius(), style); 701 RefPtr<CSSValueList> bottomLeftRadius = valuesForBorderRadiusCorner(style.borderBottomLeftRadius(), style); 702 703 RefPtr<CSSValueList> horizontalRadii = CSSValueList::createSpaceSeparated(); 704 horizontalRadii->append(topLeftRadius->item(0)); 705 if (showHorizontalTopRight) 706 horizontalRadii->append(topRightRadius->item(0)); 707 if (showHorizontalBottomRight) 708 horizontalRadii->append(bottomRightRadius->item(0)); 709 if (showHorizontalBottomLeft) 710 horizontalRadii->append(bottomLeftRadius->item(0)); 711 712 list->append(horizontalRadii.release()); 713 714 RefPtr<CSSValueList> verticalRadii = CSSValueList::createSpaceSeparated(); 715 verticalRadii->append(topLeftRadius->item(1)); 716 if (showVerticalTopRight) 717 verticalRadii->append(topRightRadius->item(1)); 718 if (showVerticalBottomRight) 719 verticalRadii->append(bottomRightRadius->item(1)); 720 if (showVerticalBottomLeft) 721 verticalRadii->append(bottomLeftRadius->item(1)); 722 723 if (!verticalRadii->equals(*toCSSValueList(list->item(0)))) 724 list->append(verticalRadii.release()); 725 726 return list.release(); 727 } 728 729 static LayoutRect sizingBox(RenderObject* renderer) 730 { 731 if (!renderer->isBox()) 732 return LayoutRect(); 733 734 RenderBox* box = toRenderBox(renderer); 735 return box->style()->boxSizing() == BORDER_BOX ? box->borderBoxRect() : box->computedCSSContentBoxRect(); 736 } 737 738 static PassRefPtr<CSSTransformValue> valueForMatrixTransform(const TransformationMatrix& transform, const RenderStyle& style) 739 { 740 RefPtr<CSSTransformValue> transformValue; 741 if (transform.isAffine()) { 742 transformValue = CSSTransformValue::create(CSSTransformValue::MatrixTransformOperation); 743 744 transformValue->append(cssValuePool().createValue(transform.a(), CSSPrimitiveValue::CSS_NUMBER)); 745 transformValue->append(cssValuePool().createValue(transform.b(), CSSPrimitiveValue::CSS_NUMBER)); 746 transformValue->append(cssValuePool().createValue(transform.c(), CSSPrimitiveValue::CSS_NUMBER)); 747 transformValue->append(cssValuePool().createValue(transform.d(), CSSPrimitiveValue::CSS_NUMBER)); 748 transformValue->append(zoomAdjustedNumberValue(transform.e(), style)); 749 transformValue->append(zoomAdjustedNumberValue(transform.f(), style)); 750 } else { 751 transformValue = CSSTransformValue::create(CSSTransformValue::Matrix3DTransformOperation); 752 753 transformValue->append(cssValuePool().createValue(transform.m11(), CSSPrimitiveValue::CSS_NUMBER)); 754 transformValue->append(cssValuePool().createValue(transform.m12(), CSSPrimitiveValue::CSS_NUMBER)); 755 transformValue->append(cssValuePool().createValue(transform.m13(), CSSPrimitiveValue::CSS_NUMBER)); 756 transformValue->append(cssValuePool().createValue(transform.m14(), CSSPrimitiveValue::CSS_NUMBER)); 757 758 transformValue->append(cssValuePool().createValue(transform.m21(), CSSPrimitiveValue::CSS_NUMBER)); 759 transformValue->append(cssValuePool().createValue(transform.m22(), CSSPrimitiveValue::CSS_NUMBER)); 760 transformValue->append(cssValuePool().createValue(transform.m23(), CSSPrimitiveValue::CSS_NUMBER)); 761 transformValue->append(cssValuePool().createValue(transform.m24(), CSSPrimitiveValue::CSS_NUMBER)); 762 763 transformValue->append(cssValuePool().createValue(transform.m31(), CSSPrimitiveValue::CSS_NUMBER)); 764 transformValue->append(cssValuePool().createValue(transform.m32(), CSSPrimitiveValue::CSS_NUMBER)); 765 transformValue->append(cssValuePool().createValue(transform.m33(), CSSPrimitiveValue::CSS_NUMBER)); 766 transformValue->append(cssValuePool().createValue(transform.m34(), CSSPrimitiveValue::CSS_NUMBER)); 767 768 transformValue->append(zoomAdjustedNumberValue(transform.m41(), style)); 769 transformValue->append(zoomAdjustedNumberValue(transform.m42(), style)); 770 transformValue->append(zoomAdjustedNumberValue(transform.m43(), style)); 771 transformValue->append(cssValuePool().createValue(transform.m44(), CSSPrimitiveValue::CSS_NUMBER)); 772 } 773 774 return transformValue.release(); 775 } 776 777 static PassRefPtr<CSSValue> computedTransform(RenderObject* renderer, const RenderStyle& style) 778 { 779 if (!renderer || !renderer->hasTransform() || !style.hasTransform()) 780 return cssValuePool().createIdentifierValue(CSSValueNone); 781 782 IntRect box; 783 if (renderer->isBox()) 784 box = pixelSnappedIntRect(toRenderBox(renderer)->borderBoxRect()); 785 786 TransformationMatrix transform; 787 style.applyTransform(transform, box.size(), RenderStyle::ExcludeTransformOrigin); 788 789 // FIXME: Need to print out individual functions (https://bugs.webkit.org/show_bug.cgi?id=23924) 790 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); 791 list->append(valueForMatrixTransform(transform, style)); 792 793 return list.release(); 794 } 795 796 static PassRefPtr<CSSValue> valueForCustomFilterArrayParameter(const CustomFilterArrayParameter* arrayParameter) 797 { 798 RefPtr<CSSArrayFunctionValue> arrayParameterValue = CSSArrayFunctionValue::create(); 799 for (unsigned i = 0, size = arrayParameter->size(); i < size; ++i) 800 arrayParameterValue->append(cssValuePool().createValue(arrayParameter->valueAt(i), CSSPrimitiveValue::CSS_NUMBER)); 801 return arrayParameterValue.release(); 802 } 803 804 static PassRefPtr<CSSValue> valueForCustomFilterNumberParameter(const CustomFilterNumberParameter* numberParameter) 805 { 806 RefPtr<CSSValueList> numberParameterValue = CSSValueList::createSpaceSeparated(); 807 for (unsigned i = 0; i < numberParameter->size(); ++i) 808 numberParameterValue->append(cssValuePool().createValue(numberParameter->valueAt(i), CSSPrimitiveValue::CSS_NUMBER)); 809 return numberParameterValue.release(); 810 } 811 812 static PassRefPtr<CSSValue> valueForCustomFilterTransformParameter(const RenderObject* renderer, const RenderStyle& style, const CustomFilterTransformParameter* transformParameter) 813 { 814 IntSize size; 815 if (renderer && renderer->isBox()) 816 size = pixelSnappedIntRect(toRenderBox(renderer)->borderBoxRect()).size(); 817 818 TransformationMatrix transform; 819 transformParameter->applyTransform(transform, size); 820 // FIXME: Need to print out individual functions (https://bugs.webkit.org/show_bug.cgi?id=23924) 821 return valueForMatrixTransform(transform, style); 822 } 823 824 static PassRefPtr<CSSValue> valueForCustomFilterParameter(const RenderObject* renderer, const RenderStyle& style, const CustomFilterParameter* parameter) 825 { 826 // FIXME: Add here computed style for the other types: boolean, transform, matrix, texture. 827 ASSERT(parameter); 828 switch (parameter->parameterType()) { 829 case CustomFilterParameter::Array: 830 return valueForCustomFilterArrayParameter(static_cast<const CustomFilterArrayParameter*>(parameter)); 831 case CustomFilterParameter::Number: 832 return valueForCustomFilterNumberParameter(static_cast<const CustomFilterNumberParameter*>(parameter)); 833 case CustomFilterParameter::Transform: 834 return valueForCustomFilterTransformParameter(renderer, style, static_cast<const CustomFilterTransformParameter*>(parameter)); 835 } 836 837 ASSERT_NOT_REACHED(); 838 return 0; 839 } 840 841 PassRefPtr<CSSValue> CSSComputedStyleDeclaration::valueForFilter(const RenderObject* renderer, const RenderStyle& style) const 842 { 843 if (style.filter().operations().isEmpty()) 844 return cssValuePool().createIdentifierValue(CSSValueNone); 845 846 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); 847 848 RefPtr<CSSFilterValue> filterValue; 849 850 Vector<RefPtr<FilterOperation> >::const_iterator end = style.filter().operations().end(); 851 for (Vector<RefPtr<FilterOperation> >::const_iterator it = style.filter().operations().begin(); it != end; ++it) { 852 FilterOperation* filterOperation = (*it).get(); 853 switch (filterOperation->type()) { 854 case FilterOperation::REFERENCE: 855 filterValue = CSSFilterValue::create(CSSFilterValue::ReferenceFilterOperation); 856 filterValue->append(cssValuePool().createValue(toReferenceFilterOperation(filterOperation)->url(), CSSPrimitiveValue::CSS_STRING)); 857 break; 858 case FilterOperation::GRAYSCALE: 859 filterValue = CSSFilterValue::create(CSSFilterValue::GrayscaleFilterOperation); 860 filterValue->append(cssValuePool().createValue(toBasicColorMatrixFilterOperation(filterOperation)->amount(), CSSPrimitiveValue::CSS_NUMBER)); 861 break; 862 case FilterOperation::SEPIA: 863 filterValue = CSSFilterValue::create(CSSFilterValue::SepiaFilterOperation); 864 filterValue->append(cssValuePool().createValue(toBasicColorMatrixFilterOperation(filterOperation)->amount(), CSSPrimitiveValue::CSS_NUMBER)); 865 break; 866 case FilterOperation::SATURATE: 867 filterValue = CSSFilterValue::create(CSSFilterValue::SaturateFilterOperation); 868 filterValue->append(cssValuePool().createValue(toBasicColorMatrixFilterOperation(filterOperation)->amount(), CSSPrimitiveValue::CSS_NUMBER)); 869 break; 870 case FilterOperation::HUE_ROTATE: 871 filterValue = CSSFilterValue::create(CSSFilterValue::HueRotateFilterOperation); 872 filterValue->append(cssValuePool().createValue(toBasicColorMatrixFilterOperation(filterOperation)->amount(), CSSPrimitiveValue::CSS_DEG)); 873 break; 874 case FilterOperation::INVERT: 875 filterValue = CSSFilterValue::create(CSSFilterValue::InvertFilterOperation); 876 filterValue->append(cssValuePool().createValue(toBasicComponentTransferFilterOperation(filterOperation)->amount(), CSSPrimitiveValue::CSS_NUMBER)); 877 break; 878 case FilterOperation::OPACITY: 879 filterValue = CSSFilterValue::create(CSSFilterValue::OpacityFilterOperation); 880 filterValue->append(cssValuePool().createValue(toBasicComponentTransferFilterOperation(filterOperation)->amount(), CSSPrimitiveValue::CSS_NUMBER)); 881 break; 882 case FilterOperation::BRIGHTNESS: 883 filterValue = CSSFilterValue::create(CSSFilterValue::BrightnessFilterOperation); 884 filterValue->append(cssValuePool().createValue(toBasicComponentTransferFilterOperation(filterOperation)->amount(), CSSPrimitiveValue::CSS_NUMBER)); 885 break; 886 case FilterOperation::CONTRAST: 887 filterValue = CSSFilterValue::create(CSSFilterValue::ContrastFilterOperation); 888 filterValue->append(cssValuePool().createValue(toBasicComponentTransferFilterOperation(filterOperation)->amount(), CSSPrimitiveValue::CSS_NUMBER)); 889 break; 890 case FilterOperation::BLUR: 891 filterValue = CSSFilterValue::create(CSSFilterValue::BlurFilterOperation); 892 filterValue->append(zoomAdjustedPixelValue(toBlurFilterOperation(filterOperation)->stdDeviation().value(), style)); 893 break; 894 case FilterOperation::DROP_SHADOW: { 895 DropShadowFilterOperation* dropShadowOperation = toDropShadowFilterOperation(filterOperation); 896 filterValue = CSSFilterValue::create(CSSFilterValue::DropShadowFilterOperation); 897 // We want our computed style to look like that of a text shadow (has neither spread nor inset style). 898 ShadowData shadow(dropShadowOperation->location(), dropShadowOperation->stdDeviation(), 0, Normal, dropShadowOperation->color()); 899 filterValue->append(valueForShadowData(shadow, style, false)); 900 break; 901 } 902 case FilterOperation::VALIDATED_CUSTOM: 903 // ValidatedCustomFilterOperation is not supposed to end up in the RenderStyle. 904 ASSERT_NOT_REACHED(); 905 break; 906 case FilterOperation::CUSTOM: { 907 CustomFilterOperation* customOperation = toCustomFilterOperation(filterOperation); 908 filterValue = CSSFilterValue::create(CSSFilterValue::CustomFilterOperation); 909 910 // The output should be verbose, even if the values are the default ones. 911 912 ASSERT(customOperation->program()); 913 StyleCustomFilterProgram* program = static_cast<StyleCustomFilterProgram*>(customOperation->program()); 914 915 RefPtr<CSSValueList> shadersList = CSSValueList::createSpaceSeparated(); 916 if (program->vertexShader()) 917 shadersList->append(program->vertexShader()->cssValue()); 918 else 919 shadersList->append(cssValuePool().createIdentifierValue(CSSValueNone)); 920 921 const CustomFilterProgramMixSettings mixSettings = program->mixSettings(); 922 if (program->fragmentShader()) { 923 if (program->programType() == ProgramTypeBlendsElementTexture) { 924 RefPtr<CSSMixFunctionValue> mixFunction = CSSMixFunctionValue::create(); 925 mixFunction->append(program->fragmentShader()->cssValue()); 926 mixFunction->append(cssValuePool().createValue(mixSettings.blendMode)); 927 mixFunction->append(cssValuePool().createValue(mixSettings.compositeOperator)); 928 shadersList->append(mixFunction.release()); 929 } else 930 shadersList->append(program->fragmentShader()->cssValue()); 931 } 932 else 933 shadersList->append(cssValuePool().createIdentifierValue(CSSValueNone)); 934 935 filterValue->append(shadersList.release()); 936 937 RefPtr<CSSValueList> meshParameters = CSSValueList::createSpaceSeparated(); 938 meshParameters->append(cssValuePool().createValue(customOperation->meshColumns(), CSSPrimitiveValue::CSS_NUMBER)); 939 meshParameters->append(cssValuePool().createValue(customOperation->meshRows(), CSSPrimitiveValue::CSS_NUMBER)); 940 941 // FIXME: The specification doesn't have any "attached" identifier. Should we add one? 942 // https://bugs.webkit.org/show_bug.cgi?id=72700 943 if (customOperation->meshType() == MeshTypeDetached) 944 meshParameters->append(cssValuePool().createIdentifierValue(CSSValueDetached)); 945 946 filterValue->append(meshParameters.release()); 947 948 const CustomFilterParameterList& parameters = customOperation->parameters(); 949 size_t parametersSize = parameters.size(); 950 if (!parametersSize) 951 break; 952 RefPtr<CSSValueList> parametersCSSValue = CSSValueList::createCommaSeparated(); 953 for (size_t i = 0; i < parametersSize; ++i) { 954 const CustomFilterParameter* parameter = parameters.at(i).get(); 955 RefPtr<CSSValueList> parameterCSSNameAndValue = CSSValueList::createSpaceSeparated(); 956 parameterCSSNameAndValue->append(cssValuePool().createValue(parameter->name(), CSSPrimitiveValue::CSS_STRING)); 957 parameterCSSNameAndValue->append(valueForCustomFilterParameter(renderer, style, parameter)); 958 parametersCSSValue->append(parameterCSSNameAndValue.release()); 959 } 960 961 filterValue->append(parametersCSSValue.release()); 962 break; 963 } 964 default: 965 filterValue = CSSFilterValue::create(CSSFilterValue::UnknownFilterOperation); 966 break; 967 } 968 list->append(filterValue.release()); 969 } 970 971 return list.release(); 972 } 973 974 static PassRefPtr<CSSValue> specifiedValueForGridTrackBreadth(const GridLength& trackBreadth, const RenderStyle& style, RenderView* renderView) 975 { 976 if (!trackBreadth.isLength()) 977 return cssValuePool().createValue(trackBreadth.flex(), CSSPrimitiveValue::CSS_FR); 978 979 const Length& trackBreadthLength = trackBreadth.length(); 980 if (trackBreadthLength.isAuto()) 981 return cssValuePool().createIdentifierValue(CSSValueAuto); 982 if (trackBreadthLength.isViewportPercentage()) 983 return zoomAdjustedPixelValue(valueForLength(trackBreadthLength, 0, renderView), style); 984 return zoomAdjustedPixelValueForLength(trackBreadthLength, style); 985 } 986 987 static PassRefPtr<CSSValue> specifiedValueForGridTrackSize(const GridTrackSize& trackSize, const RenderStyle& style, RenderView* renderView) 988 { 989 switch (trackSize.type()) { 990 case LengthTrackSizing: 991 return specifiedValueForGridTrackBreadth(trackSize.length(), style, renderView); 992 case MinMaxTrackSizing: 993 RefPtr<CSSValueList> minMaxTrackBreadths = CSSValueList::createCommaSeparated(); 994 minMaxTrackBreadths->append(specifiedValueForGridTrackBreadth(trackSize.minTrackBreadth(), style, renderView)); 995 minMaxTrackBreadths->append(specifiedValueForGridTrackBreadth(trackSize.maxTrackBreadth(), style, renderView)); 996 return CSSFunctionValue::create("minmax(", minMaxTrackBreadths); 997 } 998 ASSERT_NOT_REACHED(); 999 return 0; 1000 } 1001 1002 static void addValuesForNamedGridLinesAtIndex(const OrderedNamedGridLines& orderedNamedGridLines, size_t i, CSSValueList& list) 1003 { 1004 const Vector<String>& namedGridLines = orderedNamedGridLines.get(i); 1005 if (namedGridLines.isEmpty()) 1006 return; 1007 1008 RefPtr<CSSGridLineNamesValue> lineNames = CSSGridLineNamesValue::create(); 1009 for (size_t j = 0; j < namedGridLines.size(); ++j) 1010 lineNames->append(cssValuePool().createValue(namedGridLines[j], CSSPrimitiveValue::CSS_STRING)); 1011 list.append(lineNames.release()); 1012 } 1013 1014 static PassRefPtr<CSSValue> valueForGridTrackList(GridTrackSizingDirection direction, RenderObject* renderer, const RenderStyle& style, RenderView* renderView) 1015 { 1016 const Vector<GridTrackSize>& trackSizes = direction == ForColumns ? style.gridDefinitionColumns() : style.gridDefinitionRows(); 1017 const OrderedNamedGridLines& orderedNamedGridLines = direction == ForColumns ? style.orderedNamedGridColumnLines() : style.orderedNamedGridRowLines(); 1018 1019 // Handle the 'none' case here. 1020 if (!trackSizes.size()) { 1021 ASSERT(orderedNamedGridLines.isEmpty()); 1022 return cssValuePool().createIdentifierValue(CSSValueNone); 1023 } 1024 1025 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); 1026 if (renderer && renderer->isRenderGrid()) { 1027 const Vector<LayoutUnit>& trackPositions = direction == ForColumns ? toRenderGrid(renderer)->columnPositions() : toRenderGrid(renderer)->rowPositions(); 1028 // There are at least #tracks + 1 grid lines (trackPositions). Apart from that, the grid container can generate implicit grid tracks, 1029 // so we'll have more trackPositions than trackSizes as the latter only contain the explicit grid. 1030 ASSERT(trackPositions.size() - 1 >= trackSizes.size()); 1031 1032 for (size_t i = 0; i < trackSizes.size(); ++i) { 1033 addValuesForNamedGridLinesAtIndex(orderedNamedGridLines, i, *list); 1034 list->append(zoomAdjustedPixelValue(trackPositions[i + 1] - trackPositions[i], style)); 1035 } 1036 } else { 1037 for (size_t i = 0; i < trackSizes.size(); ++i) { 1038 addValuesForNamedGridLinesAtIndex(orderedNamedGridLines, i, *list); 1039 list->append(specifiedValueForGridTrackSize(trackSizes[i], style, renderView)); 1040 } 1041 } 1042 // Those are the trailing <string>* allowed in the syntax. 1043 addValuesForNamedGridLinesAtIndex(orderedNamedGridLines, trackSizes.size(), *list); 1044 return list.release(); 1045 } 1046 1047 static PassRefPtr<CSSValue> valueForGridPosition(const GridPosition& position) 1048 { 1049 if (position.isAuto()) 1050 return cssValuePool().createIdentifierValue(CSSValueAuto); 1051 1052 if (position.isNamedGridArea()) 1053 return cssValuePool().createValue(position.namedGridLine(), CSSPrimitiveValue::CSS_STRING); 1054 1055 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); 1056 if (position.isSpan()) { 1057 list->append(cssValuePool().createIdentifierValue(CSSValueSpan)); 1058 list->append(cssValuePool().createValue(position.spanPosition(), CSSPrimitiveValue::CSS_NUMBER)); 1059 } else 1060 list->append(cssValuePool().createValue(position.integerPosition(), CSSPrimitiveValue::CSS_NUMBER)); 1061 1062 if (!position.namedGridLine().isNull()) 1063 list->append(cssValuePool().createValue(position.namedGridLine(), CSSPrimitiveValue::CSS_STRING)); 1064 return list; 1065 } 1066 static PassRefPtr<CSSValue> createTransitionPropertyValue(const CSSAnimationData* animation) 1067 { 1068 RefPtr<CSSValue> propertyValue; 1069 if (animation->animationMode() == CSSAnimationData::AnimateNone) 1070 propertyValue = cssValuePool().createIdentifierValue(CSSValueNone); 1071 else if (animation->animationMode() == CSSAnimationData::AnimateAll) 1072 propertyValue = cssValuePool().createIdentifierValue(CSSValueAll); 1073 else 1074 propertyValue = cssValuePool().createValue(getPropertyNameString(animation->property()), CSSPrimitiveValue::CSS_STRING); 1075 return propertyValue.release(); 1076 } 1077 static PassRefPtr<CSSValue> valueForTransitionProperty(const CSSAnimationDataList* animList) 1078 { 1079 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); 1080 if (animList) { 1081 for (size_t i = 0; i < animList->size(); ++i) 1082 list->append(createTransitionPropertyValue(animList->animation(i))); 1083 } else 1084 list->append(cssValuePool().createIdentifierValue(CSSValueAll)); 1085 return list.release(); 1086 } 1087 1088 static PassRefPtr<CSSValue> valueForAnimationDelay(const CSSAnimationDataList* animList) 1089 { 1090 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); 1091 if (animList) { 1092 for (size_t i = 0; i < animList->size(); ++i) 1093 list->append(cssValuePool().createValue(animList->animation(i)->delay(), CSSPrimitiveValue::CSS_S)); 1094 } else { 1095 // Note that initialAnimationDelay() is used for both transitions and animations 1096 list->append(cssValuePool().createValue(CSSAnimationData::initialAnimationDelay(), CSSPrimitiveValue::CSS_S)); 1097 } 1098 return list.release(); 1099 } 1100 1101 static PassRefPtr<CSSValue> valueForAnimationDuration(const CSSAnimationDataList* animList) 1102 { 1103 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); 1104 if (animList) { 1105 for (size_t i = 0; i < animList->size(); ++i) 1106 list->append(cssValuePool().createValue(animList->animation(i)->duration(), CSSPrimitiveValue::CSS_S)); 1107 } else { 1108 // Note that initialAnimationDuration() is used for both transitions and animations 1109 list->append(cssValuePool().createValue(CSSAnimationData::initialAnimationDuration(), CSSPrimitiveValue::CSS_S)); 1110 } 1111 return list.release(); 1112 } 1113 1114 static PassRefPtr<CSSValue> createTimingFunctionValue(const TimingFunction* timingFunction) 1115 { 1116 switch (timingFunction->type()) { 1117 case TimingFunction::CubicBezierFunction: 1118 { 1119 const CubicBezierTimingFunction* bezierTimingFunction = toCubicBezierTimingFunction(timingFunction); 1120 if (bezierTimingFunction->subType() != CubicBezierTimingFunction::Custom) { 1121 CSSValueID valueId = CSSValueInvalid; 1122 switch (bezierTimingFunction->subType()) { 1123 case CubicBezierTimingFunction::Ease: 1124 valueId = CSSValueEase; 1125 break; 1126 case CubicBezierTimingFunction::EaseIn: 1127 valueId = CSSValueEaseIn; 1128 break; 1129 case CubicBezierTimingFunction::EaseOut: 1130 valueId = CSSValueEaseOut; 1131 break; 1132 case CubicBezierTimingFunction::EaseInOut: 1133 valueId = CSSValueEaseInOut; 1134 break; 1135 default: 1136 ASSERT_NOT_REACHED(); 1137 return 0; 1138 } 1139 return cssValuePool().createIdentifierValue(valueId); 1140 } 1141 return CSSCubicBezierTimingFunctionValue::create(bezierTimingFunction->x1(), bezierTimingFunction->y1(), bezierTimingFunction->x2(), bezierTimingFunction->y2()); 1142 } 1143 1144 case TimingFunction::StepsFunction: 1145 { 1146 const StepsTimingFunction* stepsTimingFunction = toStepsTimingFunction(timingFunction); 1147 if (stepsTimingFunction->subType() == StepsTimingFunction::Custom) 1148 return CSSStepsTimingFunctionValue::create(stepsTimingFunction->numberOfSteps(), stepsTimingFunction->stepAtStart()); 1149 CSSValueID valueId; 1150 switch (stepsTimingFunction->subType()) { 1151 case StepsTimingFunction::Start: 1152 valueId = CSSValueStepStart; 1153 break; 1154 case StepsTimingFunction::End: 1155 valueId = CSSValueStepEnd; 1156 break; 1157 default: 1158 ASSERT_NOT_REACHED(); 1159 return 0; 1160 } 1161 return cssValuePool().createIdentifierValue(valueId); 1162 } 1163 1164 default: 1165 return cssValuePool().createIdentifierValue(CSSValueLinear); 1166 } 1167 } 1168 1169 static PassRefPtr<CSSValue> valueForAnimationTimingFunction(const CSSAnimationDataList* animList) 1170 { 1171 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); 1172 if (animList) { 1173 for (size_t i = 0; i < animList->size(); ++i) 1174 list->append(createTimingFunctionValue(animList->animation(i)->timingFunction())); 1175 } else 1176 // Note that initialAnimationTimingFunction() is used for both transitions and animations 1177 list->append(createTimingFunctionValue(CSSAnimationData::initialAnimationTimingFunction().get())); 1178 return list.release(); 1179 } 1180 1181 static PassRefPtr<CSSValue> valueForAnimationFillMode(unsigned fillMode) 1182 { 1183 switch (fillMode) { 1184 case AnimationFillModeNone: 1185 return cssValuePool().createIdentifierValue(CSSValueNone); 1186 case AnimationFillModeForwards: 1187 return cssValuePool().createIdentifierValue(CSSValueForwards); 1188 case AnimationFillModeBackwards: 1189 return cssValuePool().createIdentifierValue(CSSValueBackwards); 1190 case AnimationFillModeBoth: 1191 return cssValuePool().createIdentifierValue(CSSValueBoth); 1192 default: 1193 ASSERT_NOT_REACHED(); 1194 return 0; 1195 } 1196 } 1197 1198 static PassRefPtr<CSSValue> valueForAnimationDirection(CSSAnimationData::AnimationDirection direction) 1199 { 1200 switch (direction) { 1201 case CSSAnimationData::AnimationDirectionNormal: 1202 return cssValuePool().createIdentifierValue(CSSValueNormal); 1203 case CSSAnimationData::AnimationDirectionAlternate: 1204 return cssValuePool().createIdentifierValue(CSSValueAlternate); 1205 case CSSAnimationData::AnimationDirectionReverse: 1206 return cssValuePool().createIdentifierValue(CSSValueReverse); 1207 case CSSAnimationData::AnimationDirectionAlternateReverse: 1208 return cssValuePool().createIdentifierValue(CSSValueAlternateReverse); 1209 default: 1210 ASSERT_NOT_REACHED(); 1211 return 0; 1212 } 1213 } 1214 1215 static PassRefPtr<CSSValue> createLineBoxContainValue(unsigned lineBoxContain) 1216 { 1217 if (!lineBoxContain) 1218 return cssValuePool().createIdentifierValue(CSSValueNone); 1219 return CSSLineBoxContainValue::create(lineBoxContain); 1220 } 1221 1222 CSSComputedStyleDeclaration::CSSComputedStyleDeclaration(PassRefPtr<Node> n, bool allowVisitedStyle, const String& pseudoElementName) 1223 : m_node(n) 1224 , m_allowVisitedStyle(allowVisitedStyle) 1225 , m_refCount(1) 1226 { 1227 unsigned nameWithoutColonsStart = pseudoElementName[0] == ':' ? (pseudoElementName[1] == ':' ? 2 : 1) : 0; 1228 m_pseudoElementSpecifier = CSSSelector::pseudoId(CSSSelector::parsePseudoType( 1229 AtomicString(pseudoElementName.substring(nameWithoutColonsStart)))); 1230 } 1231 1232 CSSComputedStyleDeclaration::~CSSComputedStyleDeclaration() 1233 { 1234 } 1235 1236 void CSSComputedStyleDeclaration::ref() 1237 { 1238 ++m_refCount; 1239 } 1240 1241 void CSSComputedStyleDeclaration::deref() 1242 { 1243 ASSERT(m_refCount); 1244 if (!--m_refCount) 1245 delete this; 1246 } 1247 1248 String CSSComputedStyleDeclaration::cssText() const 1249 { 1250 StringBuilder result; 1251 const Vector<CSSPropertyID>& properties = computableProperties(); 1252 1253 for (unsigned i = 0; i < properties.size(); i++) { 1254 if (i) 1255 result.append(' '); 1256 result.append(getPropertyName(properties[i])); 1257 result.append(": ", 2); 1258 result.append(getPropertyValue(properties[i])); 1259 result.append(';'); 1260 } 1261 1262 return result.toString(); 1263 } 1264 1265 void CSSComputedStyleDeclaration::setCSSText(const String&, ExceptionState& exceptionState) 1266 { 1267 exceptionState.throwDOMException(NoModificationAllowedError, "These styles are computed, and therefore read-only."); 1268 } 1269 1270 static CSSValueID cssIdentifierForFontSizeKeyword(int keywordSize) 1271 { 1272 ASSERT_ARG(keywordSize, keywordSize); 1273 ASSERT_ARG(keywordSize, keywordSize <= 8); 1274 return static_cast<CSSValueID>(CSSValueXxSmall + keywordSize - 1); 1275 } 1276 1277 PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getFontSizeCSSValuePreferringKeyword() const 1278 { 1279 if (!m_node) 1280 return 0; 1281 1282 m_node->document().updateLayoutIgnorePendingStylesheets(); 1283 1284 RefPtr<RenderStyle> style = m_node->computedStyle(m_pseudoElementSpecifier); 1285 if (!style) 1286 return 0; 1287 1288 if (int keywordSize = style->fontDescription().keywordSize()) 1289 return cssValuePool().createIdentifierValue(cssIdentifierForFontSizeKeyword(keywordSize)); 1290 1291 1292 return zoomAdjustedPixelValue(style->fontDescription().computedPixelSize(), *style); 1293 } 1294 1295 bool CSSComputedStyleDeclaration::useFixedFontDefaultSize() const 1296 { 1297 if (!m_node) 1298 return false; 1299 1300 RefPtr<RenderStyle> style = m_node->computedStyle(m_pseudoElementSpecifier); 1301 if (!style) 1302 return false; 1303 1304 return style->fontDescription().useFixedDefaultSize(); 1305 } 1306 1307 PassRefPtr<CSSValue> CSSComputedStyleDeclaration::valueForShadowData(const ShadowData& shadow, const RenderStyle& style, bool useSpread) const 1308 { 1309 RefPtr<CSSPrimitiveValue> x = zoomAdjustedPixelValue(shadow.x(), style); 1310 RefPtr<CSSPrimitiveValue> y = zoomAdjustedPixelValue(shadow.y(), style); 1311 RefPtr<CSSPrimitiveValue> blur = zoomAdjustedPixelValue(shadow.blur(), style); 1312 RefPtr<CSSPrimitiveValue> spread = useSpread ? zoomAdjustedPixelValue(shadow.spread(), style) : PassRefPtr<CSSPrimitiveValue>(); 1313 RefPtr<CSSPrimitiveValue> shadowStyle = shadow.style() == Normal ? PassRefPtr<CSSPrimitiveValue>() : cssValuePool().createIdentifierValue(CSSValueInset); 1314 RefPtr<CSSPrimitiveValue> color = currentColorOrValidColor(style, shadow.color()); 1315 return CSSShadowValue::create(x.release(), y.release(), blur.release(), spread.release(), shadowStyle.release(), color.release()); 1316 } 1317 1318 PassRefPtr<CSSValue> CSSComputedStyleDeclaration::valueForShadowList(const ShadowList* shadowList, const RenderStyle& style, bool useSpread) const 1319 { 1320 if (!shadowList) 1321 return cssValuePool().createIdentifierValue(CSSValueNone); 1322 1323 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); 1324 size_t shadowCount = shadowList->shadows().size(); 1325 for (size_t i = 0; i < shadowCount; ++i) 1326 list->append(valueForShadowData(shadowList->shadows()[i], style, useSpread)); 1327 return list.release(); 1328 } 1329 1330 PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropertyID propertyID) const 1331 { 1332 return getPropertyCSSValue(propertyID, UpdateLayout); 1333 } 1334 1335 static CSSValueID identifierForFamily(const AtomicString& family) 1336 { 1337 if (family == FontFamilyNames::webkit_cursive) 1338 return CSSValueCursive; 1339 if (family == FontFamilyNames::webkit_fantasy) 1340 return CSSValueFantasy; 1341 if (family == FontFamilyNames::webkit_monospace) 1342 return CSSValueMonospace; 1343 if (family == FontFamilyNames::webkit_pictograph) 1344 return CSSValueWebkitPictograph; 1345 if (family == FontFamilyNames::webkit_sans_serif) 1346 return CSSValueSansSerif; 1347 if (family == FontFamilyNames::webkit_serif) 1348 return CSSValueSerif; 1349 return CSSValueInvalid; 1350 } 1351 1352 static PassRefPtr<CSSPrimitiveValue> valueForFamily(const AtomicString& family) 1353 { 1354 if (CSSValueID familyIdentifier = identifierForFamily(family)) 1355 return cssValuePool().createIdentifierValue(familyIdentifier); 1356 return cssValuePool().createValue(family.string(), CSSPrimitiveValue::CSS_STRING); 1357 } 1358 1359 static PassRefPtr<CSSValue> renderTextDecorationFlagsToCSSValue(int textDecoration) 1360 { 1361 // Blink value is ignored. 1362 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); 1363 if (textDecoration & TextDecorationUnderline) 1364 list->append(cssValuePool().createIdentifierValue(CSSValueUnderline)); 1365 if (textDecoration & TextDecorationOverline) 1366 list->append(cssValuePool().createIdentifierValue(CSSValueOverline)); 1367 if (textDecoration & TextDecorationLineThrough) 1368 list->append(cssValuePool().createIdentifierValue(CSSValueLineThrough)); 1369 1370 if (!list->length()) 1371 return cssValuePool().createIdentifierValue(CSSValueNone); 1372 return list.release(); 1373 } 1374 1375 static PassRefPtr<CSSValue> valueForTextDecorationStyle(TextDecorationStyle textDecorationStyle) 1376 { 1377 switch (textDecorationStyle) { 1378 case TextDecorationStyleSolid: 1379 return cssValuePool().createIdentifierValue(CSSValueSolid); 1380 case TextDecorationStyleDouble: 1381 return cssValuePool().createIdentifierValue(CSSValueDouble); 1382 case TextDecorationStyleDotted: 1383 return cssValuePool().createIdentifierValue(CSSValueDotted); 1384 case TextDecorationStyleDashed: 1385 return cssValuePool().createIdentifierValue(CSSValueDashed); 1386 case TextDecorationStyleWavy: 1387 return cssValuePool().createIdentifierValue(CSSValueWavy); 1388 } 1389 1390 ASSERT_NOT_REACHED(); 1391 return cssValuePool().createExplicitInitialValue(); 1392 } 1393 1394 static PassRefPtr<CSSValue> valueForFillRepeat(EFillRepeat xRepeat, EFillRepeat yRepeat) 1395 { 1396 // For backwards compatibility, if both values are equal, just return one of them. And 1397 // if the two values are equivalent to repeat-x or repeat-y, just return the shorthand. 1398 if (xRepeat == yRepeat) 1399 return cssValuePool().createValue(xRepeat); 1400 if (xRepeat == RepeatFill && yRepeat == NoRepeatFill) 1401 return cssValuePool().createIdentifierValue(CSSValueRepeatX); 1402 if (xRepeat == NoRepeatFill && yRepeat == RepeatFill) 1403 return cssValuePool().createIdentifierValue(CSSValueRepeatY); 1404 1405 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); 1406 list->append(cssValuePool().createValue(xRepeat)); 1407 list->append(cssValuePool().createValue(yRepeat)); 1408 return list.release(); 1409 } 1410 1411 static PassRefPtr<CSSValue> valueForFillSourceType(EMaskSourceType type) 1412 { 1413 switch (type) { 1414 case MaskAlpha: 1415 return cssValuePool().createValue(CSSValueAlpha); 1416 case MaskLuminance: 1417 return cssValuePool().createValue(CSSValueLuminance); 1418 } 1419 1420 ASSERT_NOT_REACHED(); 1421 1422 return 0; 1423 } 1424 1425 static PassRefPtr<CSSValue> valueForFillSize(const FillSize& fillSize, const RenderStyle& style) 1426 { 1427 if (fillSize.type == Contain) 1428 return cssValuePool().createIdentifierValue(CSSValueContain); 1429 1430 if (fillSize.type == Cover) 1431 return cssValuePool().createIdentifierValue(CSSValueCover); 1432 1433 if (fillSize.size.height().isAuto()) 1434 return zoomAdjustedPixelValueForLength(fillSize.size.width(), style); 1435 1436 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); 1437 list->append(zoomAdjustedPixelValueForLength(fillSize.size.width(), style)); 1438 list->append(zoomAdjustedPixelValueForLength(fillSize.size.height(), style)); 1439 return list.release(); 1440 } 1441 1442 static PassRefPtr<CSSValue> valueForContentData(const RenderStyle& style) 1443 { 1444 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); 1445 for (const ContentData* contentData = style.contentData(); contentData; contentData = contentData->next()) { 1446 if (contentData->isCounter()) { 1447 const CounterContent* counter = static_cast<const CounterContentData*>(contentData)->counter(); 1448 ASSERT(counter); 1449 list->append(cssValuePool().createValue(counter->identifier(), CSSPrimitiveValue::CSS_COUNTER_NAME)); 1450 } else if (contentData->isImage()) { 1451 const StyleImage* image = static_cast<const ImageContentData*>(contentData)->image(); 1452 ASSERT(image); 1453 list->append(image->cssValue()); 1454 } else if (contentData->isText()) 1455 list->append(cssValuePool().createValue(static_cast<const TextContentData*>(contentData)->text(), CSSPrimitiveValue::CSS_STRING)); 1456 } 1457 if (style.hasFlowFrom()) 1458 list->append(cssValuePool().createValue(style.regionThread(), CSSPrimitiveValue::CSS_STRING)); 1459 return list.release(); 1460 } 1461 1462 static PassRefPtr<CSSValue> valueForCounterDirectives(const RenderStyle& style, CSSPropertyID propertyID) 1463 { 1464 const CounterDirectiveMap* map = style.counterDirectives(); 1465 if (!map) 1466 return 0; 1467 1468 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); 1469 for (CounterDirectiveMap::const_iterator it = map->begin(); it != map->end(); ++it) { 1470 list->append(cssValuePool().createValue(it->key, CSSPrimitiveValue::CSS_STRING)); 1471 short number = propertyID == CSSPropertyCounterIncrement ? it->value.incrementValue() : it->value.resetValue(); 1472 list->append(cssValuePool().createValue((double)number, CSSPrimitiveValue::CSS_NUMBER)); 1473 } 1474 return list.release(); 1475 } 1476 1477 static void logUnimplementedPropertyID(CSSPropertyID propertyID) 1478 { 1479 DEFINE_STATIC_LOCAL(HashSet<CSSPropertyID>, propertyIDSet, ()); 1480 if (!propertyIDSet.add(propertyID).isNewEntry) 1481 return; 1482 1483 WTF_LOG_ERROR("WebKit does not yet implement getComputedStyle for '%s'.", getPropertyName(propertyID)); 1484 } 1485 1486 static PassRefPtr<CSSValueList> valueForFontFamily(RenderStyle& style) 1487 { 1488 const FontFamily& firstFamily = style.fontDescription().family(); 1489 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); 1490 for (const FontFamily* family = &firstFamily; family; family = family->next()) 1491 list->append(valueForFamily(family->family())); 1492 return list.release(); 1493 } 1494 1495 static PassRefPtr<CSSPrimitiveValue> valueForLineHeight(RenderStyle& style, RenderView* renderView) 1496 { 1497 Length length = style.lineHeight(); 1498 if (length.isNegative()) 1499 return cssValuePool().createIdentifierValue(CSSValueNormal); 1500 1501 return zoomAdjustedPixelValue(floatValueForLength(length, style.fontDescription().specifiedSize(), renderView), style); 1502 } 1503 1504 static PassRefPtr<CSSPrimitiveValue> valueForFontSize(RenderStyle& style) 1505 { 1506 return zoomAdjustedPixelValue(style.fontDescription().computedPixelSize(), style); 1507 } 1508 1509 static PassRefPtr<CSSPrimitiveValue> valueForFontStyle(RenderStyle& style) 1510 { 1511 if (style.fontDescription().italic()) 1512 return cssValuePool().createIdentifierValue(CSSValueItalic); 1513 return cssValuePool().createIdentifierValue(CSSValueNormal); 1514 } 1515 1516 static PassRefPtr<CSSPrimitiveValue> valueForFontVariant(RenderStyle& style) 1517 { 1518 if (style.fontDescription().smallCaps()) 1519 return cssValuePool().createIdentifierValue(CSSValueSmallCaps); 1520 return cssValuePool().createIdentifierValue(CSSValueNormal); 1521 } 1522 1523 static PassRefPtr<CSSPrimitiveValue> valueForFontWeight(RenderStyle& style) 1524 { 1525 switch (style.fontDescription().weight()) { 1526 case FontWeight100: 1527 return cssValuePool().createIdentifierValue(CSSValue100); 1528 case FontWeight200: 1529 return cssValuePool().createIdentifierValue(CSSValue200); 1530 case FontWeight300: 1531 return cssValuePool().createIdentifierValue(CSSValue300); 1532 case FontWeightNormal: 1533 return cssValuePool().createIdentifierValue(CSSValueNormal); 1534 case FontWeight500: 1535 return cssValuePool().createIdentifierValue(CSSValue500); 1536 case FontWeight600: 1537 return cssValuePool().createIdentifierValue(CSSValue600); 1538 case FontWeightBold: 1539 return cssValuePool().createIdentifierValue(CSSValueBold); 1540 case FontWeight800: 1541 return cssValuePool().createIdentifierValue(CSSValue800); 1542 case FontWeight900: 1543 return cssValuePool().createIdentifierValue(CSSValue900); 1544 } 1545 ASSERT_NOT_REACHED(); 1546 return cssValuePool().createIdentifierValue(CSSValueNormal); 1547 } 1548 1549 static PassRefPtr<CSSValue> touchActionFlagsToCSSValue(TouchAction touchAction) 1550 { 1551 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); 1552 if (touchAction == TouchActionAuto) 1553 list->append(cssValuePool().createIdentifierValue(CSSValueAuto)); 1554 if (touchAction & TouchActionNone) { 1555 ASSERT(touchAction == TouchActionNone); 1556 list->append(cssValuePool().createIdentifierValue(CSSValueNone)); 1557 } 1558 if (touchAction & TouchActionPanX) 1559 list->append(cssValuePool().createIdentifierValue(CSSValuePanX)); 1560 if (touchAction & TouchActionPanY) 1561 list->append(cssValuePool().createIdentifierValue(CSSValuePanY)); 1562 1563 ASSERT(list->length()); 1564 return list.release(); 1565 } 1566 1567 static bool isLayoutDependent(CSSPropertyID propertyID, PassRefPtr<RenderStyle> style, RenderObject* renderer) 1568 { 1569 // Some properties only depend on layout in certain conditions which 1570 // are specified in the main switch statement below. So we can avoid 1571 // forcing layout in those conditions. The conditions in this switch 1572 // statement must remain in sync with the conditions in the main switch. 1573 // FIXME: Some of these cases could be narrowed down or optimized better. 1574 switch (propertyID) { 1575 case CSSPropertyBottom: 1576 case CSSPropertyGridDefinitionColumns: 1577 case CSSPropertyGridDefinitionRows: 1578 case CSSPropertyHeight: 1579 case CSSPropertyLeft: 1580 case CSSPropertyRight: 1581 case CSSPropertyTop: 1582 case CSSPropertyWebkitPerspectiveOrigin: 1583 case CSSPropertyWebkitTransform: 1584 case CSSPropertyWebkitTransformOrigin: 1585 case CSSPropertyWidth: 1586 case CSSPropertyWebkitFilter: 1587 return true; 1588 case CSSPropertyMargin: 1589 return renderer && renderer->isBox() && (!style || !style->marginBottom().isFixed() || !style->marginTop().isFixed() || !style->marginLeft().isFixed() || !style->marginRight().isFixed()); 1590 case CSSPropertyMarginLeft: 1591 return renderer && renderer->isBox() && (!style || !style->marginLeft().isFixed()); 1592 case CSSPropertyMarginRight: 1593 return renderer && renderer->isBox() && (!style || !style->marginRight().isFixed()); 1594 case CSSPropertyMarginTop: 1595 return renderer && renderer->isBox() && (!style || !style->marginTop().isFixed()); 1596 case CSSPropertyMarginBottom: 1597 return renderer && renderer->isBox() && (!style || !style->marginBottom().isFixed()); 1598 case CSSPropertyPadding: 1599 return renderer && renderer->isBox() && (!style || !style->paddingBottom().isFixed() || !style->paddingTop().isFixed() || !style->paddingLeft().isFixed() || !style->paddingRight().isFixed()); 1600 case CSSPropertyPaddingBottom: 1601 return renderer && renderer->isBox() && (!style || !style->paddingBottom().isFixed()); 1602 case CSSPropertyPaddingLeft: 1603 return renderer && renderer->isBox() && (!style || !style->paddingLeft().isFixed()); 1604 case CSSPropertyPaddingRight: 1605 return renderer && renderer->isBox() && (!style || !style->paddingRight().isFixed()); 1606 case CSSPropertyPaddingTop: 1607 return renderer && renderer->isBox() && (!style || !style->paddingTop().isFixed()); 1608 default: 1609 return false; 1610 } 1611 } 1612 1613 PassRefPtr<RenderStyle> CSSComputedStyleDeclaration::computeRenderStyle(CSSPropertyID propertyID) const 1614 { 1615 Node* styledNode = this->styledNode(); 1616 ASSERT(styledNode); 1617 RenderObject* renderer = styledNode->renderer(); 1618 if (renderer && renderer->compositingState() == PaintsIntoOwnBacking 1619 && !RuntimeEnabledFeatures::webAnimationsCSSEnabled() && AnimationController::supportsAcceleratedAnimationOfProperty(propertyID)) { 1620 AnimationUpdateBlock animationUpdateBlock(renderer->animation()); 1621 if (m_pseudoElementSpecifier && !styledNode->isPseudoElement()) { 1622 // FIXME: This cached pseudo style will only exist if the animation has been run at least once. 1623 return renderer->animation().getAnimatedStyleForRenderer(renderer)->getCachedPseudoStyle(m_pseudoElementSpecifier); 1624 } 1625 return renderer->animation().getAnimatedStyleForRenderer(renderer); 1626 } 1627 return styledNode->computedStyle(styledNode->isPseudoElement() ? NOPSEUDO : m_pseudoElementSpecifier); 1628 } 1629 1630 Node* CSSComputedStyleDeclaration::styledNode() const 1631 { 1632 if (!m_node) 1633 return 0; 1634 if (m_node->isElementNode()) { 1635 if (PseudoElement* element = toElement(m_node)->pseudoElement(m_pseudoElementSpecifier)) 1636 return element; 1637 } 1638 return m_node.get(); 1639 } 1640 1641 PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropertyID propertyID, EUpdateLayout updateLayout) const 1642 { 1643 Node* styledNode = this->styledNode(); 1644 if (!styledNode) 1645 return 0; 1646 RenderObject* renderer = styledNode->renderer(); 1647 RefPtr<RenderStyle> style; 1648 1649 if (updateLayout) { 1650 Document& document = styledNode->document(); 1651 1652 // If a compositor animation is running we may need to service animations 1653 // in order to generate an up to date value. 1654 DocumentAnimations::serviceBeforeGetComputedStyle(*styledNode, propertyID); 1655 1656 document.updateStyleForNodeIfNeeded(styledNode); 1657 1658 // The style recalc could have caused the styled node to be discarded or replaced 1659 // if it was a PseudoElement so we need to update it. 1660 styledNode = this->styledNode(); 1661 renderer = styledNode->renderer(); 1662 1663 style = computeRenderStyle(propertyID); 1664 1665 bool forceFullLayout = isLayoutDependent(propertyID, style, renderer) 1666 || styledNode->isInShadowTree() 1667 || (document.ownerElement() && document.ensureStyleResolver().hasViewportDependentMediaQueries()) 1668 || document.seamlessParentIFrame(); 1669 1670 if (forceFullLayout) { 1671 document.updateLayoutIgnorePendingStylesheets(); 1672 styledNode = this->styledNode(); 1673 style = computeRenderStyle(propertyID); 1674 renderer = styledNode->renderer(); 1675 } 1676 } else { 1677 style = computeRenderStyle(propertyID); 1678 } 1679 1680 if (!style) 1681 return 0; 1682 1683 propertyID = CSSProperty::resolveDirectionAwareProperty(propertyID, style->direction(), style->writingMode()); 1684 1685 switch (propertyID) { 1686 case CSSPropertyInvalid: 1687 case CSSPropertyVariable: 1688 break; 1689 1690 case CSSPropertyBackgroundColor: 1691 return cssValuePool().createColorValue(m_allowVisitedStyle? style->visitedDependentColor(CSSPropertyBackgroundColor).rgb() : style->backgroundColor().rgb()); 1692 case CSSPropertyBackgroundImage: 1693 case CSSPropertyWebkitMaskImage: { 1694 const FillLayer* layers = propertyID == CSSPropertyWebkitMaskImage ? style->maskLayers() : style->backgroundLayers(); 1695 if (!layers) 1696 return cssValuePool().createIdentifierValue(CSSValueNone); 1697 1698 if (!layers->next()) { 1699 if (layers->image()) 1700 return layers->image()->cssValue(); 1701 1702 return cssValuePool().createIdentifierValue(CSSValueNone); 1703 } 1704 1705 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); 1706 for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) { 1707 if (currLayer->image()) 1708 list->append(currLayer->image()->cssValue()); 1709 else 1710 list->append(cssValuePool().createIdentifierValue(CSSValueNone)); 1711 } 1712 return list.release(); 1713 } 1714 case CSSPropertyBackgroundSize: 1715 case CSSPropertyWebkitBackgroundSize: 1716 case CSSPropertyWebkitMaskSize: { 1717 const FillLayer* layers = propertyID == CSSPropertyWebkitMaskSize ? style->maskLayers() : style->backgroundLayers(); 1718 if (!layers->next()) 1719 return valueForFillSize(layers->size(), *style); 1720 1721 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); 1722 for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) 1723 list->append(valueForFillSize(currLayer->size(), *style)); 1724 1725 return list.release(); 1726 } 1727 case CSSPropertyBackgroundRepeat: 1728 case CSSPropertyWebkitMaskRepeat: { 1729 const FillLayer* layers = propertyID == CSSPropertyWebkitMaskRepeat ? style->maskLayers() : style->backgroundLayers(); 1730 if (!layers->next()) 1731 return valueForFillRepeat(layers->repeatX(), layers->repeatY()); 1732 1733 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); 1734 for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) 1735 list->append(valueForFillRepeat(currLayer->repeatX(), currLayer->repeatY())); 1736 1737 return list.release(); 1738 } 1739 case CSSPropertyMaskSourceType: { 1740 const FillLayer* layers = style->maskLayers(); 1741 1742 if (!layers) 1743 return cssValuePool().createIdentifierValue(CSSValueNone); 1744 1745 if (!layers->next()) 1746 return valueForFillSourceType(layers->maskSourceType()); 1747 1748 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); 1749 for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) 1750 list->append(valueForFillSourceType(currLayer->maskSourceType())); 1751 1752 return list.release(); 1753 } 1754 case CSSPropertyWebkitBackgroundComposite: 1755 case CSSPropertyWebkitMaskComposite: { 1756 const FillLayer* layers = propertyID == CSSPropertyWebkitMaskComposite ? style->maskLayers() : style->backgroundLayers(); 1757 if (!layers->next()) 1758 return cssValuePool().createValue(layers->composite()); 1759 1760 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); 1761 for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) 1762 list->append(cssValuePool().createValue(currLayer->composite())); 1763 1764 return list.release(); 1765 } 1766 case CSSPropertyBackgroundAttachment: { 1767 const FillLayer* layers = style->backgroundLayers(); 1768 if (!layers->next()) 1769 return cssValuePool().createValue(layers->attachment()); 1770 1771 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); 1772 for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) 1773 list->append(cssValuePool().createValue(currLayer->attachment())); 1774 1775 return list.release(); 1776 } 1777 case CSSPropertyBackgroundClip: 1778 case CSSPropertyBackgroundOrigin: 1779 case CSSPropertyWebkitBackgroundClip: 1780 case CSSPropertyWebkitBackgroundOrigin: 1781 case CSSPropertyWebkitMaskClip: 1782 case CSSPropertyWebkitMaskOrigin: { 1783 const FillLayer* layers = (propertyID == CSSPropertyWebkitMaskClip || propertyID == CSSPropertyWebkitMaskOrigin) ? style->maskLayers() : style->backgroundLayers(); 1784 bool isClip = propertyID == CSSPropertyBackgroundClip || propertyID == CSSPropertyWebkitBackgroundClip || propertyID == CSSPropertyWebkitMaskClip; 1785 if (!layers->next()) { 1786 EFillBox box = isClip ? layers->clip() : layers->origin(); 1787 return cssValuePool().createValue(box); 1788 } 1789 1790 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); 1791 for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) { 1792 EFillBox box = isClip ? currLayer->clip() : currLayer->origin(); 1793 list->append(cssValuePool().createValue(box)); 1794 } 1795 1796 return list.release(); 1797 } 1798 case CSSPropertyBackgroundPosition: 1799 case CSSPropertyWebkitMaskPosition: { 1800 const FillLayer* layers = propertyID == CSSPropertyWebkitMaskPosition ? style->maskLayers() : style->backgroundLayers(); 1801 if (!layers->next()) 1802 return createPositionListForLayer(propertyID, layers, *style); 1803 1804 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); 1805 for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) 1806 list->append(createPositionListForLayer(propertyID, currLayer, *style)); 1807 return list.release(); 1808 } 1809 case CSSPropertyBackgroundPositionX: 1810 case CSSPropertyWebkitMaskPositionX: { 1811 const FillLayer* layers = propertyID == CSSPropertyWebkitMaskPositionX ? style->maskLayers() : style->backgroundLayers(); 1812 if (!layers->next()) 1813 return cssValuePool().createValue(layers->xPosition()); 1814 1815 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); 1816 for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) 1817 list->append(cssValuePool().createValue(currLayer->xPosition())); 1818 1819 return list.release(); 1820 } 1821 case CSSPropertyBackgroundPositionY: 1822 case CSSPropertyWebkitMaskPositionY: { 1823 const FillLayer* layers = propertyID == CSSPropertyWebkitMaskPositionY ? style->maskLayers() : style->backgroundLayers(); 1824 if (!layers->next()) 1825 return cssValuePool().createValue(layers->yPosition()); 1826 1827 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); 1828 for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) 1829 list->append(cssValuePool().createValue(currLayer->yPosition())); 1830 1831 return list.release(); 1832 } 1833 case CSSPropertyBorderCollapse: 1834 if (style->borderCollapse()) 1835 return cssValuePool().createIdentifierValue(CSSValueCollapse); 1836 return cssValuePool().createIdentifierValue(CSSValueSeparate); 1837 case CSSPropertyBorderSpacing: { 1838 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); 1839 list->append(zoomAdjustedPixelValue(style->horizontalBorderSpacing(), *style)); 1840 list->append(zoomAdjustedPixelValue(style->verticalBorderSpacing(), *style)); 1841 return list.release(); 1842 } 1843 case CSSPropertyWebkitBorderHorizontalSpacing: 1844 return zoomAdjustedPixelValue(style->horizontalBorderSpacing(), *style); 1845 case CSSPropertyWebkitBorderVerticalSpacing: 1846 return zoomAdjustedPixelValue(style->verticalBorderSpacing(), *style); 1847 case CSSPropertyBorderImageSource: 1848 if (style->borderImageSource()) 1849 return style->borderImageSource()->cssValue(); 1850 return cssValuePool().createIdentifierValue(CSSValueNone); 1851 case CSSPropertyBorderTopColor: 1852 return m_allowVisitedStyle ? cssValuePool().createColorValue(style->visitedDependentColor(CSSPropertyBorderTopColor).rgb()) : currentColorOrValidColor(*style, style->borderTopColor()); 1853 case CSSPropertyBorderRightColor: 1854 return m_allowVisitedStyle ? cssValuePool().createColorValue(style->visitedDependentColor(CSSPropertyBorderRightColor).rgb()) : currentColorOrValidColor(*style, style->borderRightColor()); 1855 case CSSPropertyBorderBottomColor: 1856 return m_allowVisitedStyle ? cssValuePool().createColorValue(style->visitedDependentColor(CSSPropertyBorderBottomColor).rgb()) : currentColorOrValidColor(*style, style->borderBottomColor()); 1857 case CSSPropertyBorderLeftColor: 1858 return m_allowVisitedStyle ? cssValuePool().createColorValue(style->visitedDependentColor(CSSPropertyBorderLeftColor).rgb()) : currentColorOrValidColor(*style, style->borderLeftColor()); 1859 case CSSPropertyBorderTopStyle: 1860 return cssValuePool().createValue(style->borderTopStyle()); 1861 case CSSPropertyBorderRightStyle: 1862 return cssValuePool().createValue(style->borderRightStyle()); 1863 case CSSPropertyBorderBottomStyle: 1864 return cssValuePool().createValue(style->borderBottomStyle()); 1865 case CSSPropertyBorderLeftStyle: 1866 return cssValuePool().createValue(style->borderLeftStyle()); 1867 case CSSPropertyBorderTopWidth: 1868 return zoomAdjustedPixelValue(style->borderTopWidth(), *style); 1869 case CSSPropertyBorderRightWidth: 1870 return zoomAdjustedPixelValue(style->borderRightWidth(), *style); 1871 case CSSPropertyBorderBottomWidth: 1872 return zoomAdjustedPixelValue(style->borderBottomWidth(), *style); 1873 case CSSPropertyBorderLeftWidth: 1874 return zoomAdjustedPixelValue(style->borderLeftWidth(), *style); 1875 case CSSPropertyBottom: 1876 return valueForPositionOffset(*style, CSSPropertyBottom, renderer, m_node->document().renderView()); 1877 case CSSPropertyWebkitBoxAlign: 1878 return cssValuePool().createValue(style->boxAlign()); 1879 case CSSPropertyWebkitBoxDecorationBreak: 1880 if (style->boxDecorationBreak() == DSLICE) 1881 return cssValuePool().createIdentifierValue(CSSValueSlice); 1882 return cssValuePool().createIdentifierValue(CSSValueClone); 1883 case CSSPropertyWebkitBoxDirection: 1884 return cssValuePool().createValue(style->boxDirection()); 1885 case CSSPropertyWebkitBoxFlex: 1886 return cssValuePool().createValue(style->boxFlex(), CSSPrimitiveValue::CSS_NUMBER); 1887 case CSSPropertyWebkitBoxFlexGroup: 1888 return cssValuePool().createValue(style->boxFlexGroup(), CSSPrimitiveValue::CSS_NUMBER); 1889 case CSSPropertyWebkitBoxLines: 1890 return cssValuePool().createValue(style->boxLines()); 1891 case CSSPropertyWebkitBoxOrdinalGroup: 1892 return cssValuePool().createValue(style->boxOrdinalGroup(), CSSPrimitiveValue::CSS_NUMBER); 1893 case CSSPropertyWebkitBoxOrient: 1894 return cssValuePool().createValue(style->boxOrient()); 1895 case CSSPropertyWebkitBoxPack: 1896 return cssValuePool().createValue(style->boxPack()); 1897 case CSSPropertyWebkitBoxReflect: 1898 return valueForReflection(style->boxReflect(), *style); 1899 case CSSPropertyBoxShadow: 1900 case CSSPropertyWebkitBoxShadow: 1901 return valueForShadowList(style->boxShadow(), *style, true); 1902 case CSSPropertyCaptionSide: 1903 return cssValuePool().createValue(style->captionSide()); 1904 case CSSPropertyClear: 1905 return cssValuePool().createValue(style->clear()); 1906 case CSSPropertyColor: 1907 return cssValuePool().createColorValue(m_allowVisitedStyle ? style->visitedDependentColor(CSSPropertyColor).rgb() : style->color().rgb()); 1908 case CSSPropertyWebkitPrintColorAdjust: 1909 return cssValuePool().createValue(style->printColorAdjust()); 1910 case CSSPropertyWebkitColumnAxis: 1911 return cssValuePool().createValue(style->columnAxis()); 1912 case CSSPropertyWebkitColumnCount: 1913 if (style->hasAutoColumnCount()) 1914 return cssValuePool().createIdentifierValue(CSSValueAuto); 1915 return cssValuePool().createValue(style->columnCount(), CSSPrimitiveValue::CSS_NUMBER); 1916 case CSSPropertyColumnFill: 1917 if (RuntimeEnabledFeatures::regionBasedColumnsEnabled()) 1918 return cssValuePool().createValue(style->columnFill()); 1919 return 0; 1920 case CSSPropertyWebkitColumnGap: 1921 if (style->hasNormalColumnGap()) 1922 return cssValuePool().createIdentifierValue(CSSValueNormal); 1923 return zoomAdjustedPixelValue(style->columnGap(), *style); 1924 case CSSPropertyWebkitColumnProgression: 1925 return cssValuePool().createValue(style->columnProgression()); 1926 case CSSPropertyWebkitColumnRuleColor: 1927 return m_allowVisitedStyle ? cssValuePool().createColorValue(style->visitedDependentColor(CSSPropertyOutlineColor).rgb()) : currentColorOrValidColor(*style, style->columnRuleColor()); 1928 case CSSPropertyWebkitColumnRuleStyle: 1929 return cssValuePool().createValue(style->columnRuleStyle()); 1930 case CSSPropertyWebkitColumnRuleWidth: 1931 return zoomAdjustedPixelValue(style->columnRuleWidth(), *style); 1932 case CSSPropertyWebkitColumnSpan: 1933 return cssValuePool().createIdentifierValue(style->columnSpan() ? CSSValueAll : CSSValueNone); 1934 case CSSPropertyWebkitColumnBreakAfter: 1935 return cssValuePool().createValue(style->columnBreakAfter()); 1936 case CSSPropertyWebkitColumnBreakBefore: 1937 return cssValuePool().createValue(style->columnBreakBefore()); 1938 case CSSPropertyWebkitColumnBreakInside: 1939 return cssValuePool().createValue(style->columnBreakInside()); 1940 case CSSPropertyWebkitColumnWidth: 1941 if (style->hasAutoColumnWidth()) 1942 return cssValuePool().createIdentifierValue(CSSValueAuto); 1943 return zoomAdjustedPixelValue(style->columnWidth(), *style); 1944 case CSSPropertyTabSize: 1945 return cssValuePool().createValue(style->tabSize(), CSSPrimitiveValue::CSS_NUMBER); 1946 case CSSPropertyWebkitRegionBreakAfter: 1947 return cssValuePool().createValue(style->regionBreakAfter()); 1948 case CSSPropertyWebkitRegionBreakBefore: 1949 return cssValuePool().createValue(style->regionBreakBefore()); 1950 case CSSPropertyWebkitRegionBreakInside: 1951 return cssValuePool().createValue(style->regionBreakInside()); 1952 case CSSPropertyCursor: { 1953 RefPtr<CSSValueList> list; 1954 CursorList* cursors = style->cursors(); 1955 if (cursors && cursors->size() > 0) { 1956 list = CSSValueList::createCommaSeparated(); 1957 for (unsigned i = 0; i < cursors->size(); ++i) 1958 if (StyleImage* image = cursors->at(i).image()) 1959 list->append(image->cssValue()); 1960 } 1961 RefPtr<CSSValue> value = cssValuePool().createValue(style->cursor()); 1962 if (list) { 1963 list->append(value.release()); 1964 return list.release(); 1965 } 1966 return value.release(); 1967 } 1968 case CSSPropertyDirection: 1969 return cssValuePool().createValue(style->direction()); 1970 case CSSPropertyDisplay: 1971 return cssValuePool().createValue(style->display()); 1972 case CSSPropertyEmptyCells: 1973 return cssValuePool().createValue(style->emptyCells()); 1974 case CSSPropertyAlignContent: 1975 return cssValuePool().createValue(style->alignContent()); 1976 case CSSPropertyAlignItems: 1977 return cssValuePool().createValue(style->alignItems()); 1978 case CSSPropertyAlignSelf: 1979 if (style->alignSelf() == AlignAuto) { 1980 Node* parent = styledNode->parentNode(); 1981 if (parent && parent->computedStyle()) 1982 return cssValuePool().createValue(parent->computedStyle()->alignItems()); 1983 return cssValuePool().createValue(AlignStretch); 1984 } 1985 return cssValuePool().createValue(style->alignSelf()); 1986 case CSSPropertyFlex: 1987 return valuesForShorthandProperty(flexShorthand()); 1988 case CSSPropertyFlexBasis: 1989 return cssValuePool().createValue(style->flexBasis()); 1990 case CSSPropertyFlexDirection: 1991 return cssValuePool().createValue(style->flexDirection()); 1992 case CSSPropertyFlexFlow: 1993 return valuesForShorthandProperty(flexFlowShorthand()); 1994 case CSSPropertyFlexGrow: 1995 return cssValuePool().createValue(style->flexGrow()); 1996 case CSSPropertyFlexShrink: 1997 return cssValuePool().createValue(style->flexShrink()); 1998 case CSSPropertyFlexWrap: 1999 return cssValuePool().createValue(style->flexWrap()); 2000 case CSSPropertyJustifyContent: 2001 return cssValuePool().createValue(style->justifyContent()); 2002 case CSSPropertyOrder: 2003 return cssValuePool().createValue(style->order(), CSSPrimitiveValue::CSS_NUMBER); 2004 case CSSPropertyFloat: 2005 if (style->display() != NONE && style->hasOutOfFlowPosition()) 2006 return cssValuePool().createIdentifierValue(CSSValueNone); 2007 return cssValuePool().createValue(style->floating()); 2008 case CSSPropertyFont: { 2009 RefPtr<CSSFontValue> computedFont = CSSFontValue::create(); 2010 computedFont->style = valueForFontStyle(*style); 2011 computedFont->variant = valueForFontVariant(*style); 2012 computedFont->weight = valueForFontWeight(*style); 2013 computedFont->size = valueForFontSize(*style); 2014 computedFont->lineHeight = valueForLineHeight(*style, m_node->document().renderView()); 2015 computedFont->family = valueForFontFamily(*style); 2016 return computedFont.release(); 2017 } 2018 case CSSPropertyFontFamily: { 2019 RefPtr<CSSValueList> fontFamilyList = valueForFontFamily(*style); 2020 // If there's only a single family, return that as a CSSPrimitiveValue. 2021 // NOTE: Gecko always returns this as a comma-separated CSSPrimitiveValue string. 2022 if (fontFamilyList->length() == 1) 2023 return fontFamilyList->item(0); 2024 return fontFamilyList.release(); 2025 } 2026 case CSSPropertyFontSize: 2027 return valueForFontSize(*style); 2028 case CSSPropertyFontStyle: 2029 return valueForFontStyle(*style); 2030 case CSSPropertyFontVariant: 2031 return valueForFontVariant(*style); 2032 case CSSPropertyFontWeight: 2033 return valueForFontWeight(*style); 2034 case CSSPropertyWebkitFontFeatureSettings: { 2035 const FontFeatureSettings* featureSettings = style->fontDescription().featureSettings(); 2036 if (!featureSettings || !featureSettings->size()) 2037 return cssValuePool().createIdentifierValue(CSSValueNormal); 2038 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); 2039 for (unsigned i = 0; i < featureSettings->size(); ++i) { 2040 const FontFeature& feature = featureSettings->at(i); 2041 RefPtr<CSSFontFeatureValue> featureValue = CSSFontFeatureValue::create(feature.tag(), feature.value()); 2042 list->append(featureValue.release()); 2043 } 2044 return list.release(); 2045 } 2046 case CSSPropertyGridAutoFlow: 2047 return cssValuePool().createValue(style->gridAutoFlow()); 2048 2049 // Specs mention that getComputedStyle() should return the used value of the property instead of the computed 2050 // one for grid-definition-{rows|columns} but not for the grid-auto-{rows|columns} as things like 2051 // grid-auto-columns: 2fr; cannot be resolved to a value in pixels as the '2fr' means very different things 2052 // depending on the size of the explicit grid or the number of implicit tracks added to the grid. See 2053 // http://lists.w3.org/Archives/Public/www-style/2013Nov/0014.html 2054 case CSSPropertyGridAutoColumns: 2055 return specifiedValueForGridTrackSize(style->gridAutoColumns(), *style, m_node->document().renderView()); 2056 case CSSPropertyGridAutoRows: 2057 return specifiedValueForGridTrackSize(style->gridAutoRows(), *style, m_node->document().renderView()); 2058 2059 case CSSPropertyGridDefinitionColumns: 2060 return valueForGridTrackList(ForColumns, renderer, *style, m_node->document().renderView()); 2061 case CSSPropertyGridDefinitionRows: 2062 return valueForGridTrackList(ForRows, renderer, *style, m_node->document().renderView()); 2063 2064 case CSSPropertyGridColumnStart: 2065 return valueForGridPosition(style->gridColumnStart()); 2066 case CSSPropertyGridColumnEnd: 2067 return valueForGridPosition(style->gridColumnEnd()); 2068 case CSSPropertyGridRowStart: 2069 return valueForGridPosition(style->gridRowStart()); 2070 case CSSPropertyGridRowEnd: 2071 return valueForGridPosition(style->gridRowEnd()); 2072 case CSSPropertyGridColumn: 2073 return valuesForGridShorthand(gridColumnShorthand()); 2074 case CSSPropertyGridRow: 2075 return valuesForGridShorthand(gridRowShorthand()); 2076 case CSSPropertyGridArea: 2077 return valuesForGridShorthand(gridAreaShorthand()); 2078 2079 case CSSPropertyGridTemplate: 2080 if (!style->namedGridAreaRowCount()) { 2081 ASSERT(!style->namedGridAreaColumnCount()); 2082 return cssValuePool().createIdentifierValue(CSSValueNone); 2083 } 2084 2085 return CSSGridTemplateValue::create(style->namedGridArea(), style->namedGridAreaRowCount(), style->namedGridAreaColumnCount()); 2086 2087 case CSSPropertyHeight: 2088 if (renderer) { 2089 // According to http://www.w3.org/TR/CSS2/visudet.html#the-height-property, 2090 // the "height" property does not apply for non-replaced inline elements. 2091 if (!renderer->isReplaced() && renderer->isInline()) 2092 return cssValuePool().createIdentifierValue(CSSValueAuto); 2093 return zoomAdjustedPixelValue(sizingBox(renderer).height(), *style); 2094 } 2095 return zoomAdjustedPixelValueForLength(style->height(), *style); 2096 case CSSPropertyWebkitHighlight: 2097 if (style->highlight() == nullAtom) 2098 return cssValuePool().createIdentifierValue(CSSValueNone); 2099 return cssValuePool().createValue(style->highlight(), CSSPrimitiveValue::CSS_STRING); 2100 case CSSPropertyWebkitHyphenateCharacter: 2101 if (style->hyphenationString().isNull()) 2102 return cssValuePool().createIdentifierValue(CSSValueAuto); 2103 return cssValuePool().createValue(style->hyphenationString(), CSSPrimitiveValue::CSS_STRING); 2104 case CSSPropertyWebkitBorderFit: 2105 if (style->borderFit() == BorderFitBorder) 2106 return cssValuePool().createIdentifierValue(CSSValueBorder); 2107 return cssValuePool().createIdentifierValue(CSSValueLines); 2108 case CSSPropertyImageRendering: 2109 return CSSPrimitiveValue::create(style->imageRendering()); 2110 case CSSPropertyIsolation: 2111 return cssValuePool().createValue(style->isolation()); 2112 case CSSPropertyLeft: 2113 return valueForPositionOffset(*style, CSSPropertyLeft, renderer, m_node->document().renderView()); 2114 case CSSPropertyLetterSpacing: 2115 if (!style->letterSpacing()) 2116 return cssValuePool().createIdentifierValue(CSSValueNormal); 2117 return zoomAdjustedPixelValue(style->letterSpacing(), *style); 2118 case CSSPropertyWebkitLineClamp: 2119 if (style->lineClamp().isNone()) 2120 return cssValuePool().createIdentifierValue(CSSValueNone); 2121 return cssValuePool().createValue(style->lineClamp().value(), style->lineClamp().isPercentage() ? CSSPrimitiveValue::CSS_PERCENTAGE : CSSPrimitiveValue::CSS_NUMBER); 2122 case CSSPropertyLineHeight: 2123 return valueForLineHeight(*style, m_node->document().renderView()); 2124 case CSSPropertyListStyleImage: 2125 if (style->listStyleImage()) 2126 return style->listStyleImage()->cssValue(); 2127 return cssValuePool().createIdentifierValue(CSSValueNone); 2128 case CSSPropertyListStylePosition: 2129 return cssValuePool().createValue(style->listStylePosition()); 2130 case CSSPropertyListStyleType: 2131 return cssValuePool().createValue(style->listStyleType()); 2132 case CSSPropertyWebkitLocale: 2133 if (style->locale().isNull()) 2134 return cssValuePool().createIdentifierValue(CSSValueAuto); 2135 return cssValuePool().createValue(style->locale(), CSSPrimitiveValue::CSS_STRING); 2136 case CSSPropertyMarginTop: { 2137 Length marginTop = style->marginTop(); 2138 if (marginTop.isFixed() || !renderer || !renderer->isBox()) 2139 return zoomAdjustedPixelValueForLength(marginTop, *style); 2140 return zoomAdjustedPixelValue(toRenderBox(renderer)->marginTop(), *style); 2141 } 2142 case CSSPropertyMarginRight: { 2143 Length marginRight = style->marginRight(); 2144 if (marginRight.isFixed() || !renderer || !renderer->isBox()) 2145 return zoomAdjustedPixelValueForLength(marginRight, *style); 2146 float value; 2147 if (marginRight.isPercent() || marginRight.isViewportPercentage()) { 2148 // RenderBox gives a marginRight() that is the distance between the right-edge of the child box 2149 // and the right-edge of the containing box, when display == BLOCK. Let's calculate the absolute 2150 // value of the specified margin-right % instead of relying on RenderBox's marginRight() value. 2151 value = minimumValueForLength(marginRight, toRenderBox(renderer)->containingBlockLogicalWidthForContent(), m_node->document().renderView()); 2152 } else { 2153 value = toRenderBox(renderer)->marginRight(); 2154 } 2155 return zoomAdjustedPixelValue(value, *style); 2156 } 2157 case CSSPropertyMarginBottom: { 2158 Length marginBottom = style->marginBottom(); 2159 if (marginBottom.isFixed() || !renderer || !renderer->isBox()) 2160 return zoomAdjustedPixelValueForLength(marginBottom, *style); 2161 return zoomAdjustedPixelValue(toRenderBox(renderer)->marginBottom(), *style); 2162 } 2163 case CSSPropertyMarginLeft: { 2164 Length marginLeft = style->marginLeft(); 2165 if (marginLeft.isFixed() || !renderer || !renderer->isBox()) 2166 return zoomAdjustedPixelValueForLength(marginLeft, *style); 2167 return zoomAdjustedPixelValue(toRenderBox(renderer)->marginLeft(), *style); 2168 } 2169 case CSSPropertyWebkitUserModify: 2170 return cssValuePool().createValue(style->userModify()); 2171 case CSSPropertyMaxHeight: { 2172 const Length& maxHeight = style->maxHeight(); 2173 if (maxHeight.isUndefined()) 2174 return cssValuePool().createIdentifierValue(CSSValueNone); 2175 return zoomAdjustedPixelValueForLength(maxHeight, *style); 2176 } 2177 case CSSPropertyMaxWidth: { 2178 const Length& maxWidth = style->maxWidth(); 2179 if (maxWidth.isUndefined()) 2180 return cssValuePool().createIdentifierValue(CSSValueNone); 2181 return zoomAdjustedPixelValueForLength(maxWidth, *style); 2182 } 2183 case CSSPropertyMinHeight: 2184 // FIXME: For flex-items, min-height:auto should compute to min-content. 2185 if (style->minHeight().isAuto()) 2186 return zoomAdjustedPixelValue(0, *style); 2187 return zoomAdjustedPixelValueForLength(style->minHeight(), *style); 2188 case CSSPropertyMinWidth: 2189 // FIXME: For flex-items, min-width:auto should compute to min-content. 2190 if (style->minWidth().isAuto()) 2191 return zoomAdjustedPixelValue(0, *style); 2192 return zoomAdjustedPixelValueForLength(style->minWidth(), *style); 2193 case CSSPropertyObjectFit: 2194 return cssValuePool().createValue(style->objectFit()); 2195 case CSSPropertyObjectPosition: 2196 return cssValuePool().createValue( 2197 Pair::create( 2198 zoomAdjustedPixelValueForLength(style->objectPosition().x(), *style), 2199 zoomAdjustedPixelValueForLength(style->objectPosition().y(), *style), 2200 Pair::KeepIdenticalValues)); 2201 case CSSPropertyOpacity: 2202 return cssValuePool().createValue(style->opacity(), CSSPrimitiveValue::CSS_NUMBER); 2203 case CSSPropertyOrphans: 2204 if (style->hasAutoOrphans()) 2205 return cssValuePool().createIdentifierValue(CSSValueAuto); 2206 return cssValuePool().createValue(style->orphans(), CSSPrimitiveValue::CSS_NUMBER); 2207 case CSSPropertyOutlineColor: 2208 return m_allowVisitedStyle ? cssValuePool().createColorValue(style->visitedDependentColor(CSSPropertyOutlineColor).rgb()) : currentColorOrValidColor(*style, style->outlineColor()); 2209 case CSSPropertyOutlineOffset: 2210 return zoomAdjustedPixelValue(style->outlineOffset(), *style); 2211 case CSSPropertyOutlineStyle: 2212 if (style->outlineStyleIsAuto()) 2213 return cssValuePool().createIdentifierValue(CSSValueAuto); 2214 return cssValuePool().createValue(style->outlineStyle()); 2215 case CSSPropertyOutlineWidth: 2216 return zoomAdjustedPixelValue(style->outlineWidth(), *style); 2217 case CSSPropertyOverflow: 2218 return cssValuePool().createValue(max(style->overflowX(), style->overflowY())); 2219 case CSSPropertyOverflowWrap: 2220 return cssValuePool().createValue(style->overflowWrap()); 2221 case CSSPropertyOverflowX: 2222 return cssValuePool().createValue(style->overflowX()); 2223 case CSSPropertyOverflowY: 2224 return cssValuePool().createValue(style->overflowY()); 2225 case CSSPropertyPaddingTop: { 2226 Length paddingTop = style->paddingTop(); 2227 if (paddingTop.isFixed() || !renderer || !renderer->isBox()) 2228 return zoomAdjustedPixelValueForLength(paddingTop, *style); 2229 return zoomAdjustedPixelValue(toRenderBox(renderer)->computedCSSPaddingTop(), *style); 2230 } 2231 case CSSPropertyPaddingRight: { 2232 Length paddingRight = style->paddingRight(); 2233 if (paddingRight.isFixed() || !renderer || !renderer->isBox()) 2234 return zoomAdjustedPixelValueForLength(paddingRight, *style); 2235 return zoomAdjustedPixelValue(toRenderBox(renderer)->computedCSSPaddingRight(), *style); 2236 } 2237 case CSSPropertyPaddingBottom: { 2238 Length paddingBottom = style->paddingBottom(); 2239 if (paddingBottom.isFixed() || !renderer || !renderer->isBox()) 2240 return zoomAdjustedPixelValueForLength(paddingBottom, *style); 2241 return zoomAdjustedPixelValue(toRenderBox(renderer)->computedCSSPaddingBottom(), *style); 2242 } 2243 case CSSPropertyPaddingLeft: { 2244 Length paddingLeft = style->paddingLeft(); 2245 if (paddingLeft.isFixed() || !renderer || !renderer->isBox()) 2246 return zoomAdjustedPixelValueForLength(paddingLeft, *style); 2247 return zoomAdjustedPixelValue(toRenderBox(renderer)->computedCSSPaddingLeft(), *style); 2248 } 2249 case CSSPropertyPageBreakAfter: 2250 return cssValuePool().createValue(style->pageBreakAfter()); 2251 case CSSPropertyPageBreakBefore: 2252 return cssValuePool().createValue(style->pageBreakBefore()); 2253 case CSSPropertyPageBreakInside: { 2254 EPageBreak pageBreak = style->pageBreakInside(); 2255 ASSERT(pageBreak != PBALWAYS); 2256 if (pageBreak == PBALWAYS) 2257 return 0; 2258 return cssValuePool().createValue(style->pageBreakInside()); 2259 } 2260 case CSSPropertyPosition: 2261 return cssValuePool().createValue(style->position()); 2262 case CSSPropertyRight: 2263 return valueForPositionOffset(*style, CSSPropertyRight, renderer, m_node->document().renderView()); 2264 case CSSPropertyWebkitRubyPosition: 2265 return cssValuePool().createValue(style->rubyPosition()); 2266 case CSSPropertyTableLayout: 2267 return cssValuePool().createValue(style->tableLayout()); 2268 case CSSPropertyTextAlign: 2269 return cssValuePool().createValue(style->textAlign()); 2270 case CSSPropertyTextAlignLast: 2271 return cssValuePool().createValue(style->textAlignLast()); 2272 case CSSPropertyTextDecoration: 2273 return valuesForShorthandProperty(textDecorationShorthand()); 2274 case CSSPropertyTextDecorationLine: 2275 return renderTextDecorationFlagsToCSSValue(style->textDecoration()); 2276 case CSSPropertyTextDecorationStyle: 2277 return valueForTextDecorationStyle(style->textDecorationStyle()); 2278 case CSSPropertyTextDecorationColor: 2279 return currentColorOrValidColor(*style, style->textDecorationColor()); 2280 case CSSPropertyTextJustify: 2281 return cssValuePool().createValue(style->textJustify()); 2282 case CSSPropertyTextUnderlinePosition: 2283 return cssValuePool().createValue(style->textUnderlinePosition()); 2284 case CSSPropertyWebkitTextDecorationsInEffect: 2285 return renderTextDecorationFlagsToCSSValue(style->textDecorationsInEffect()); 2286 case CSSPropertyWebkitTextFillColor: 2287 return currentColorOrValidColor(*style, style->textFillColor()); 2288 case CSSPropertyWebkitTextEmphasisColor: 2289 return currentColorOrValidColor(*style, style->textEmphasisColor()); 2290 case CSSPropertyWebkitTextEmphasisPosition: 2291 return cssValuePool().createValue(style->textEmphasisPosition()); 2292 case CSSPropertyWebkitTextEmphasisStyle: 2293 switch (style->textEmphasisMark()) { 2294 case TextEmphasisMarkNone: 2295 return cssValuePool().createIdentifierValue(CSSValueNone); 2296 case TextEmphasisMarkCustom: 2297 return cssValuePool().createValue(style->textEmphasisCustomMark(), CSSPrimitiveValue::CSS_STRING); 2298 case TextEmphasisMarkAuto: 2299 ASSERT_NOT_REACHED(); 2300 // Fall through 2301 case TextEmphasisMarkDot: 2302 case TextEmphasisMarkCircle: 2303 case TextEmphasisMarkDoubleCircle: 2304 case TextEmphasisMarkTriangle: 2305 case TextEmphasisMarkSesame: { 2306 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); 2307 list->append(cssValuePool().createValue(style->textEmphasisFill())); 2308 list->append(cssValuePool().createValue(style->textEmphasisMark())); 2309 return list.release(); 2310 } 2311 } 2312 case CSSPropertyTextIndent: { 2313 RefPtr<CSSValue> textIndent = zoomAdjustedPixelValueForLength(style->textIndent(), *style); 2314 if (RuntimeEnabledFeatures::css3TextEnabled() && style->textIndentLine() == TextIndentEachLine) { 2315 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); 2316 list->append(textIndent.release()); 2317 list->append(cssValuePool().createIdentifierValue(CSSValueEachLine)); 2318 return list.release(); 2319 } 2320 return textIndent.release(); 2321 } 2322 case CSSPropertyTextShadow: 2323 return valueForShadowList(style->textShadow(), *style, false); 2324 case CSSPropertyTextRendering: 2325 return cssValuePool().createValue(style->fontDescription().textRenderingMode()); 2326 case CSSPropertyTextOverflow: 2327 if (style->textOverflow()) 2328 return cssValuePool().createIdentifierValue(CSSValueEllipsis); 2329 return cssValuePool().createIdentifierValue(CSSValueClip); 2330 case CSSPropertyWebkitTextSecurity: 2331 return cssValuePool().createValue(style->textSecurity()); 2332 case CSSPropertyWebkitTextStrokeColor: 2333 return currentColorOrValidColor(*style, style->textStrokeColor()); 2334 case CSSPropertyWebkitTextStrokeWidth: 2335 return zoomAdjustedPixelValue(style->textStrokeWidth(), *style); 2336 case CSSPropertyTextTransform: 2337 return cssValuePool().createValue(style->textTransform()); 2338 case CSSPropertyTop: 2339 return valueForPositionOffset(*style, CSSPropertyTop, renderer, m_node->document().renderView()); 2340 case CSSPropertyTouchAction: 2341 return touchActionFlagsToCSSValue(style->touchAction()); 2342 case CSSPropertyTouchActionDelay: 2343 return cssValuePool().createValue(style->touchActionDelay()); 2344 case CSSPropertyUnicodeBidi: 2345 return cssValuePool().createValue(style->unicodeBidi()); 2346 case CSSPropertyVerticalAlign: 2347 switch (style->verticalAlign()) { 2348 case BASELINE: 2349 return cssValuePool().createIdentifierValue(CSSValueBaseline); 2350 case MIDDLE: 2351 return cssValuePool().createIdentifierValue(CSSValueMiddle); 2352 case SUB: 2353 return cssValuePool().createIdentifierValue(CSSValueSub); 2354 case SUPER: 2355 return cssValuePool().createIdentifierValue(CSSValueSuper); 2356 case TEXT_TOP: 2357 return cssValuePool().createIdentifierValue(CSSValueTextTop); 2358 case TEXT_BOTTOM: 2359 return cssValuePool().createIdentifierValue(CSSValueTextBottom); 2360 case TOP: 2361 return cssValuePool().createIdentifierValue(CSSValueTop); 2362 case BOTTOM: 2363 return cssValuePool().createIdentifierValue(CSSValueBottom); 2364 case BASELINE_MIDDLE: 2365 return cssValuePool().createIdentifierValue(CSSValueWebkitBaselineMiddle); 2366 case LENGTH: 2367 return cssValuePool().createValue(style->verticalAlignLength()); 2368 } 2369 ASSERT_NOT_REACHED(); 2370 return 0; 2371 case CSSPropertyVisibility: 2372 return cssValuePool().createValue(style->visibility()); 2373 case CSSPropertyWhiteSpace: 2374 return cssValuePool().createValue(style->whiteSpace()); 2375 case CSSPropertyWidows: 2376 if (style->hasAutoWidows()) 2377 return cssValuePool().createIdentifierValue(CSSValueAuto); 2378 return cssValuePool().createValue(style->widows(), CSSPrimitiveValue::CSS_NUMBER); 2379 case CSSPropertyWidth: 2380 if (renderer) { 2381 // According to http://www.w3.org/TR/CSS2/visudet.html#the-width-property, 2382 // the "width" property does not apply for non-replaced inline elements. 2383 if (!renderer->isReplaced() && renderer->isInline()) 2384 return cssValuePool().createIdentifierValue(CSSValueAuto); 2385 return zoomAdjustedPixelValue(sizingBox(renderer).width(), *style); 2386 } 2387 return zoomAdjustedPixelValueForLength(style->width(), *style); 2388 case CSSPropertyWordBreak: 2389 return cssValuePool().createValue(style->wordBreak()); 2390 case CSSPropertyWordSpacing: 2391 return zoomAdjustedPixelValue(style->wordSpacing(), *style); 2392 case CSSPropertyWordWrap: 2393 return cssValuePool().createValue(style->overflowWrap()); 2394 case CSSPropertyWebkitLineBreak: 2395 return cssValuePool().createValue(style->lineBreak()); 2396 case CSSPropertyResize: 2397 return cssValuePool().createValue(style->resize()); 2398 case CSSPropertyFontKerning: 2399 return cssValuePool().createValue(style->fontDescription().kerning()); 2400 case CSSPropertyWebkitFontSmoothing: 2401 return cssValuePool().createValue(style->fontDescription().fontSmoothing()); 2402 case CSSPropertyWebkitFontVariantLigatures: { 2403 FontDescription::LigaturesState commonLigaturesState = style->fontDescription().commonLigaturesState(); 2404 FontDescription::LigaturesState discretionaryLigaturesState = style->fontDescription().discretionaryLigaturesState(); 2405 FontDescription::LigaturesState historicalLigaturesState = style->fontDescription().historicalLigaturesState(); 2406 if (commonLigaturesState == FontDescription::NormalLigaturesState && discretionaryLigaturesState == FontDescription::NormalLigaturesState 2407 && historicalLigaturesState == FontDescription::NormalLigaturesState) 2408 return cssValuePool().createIdentifierValue(CSSValueNormal); 2409 2410 RefPtr<CSSValueList> valueList = CSSValueList::createSpaceSeparated(); 2411 if (commonLigaturesState != FontDescription::NormalLigaturesState) 2412 valueList->append(cssValuePool().createIdentifierValue(commonLigaturesState == FontDescription::DisabledLigaturesState ? CSSValueNoCommonLigatures : CSSValueCommonLigatures)); 2413 if (discretionaryLigaturesState != FontDescription::NormalLigaturesState) 2414 valueList->append(cssValuePool().createIdentifierValue(discretionaryLigaturesState == FontDescription::DisabledLigaturesState ? CSSValueNoDiscretionaryLigatures : CSSValueDiscretionaryLigatures)); 2415 if (historicalLigaturesState != FontDescription::NormalLigaturesState) 2416 valueList->append(cssValuePool().createIdentifierValue(historicalLigaturesState == FontDescription::DisabledLigaturesState ? CSSValueNoHistoricalLigatures : CSSValueHistoricalLigatures)); 2417 return valueList; 2418 } 2419 case CSSPropertyZIndex: 2420 if (style->hasAutoZIndex()) 2421 return cssValuePool().createIdentifierValue(CSSValueAuto); 2422 return cssValuePool().createValue(style->zIndex(), CSSPrimitiveValue::CSS_NUMBER); 2423 case CSSPropertyZoom: 2424 return cssValuePool().createValue(style->zoom(), CSSPrimitiveValue::CSS_NUMBER); 2425 case CSSPropertyBoxSizing: 2426 if (style->boxSizing() == CONTENT_BOX) 2427 return cssValuePool().createIdentifierValue(CSSValueContentBox); 2428 return cssValuePool().createIdentifierValue(CSSValueBorderBox); 2429 case CSSPropertyWebkitAppRegion: 2430 return cssValuePool().createIdentifierValue(style->getDraggableRegionMode() == DraggableRegionDrag ? CSSValueDrag : CSSValueNoDrag); 2431 case CSSPropertyAnimationDelay: 2432 ASSERT(RuntimeEnabledFeatures::cssAnimationUnprefixedEnabled()); 2433 case CSSPropertyWebkitAnimationDelay: 2434 return valueForAnimationDelay(style->animations()); 2435 case CSSPropertyAnimationDirection: 2436 ASSERT(RuntimeEnabledFeatures::cssAnimationUnprefixedEnabled()); 2437 case CSSPropertyWebkitAnimationDirection: { 2438 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); 2439 const CSSAnimationDataList* t = style->animations(); 2440 if (t) { 2441 for (size_t i = 0; i < t->size(); ++i) 2442 list->append(valueForAnimationDirection(t->animation(i)->direction())); 2443 } else 2444 list->append(cssValuePool().createIdentifierValue(CSSValueNormal)); 2445 return list.release(); 2446 } 2447 case CSSPropertyAnimationDuration: 2448 ASSERT(RuntimeEnabledFeatures::cssAnimationUnprefixedEnabled()); 2449 case CSSPropertyWebkitAnimationDuration: 2450 return valueForAnimationDuration(style->animations()); 2451 case CSSPropertyAnimationFillMode: 2452 ASSERT(RuntimeEnabledFeatures::cssAnimationUnprefixedEnabled()); 2453 case CSSPropertyWebkitAnimationFillMode: { 2454 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); 2455 const CSSAnimationDataList* t = style->animations(); 2456 if (t) { 2457 for (size_t i = 0; i < t->size(); ++i) 2458 list->append(valueForAnimationFillMode(t->animation(i)->fillMode())); 2459 } else 2460 list->append(cssValuePool().createIdentifierValue(CSSValueNone)); 2461 return list.release(); 2462 } 2463 case CSSPropertyAnimationIterationCount: 2464 ASSERT(RuntimeEnabledFeatures::cssAnimationUnprefixedEnabled()); 2465 case CSSPropertyWebkitAnimationIterationCount: { 2466 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); 2467 const CSSAnimationDataList* t = style->animations(); 2468 if (t) { 2469 for (size_t i = 0; i < t->size(); ++i) { 2470 double iterationCount = t->animation(i)->iterationCount(); 2471 if (iterationCount == CSSAnimationData::IterationCountInfinite) 2472 list->append(cssValuePool().createIdentifierValue(CSSValueInfinite)); 2473 else 2474 list->append(cssValuePool().createValue(iterationCount, CSSPrimitiveValue::CSS_NUMBER)); 2475 } 2476 } else 2477 list->append(cssValuePool().createValue(CSSAnimationData::initialAnimationIterationCount(), CSSPrimitiveValue::CSS_NUMBER)); 2478 return list.release(); 2479 } 2480 case CSSPropertyAnimationName: 2481 ASSERT(RuntimeEnabledFeatures::cssAnimationUnprefixedEnabled()); 2482 case CSSPropertyWebkitAnimationName: { 2483 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); 2484 const CSSAnimationDataList* t = style->animations(); 2485 if (t) { 2486 for (size_t i = 0; i < t->size(); ++i) 2487 list->append(cssValuePool().createValue(t->animation(i)->name(), CSSPrimitiveValue::CSS_STRING)); 2488 } else 2489 list->append(cssValuePool().createIdentifierValue(CSSValueNone)); 2490 return list.release(); 2491 } 2492 case CSSPropertyAnimationPlayState: 2493 ASSERT(RuntimeEnabledFeatures::cssAnimationUnprefixedEnabled()); 2494 case CSSPropertyWebkitAnimationPlayState: { 2495 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); 2496 const CSSAnimationDataList* t = style->animations(); 2497 if (t) { 2498 for (size_t i = 0; i < t->size(); ++i) { 2499 int prop = t->animation(i)->playState(); 2500 if (prop == AnimPlayStatePlaying) 2501 list->append(cssValuePool().createIdentifierValue(CSSValueRunning)); 2502 else 2503 list->append(cssValuePool().createIdentifierValue(CSSValuePaused)); 2504 } 2505 } else 2506 list->append(cssValuePool().createIdentifierValue(CSSValueRunning)); 2507 return list.release(); 2508 } 2509 case CSSPropertyAnimationTimingFunction: 2510 ASSERT(RuntimeEnabledFeatures::cssAnimationUnprefixedEnabled()); 2511 case CSSPropertyWebkitAnimationTimingFunction: 2512 return valueForAnimationTimingFunction(style->animations()); 2513 case CSSPropertyAnimation: 2514 case CSSPropertyWebkitAnimation: { 2515 const CSSAnimationDataList* animations = style->animations(); 2516 if (animations) { 2517 RefPtr<CSSValueList> animationsList = CSSValueList::createCommaSeparated(); 2518 for (size_t i = 0; i < animations->size(); ++i) { 2519 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); 2520 const CSSAnimationData* animation = animations->animation(i); 2521 list->append(cssValuePool().createValue(animation->name(), CSSPrimitiveValue::CSS_STRING)); 2522 list->append(cssValuePool().createValue(animation->duration(), CSSPrimitiveValue::CSS_S)); 2523 list->append(createTimingFunctionValue(animation->timingFunction())); 2524 list->append(cssValuePool().createValue(animation->delay(), CSSPrimitiveValue::CSS_S)); 2525 if (animation->iterationCount() == CSSAnimationData::IterationCountInfinite) 2526 list->append(cssValuePool().createIdentifierValue(CSSValueInfinite)); 2527 else 2528 list->append(cssValuePool().createValue(animation->iterationCount(), CSSPrimitiveValue::CSS_NUMBER)); 2529 list->append(valueForAnimationDirection(animation->direction())); 2530 list->append(valueForAnimationFillMode(animation->fillMode())); 2531 if (animation->playState() == AnimPlayStatePaused) 2532 list->append(cssValuePool().createIdentifierValue(CSSValuePaused)); 2533 else 2534 list->append(cssValuePool().createIdentifierValue(CSSValueRunning)); 2535 animationsList->append(list); 2536 } 2537 return animationsList.release(); 2538 } 2539 2540 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); 2541 // animation-name default value. 2542 list->append(cssValuePool().createIdentifierValue(CSSValueNone)); 2543 list->append(cssValuePool().createValue(CSSAnimationData::initialAnimationDuration(), CSSPrimitiveValue::CSS_S)); 2544 list->append(createTimingFunctionValue(CSSAnimationData::initialAnimationTimingFunction().get())); 2545 list->append(cssValuePool().createValue(CSSAnimationData::initialAnimationDelay(), CSSPrimitiveValue::CSS_S)); 2546 list->append(cssValuePool().createValue(CSSAnimationData::initialAnimationIterationCount(), CSSPrimitiveValue::CSS_NUMBER)); 2547 list->append(valueForAnimationDirection(CSSAnimationData::initialAnimationDirection())); 2548 list->append(valueForAnimationFillMode(CSSAnimationData::initialAnimationFillMode())); 2549 // Initial animation-play-state. 2550 list->append(cssValuePool().createIdentifierValue(CSSValueRunning)); 2551 return list.release(); 2552 } 2553 case CSSPropertyWebkitAppearance: 2554 return cssValuePool().createValue(style->appearance()); 2555 case CSSPropertyWebkitAspectRatio: 2556 if (!style->hasAspectRatio()) 2557 return cssValuePool().createIdentifierValue(CSSValueNone); 2558 return CSSAspectRatioValue::create(style->aspectRatioNumerator(), style->aspectRatioDenominator()); 2559 case CSSPropertyWebkitBackfaceVisibility: 2560 return cssValuePool().createIdentifierValue((style->backfaceVisibility() == BackfaceVisibilityHidden) ? CSSValueHidden : CSSValueVisible); 2561 case CSSPropertyWebkitBorderImage: 2562 return valueForNinePieceImage(style->borderImage(), *style); 2563 case CSSPropertyBorderImageOutset: 2564 return valueForNinePieceImageQuad(style->borderImage().outset(), *style); 2565 case CSSPropertyBorderImageRepeat: 2566 return valueForNinePieceImageRepeat(style->borderImage()); 2567 case CSSPropertyBorderImageSlice: 2568 return valueForNinePieceImageSlice(style->borderImage()); 2569 case CSSPropertyBorderImageWidth: 2570 return valueForNinePieceImageQuad(style->borderImage().borderSlices(), *style); 2571 case CSSPropertyWebkitMaskBoxImage: 2572 return valueForNinePieceImage(style->maskBoxImage(), *style); 2573 case CSSPropertyWebkitMaskBoxImageOutset: 2574 return valueForNinePieceImageQuad(style->maskBoxImage().outset(), *style); 2575 case CSSPropertyWebkitMaskBoxImageRepeat: 2576 return valueForNinePieceImageRepeat(style->maskBoxImage()); 2577 case CSSPropertyWebkitMaskBoxImageSlice: 2578 return valueForNinePieceImageSlice(style->maskBoxImage()); 2579 case CSSPropertyWebkitMaskBoxImageWidth: 2580 return valueForNinePieceImageQuad(style->maskBoxImage().borderSlices(), *style); 2581 case CSSPropertyWebkitMaskBoxImageSource: 2582 if (style->maskBoxImageSource()) 2583 return style->maskBoxImageSource()->cssValue(); 2584 return cssValuePool().createIdentifierValue(CSSValueNone); 2585 case CSSPropertyWebkitFontSizeDelta: 2586 // Not a real style property -- used by the editing engine -- so has no computed value. 2587 break; 2588 case CSSPropertyWebkitMarginBottomCollapse: 2589 case CSSPropertyWebkitMarginAfterCollapse: 2590 return cssValuePool().createValue(style->marginAfterCollapse()); 2591 case CSSPropertyWebkitMarginTopCollapse: 2592 case CSSPropertyWebkitMarginBeforeCollapse: 2593 return cssValuePool().createValue(style->marginBeforeCollapse()); 2594 case CSSPropertyWebkitPerspective: 2595 if (!style->hasPerspective()) 2596 return cssValuePool().createIdentifierValue(CSSValueNone); 2597 return zoomAdjustedPixelValue(style->perspective(), *style); 2598 case CSSPropertyWebkitPerspectiveOrigin: { 2599 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); 2600 if (renderer) { 2601 LayoutRect box; 2602 if (renderer->isBox()) 2603 box = toRenderBox(renderer)->borderBoxRect(); 2604 2605 RenderView* renderView = m_node->document().renderView(); 2606 list->append(zoomAdjustedPixelValue(minimumValueForLength(style->perspectiveOriginX(), box.width(), renderView), *style)); 2607 list->append(zoomAdjustedPixelValue(minimumValueForLength(style->perspectiveOriginY(), box.height(), renderView), *style)); 2608 } 2609 else { 2610 list->append(zoomAdjustedPixelValueForLength(style->perspectiveOriginX(), *style)); 2611 list->append(zoomAdjustedPixelValueForLength(style->perspectiveOriginY(), *style)); 2612 2613 } 2614 return list.release(); 2615 } 2616 case CSSPropertyWebkitRtlOrdering: 2617 return cssValuePool().createIdentifierValue(style->rtlOrdering() ? CSSValueVisual : CSSValueLogical); 2618 case CSSPropertyWebkitTapHighlightColor: 2619 return currentColorOrValidColor(*style, style->tapHighlightColor()); 2620 case CSSPropertyWebkitUserDrag: 2621 return cssValuePool().createValue(style->userDrag()); 2622 case CSSPropertyWebkitUserSelect: 2623 return cssValuePool().createValue(style->userSelect()); 2624 case CSSPropertyBorderBottomLeftRadius: 2625 return valueForBorderRadiusCorner(style->borderBottomLeftRadius(), *style); 2626 case CSSPropertyBorderBottomRightRadius: 2627 return valueForBorderRadiusCorner(style->borderBottomRightRadius(), *style); 2628 case CSSPropertyBorderTopLeftRadius: 2629 return valueForBorderRadiusCorner(style->borderTopLeftRadius(), *style); 2630 case CSSPropertyBorderTopRightRadius: 2631 return valueForBorderRadiusCorner(style->borderTopRightRadius(), *style); 2632 case CSSPropertyClip: { 2633 if (!style->hasClip()) 2634 return cssValuePool().createIdentifierValue(CSSValueAuto); 2635 RefPtr<Rect> rect = Rect::create(); 2636 rect->setTop(zoomAdjustedPixelValue(style->clip().top().value(), *style)); 2637 rect->setRight(zoomAdjustedPixelValue(style->clip().right().value(), *style)); 2638 rect->setBottom(zoomAdjustedPixelValue(style->clip().bottom().value(), *style)); 2639 rect->setLeft(zoomAdjustedPixelValue(style->clip().left().value(), *style)); 2640 return cssValuePool().createValue(rect.release()); 2641 } 2642 case CSSPropertySpeak: 2643 return cssValuePool().createValue(style->speak()); 2644 case CSSPropertyWebkitTransform: 2645 return computedTransform(renderer, *style); 2646 case CSSPropertyWebkitTransformOrigin: { 2647 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); 2648 if (renderer) { 2649 LayoutRect box; 2650 if (renderer->isBox()) 2651 box = toRenderBox(renderer)->borderBoxRect(); 2652 2653 RenderView* renderView = m_node->document().renderView(); 2654 list->append(zoomAdjustedPixelValue(minimumValueForLength(style->transformOriginX(), box.width(), renderView), *style)); 2655 list->append(zoomAdjustedPixelValue(minimumValueForLength(style->transformOriginY(), box.height(), renderView), *style)); 2656 if (style->transformOriginZ() != 0) 2657 list->append(zoomAdjustedPixelValue(style->transformOriginZ(), *style)); 2658 } else { 2659 list->append(zoomAdjustedPixelValueForLength(style->transformOriginX(), *style)); 2660 list->append(zoomAdjustedPixelValueForLength(style->transformOriginY(), *style)); 2661 if (style->transformOriginZ() != 0) 2662 list->append(zoomAdjustedPixelValue(style->transformOriginZ(), *style)); 2663 } 2664 return list.release(); 2665 } 2666 case CSSPropertyWebkitTransformStyle: 2667 return cssValuePool().createIdentifierValue((style->transformStyle3D() == TransformStyle3DPreserve3D) ? CSSValuePreserve3d : CSSValueFlat); 2668 case CSSPropertyTransitionDelay: 2669 case CSSPropertyWebkitTransitionDelay: 2670 return valueForAnimationDelay(style->transitions()); 2671 case CSSPropertyTransitionDuration: 2672 case CSSPropertyWebkitTransitionDuration: 2673 return valueForAnimationDuration(style->transitions()); 2674 case CSSPropertyTransitionProperty: 2675 case CSSPropertyWebkitTransitionProperty: 2676 return valueForTransitionProperty(style->transitions()); 2677 case CSSPropertyTransitionTimingFunction: 2678 case CSSPropertyWebkitTransitionTimingFunction: 2679 return valueForAnimationTimingFunction(style->transitions()); 2680 case CSSPropertyTransition: 2681 case CSSPropertyWebkitTransition: { 2682 const CSSAnimationDataList* animList = style->transitions(); 2683 if (animList) { 2684 RefPtr<CSSValueList> transitionsList = CSSValueList::createCommaSeparated(); 2685 for (size_t i = 0; i < animList->size(); ++i) { 2686 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); 2687 const CSSAnimationData* animation = animList->animation(i); 2688 list->append(createTransitionPropertyValue(animation)); 2689 list->append(cssValuePool().createValue(animation->duration(), CSSPrimitiveValue::CSS_S)); 2690 list->append(createTimingFunctionValue(animation->timingFunction())); 2691 list->append(cssValuePool().createValue(animation->delay(), CSSPrimitiveValue::CSS_S)); 2692 transitionsList->append(list); 2693 } 2694 return transitionsList.release(); 2695 } 2696 2697 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); 2698 // transition-property default value. 2699 list->append(cssValuePool().createIdentifierValue(CSSValueAll)); 2700 list->append(cssValuePool().createValue(CSSAnimationData::initialAnimationDuration(), CSSPrimitiveValue::CSS_S)); 2701 list->append(createTimingFunctionValue(CSSAnimationData::initialAnimationTimingFunction().get())); 2702 list->append(cssValuePool().createValue(CSSAnimationData::initialAnimationDelay(), CSSPrimitiveValue::CSS_S)); 2703 return list.release(); 2704 } 2705 case CSSPropertyPointerEvents: 2706 return cssValuePool().createValue(style->pointerEvents()); 2707 case CSSPropertyWebkitLineGrid: 2708 if (style->lineGrid().isNull()) 2709 return cssValuePool().createIdentifierValue(CSSValueNone); 2710 return cssValuePool().createValue(style->lineGrid(), CSSPrimitiveValue::CSS_STRING); 2711 case CSSPropertyWebkitLineSnap: 2712 return CSSPrimitiveValue::create(style->lineSnap()); 2713 case CSSPropertyWebkitLineAlign: 2714 return CSSPrimitiveValue::create(style->lineAlign()); 2715 case CSSPropertyWebkitWritingMode: 2716 return cssValuePool().createValue(style->writingMode()); 2717 case CSSPropertyWebkitTextCombine: 2718 return cssValuePool().createValue(style->textCombine()); 2719 case CSSPropertyWebkitTextOrientation: 2720 return CSSPrimitiveValue::create(style->textOrientation()); 2721 case CSSPropertyWebkitLineBoxContain: 2722 return createLineBoxContainValue(style->lineBoxContain()); 2723 case CSSPropertyContent: 2724 return valueForContentData(*style); 2725 case CSSPropertyCounterIncrement: 2726 return valueForCounterDirectives(*style, propertyID); 2727 case CSSPropertyCounterReset: 2728 return valueForCounterDirectives(*style, propertyID); 2729 case CSSPropertyWebkitClipPath: 2730 if (ClipPathOperation* operation = style->clipPath()) { 2731 if (operation->type() == ClipPathOperation::SHAPE) 2732 return valueForBasicShape(*style, toShapeClipPathOperation(operation)->basicShape()); 2733 if (operation->type() == ClipPathOperation::REFERENCE) 2734 return CSSPrimitiveValue::create(toReferenceClipPathOperation(operation)->url(), CSSPrimitiveValue::CSS_URI); 2735 } 2736 return cssValuePool().createIdentifierValue(CSSValueNone); 2737 case CSSPropertyWebkitFlowInto: 2738 if (style->flowThread().isNull()) 2739 return cssValuePool().createIdentifierValue(CSSValueNone); 2740 return cssValuePool().createValue(style->flowThread(), CSSPrimitiveValue::CSS_STRING); 2741 case CSSPropertyWebkitFlowFrom: 2742 if (!style->hasFlowFrom()) 2743 return cssValuePool().createIdentifierValue(CSSValueNone); 2744 return cssValuePool().createValue(style->regionThread(), CSSPrimitiveValue::CSS_STRING); 2745 case CSSPropertyWebkitRegionFragment: 2746 return cssValuePool().createValue(style->regionFragment()); 2747 case CSSPropertyWebkitWrapFlow: 2748 return cssValuePool().createValue(style->wrapFlow()); 2749 case CSSPropertyShapeMargin: 2750 return cssValuePool().createValue(style->shapeMargin()); 2751 case CSSPropertyShapePadding: 2752 return cssValuePool().createValue(style->shapePadding()); 2753 case CSSPropertyShapeImageThreshold: 2754 return cssValuePool().createValue(style->shapeImageThreshold(), CSSPrimitiveValue::CSS_NUMBER); 2755 case CSSPropertyShapeInside: 2756 if (!style->shapeInside()) 2757 return cssValuePool().createIdentifierValue(CSSValueAuto); 2758 if (style->shapeInside()->type() == ShapeValue::Box) 2759 return cssValuePool().createValue(style->shapeInside()->layoutBox()); 2760 if (style->shapeInside()->type() == ShapeValue::Outside) 2761 return cssValuePool().createIdentifierValue(CSSValueOutsideShape); 2762 if (style->shapeInside()->type() == ShapeValue::Image) { 2763 if (style->shapeInside()->image()) 2764 return style->shapeInside()->image()->cssValue(); 2765 return cssValuePool().createIdentifierValue(CSSValueNone); 2766 } 2767 ASSERT(style->shapeInside()->type() == ShapeValue::Shape); 2768 return valueForBasicShape(*style, style->shapeInside()->shape()); 2769 case CSSPropertyShapeOutside: 2770 if (!style->shapeOutside()) 2771 return cssValuePool().createIdentifierValue(CSSValueAuto); 2772 if (style->shapeOutside()->type() == ShapeValue::Box) 2773 return cssValuePool().createValue(style->shapeOutside()->layoutBox()); 2774 if (style->shapeOutside()->type() == ShapeValue::Image) { 2775 if (style->shapeOutside()->image()) 2776 return style->shapeOutside()->image()->cssValue(); 2777 return cssValuePool().createIdentifierValue(CSSValueNone); 2778 } 2779 ASSERT(style->shapeOutside()->type() == ShapeValue::Shape); 2780 return valueForBasicShape(*style, style->shapeOutside()->shape()); 2781 case CSSPropertyWebkitWrapThrough: 2782 return cssValuePool().createValue(style->wrapThrough()); 2783 case CSSPropertyWebkitFilter: 2784 return valueForFilter(renderer, *style); 2785 case CSSPropertyMixBlendMode: 2786 return cssValuePool().createValue(style->blendMode()); 2787 2788 case CSSPropertyBackgroundBlendMode: { 2789 const FillLayer* layers = style->backgroundLayers(); 2790 if (!layers->next()) 2791 return cssValuePool().createValue(layers->blendMode()); 2792 2793 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); 2794 for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) 2795 list->append(cssValuePool().createValue(currLayer->blendMode())); 2796 2797 return list.release(); 2798 } 2799 case CSSPropertyBackground: 2800 return valuesForBackgroundShorthand(); 2801 case CSSPropertyBorder: { 2802 RefPtr<CSSValue> value = getPropertyCSSValue(CSSPropertyBorderTop, DoNotUpdateLayout); 2803 const CSSPropertyID properties[3] = { CSSPropertyBorderRight, CSSPropertyBorderBottom, 2804 CSSPropertyBorderLeft }; 2805 for (size_t i = 0; i < WTF_ARRAY_LENGTH(properties); ++i) { 2806 if (!compareCSSValuePtr<CSSValue>(value, getPropertyCSSValue(properties[i], DoNotUpdateLayout))) 2807 return 0; 2808 } 2809 return value.release(); 2810 } 2811 case CSSPropertyBorderBottom: 2812 return valuesForShorthandProperty(borderBottomShorthand()); 2813 case CSSPropertyBorderColor: 2814 return valuesForSidesShorthand(borderColorShorthand()); 2815 case CSSPropertyBorderLeft: 2816 return valuesForShorthandProperty(borderLeftShorthand()); 2817 case CSSPropertyBorderImage: 2818 return valueForNinePieceImage(style->borderImage(), *style); 2819 case CSSPropertyBorderRadius: 2820 return valueForBorderRadiusShorthand(*style); 2821 case CSSPropertyBorderRight: 2822 return valuesForShorthandProperty(borderRightShorthand()); 2823 case CSSPropertyBorderStyle: 2824 return valuesForSidesShorthand(borderStyleShorthand()); 2825 case CSSPropertyBorderTop: 2826 return valuesForShorthandProperty(borderTopShorthand()); 2827 case CSSPropertyBorderWidth: 2828 return valuesForSidesShorthand(borderWidthShorthand()); 2829 case CSSPropertyWebkitColumnRule: 2830 return valuesForShorthandProperty(webkitColumnRuleShorthand()); 2831 case CSSPropertyWebkitColumns: 2832 return valuesForShorthandProperty(webkitColumnsShorthand()); 2833 case CSSPropertyListStyle: 2834 return valuesForShorthandProperty(listStyleShorthand()); 2835 case CSSPropertyMargin: 2836 return valuesForSidesShorthand(marginShorthand()); 2837 case CSSPropertyOutline: 2838 return valuesForShorthandProperty(outlineShorthand()); 2839 case CSSPropertyPadding: 2840 return valuesForSidesShorthand(paddingShorthand()); 2841 /* Individual properties not part of the spec */ 2842 case CSSPropertyBackgroundRepeatX: 2843 case CSSPropertyBackgroundRepeatY: 2844 break; 2845 case CSSPropertyInternalCallback: 2846 // This property is hidden from the web. 2847 return 0; 2848 2849 /* Unimplemented CSS 3 properties (including CSS3 shorthand properties) */ 2850 case CSSPropertyWebkitTextEmphasis: 2851 case CSSPropertyTextLineThroughColor: 2852 case CSSPropertyTextLineThroughMode: 2853 case CSSPropertyTextLineThroughStyle: 2854 case CSSPropertyTextLineThroughWidth: 2855 case CSSPropertyTextOverlineColor: 2856 case CSSPropertyTextOverlineMode: 2857 case CSSPropertyTextOverlineStyle: 2858 case CSSPropertyTextOverlineWidth: 2859 case CSSPropertyTextUnderlineColor: 2860 case CSSPropertyTextUnderlineMode: 2861 case CSSPropertyTextUnderlineStyle: 2862 case CSSPropertyTextUnderlineWidth: 2863 break; 2864 2865 /* Directional properties are resolved by resolveDirectionAwareProperty() before the switch. */ 2866 case CSSPropertyWebkitBorderEnd: 2867 case CSSPropertyWebkitBorderEndColor: 2868 case CSSPropertyWebkitBorderEndStyle: 2869 case CSSPropertyWebkitBorderEndWidth: 2870 case CSSPropertyWebkitBorderStart: 2871 case CSSPropertyWebkitBorderStartColor: 2872 case CSSPropertyWebkitBorderStartStyle: 2873 case CSSPropertyWebkitBorderStartWidth: 2874 case CSSPropertyWebkitBorderAfter: 2875 case CSSPropertyWebkitBorderAfterColor: 2876 case CSSPropertyWebkitBorderAfterStyle: 2877 case CSSPropertyWebkitBorderAfterWidth: 2878 case CSSPropertyWebkitBorderBefore: 2879 case CSSPropertyWebkitBorderBeforeColor: 2880 case CSSPropertyWebkitBorderBeforeStyle: 2881 case CSSPropertyWebkitBorderBeforeWidth: 2882 case CSSPropertyWebkitMarginEnd: 2883 case CSSPropertyWebkitMarginStart: 2884 case CSSPropertyWebkitMarginAfter: 2885 case CSSPropertyWebkitMarginBefore: 2886 case CSSPropertyWebkitPaddingEnd: 2887 case CSSPropertyWebkitPaddingStart: 2888 case CSSPropertyWebkitPaddingAfter: 2889 case CSSPropertyWebkitPaddingBefore: 2890 case CSSPropertyWebkitLogicalWidth: 2891 case CSSPropertyWebkitLogicalHeight: 2892 case CSSPropertyWebkitMinLogicalWidth: 2893 case CSSPropertyWebkitMinLogicalHeight: 2894 case CSSPropertyWebkitMaxLogicalWidth: 2895 case CSSPropertyWebkitMaxLogicalHeight: 2896 ASSERT_NOT_REACHED(); 2897 break; 2898 2899 /* Unimplemented @font-face properties */ 2900 case CSSPropertyFontStretch: 2901 case CSSPropertySrc: 2902 case CSSPropertyUnicodeRange: 2903 break; 2904 2905 /* Other unimplemented properties */ 2906 case CSSPropertyPage: // for @page 2907 case CSSPropertyQuotes: // FIXME: needs implementation 2908 case CSSPropertySize: // for @page 2909 break; 2910 2911 /* Unimplemented -webkit- properties */ 2912 case CSSPropertyWebkitBorderRadius: 2913 case CSSPropertyWebkitMarginCollapse: 2914 case CSSPropertyWebkitMask: 2915 case CSSPropertyWebkitMaskRepeatX: 2916 case CSSPropertyWebkitMaskRepeatY: 2917 case CSSPropertyWebkitPerspectiveOriginX: 2918 case CSSPropertyWebkitPerspectiveOriginY: 2919 case CSSPropertyWebkitTextStroke: 2920 case CSSPropertyWebkitTransformOriginX: 2921 case CSSPropertyWebkitTransformOriginY: 2922 case CSSPropertyWebkitTransformOriginZ: 2923 break; 2924 2925 /* @viewport rule properties */ 2926 case CSSPropertyMaxZoom: 2927 case CSSPropertyMinZoom: 2928 case CSSPropertyOrientation: 2929 case CSSPropertyUserZoom: 2930 break; 2931 2932 // Internal properties that shouldn't be exposed throught getComputedStyle. 2933 case CSSPropertyInternalMarqueeDirection: 2934 case CSSPropertyInternalMarqueeIncrement: 2935 case CSSPropertyInternalMarqueeRepetition: 2936 case CSSPropertyInternalMarqueeSpeed: 2937 case CSSPropertyInternalMarqueeStyle: 2938 ASSERT_NOT_REACHED(); 2939 return 0; 2940 2941 case CSSPropertyBufferedRendering: 2942 case CSSPropertyClipPath: 2943 case CSSPropertyClipRule: 2944 case CSSPropertyMask: 2945 case CSSPropertyEnableBackground: 2946 case CSSPropertyFilter: 2947 case CSSPropertyFloodColor: 2948 case CSSPropertyFloodOpacity: 2949 case CSSPropertyLightingColor: 2950 case CSSPropertyStopColor: 2951 case CSSPropertyStopOpacity: 2952 case CSSPropertyColorInterpolation: 2953 case CSSPropertyColorInterpolationFilters: 2954 case CSSPropertyColorProfile: 2955 case CSSPropertyColorRendering: 2956 case CSSPropertyFill: 2957 case CSSPropertyFillOpacity: 2958 case CSSPropertyFillRule: 2959 case CSSPropertyMarker: 2960 case CSSPropertyMarkerEnd: 2961 case CSSPropertyMarkerMid: 2962 case CSSPropertyMarkerStart: 2963 case CSSPropertyMaskType: 2964 case CSSPropertyShapeRendering: 2965 case CSSPropertyStroke: 2966 case CSSPropertyStrokeDasharray: 2967 case CSSPropertyStrokeDashoffset: 2968 case CSSPropertyStrokeLinecap: 2969 case CSSPropertyStrokeLinejoin: 2970 case CSSPropertyStrokeMiterlimit: 2971 case CSSPropertyStrokeOpacity: 2972 case CSSPropertyStrokeWidth: 2973 case CSSPropertyAlignmentBaseline: 2974 case CSSPropertyBaselineShift: 2975 case CSSPropertyDominantBaseline: 2976 case CSSPropertyGlyphOrientationHorizontal: 2977 case CSSPropertyGlyphOrientationVertical: 2978 case CSSPropertyKerning: 2979 case CSSPropertyTextAnchor: 2980 case CSSPropertyVectorEffect: 2981 case CSSPropertyPaintOrder: 2982 case CSSPropertyWritingMode: 2983 return getSVGPropertyCSSValue(propertyID, DoNotUpdateLayout); 2984 } 2985 2986 logUnimplementedPropertyID(propertyID); 2987 return 0; 2988 } 2989 2990 String CSSComputedStyleDeclaration::getPropertyValue(CSSPropertyID propertyID) const 2991 { 2992 RefPtr<CSSValue> value = getPropertyCSSValue(propertyID); 2993 if (value) 2994 return value->cssText(); 2995 return ""; 2996 } 2997 2998 2999 unsigned CSSComputedStyleDeclaration::length() const 3000 { 3001 Node* node = m_node.get(); 3002 if (!node) 3003 return 0; 3004 3005 RenderStyle* style = node->computedStyle(m_pseudoElementSpecifier); 3006 if (!style) 3007 return 0; 3008 3009 return computableProperties().size(); 3010 } 3011 3012 String CSSComputedStyleDeclaration::item(unsigned i) const 3013 { 3014 if (i >= length()) 3015 return ""; 3016 3017 return getPropertyNameString(computableProperties()[i]); 3018 } 3019 3020 bool CSSComputedStyleDeclaration::cssPropertyMatches(CSSPropertyID propertyID, const CSSValue* propertyValue) const 3021 { 3022 if (propertyID == CSSPropertyFontSize && propertyValue->isPrimitiveValue() && m_node) { 3023 m_node->document().updateLayoutIgnorePendingStylesheets(); 3024 RenderStyle* style = m_node->computedStyle(m_pseudoElementSpecifier); 3025 if (style && style->fontDescription().keywordSize()) { 3026 CSSValueID sizeValue = cssIdentifierForFontSizeKeyword(style->fontDescription().keywordSize()); 3027 const CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(propertyValue); 3028 if (primitiveValue->isValueID() && primitiveValue->getValueID() == sizeValue) 3029 return true; 3030 } 3031 } 3032 RefPtr<CSSValue> value = getPropertyCSSValue(propertyID); 3033 return value && propertyValue && value->equals(*propertyValue); 3034 } 3035 3036 PassRefPtr<MutableStylePropertySet> CSSComputedStyleDeclaration::copyProperties() const 3037 { 3038 return copyPropertiesInSet(computableProperties()); 3039 } 3040 3041 PassRefPtr<CSSValueList> CSSComputedStyleDeclaration::valuesForShorthandProperty(const StylePropertyShorthand& shorthand) const 3042 { 3043 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); 3044 for (size_t i = 0; i < shorthand.length(); ++i) { 3045 RefPtr<CSSValue> value = getPropertyCSSValue(shorthand.properties()[i], DoNotUpdateLayout); 3046 list->append(value); 3047 } 3048 return list.release(); 3049 } 3050 3051 PassRefPtr<CSSValueList> CSSComputedStyleDeclaration::valuesForSidesShorthand(const StylePropertyShorthand& shorthand) const 3052 { 3053 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); 3054 // Assume the properties are in the usual order top, right, bottom, left. 3055 RefPtr<CSSValue> topValue = getPropertyCSSValue(shorthand.properties()[0], DoNotUpdateLayout); 3056 RefPtr<CSSValue> rightValue = getPropertyCSSValue(shorthand.properties()[1], DoNotUpdateLayout); 3057 RefPtr<CSSValue> bottomValue = getPropertyCSSValue(shorthand.properties()[2], DoNotUpdateLayout); 3058 RefPtr<CSSValue> leftValue = getPropertyCSSValue(shorthand.properties()[3], DoNotUpdateLayout); 3059 3060 // All 4 properties must be specified. 3061 if (!topValue || !rightValue || !bottomValue || !leftValue) 3062 return 0; 3063 3064 bool showLeft = !compareCSSValuePtr(rightValue, leftValue); 3065 bool showBottom = !compareCSSValuePtr(topValue, bottomValue) || showLeft; 3066 bool showRight = !compareCSSValuePtr(topValue, rightValue) || showBottom; 3067 3068 list->append(topValue.release()); 3069 if (showRight) 3070 list->append(rightValue.release()); 3071 if (showBottom) 3072 list->append(bottomValue.release()); 3073 if (showLeft) 3074 list->append(leftValue.release()); 3075 3076 return list.release(); 3077 } 3078 3079 PassRefPtr<CSSValueList> CSSComputedStyleDeclaration::valuesForGridShorthand(const StylePropertyShorthand& shorthand) const 3080 { 3081 RefPtr<CSSValueList> list = CSSValueList::createSlashSeparated(); 3082 for (size_t i = 0; i < shorthand.length(); ++i) { 3083 RefPtr<CSSValue> value = getPropertyCSSValue(shorthand.properties()[i], DoNotUpdateLayout); 3084 list->append(value.release()); 3085 } 3086 return list.release(); 3087 } 3088 3089 PassRefPtr<MutableStylePropertySet> CSSComputedStyleDeclaration::copyPropertiesInSet(const Vector<CSSPropertyID>& properties) const 3090 { 3091 Vector<CSSProperty, 256> list; 3092 list.reserveInitialCapacity(properties.size()); 3093 for (unsigned i = 0; i < properties.size(); ++i) { 3094 RefPtr<CSSValue> value = getPropertyCSSValue(properties[i]); 3095 if (value) 3096 list.append(CSSProperty(properties[i], value.release(), false)); 3097 } 3098 return MutableStylePropertySet::create(list.data(), list.size()); 3099 } 3100 3101 CSSRule* CSSComputedStyleDeclaration::parentRule() const 3102 { 3103 return 0; 3104 } 3105 3106 PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(const String& propertyName) 3107 { 3108 CSSPropertyID propertyID = cssPropertyID(propertyName); 3109 if (!propertyID) 3110 return 0; 3111 RefPtr<CSSValue> value = getPropertyCSSValue(propertyID); 3112 return value ? value->cloneForCSSOM() : 0; 3113 } 3114 3115 String CSSComputedStyleDeclaration::getPropertyValue(const String& propertyName) 3116 { 3117 CSSPropertyID propertyID = cssPropertyID(propertyName); 3118 if (!propertyID || !RuntimeCSSEnabled::isCSSPropertyEnabled(propertyID)) 3119 return String(); 3120 return getPropertyValue(propertyID); 3121 } 3122 3123 String CSSComputedStyleDeclaration::getPropertyPriority(const String&) 3124 { 3125 // All computed styles have a priority of not "important". 3126 return ""; 3127 } 3128 3129 String CSSComputedStyleDeclaration::getPropertyShorthand(const String&) 3130 { 3131 return ""; 3132 } 3133 3134 bool CSSComputedStyleDeclaration::isPropertyImplicit(const String&) 3135 { 3136 return false; 3137 } 3138 3139 void CSSComputedStyleDeclaration::setProperty(const String& name, const String&, const String&, ExceptionState& exceptionState) 3140 { 3141 exceptionState.throwDOMException(NoModificationAllowedError, "These styles are computed, and therefore the '" + name + "' property is read-only."); 3142 } 3143 3144 String CSSComputedStyleDeclaration::removeProperty(const String& name, ExceptionState& exceptionState) 3145 { 3146 exceptionState.throwDOMException(NoModificationAllowedError, "These styles are computed, and therefore the '" + name + "' property is read-only."); 3147 return String(); 3148 } 3149 3150 PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValueInternal(CSSPropertyID propertyID) 3151 { 3152 return getPropertyCSSValue(propertyID); 3153 } 3154 3155 String CSSComputedStyleDeclaration::getPropertyValueInternal(CSSPropertyID propertyID) 3156 { 3157 return getPropertyValue(propertyID); 3158 } 3159 3160 void CSSComputedStyleDeclaration::setPropertyInternal(CSSPropertyID id, const String&, bool, ExceptionState& exceptionState) 3161 { 3162 exceptionState.throwDOMException(NoModificationAllowedError, "These styles are computed, and therefore the '" + getPropertyNameString(id) + "' property is read-only."); 3163 } 3164 3165 const HashMap<AtomicString, String>* CSSComputedStyleDeclaration::variableMap() const 3166 { 3167 ASSERT(RuntimeEnabledFeatures::cssVariablesEnabled()); 3168 Node* styledNode = this->styledNode(); 3169 if (!styledNode) 3170 return 0; 3171 RefPtr<RenderStyle> style = styledNode->computedStyle(styledNode->isPseudoElement() ? NOPSEUDO : m_pseudoElementSpecifier); 3172 if (!style) 3173 return 0; 3174 return style->variables(); 3175 } 3176 3177 unsigned CSSComputedStyleDeclaration::variableCount() const 3178 { 3179 ASSERT(RuntimeEnabledFeatures::cssVariablesEnabled()); 3180 const HashMap<AtomicString, String>* variables = variableMap(); 3181 if (!variables) 3182 return 0; 3183 return variables->size(); 3184 } 3185 3186 String CSSComputedStyleDeclaration::variableValue(const AtomicString& name) const 3187 { 3188 ASSERT(RuntimeEnabledFeatures::cssVariablesEnabled()); 3189 const HashMap<AtomicString, String>* variables = variableMap(); 3190 if (!variables) 3191 return emptyString(); 3192 HashMap<AtomicString, String>::const_iterator it = variables->find(name); 3193 if (it == variables->end()) 3194 return emptyString(); 3195 return it->value; 3196 } 3197 3198 bool CSSComputedStyleDeclaration::setVariableValue(const AtomicString& name, const String&, ExceptionState& exceptionState) 3199 { 3200 ASSERT(RuntimeEnabledFeatures::cssVariablesEnabled()); 3201 exceptionState.throwDOMException(NoModificationAllowedError, "These styles are computed, and therefore the '" + name + "' property is read-only."); 3202 return false; 3203 } 3204 3205 bool CSSComputedStyleDeclaration::removeVariable(const AtomicString&) 3206 { 3207 ASSERT(RuntimeEnabledFeatures::cssVariablesEnabled()); 3208 return false; 3209 } 3210 3211 bool CSSComputedStyleDeclaration::clearVariables(ExceptionState& exceptionState) 3212 { 3213 ASSERT(RuntimeEnabledFeatures::cssVariablesEnabled()); 3214 exceptionState.throwDOMException(NoModificationAllowedError, "These styles are computed, and therefore variables may not be cleared."); 3215 return false; 3216 } 3217 3218 CSSComputedStyleDeclaration::ComputedCSSVariablesIterator::ComputedCSSVariablesIterator(const HashMap<AtomicString, String>* variables) 3219 : m_active(variables) 3220 { 3221 ASSERT(RuntimeEnabledFeatures::cssVariablesEnabled()); 3222 if (m_active) { 3223 m_it = variables->begin(); 3224 m_end = variables->end(); 3225 } 3226 } 3227 3228 void CSSComputedStyleDeclaration::ComputedCSSVariablesIterator::advance() 3229 { 3230 ASSERT(m_active); 3231 ++m_it; 3232 m_active = !atEnd(); 3233 } 3234 3235 AtomicString CSSComputedStyleDeclaration::ComputedCSSVariablesIterator::name() const 3236 { 3237 ASSERT(m_active); 3238 return m_it->key; 3239 } 3240 3241 String CSSComputedStyleDeclaration::ComputedCSSVariablesIterator::value() const 3242 { 3243 ASSERT(m_active); 3244 return m_it->value; 3245 } 3246 3247 PassRefPtr<CSSValueList> CSSComputedStyleDeclaration::valuesForBackgroundShorthand() const 3248 { 3249 static const CSSPropertyID propertiesBeforeSlashSeperator[5] = { CSSPropertyBackgroundColor, CSSPropertyBackgroundImage, 3250 CSSPropertyBackgroundRepeat, CSSPropertyBackgroundAttachment, 3251 CSSPropertyBackgroundPosition }; 3252 static const CSSPropertyID propertiesAfterSlashSeperator[3] = { CSSPropertyBackgroundSize, CSSPropertyBackgroundOrigin, 3253 CSSPropertyBackgroundClip }; 3254 3255 RefPtr<CSSValueList> list = CSSValueList::createSlashSeparated(); 3256 list->append(valuesForShorthandProperty(StylePropertyShorthand(CSSPropertyBackground, propertiesBeforeSlashSeperator, WTF_ARRAY_LENGTH(propertiesBeforeSlashSeperator)))); 3257 list->append(valuesForShorthandProperty(StylePropertyShorthand(CSSPropertyBackground, propertiesAfterSlashSeperator, WTF_ARRAY_LENGTH(propertiesAfterSlashSeperator)))); 3258 return list.release(); 3259 } 3260 3261 } // namespace WebCore 3262