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