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