diff options
Diffstat (limited to 'Source/WebCore/css/CSSComputedStyleDeclaration.cpp')
-rw-r--r-- | Source/WebCore/css/CSSComputedStyleDeclaration.cpp | 3827 |
1 files changed, 2406 insertions, 1421 deletions
diff --git a/Source/WebCore/css/CSSComputedStyleDeclaration.cpp b/Source/WebCore/css/CSSComputedStyleDeclaration.cpp index d2e055423..392072c5f 100644 --- a/Source/WebCore/css/CSSComputedStyleDeclaration.cpp +++ b/Source/WebCore/css/CSSComputedStyleDeclaration.cpp @@ -1,6 +1,6 @@ /* * Copyright (C) 2004 Zack Rusin <zack@kde.org> - * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved. + * Copyright (C) 2004-2017 Apple Inc. All rights reserved. * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org> * Copyright (C) 2007 Nicholas Shanks <webkit@nickshanks.com> * Copyright (C) 2011 Sencha, Inc. All rights reserved. @@ -25,66 +25,90 @@ #include "config.h" #include "CSSComputedStyleDeclaration.h" -#include "AnimationController.h" #include "BasicShapeFunctions.h" #include "BasicShapes.h" +#include "CSSAnimationController.h" +#include "CSSAnimationTriggerScrollValue.h" #include "CSSAspectRatioValue.h" #include "CSSBasicShapes.h" #include "CSSBorderImage.h" +#include "CSSBorderImageSliceValue.h" +#include "CSSCustomPropertyValue.h" #include "CSSFontFeatureValue.h" #include "CSSFontValue.h" +#include "CSSFontVariationValue.h" #include "CSSFunctionValue.h" -#include "CSSGridTemplateValue.h" #include "CSSLineBoxContainValue.h" -#include "CSSParser.h" #include "CSSPrimitiveValue.h" #include "CSSPrimitiveValueMappings.h" #include "CSSPropertyNames.h" +#include "CSSPropertyParser.h" #include "CSSReflectValue.h" #include "CSSSelector.h" #include "CSSShadowValue.h" #include "CSSTimingFunctionValue.h" #include "CSSValueList.h" #include "CSSValuePool.h" +#include "ComposedTreeAncestorIterator.h" #include "ContentData.h" #include "CounterContent.h" #include "CursorList.h" +#include "DeprecatedCSSOMValue.h" #include "Document.h" #include "ExceptionCode.h" -#include "FontFeatureSettings.h" +#include "FontTaggedSettings.h" #include "HTMLFrameOwnerElement.h" +#include "NodeRenderStyle.h" #include "Pair.h" #include "PseudoElement.h" #include "Rect.h" +#include "RenderBlock.h" #include "RenderBox.h" #include "RenderStyle.h" -#include "RenderView.h" +#include "RuntimeEnabledFeatures.h" #include "SVGElement.h" +#include "Settings.h" +#include "ShapeValue.h" #include "StyleInheritedData.h" #include "StyleProperties.h" #include "StylePropertyShorthand.h" +#include "StylePropertyShorthandFunctions.h" #include "StyleResolver.h" -#include "WebKitCSSTransformValue.h" +#include "StyleScope.h" +#include "StyleScrollSnapPoints.h" +#include "Text.h" #include "WebKitFontFamilyNames.h" +#include "WillChangeData.h" +#include <wtf/NeverDestroyed.h> #include <wtf/text/StringBuilder.h> -#if ENABLE(CSS_SHAPES) -#include "ShapeValue.h" -#endif - -#if ENABLE(CSS_FILTERS) -#include "WebKitCSSFilterValue.h" -#endif +#include "CSSGridLineNamesValue.h" +#include "CSSGridTemplateAreasValue.h" +#include "RenderGrid.h" #if ENABLE(DASHBOARD_SUPPORT) #include "DashboardRegion.h" #endif +#if ENABLE(CSS_ANIMATIONS_LEVEL_2) +#include "AnimationTrigger.h" +#endif + namespace WebCore { // List of all properties we know how to compute, omitting shorthands. static const CSSPropertyID computedProperties[] = { + CSSPropertyAlt, + CSSPropertyAnimationDelay, + CSSPropertyAnimationDirection, + CSSPropertyAnimationDuration, + CSSPropertyAnimationFillMode, + CSSPropertyAnimationIterationCount, + CSSPropertyAnimationName, + CSSPropertyAnimationPlayState, + CSSPropertyAnimationTimingFunction, CSSPropertyBackgroundAttachment, + CSSPropertyBackgroundBlendMode, CSSPropertyBackgroundClip, CSSPropertyBackgroundColor, CSSPropertyBackgroundImage, @@ -121,6 +145,9 @@ static const CSSPropertyID computedProperties[] = { CSSPropertyClear, CSSPropertyClip, CSSPropertyColor, + CSSPropertyCounterIncrement, + CSSPropertyCounterReset, + CSSPropertyContent, CSSPropertyCursor, CSSPropertyDirection, CSSPropertyDisplay, @@ -129,8 +156,10 @@ static const CSSPropertyID computedProperties[] = { CSSPropertyFontFamily, CSSPropertyFontSize, CSSPropertyFontStyle, + CSSPropertyFontSynthesis, CSSPropertyFontVariant, CSSPropertyFontWeight, + CSSPropertyHangingPunctuation, CSSPropertyHeight, #if ENABLE(CSS_IMAGE_ORIENTATION) CSSPropertyImageOrientation, @@ -153,6 +182,8 @@ static const CSSPropertyID computedProperties[] = { CSSPropertyMaxWidth, CSSPropertyMinHeight, CSSPropertyMinWidth, + CSSPropertyObjectFit, + CSSPropertyObjectPosition, CSSPropertyOpacity, CSSPropertyOrphans, CSSPropertyOutlineColor, @@ -193,6 +224,9 @@ static const CSSPropertyID computedProperties[] = { CSSPropertyTextOverflow, CSSPropertyTextTransform, CSSPropertyTop, + CSSPropertyTransform, + CSSPropertyTransformOrigin, + CSSPropertyTransformStyle, CSSPropertyTransitionDelay, CSSPropertyTransitionDuration, CSSPropertyTransitionProperty, @@ -203,30 +237,38 @@ static const CSSPropertyID computedProperties[] = { CSSPropertyWhiteSpace, CSSPropertyWidows, CSSPropertyWidth, + CSSPropertyWillChange, CSSPropertyWordBreak, CSSPropertyWordSpacing, CSSPropertyWordWrap, +#if ENABLE(CSS_SCROLL_SNAP) + CSSPropertyScrollSnapMargin, + CSSPropertyScrollSnapMarginLeft, + CSSPropertyScrollSnapMarginTop, + CSSPropertyScrollSnapMarginRight, + CSSPropertyScrollSnapMarginBottom, + CSSPropertyScrollPadding, + CSSPropertyScrollPaddingLeft, + CSSPropertyScrollPaddingTop, + CSSPropertyScrollPaddingRight, + CSSPropertyScrollPaddingBottom, + CSSPropertyScrollSnapType, + CSSPropertyScrollSnapAlign, +#endif CSSPropertyZIndex, CSSPropertyZoom, - - CSSPropertyWebkitAlt, - CSSPropertyWebkitAnimationDelay, - CSSPropertyWebkitAnimationDirection, - CSSPropertyWebkitAnimationDuration, - CSSPropertyWebkitAnimationFillMode, - CSSPropertyWebkitAnimationIterationCount, - CSSPropertyWebkitAnimationName, - CSSPropertyWebkitAnimationPlayState, - CSSPropertyWebkitAnimationTimingFunction, +#if ENABLE(CSS_ANIMATIONS_LEVEL_2) + CSSPropertyWebkitAnimationTrigger, +#endif CSSPropertyWebkitAppearance, CSSPropertyWebkitBackfaceVisibility, - CSSPropertyWebkitBackgroundBlendMode, CSSPropertyWebkitBackgroundClip, CSSPropertyWebkitBackgroundComposite, CSSPropertyWebkitBackgroundOrigin, CSSPropertyWebkitBackgroundSize, #if ENABLE(CSS_COMPOSITING) - CSSPropertyWebkitBlendMode, + CSSPropertyMixBlendMode, + CSSPropertyIsolation, #endif CSSPropertyWebkitBorderFit, CSSPropertyWebkitBorderHorizontalSpacing, @@ -246,55 +288,70 @@ static const CSSPropertyID computedProperties[] = { CSSPropertyWebkitBoxReflect, CSSPropertyWebkitBoxShadow, CSSPropertyWebkitClipPath, - CSSPropertyWebkitColorCorrection, CSSPropertyWebkitColumnBreakAfter, CSSPropertyWebkitColumnBreakBefore, CSSPropertyWebkitColumnBreakInside, CSSPropertyWebkitColumnAxis, - CSSPropertyWebkitColumnCount, - CSSPropertyWebkitColumnGap, + CSSPropertyColumnCount, + CSSPropertyColumnFill, + CSSPropertyColumnGap, CSSPropertyWebkitColumnProgression, - CSSPropertyWebkitColumnRuleColor, - CSSPropertyWebkitColumnRuleStyle, - CSSPropertyWebkitColumnRuleWidth, - CSSPropertyWebkitColumnSpan, - CSSPropertyWebkitColumnWidth, + CSSPropertyColumnRuleColor, + CSSPropertyColumnRuleStyle, + CSSPropertyColumnRuleWidth, + CSSPropertyColumnSpan, + CSSPropertyColumnWidth, #if ENABLE(CURSOR_VISIBILITY) CSSPropertyWebkitCursorVisibility, #endif #if ENABLE(DASHBOARD_SUPPORT) CSSPropertyWebkitDashboardRegion, #endif -#if ENABLE(CSS_FILTERS) - CSSPropertyWebkitFilter, + CSSPropertyAlignContent, + CSSPropertyAlignItems, + CSSPropertyAlignSelf, + CSSPropertyFilter, + CSSPropertyFlexBasis, + CSSPropertyFlexDirection, + CSSPropertyFlexFlow, + CSSPropertyFlexGrow, + CSSPropertyFlexShrink, + CSSPropertyFlexWrap, + CSSPropertyJustifyContent, + CSSPropertyJustifySelf, + CSSPropertyJustifyItems, +#if ENABLE(FILTERS_LEVEL_2) + CSSPropertyWebkitBackdropFilter, #endif - CSSPropertyWebkitAlignContent, - CSSPropertyWebkitAlignItems, - CSSPropertyWebkitAlignSelf, - CSSPropertyWebkitFlexBasis, - CSSPropertyWebkitFlexGrow, - CSSPropertyWebkitFlexShrink, - CSSPropertyWebkitFlexDirection, - CSSPropertyWebkitFlexWrap, - CSSPropertyWebkitJustifyContent, CSSPropertyWebkitFontKerning, CSSPropertyWebkitFontSmoothing, - CSSPropertyWebkitFontVariantLigatures, - CSSPropertyWebkitGridAutoColumns, - CSSPropertyWebkitGridAutoFlow, - CSSPropertyWebkitGridAutoRows, - CSSPropertyWebkitGridColumnEnd, - CSSPropertyWebkitGridColumnStart, - CSSPropertyWebkitGridDefinitionColumns, - CSSPropertyWebkitGridDefinitionRows, - CSSPropertyWebkitGridRowEnd, - CSSPropertyWebkitGridRowStart, - CSSPropertyWebkitHighlight, + CSSPropertyFontVariantLigatures, + CSSPropertyFontVariantPosition, + CSSPropertyFontVariantCaps, + CSSPropertyFontVariantNumeric, + CSSPropertyFontVariantAlternates, + CSSPropertyFontVariantEastAsian, +#if ENABLE(VARIATION_FONTS) + CSSPropertyFontVariationSettings, +#endif + CSSPropertyGridAutoColumns, + CSSPropertyGridAutoFlow, + CSSPropertyGridAutoRows, + CSSPropertyGridColumnEnd, + CSSPropertyGridColumnStart, + CSSPropertyGridTemplateAreas, + CSSPropertyGridTemplateColumns, + CSSPropertyGridTemplateRows, + CSSPropertyGridRowEnd, + CSSPropertyGridRowStart, + CSSPropertyGridColumnGap, + CSSPropertyGridRowGap, CSSPropertyWebkitHyphenateCharacter, CSSPropertyWebkitHyphenateLimitAfter, CSSPropertyWebkitHyphenateLimitBefore, CSSPropertyWebkitHyphenateLimitLines, CSSPropertyWebkitHyphens, + CSSPropertyWebkitInitialLetter, CSSPropertyWebkitLineAlign, CSSPropertyWebkitLineBoxContain, CSSPropertyWebkitLineBreak, @@ -323,25 +380,18 @@ static const CSSPropertyID computedProperties[] = { CSSPropertyWebkitMaskSize, CSSPropertyWebkitMaskSourceType, CSSPropertyWebkitNbspMode, - CSSPropertyWebkitOrder, + CSSPropertyOrder, #if ENABLE(ACCELERATED_OVERFLOW_SCROLLING) CSSPropertyWebkitOverflowScrolling, #endif - CSSPropertyWebkitPerspective, - CSSPropertyWebkitPerspectiveOrigin, + CSSPropertyPerspective, + CSSPropertyPerspectiveOrigin, CSSPropertyWebkitPrintColorAdjust, CSSPropertyWebkitRtlOrdering, #if PLATFORM(IOS) CSSPropertyWebkitTouchCallout, - - // FIXME: This property shouldn't be iOS-specific. Once we fix up its usage in InlineTextBox::paintCompositionBackground() - // we should move it outside the PLATFORM(IOS)-guard. See <https://bugs.webkit.org/show_bug.cgi?id=126296>. - CSSPropertyWebkitCompositionFillColor, -#endif -#if ENABLE(CSS_SHAPES) - CSSPropertyWebkitShapeInside, - CSSPropertyWebkitShapeOutside, #endif + CSSPropertyShapeOutside, #if ENABLE(TOUCH_EVENTS) CSSPropertyWebkitTapHighlightColor, #endif @@ -353,22 +403,16 @@ static const CSSPropertyID computedProperties[] = { CSSPropertyWebkitTextFillColor, CSSPropertyWebkitTextOrientation, CSSPropertyWebkitTextSecurity, -#if ENABLE(IOS_TEXT_AUTOSIZING) +#if ENABLE(TEXT_AUTOSIZING) CSSPropertyWebkitTextSizeAdjust, #endif CSSPropertyWebkitTextStrokeColor, CSSPropertyWebkitTextStrokeWidth, - CSSPropertyWebkitTransform, - CSSPropertyWebkitTransformOrigin, + CSSPropertyWebkitTextZoom, CSSPropertyWebkitTransformStyle, - CSSPropertyWebkitTransitionDelay, - CSSPropertyWebkitTransitionDuration, - CSSPropertyWebkitTransitionProperty, - CSSPropertyWebkitTransitionTimingFunction, CSSPropertyWebkitUserDrag, CSSPropertyWebkitUserModify, CSSPropertyWebkitUserSelect, - CSSPropertyWebkitWritingMode, #if ENABLE(CSS_REGIONS) CSSPropertyWebkitFlowInto, CSSPropertyWebkitFlowFrom, @@ -377,20 +421,17 @@ static const CSSPropertyID computedProperties[] = { CSSPropertyWebkitRegionBreakInside, CSSPropertyWebkitRegionFragment, #endif -#if ENABLE(CSS_EXCLUSIONS) - CSSPropertyWebkitWrapFlow, - CSSPropertyWebkitWrapThrough, -#endif -#if ENABLE(CSS_SHAPES) - CSSPropertyWebkitShapeMargin, - CSSPropertyWebkitShapePadding, - CSSPropertyWebkitShapeImageThreshold, -#endif -#if ENABLE(SVG) + CSSPropertyShapeImageThreshold, + CSSPropertyShapeMargin, + CSSPropertyShapeOutside, + CSSPropertyShapeRendering, CSSPropertyBufferedRendering, CSSPropertyClipPath, CSSPropertyClipRule, + CSSPropertyCx, + CSSPropertyCy, CSSPropertyMask, + CSSPropertyMaskType, CSSPropertyFilter, CSSPropertyFloodColor, CSSPropertyFloodOpacity, @@ -406,8 +447,10 @@ static const CSSPropertyID computedProperties[] = { CSSPropertyMarkerEnd, CSSPropertyMarkerMid, CSSPropertyMarkerStart, - CSSPropertyMaskType, - CSSPropertyShapeRendering, + CSSPropertyPaintOrder, + CSSPropertyR, + CSSPropertyRx, + CSSPropertyRy, CSSPropertyStroke, CSSPropertyStrokeDasharray, CSSPropertyStrokeDashoffset, @@ -425,8 +468,9 @@ static const CSSPropertyID computedProperties[] = { CSSPropertyGlyphOrientationHorizontal, CSSPropertyGlyphOrientationVertical, CSSPropertyWebkitSvgShadow, - CSSPropertyVectorEffect -#endif + CSSPropertyVectorEffect, + CSSPropertyX, + CSSPropertyY }; const unsigned numComputedProperties = WTF_ARRAY_LENGTH(computedProperties); @@ -445,71 +489,74 @@ static CSSValueID valueForRepeatRule(int rule) } } -static PassRefPtr<CSSBorderImageSliceValue> valueForNinePieceImageSlice(const NinePieceImage& image) +static Ref<CSSPrimitiveValue> valueForImageSliceSide(const Length& length) { - // Create the slices. - RefPtr<CSSPrimitiveValue> top; + // These values can be percentages, numbers, or while an animation of mixed types is in progress, + // a calculation that combines a percentage and a number. + if (length.isPercent()) + return CSSValuePool::singleton().createValue(length.percent(), CSSPrimitiveValue::CSS_PERCENTAGE); + if (length.isFixed()) + return CSSValuePool::singleton().createValue(length.value(), CSSPrimitiveValue::CSS_NUMBER); + + // Calculating the actual length currently in use would require most of the code from RenderBoxModelObject::paintNinePieceImage. + // And even if we could do that, it's not clear if that's exactly what we'd want during animation. + // FIXME: For now, just return 0. + ASSERT(length.isCalculated()); + return CSSValuePool::singleton().createValue(0, CSSPrimitiveValue::CSS_NUMBER); +} + +static Ref<CSSBorderImageSliceValue> valueForNinePieceImageSlice(const NinePieceImage& image) +{ + auto& slices = image.imageSlices(); + + RefPtr<CSSPrimitiveValue> top = valueForImageSliceSide(slices.top()); + RefPtr<CSSPrimitiveValue> right; RefPtr<CSSPrimitiveValue> bottom; RefPtr<CSSPrimitiveValue> left; - if (image.imageSlices().top().isPercent()) - top = cssValuePool().createValue(image.imageSlices().top().value(), CSSPrimitiveValue::CSS_PERCENTAGE); - else - top = cssValuePool().createValue(image.imageSlices().top().value(), CSSPrimitiveValue::CSS_NUMBER); - - if (image.imageSlices().right() == image.imageSlices().top() && image.imageSlices().bottom() == image.imageSlices().top() - && image.imageSlices().left() == image.imageSlices().top()) { + if (slices.right() == slices.top() && slices.bottom() == slices.top() && slices.left() == slices.top()) { right = top; bottom = top; left = top; } else { - if (image.imageSlices().right().isPercent()) - right = cssValuePool().createValue(image.imageSlices().right().value(), CSSPrimitiveValue::CSS_PERCENTAGE); - else - right = cssValuePool().createValue(image.imageSlices().right().value(), CSSPrimitiveValue::CSS_NUMBER); + right = valueForImageSliceSide(slices.right()); - if (image.imageSlices().bottom() == image.imageSlices().top() && image.imageSlices().right() == image.imageSlices().left()) { + if (slices.bottom() == slices.top() && slices.right() == slices.left()) { bottom = top; left = right; } else { - if (image.imageSlices().bottom().isPercent()) - bottom = cssValuePool().createValue(image.imageSlices().bottom().value(), CSSPrimitiveValue::CSS_PERCENTAGE); - else - bottom = cssValuePool().createValue(image.imageSlices().bottom().value(), CSSPrimitiveValue::CSS_NUMBER); + bottom = valueForImageSliceSide(slices.bottom()); - if (image.imageSlices().left() == image.imageSlices().right()) + if (slices.left() == slices.right()) left = right; - else { - if (image.imageSlices().left().isPercent()) - left = cssValuePool().createValue(image.imageSlices().left().value(), CSSPrimitiveValue::CSS_PERCENTAGE); - else - left = cssValuePool().createValue(image.imageSlices().left().value(), CSSPrimitiveValue::CSS_NUMBER); - } + else + left = valueForImageSliceSide(slices.left()); } } - RefPtr<Quad> quad = Quad::create(); - quad->setTop(top); - quad->setRight(right); - quad->setBottom(bottom); - quad->setLeft(left); + auto quad = Quad::create(); + quad->setTop(WTFMove(top)); + quad->setRight(WTFMove(right)); + quad->setBottom(WTFMove(bottom)); + quad->setLeft(WTFMove(left)); - return CSSBorderImageSliceValue::create(cssValuePool().createValue(quad.release()), image.fill()); + return CSSBorderImageSliceValue::create(CSSValuePool::singleton().createValue(WTFMove(quad)), image.fill()); } -static PassRefPtr<CSSPrimitiveValue> valueForNinePieceImageQuad(const LengthBox& box) +static Ref<CSSPrimitiveValue> valueForNinePieceImageQuad(const LengthBox& box) { - // Create the slices. RefPtr<CSSPrimitiveValue> top; RefPtr<CSSPrimitiveValue> right; RefPtr<CSSPrimitiveValue> bottom; RefPtr<CSSPrimitiveValue> left; + auto& cssValuePool = CSSValuePool::singleton(); + if (box.top().isRelative()) - top = cssValuePool().createValue(box.top().value(), CSSPrimitiveValue::CSS_NUMBER); + top = cssValuePool.createValue(box.top().value(), CSSPrimitiveValue::CSS_NUMBER); else - top = cssValuePool().createValue(box.top()); + top = cssValuePool.createValue(box.top()); if (box.right() == box.top() && box.bottom() == box.top() && box.left() == box.top()) { right = top; @@ -517,56 +564,55 @@ static PassRefPtr<CSSPrimitiveValue> valueForNinePieceImageQuad(const LengthBox& left = top; } else { if (box.right().isRelative()) - right = cssValuePool().createValue(box.right().value(), CSSPrimitiveValue::CSS_NUMBER); + right = cssValuePool.createValue(box.right().value(), CSSPrimitiveValue::CSS_NUMBER); else - right = cssValuePool().createValue(box.right()); + right = cssValuePool.createValue(box.right()); if (box.bottom() == box.top() && box.right() == box.left()) { bottom = top; left = right; } else { if (box.bottom().isRelative()) - bottom = cssValuePool().createValue(box.bottom().value(), CSSPrimitiveValue::CSS_NUMBER); + bottom = cssValuePool.createValue(box.bottom().value(), CSSPrimitiveValue::CSS_NUMBER); else - bottom = cssValuePool().createValue(box.bottom()); + bottom = cssValuePool.createValue(box.bottom()); if (box.left() == box.right()) left = right; else { if (box.left().isRelative()) - left = cssValuePool().createValue(box.left().value(), CSSPrimitiveValue::CSS_NUMBER); + left = cssValuePool.createValue(box.left().value(), CSSPrimitiveValue::CSS_NUMBER); else - left = cssValuePool().createValue(box.left()); + left = cssValuePool.createValue(box.left()); } } } - RefPtr<Quad> quad = Quad::create(); - quad->setTop(top); - quad->setRight(right); - quad->setBottom(bottom); - quad->setLeft(left); + auto quad = Quad::create(); + quad->setTop(WTFMove(top)); + quad->setRight(WTFMove(right)); + quad->setBottom(WTFMove(bottom)); + quad->setLeft(WTFMove(left)); - return cssValuePool().createValue(quad.release()); + return cssValuePool.createValue(WTFMove(quad)); } -static PassRef<CSSValue> valueForNinePieceImageRepeat(const NinePieceImage& image) +static Ref<CSSValue> valueForNinePieceImageRepeat(const NinePieceImage& image) { - RefPtr<CSSPrimitiveValue> horizontalRepeat; + auto& cssValuePool = CSSValuePool::singleton(); + auto horizontalRepeat = cssValuePool.createIdentifierValue(valueForRepeatRule(image.horizontalRule())); RefPtr<CSSPrimitiveValue> verticalRepeat; - - horizontalRepeat = cssValuePool().createIdentifierValue(valueForRepeatRule(image.horizontalRule())); if (image.horizontalRule() == image.verticalRule()) - verticalRepeat = horizontalRepeat; + verticalRepeat = horizontalRepeat.copyRef(); else - verticalRepeat = cssValuePool().createIdentifierValue(valueForRepeatRule(image.verticalRule())); - return cssValuePool().createValue(Pair::create(horizontalRepeat.release(), verticalRepeat.release())); + verticalRepeat = cssValuePool.createIdentifierValue(valueForRepeatRule(image.verticalRule())); + return cssValuePool.createValue(Pair::create(WTFMove(horizontalRepeat), WTFMove(verticalRepeat))); } -static PassRefPtr<CSSValue> valueForNinePieceImage(const NinePieceImage& image) +static Ref<CSSValue> valueForNinePieceImage(const NinePieceImage& image) { if (!image.hasImage()) - return cssValuePool().createIdentifierValue(CSSValueNone); + return CSSValuePool::singleton().createIdentifierValue(CSSValueNone); // Image first. RefPtr<CSSValue> imageValue; @@ -585,513 +631,864 @@ static PassRefPtr<CSSValue> valueForNinePieceImage(const NinePieceImage& image) // Create the repeat rules. RefPtr<CSSValue> repeat = valueForNinePieceImageRepeat(image); - return createBorderImageValue(imageValue.release(), imageSlices.release(), borderSlices.release(), outset.release(), repeat.release()); + return createBorderImageValue(WTFMove(imageValue), WTFMove(imageSlices), WTFMove(borderSlices), WTFMove(outset), WTFMove(repeat)); } -inline static PassRef<CSSPrimitiveValue> zoomAdjustedPixelValue(double value, const RenderStyle* style) +inline static Ref<CSSPrimitiveValue> zoomAdjustedPixelValue(double value, const RenderStyle& style) { - return cssValuePool().createValue(adjustFloatForAbsoluteZoom(value, style), CSSPrimitiveValue::CSS_PX); + return CSSValuePool::singleton().createValue(adjustFloatForAbsoluteZoom(value, style), CSSPrimitiveValue::CSS_PX); } -inline static PassRef<CSSPrimitiveValue> zoomAdjustedNumberValue(double value, const RenderStyle* style) +inline static Ref<CSSPrimitiveValue> zoomAdjustedNumberValue(double value, const RenderStyle& style) { - return cssValuePool().createValue(value / style->effectiveZoom(), CSSPrimitiveValue::CSS_NUMBER); + return CSSValuePool::singleton().createValue(value / style.effectiveZoom(), CSSPrimitiveValue::CSS_NUMBER); } -static PassRef<CSSValue> zoomAdjustedPixelValueForLength(const Length& length, const RenderStyle* style) +static Ref<CSSValue> zoomAdjustedPixelValueForLength(const Length& length, const RenderStyle& style) { if (length.isFixed()) return zoomAdjustedPixelValue(length.value(), style); - return cssValuePool().createValue(length); + return CSSValuePool::singleton().createValue(length, style); } -static PassRef<CSSValue> valueForReflection(const StyleReflection* reflection, const RenderStyle* style) +static Ref<CSSValue> valueForReflection(const StyleReflection* reflection, const RenderStyle& style) { if (!reflection) - return cssValuePool().createIdentifierValue(CSSValueNone); + return CSSValuePool::singleton().createIdentifierValue(CSSValueNone); RefPtr<CSSPrimitiveValue> offset; - if (reflection->offset().isPercent()) - offset = cssValuePool().createValue(reflection->offset().percent(), CSSPrimitiveValue::CSS_PERCENTAGE); + if (reflection->offset().isPercentOrCalculated()) + offset = CSSValuePool::singleton().createValue(reflection->offset().percent(), CSSPrimitiveValue::CSS_PERCENTAGE); else offset = zoomAdjustedPixelValue(reflection->offset().value(), style); RefPtr<CSSPrimitiveValue> direction; switch (reflection->direction()) { case ReflectionBelow: - direction = cssValuePool().createIdentifierValue(CSSValueBelow); + direction = CSSValuePool::singleton().createIdentifierValue(CSSValueBelow); break; case ReflectionAbove: - direction = cssValuePool().createIdentifierValue(CSSValueAbove); + direction = CSSValuePool::singleton().createIdentifierValue(CSSValueAbove); break; case ReflectionLeft: - direction = cssValuePool().createIdentifierValue(CSSValueLeft); + direction = CSSValuePool::singleton().createIdentifierValue(CSSValueLeft); break; case ReflectionRight: - direction = cssValuePool().createIdentifierValue(CSSValueRight); + direction = CSSValuePool::singleton().createIdentifierValue(CSSValueRight); break; } - return CSSReflectValue::create(direction.release(), offset.release(), valueForNinePieceImage(reflection->mask())); + return CSSReflectValue::create(direction.releaseNonNull(), offset.releaseNonNull(), valueForNinePieceImage(reflection->mask())); } -static PassRef<CSSValueList> createPositionListForLayer(CSSPropertyID propertyID, const FillLayer* layer, const RenderStyle* style) +static Ref<CSSValueList> createPositionListForLayer(CSSPropertyID propertyID, const FillLayer& layer, const RenderStyle& style) { - auto positionList = CSSValueList::createSpaceSeparated(); - if (layer->isBackgroundOriginSet()) { + auto list = CSSValueList::createSpaceSeparated(); + if (layer.isBackgroundXOriginSet()) { ASSERT_UNUSED(propertyID, propertyID == CSSPropertyBackgroundPosition || propertyID == CSSPropertyWebkitMaskPosition); - positionList.get().append(cssValuePool().createValue(layer->backgroundXOrigin())); + list->append(CSSValuePool::singleton().createValue(layer.backgroundXOrigin())); } - positionList.get().append(zoomAdjustedPixelValueForLength(layer->xPosition(), style)); - if (layer->isBackgroundOriginSet()) { + list->append(zoomAdjustedPixelValueForLength(layer.xPosition(), style)); + if (layer.isBackgroundYOriginSet()) { ASSERT(propertyID == CSSPropertyBackgroundPosition || propertyID == CSSPropertyWebkitMaskPosition); - positionList.get().append(cssValuePool().createValue(layer->backgroundYOrigin())); + list->append(CSSValuePool::singleton().createValue(layer.backgroundYOrigin())); } - positionList.get().append(zoomAdjustedPixelValueForLength(layer->yPosition(), style)); - return positionList; + list->append(zoomAdjustedPixelValueForLength(layer.yPosition(), style)); + return list; } -static PassRefPtr<CSSValue> getPositionOffsetValue(RenderStyle* style, CSSPropertyID propertyID, RenderView* renderView) +static RefPtr<CSSValue> positionOffsetValue(const RenderStyle& style, CSSPropertyID propertyID) { - if (!style) - return 0; - - Length l; + Length length; switch (propertyID) { case CSSPropertyLeft: - l = style->left(); + length = style.left(); break; case CSSPropertyRight: - l = style->right(); + length = style.right(); break; case CSSPropertyTop: - l = style->top(); + length = style.top(); break; case CSSPropertyBottom: - l = style->bottom(); + length = style.bottom(); break; default: - return 0; + return nullptr; } - if (style->hasOutOfFlowPosition()) { - if (l.type() == WebCore::Fixed) - return zoomAdjustedPixelValue(l.value(), style); - else if (l.isViewportPercentage()) - return zoomAdjustedPixelValue(valueForLength(l, 0, renderView), style); - return cssValuePool().createValue(l); + if (style.hasOutOfFlowPosition()) { + if (length.isFixed()) + return zoomAdjustedPixelValue(length.value(), style); + + return CSSValuePool::singleton().createValue(length); } - if (style->hasInFlowPosition()) { + if (style.hasInFlowPosition()) { // FIXME: It's not enough to simply return "auto" values for one offset if the other side is defined. // In other words if left is auto and right is not auto, then left's computed value is negative right(). // So we should get the opposite length unit and see if it is auto. - return cssValuePool().createValue(l); + return CSSValuePool::singleton().createValue(length); } - return cssValuePool().createIdentifierValue(CSSValueAuto); + return CSSValuePool::singleton().createIdentifierValue(CSSValueAuto); } -PassRefPtr<CSSPrimitiveValue> ComputedStyleExtractor::currentColorOrValidColor(RenderStyle* style, const Color& color) const +RefPtr<CSSPrimitiveValue> ComputedStyleExtractor::currentColorOrValidColor(const RenderStyle* style, const Color& color) const { // This function does NOT look at visited information, so that computed style doesn't expose that. if (!color.isValid()) - return cssValuePool().createColorValue(style->color().rgb()); - return cssValuePool().createColorValue(color.rgb()); + return CSSValuePool::singleton().createColorValue(style->color()); + return CSSValuePool::singleton().createColorValue(color); } -static PassRef<CSSValueList> getBorderRadiusCornerValues(const LengthSize& radius, const RenderStyle* style, RenderView* renderView) +static Ref<CSSPrimitiveValue> percentageOrZoomAdjustedValue(Length length, const RenderStyle& style) +{ + if (length.isPercent()) + return CSSValuePool::singleton().createValue(length.percent(), CSSPrimitiveValue::CSS_PERCENTAGE); + + return zoomAdjustedPixelValue(valueForLength(length, 0), style); +} + +static Ref<CSSPrimitiveValue> autoOrZoomAdjustedValue(Length length, const RenderStyle& style) +{ + if (length.isAuto()) + return CSSValuePool::singleton().createIdentifierValue(CSSValueAuto); + + return zoomAdjustedPixelValue(valueForLength(length, 0), style); +} + +static Ref<CSSValueList> borderRadiusCornerValues(const LengthSize& radius, const RenderStyle& style) { auto list = CSSValueList::createSpaceSeparated(); - if (radius.width().type() == Percent) - list.get().append(cssValuePool().createValue(radius.width().percent(), CSSPrimitiveValue::CSS_PERCENTAGE)); - else - list.get().append(zoomAdjustedPixelValue(valueForLength(radius.width(), 0, renderView), style)); - if (radius.height().type() == Percent) - list.get().append(cssValuePool().createValue(radius.height().percent(), CSSPrimitiveValue::CSS_PERCENTAGE)); - else - list.get().append(zoomAdjustedPixelValue(valueForLength(radius.height(), 0, renderView), style)); + list->append(percentageOrZoomAdjustedValue(radius.width, style)); + list->append(percentageOrZoomAdjustedValue(radius.height, style)); return list; } -static PassRef<CSSValue> getBorderRadiusCornerValue(const LengthSize& radius, const RenderStyle* style, RenderView* renderView) +static Ref<CSSValue> borderRadiusCornerValue(const LengthSize& radius, const RenderStyle& style) { - if (radius.width() == radius.height()) { - if (radius.width().type() == Percent) - return cssValuePool().createValue(radius.width().percent(), CSSPrimitiveValue::CSS_PERCENTAGE); - return zoomAdjustedPixelValue(valueForLength(radius.width(), 0, renderView), style); - } - return getBorderRadiusCornerValues(radius, style, renderView); + if (radius.width == radius.height) + return percentageOrZoomAdjustedValue(radius.width, style); + return borderRadiusCornerValues(radius, style); } -static PassRef<CSSValueList> getBorderRadiusShorthandValue(const RenderStyle* style, RenderView* renderView) +static Ref<CSSValueList> borderRadiusShorthandValue(const RenderStyle& style) { auto list = CSSValueList::createSlashSeparated(); - bool showHorizontalBottomLeft = style->borderTopRightRadius().width() != style->borderBottomLeftRadius().width(); - bool showHorizontalBottomRight = showHorizontalBottomLeft || (style->borderBottomRightRadius().width() != style->borderTopLeftRadius().width()); - bool showHorizontalTopRight = showHorizontalBottomRight || (style->borderTopRightRadius().width() != style->borderTopLeftRadius().width()); + bool showHorizontalBottomLeft = style.borderTopRightRadius().width != style.borderBottomLeftRadius().width; + bool showHorizontalBottomRight = showHorizontalBottomLeft || (style.borderBottomRightRadius().width != style.borderTopLeftRadius().width); + bool showHorizontalTopRight = showHorizontalBottomRight || (style.borderTopRightRadius().width != style.borderTopLeftRadius().width); - bool showVerticalBottomLeft = style->borderTopRightRadius().height() != style->borderBottomLeftRadius().height(); - bool showVerticalBottomRight = showVerticalBottomLeft || (style->borderBottomRightRadius().height() != style->borderTopLeftRadius().height()); - bool showVerticalTopRight = showVerticalBottomRight || (style->borderTopRightRadius().height() != style->borderTopLeftRadius().height()); + bool showVerticalBottomLeft = style.borderTopRightRadius().height != style.borderBottomLeftRadius().height; + bool showVerticalBottomRight = showVerticalBottomLeft || (style.borderBottomRightRadius().height != style.borderTopLeftRadius().height); + bool showVerticalTopRight = showVerticalBottomRight || (style.borderTopRightRadius().height != style.borderTopLeftRadius().height); - RefPtr<CSSValueList> topLeftRadius = getBorderRadiusCornerValues(style->borderTopLeftRadius(), style, renderView); - RefPtr<CSSValueList> topRightRadius = getBorderRadiusCornerValues(style->borderTopRightRadius(), style, renderView); - RefPtr<CSSValueList> bottomRightRadius = getBorderRadiusCornerValues(style->borderBottomRightRadius(), style, renderView); - RefPtr<CSSValueList> bottomLeftRadius = getBorderRadiusCornerValues(style->borderBottomLeftRadius(), style, renderView); + auto topLeftRadius = borderRadiusCornerValues(style.borderTopLeftRadius(), style); + auto topRightRadius = borderRadiusCornerValues(style.borderTopRightRadius(), style); + auto bottomRightRadius = borderRadiusCornerValues(style.borderBottomRightRadius(), style); + auto bottomLeftRadius = borderRadiusCornerValues(style.borderBottomLeftRadius(), style); - RefPtr<CSSValueList> horizontalRadii = CSSValueList::createSpaceSeparated(); - horizontalRadii->append(topLeftRadius->item(0)); + auto horizontalRadii = CSSValueList::createSpaceSeparated(); + horizontalRadii->append(*topLeftRadius->item(0)); if (showHorizontalTopRight) - horizontalRadii->append(topRightRadius->item(0)); + horizontalRadii->append(*topRightRadius->item(0)); if (showHorizontalBottomRight) - horizontalRadii->append(bottomRightRadius->item(0)); + horizontalRadii->append(*bottomRightRadius->item(0)); if (showHorizontalBottomLeft) - horizontalRadii->append(bottomLeftRadius->item(0)); + horizontalRadii->append(*bottomLeftRadius->item(0)); - list.get().append(horizontalRadii.release()); + list->append(WTFMove(horizontalRadii)); - RefPtr<CSSValueList> verticalRadiiList = CSSValueList::createSpaceSeparated(); - verticalRadiiList->append(topLeftRadius->item(1)); + auto verticalRadiiList = CSSValueList::createSpaceSeparated(); + verticalRadiiList->append(*topLeftRadius->item(1)); if (showVerticalTopRight) - verticalRadiiList->append(topRightRadius->item(1)); + verticalRadiiList->append(*topRightRadius->item(1)); if (showVerticalBottomRight) - verticalRadiiList->append(bottomRightRadius->item(1)); + verticalRadiiList->append(*bottomRightRadius->item(1)); if (showVerticalBottomLeft) - verticalRadiiList->append(bottomLeftRadius->item(1)); + verticalRadiiList->append(*bottomLeftRadius->item(1)); - if (!verticalRadiiList->equals(*toCSSValueList(list.get().item(0)))) - list.get().append(verticalRadiiList.release()); + if (!verticalRadiiList->equals(downcast<CSSValueList>(*list->item(0)))) + list->append(WTFMove(verticalRadiiList)); return list; } -static LayoutRect sizingBox(RenderObject* renderer) +static LayoutRect sizingBox(RenderObject& renderer) { - if (!renderer->isBox()) + if (!is<RenderBox>(renderer)) return LayoutRect(); - RenderBox* box = toRenderBox(renderer); - return box->style().boxSizing() == BORDER_BOX ? box->borderBoxRect() : box->computedCSSContentBoxRect(); + auto& box = downcast<RenderBox>(renderer); + return box.style().boxSizing() == BORDER_BOX ? box.borderBoxRect() : box.computedCSSContentBoxRect(); } -static PassRef<WebKitCSSTransformValue> matrixTransformValue(const TransformationMatrix& transform, const RenderStyle* style) +static Ref<CSSFunctionValue> matrixTransformValue(const TransformationMatrix& transform, const RenderStyle& style) { - RefPtr<WebKitCSSTransformValue> transformValue; + RefPtr<CSSFunctionValue> transformValue; + auto& cssValuePool = CSSValuePool::singleton(); if (transform.isAffine()) { - transformValue = WebKitCSSTransformValue::create(WebKitCSSTransformValue::MatrixTransformOperation); + transformValue = CSSFunctionValue::create(CSSValueMatrix); - transformValue->append(cssValuePool().createValue(transform.a(), CSSPrimitiveValue::CSS_NUMBER)); - transformValue->append(cssValuePool().createValue(transform.b(), CSSPrimitiveValue::CSS_NUMBER)); - transformValue->append(cssValuePool().createValue(transform.c(), CSSPrimitiveValue::CSS_NUMBER)); - transformValue->append(cssValuePool().createValue(transform.d(), CSSPrimitiveValue::CSS_NUMBER)); + transformValue->append(cssValuePool.createValue(transform.a(), CSSPrimitiveValue::CSS_NUMBER)); + transformValue->append(cssValuePool.createValue(transform.b(), CSSPrimitiveValue::CSS_NUMBER)); + transformValue->append(cssValuePool.createValue(transform.c(), CSSPrimitiveValue::CSS_NUMBER)); + transformValue->append(cssValuePool.createValue(transform.d(), CSSPrimitiveValue::CSS_NUMBER)); transformValue->append(zoomAdjustedNumberValue(transform.e(), style)); transformValue->append(zoomAdjustedNumberValue(transform.f(), style)); } else { - transformValue = WebKitCSSTransformValue::create(WebKitCSSTransformValue::Matrix3DTransformOperation); + transformValue = CSSFunctionValue::create(CSSValueMatrix3d); - transformValue->append(cssValuePool().createValue(transform.m11(), CSSPrimitiveValue::CSS_NUMBER)); - transformValue->append(cssValuePool().createValue(transform.m12(), CSSPrimitiveValue::CSS_NUMBER)); - transformValue->append(cssValuePool().createValue(transform.m13(), CSSPrimitiveValue::CSS_NUMBER)); - transformValue->append(cssValuePool().createValue(transform.m14(), CSSPrimitiveValue::CSS_NUMBER)); + transformValue->append(cssValuePool.createValue(transform.m11(), CSSPrimitiveValue::CSS_NUMBER)); + transformValue->append(cssValuePool.createValue(transform.m12(), CSSPrimitiveValue::CSS_NUMBER)); + transformValue->append(cssValuePool.createValue(transform.m13(), CSSPrimitiveValue::CSS_NUMBER)); + transformValue->append(cssValuePool.createValue(transform.m14(), CSSPrimitiveValue::CSS_NUMBER)); - transformValue->append(cssValuePool().createValue(transform.m21(), CSSPrimitiveValue::CSS_NUMBER)); - transformValue->append(cssValuePool().createValue(transform.m22(), CSSPrimitiveValue::CSS_NUMBER)); - transformValue->append(cssValuePool().createValue(transform.m23(), CSSPrimitiveValue::CSS_NUMBER)); - transformValue->append(cssValuePool().createValue(transform.m24(), CSSPrimitiveValue::CSS_NUMBER)); + transformValue->append(cssValuePool.createValue(transform.m21(), CSSPrimitiveValue::CSS_NUMBER)); + transformValue->append(cssValuePool.createValue(transform.m22(), CSSPrimitiveValue::CSS_NUMBER)); + transformValue->append(cssValuePool.createValue(transform.m23(), CSSPrimitiveValue::CSS_NUMBER)); + transformValue->append(cssValuePool.createValue(transform.m24(), CSSPrimitiveValue::CSS_NUMBER)); - transformValue->append(cssValuePool().createValue(transform.m31(), CSSPrimitiveValue::CSS_NUMBER)); - transformValue->append(cssValuePool().createValue(transform.m32(), CSSPrimitiveValue::CSS_NUMBER)); - transformValue->append(cssValuePool().createValue(transform.m33(), CSSPrimitiveValue::CSS_NUMBER)); - transformValue->append(cssValuePool().createValue(transform.m34(), CSSPrimitiveValue::CSS_NUMBER)); + transformValue->append(cssValuePool.createValue(transform.m31(), CSSPrimitiveValue::CSS_NUMBER)); + transformValue->append(cssValuePool.createValue(transform.m32(), CSSPrimitiveValue::CSS_NUMBER)); + transformValue->append(cssValuePool.createValue(transform.m33(), CSSPrimitiveValue::CSS_NUMBER)); + transformValue->append(cssValuePool.createValue(transform.m34(), CSSPrimitiveValue::CSS_NUMBER)); transformValue->append(zoomAdjustedNumberValue(transform.m41(), style)); transformValue->append(zoomAdjustedNumberValue(transform.m42(), style)); transformValue->append(zoomAdjustedNumberValue(transform.m43(), style)); - transformValue->append(cssValuePool().createValue(transform.m44(), CSSPrimitiveValue::CSS_NUMBER)); + transformValue->append(cssValuePool.createValue(transform.m44(), CSSPrimitiveValue::CSS_NUMBER)); } return transformValue.releaseNonNull(); } -static PassRef<CSSValue> computedTransform(RenderObject* renderer, const RenderStyle* style) +static Ref<CSSValue> computedTransform(RenderObject* renderer, const RenderStyle& style) { - if (!renderer || !renderer->hasTransform() || !style->hasTransform()) - return cssValuePool().createIdentifierValue(CSSValueNone); + if (!renderer || !renderer->hasTransform()) + return CSSValuePool::singleton().createIdentifierValue(CSSValueNone); - IntRect box; - if (renderer->isBox()) - box = pixelSnappedIntRect(toRenderBox(renderer)->borderBoxRect()); + FloatRect pixelSnappedRect; + if (is<RenderBox>(*renderer)) + pixelSnappedRect = snapRectToDevicePixels(downcast<RenderBox>(*renderer).borderBoxRect(), renderer->document().deviceScaleFactor()); TransformationMatrix transform; - style->applyTransform(transform, box.size(), RenderStyle::ExcludeTransformOrigin); - // Note that this does not flatten to an affine transform if ENABLE(3D_RENDERING) is off, by design. + style.applyTransform(transform, pixelSnappedRect, RenderStyle::ExcludeTransformOrigin); + // Note that this does not flatten to an affine transform if ENABLE(3D_TRANSFORMS) is off, by design. // FIXME: Need to print out individual functions (https://bugs.webkit.org/show_bug.cgi?id=23924) auto list = CSSValueList::createSpaceSeparated(); - list.get().append(matrixTransformValue(transform, style)); - return std::move(list); + list->append(matrixTransformValue(transform, style)); + return WTFMove(list); } -static inline PassRef<CSSPrimitiveValue> adjustLengthForZoom(double length, const RenderStyle* style, AdjustPixelValuesForComputedStyle adjust) +static inline Ref<CSSPrimitiveValue> adjustLengthForZoom(double length, const RenderStyle& style, AdjustPixelValuesForComputedStyle adjust) { - return adjust == AdjustPixelValues ? zoomAdjustedPixelValue(length, style) : cssValuePool().createValue(length, CSSPrimitiveValue::CSS_PX); + return adjust == AdjustPixelValues ? zoomAdjustedPixelValue(length, style) : CSSValuePool::singleton().createValue(length, CSSPrimitiveValue::CSS_PX); } -static inline PassRef<CSSPrimitiveValue> adjustLengthForZoom(const Length& length, const RenderStyle* style, AdjustPixelValuesForComputedStyle adjust) +static inline Ref<CSSPrimitiveValue> adjustLengthForZoom(const Length& length, const RenderStyle& style, AdjustPixelValuesForComputedStyle adjust) { - return adjust == AdjustPixelValues ? zoomAdjustedPixelValue(length.value(), style) : cssValuePool().createValue(length); + return adjust == AdjustPixelValues ? zoomAdjustedPixelValue(length.value(), style) : CSSValuePool::singleton().createValue(length); } -PassRefPtr<CSSValue> ComputedStyleExtractor::valueForShadow(const ShadowData* shadow, CSSPropertyID propertyID, const RenderStyle* style, AdjustPixelValuesForComputedStyle adjust) +Ref<CSSValue> ComputedStyleExtractor::valueForShadow(const ShadowData* shadow, CSSPropertyID propertyID, const RenderStyle& style, AdjustPixelValuesForComputedStyle adjust) { + auto& cssValuePool = CSSValuePool::singleton(); if (!shadow) - return cssValuePool().createIdentifierValue(CSSValueNone); + return cssValuePool.createIdentifierValue(CSSValueNone); - RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); + auto list = CSSValueList::createCommaSeparated(); for (const ShadowData* currShadowData = shadow; currShadowData; currShadowData = currShadowData->next()) { - RefPtr<CSSPrimitiveValue> x = adjustLengthForZoom(currShadowData->x(), style, adjust); - RefPtr<CSSPrimitiveValue> y = adjustLengthForZoom(currShadowData->y(), style, adjust); - RefPtr<CSSPrimitiveValue> blur = adjustLengthForZoom(currShadowData->radius(), style, adjust); - RefPtr<CSSPrimitiveValue> spread = propertyID == CSSPropertyTextShadow ? PassRefPtr<CSSPrimitiveValue>() : adjustLengthForZoom(currShadowData->spread(), style, adjust); - RefPtr<CSSPrimitiveValue> style = propertyID == CSSPropertyTextShadow || currShadowData->style() == Normal ? PassRefPtr<CSSPrimitiveValue>() : cssValuePool().createIdentifierValue(CSSValueInset); - RefPtr<CSSPrimitiveValue> color = cssValuePool().createColorValue(currShadowData->color().rgb()); - list->prepend(CSSShadowValue::create(x.release(), y.release(), blur.release(), spread.release(), style.release(), color.release())); + auto x = adjustLengthForZoom(currShadowData->x(), style, adjust); + auto y = adjustLengthForZoom(currShadowData->y(), style, adjust); + auto blur = adjustLengthForZoom(currShadowData->radius(), style, adjust); + auto spread = propertyID == CSSPropertyTextShadow ? RefPtr<CSSPrimitiveValue>() : adjustLengthForZoom(currShadowData->spread(), style, adjust); + auto style = propertyID == CSSPropertyTextShadow || currShadowData->style() == Normal ? RefPtr<CSSPrimitiveValue>() : cssValuePool.createIdentifierValue(CSSValueInset); + auto color = cssValuePool.createColorValue(currShadowData->color()); + list->prepend(CSSShadowValue::create(WTFMove(x), WTFMove(y), WTFMove(blur), WTFMove(spread), WTFMove(style), WTFMove(color))); } - return list.release(); + return WTFMove(list); } -#if ENABLE(CSS_FILTERS) -PassRef<CSSValue> ComputedStyleExtractor::valueForFilter(const RenderStyle* style, const FilterOperations& filterOperations, AdjustPixelValuesForComputedStyle adjust) +Ref<CSSValue> ComputedStyleExtractor::valueForFilter(const RenderStyle& style, const FilterOperations& filterOperations, AdjustPixelValuesForComputedStyle adjust) { + auto& cssValuePool = CSSValuePool::singleton(); if (filterOperations.operations().isEmpty()) - return cssValuePool().createIdentifierValue(CSSValueNone); + return cssValuePool.createIdentifierValue(CSSValueNone); auto list = CSSValueList::createSpaceSeparated(); - RefPtr<WebKitCSSFilterValue> filterValue; - Vector<RefPtr<FilterOperation>>::const_iterator end = filterOperations.operations().end(); for (Vector<RefPtr<FilterOperation>>::const_iterator it = filterOperations.operations().begin(); it != end; ++it) { - FilterOperation* filterOperation = (*it).get(); - switch (filterOperation->type()) { - case FilterOperation::REFERENCE: { - ReferenceFilterOperation* referenceOperation = static_cast<ReferenceFilterOperation*>(filterOperation); - filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::ReferenceFilterOperation); - filterValue->append(cssValuePool().createValue(referenceOperation->url(), CSSPrimitiveValue::CSS_URI)); - break; - } - case FilterOperation::GRAYSCALE: { - BasicColorMatrixFilterOperation* colorMatrixOperation = static_cast<BasicColorMatrixFilterOperation*>(filterOperation); - filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::GrayscaleFilterOperation); - filterValue->append(cssValuePool().createValue(colorMatrixOperation->amount(), CSSPrimitiveValue::CSS_NUMBER)); - break; - } - case FilterOperation::SEPIA: { - BasicColorMatrixFilterOperation* colorMatrixOperation = static_cast<BasicColorMatrixFilterOperation*>(filterOperation); - filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::SepiaFilterOperation); - filterValue->append(cssValuePool().createValue(colorMatrixOperation->amount(), CSSPrimitiveValue::CSS_NUMBER)); - break; - } - case FilterOperation::SATURATE: { - BasicColorMatrixFilterOperation* colorMatrixOperation = static_cast<BasicColorMatrixFilterOperation*>(filterOperation); - filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::SaturateFilterOperation); - filterValue->append(cssValuePool().createValue(colorMatrixOperation->amount(), CSSPrimitiveValue::CSS_NUMBER)); - break; - } - case FilterOperation::HUE_ROTATE: { - BasicColorMatrixFilterOperation* colorMatrixOperation = static_cast<BasicColorMatrixFilterOperation*>(filterOperation); - filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::HueRotateFilterOperation); - filterValue->append(cssValuePool().createValue(colorMatrixOperation->amount(), CSSPrimitiveValue::CSS_DEG)); - break; - } - case FilterOperation::INVERT: { - BasicComponentTransferFilterOperation* componentTransferOperation = static_cast<BasicComponentTransferFilterOperation*>(filterOperation); - filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::InvertFilterOperation); - filterValue->append(cssValuePool().createValue(componentTransferOperation->amount(), CSSPrimitiveValue::CSS_NUMBER)); - break; - } - case FilterOperation::OPACITY: { - BasicComponentTransferFilterOperation* componentTransferOperation = static_cast<BasicComponentTransferFilterOperation*>(filterOperation); - filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::OpacityFilterOperation); - filterValue->append(cssValuePool().createValue(componentTransferOperation->amount(), CSSPrimitiveValue::CSS_NUMBER)); - break; - } - case FilterOperation::BRIGHTNESS: { - BasicComponentTransferFilterOperation* brightnessOperation = static_cast<BasicComponentTransferFilterOperation*>(filterOperation); - filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::BrightnessFilterOperation); - filterValue->append(cssValuePool().createValue(brightnessOperation->amount(), CSSPrimitiveValue::CSS_NUMBER)); - break; - } - case FilterOperation::CONTRAST: { - BasicComponentTransferFilterOperation* contrastOperation = static_cast<BasicComponentTransferFilterOperation*>(filterOperation); - filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::ContrastFilterOperation); - filterValue->append(cssValuePool().createValue(contrastOperation->amount(), CSSPrimitiveValue::CSS_NUMBER)); - break; - } - case FilterOperation::BLUR: { - BlurFilterOperation* blurOperation = static_cast<BlurFilterOperation*>(filterOperation); - filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::BlurFilterOperation); - filterValue->append(adjustLengthForZoom(blurOperation->stdDeviation(), style, adjust)); - break; - } - case FilterOperation::DROP_SHADOW: { - DropShadowFilterOperation* dropShadowOperation = static_cast<DropShadowFilterOperation*>(filterOperation); - filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::DropShadowFilterOperation); - // We want our computed style to look like that of a text shadow (has neither spread nor inset style). - ShadowData shadowData = ShadowData(dropShadowOperation->location(), dropShadowOperation->stdDeviation(), 0, Normal, false, dropShadowOperation->color()); - filterValue->append(valueForShadow(&shadowData, CSSPropertyTextShadow, style, adjust)); - break; - } - default: - filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::UnknownFilterOperation); - break; + FilterOperation& filterOperation = **it; + + if (filterOperation.type() == FilterOperation::REFERENCE) { + ReferenceFilterOperation& referenceOperation = downcast<ReferenceFilterOperation>(filterOperation); + list->append(cssValuePool.createValue(referenceOperation.url(), CSSPrimitiveValue::CSS_URI)); + } else { + RefPtr<CSSFunctionValue> filterValue; + switch (filterOperation.type()) { + case FilterOperation::GRAYSCALE: { + filterValue = CSSFunctionValue::create(CSSValueGrayscale); + filterValue->append(cssValuePool.createValue(downcast<BasicColorMatrixFilterOperation>(filterOperation).amount(), CSSPrimitiveValue::CSS_NUMBER)); + break; + } + case FilterOperation::SEPIA: { + filterValue = CSSFunctionValue::create(CSSValueSepia); + filterValue->append(cssValuePool.createValue(downcast<BasicColorMatrixFilterOperation>(filterOperation).amount(), CSSPrimitiveValue::CSS_NUMBER)); + break; + } + case FilterOperation::SATURATE: { + filterValue = CSSFunctionValue::create(CSSValueSaturate); + filterValue->append(cssValuePool.createValue(downcast<BasicColorMatrixFilterOperation>(filterOperation).amount(), CSSPrimitiveValue::CSS_NUMBER)); + break; + } + case FilterOperation::HUE_ROTATE: { + filterValue = CSSFunctionValue::create(CSSValueHueRotate); + filterValue->append(cssValuePool.createValue(downcast<BasicColorMatrixFilterOperation>(filterOperation).amount(), CSSPrimitiveValue::CSS_DEG)); + break; + } + case FilterOperation::INVERT: { + filterValue = CSSFunctionValue::create(CSSValueInvert); + filterValue->append(cssValuePool.createValue(downcast<BasicComponentTransferFilterOperation>(filterOperation).amount(), CSSPrimitiveValue::CSS_NUMBER)); + break; + } + case FilterOperation::OPACITY: { + filterValue = CSSFunctionValue::create(CSSValueOpacity); + filterValue->append(cssValuePool.createValue(downcast<BasicComponentTransferFilterOperation>(filterOperation).amount(), CSSPrimitiveValue::CSS_NUMBER)); + break; + } + case FilterOperation::BRIGHTNESS: { + filterValue = CSSFunctionValue::create(CSSValueBrightness); + filterValue->append(cssValuePool.createValue(downcast<BasicComponentTransferFilterOperation>(filterOperation).amount(), CSSPrimitiveValue::CSS_NUMBER)); + break; + } + case FilterOperation::CONTRAST: { + filterValue = CSSFunctionValue::create(CSSValueContrast); + filterValue->append(cssValuePool.createValue(downcast<BasicComponentTransferFilterOperation>(filterOperation).amount(), CSSPrimitiveValue::CSS_NUMBER)); + break; + } + case FilterOperation::BLUR: { + filterValue = CSSFunctionValue::create(CSSValueBlur); + filterValue->append(adjustLengthForZoom(downcast<BlurFilterOperation>(filterOperation).stdDeviation(), style, adjust)); + break; + } + case FilterOperation::DROP_SHADOW: { + DropShadowFilterOperation& dropShadowOperation = downcast<DropShadowFilterOperation>(filterOperation); + filterValue = CSSFunctionValue::create(CSSValueDropShadow); + // We want our computed style to look like that of a text shadow (has neither spread nor inset style). + ShadowData shadowData = ShadowData(dropShadowOperation.location(), dropShadowOperation.stdDeviation(), 0, Normal, false, dropShadowOperation.color()); + filterValue->append(valueForShadow(&shadowData, CSSPropertyTextShadow, style, adjust)); + break; + } + default: + ASSERT_NOT_REACHED(); + filterValue = CSSFunctionValue::create(CSSValueInvalid); + break; + } + list->append(filterValue.releaseNonNull()); } - list.get().append(filterValue.release()); } - - return std::move(list); + return WTFMove(list); } -#endif -static PassRef<CSSValue> valueForGridTrackBreadth(const GridLength& trackBreadth, const RenderStyle* style, RenderView* renderView) +static Ref<CSSValue> specifiedValueForGridTrackBreadth(const GridLength& trackBreadth, const RenderStyle& style) { if (!trackBreadth.isLength()) - return cssValuePool().createValue(trackBreadth.flex(), CSSPrimitiveValue::CSS_FR); + return CSSValuePool::singleton().createValue(trackBreadth.flex(), CSSPrimitiveValue::CSS_FR); const Length& trackBreadthLength = trackBreadth.length(); if (trackBreadthLength.isAuto()) - return cssValuePool().createIdentifierValue(CSSValueAuto); - if (trackBreadthLength.isViewportPercentage()) - return zoomAdjustedPixelValue(valueForLength(trackBreadthLength, 0, renderView), style); + return CSSValuePool::singleton().createIdentifierValue(CSSValueAuto); return zoomAdjustedPixelValueForLength(trackBreadthLength, style); } -static PassRefPtr<CSSValue> valueForGridTrackSize(const GridTrackSize& trackSize, const RenderStyle* style, RenderView* renderView) +static Ref<CSSValue> specifiedValueForGridTrackSize(const GridTrackSize& trackSize, const RenderStyle& style) { switch (trackSize.type()) { case LengthTrackSizing: - return valueForGridTrackBreadth(trackSize.length(), style, renderView); - case MinMaxTrackSizing: - RefPtr<CSSValueList> minMaxTrackBreadths = CSSValueList::createCommaSeparated(); - minMaxTrackBreadths->append(valueForGridTrackBreadth(trackSize.minTrackBreadth(), style, renderView)); - minMaxTrackBreadths->append(valueForGridTrackBreadth(trackSize.maxTrackBreadth(), style, renderView)); - return CSSFunctionValue::create("minmax(", minMaxTrackBreadths); + return specifiedValueForGridTrackBreadth(trackSize.minTrackBreadth(), style); + case FitContentTrackSizing: { + auto fitContentTrackSize = CSSFunctionValue::create(CSSValueFitContent); + fitContentTrackSize->append(zoomAdjustedPixelValueForLength(trackSize.fitContentTrackBreadth().length(), style)); + return WTFMove(fitContentTrackSize); + } + default: + ASSERT(trackSize.type() == MinMaxTrackSizing); + if (trackSize.minTrackBreadth().isAuto() && trackSize.maxTrackBreadth().isFlex()) + return CSSValuePool::singleton().createValue(trackSize.maxTrackBreadth().flex(), CSSPrimitiveValue::CSS_FR); + + auto minMaxTrackBreadths = CSSFunctionValue::create(CSSValueMinmax); + minMaxTrackBreadths->append(specifiedValueForGridTrackBreadth(trackSize.minTrackBreadth(), style)); + minMaxTrackBreadths->append(specifiedValueForGridTrackBreadth(trackSize.maxTrackBreadth(), style)); + return WTFMove(minMaxTrackBreadths); } - ASSERT_NOT_REACHED(); - return 0; } -static void addValuesForNamedGridLinesAtIndex(const NamedGridLinesMap& namedGridLines, size_t i, CSSValueList& list) +class OrderedNamedLinesCollector { + WTF_MAKE_NONCOPYABLE(OrderedNamedLinesCollector); +public: + OrderedNamedLinesCollector(const RenderStyle& style, bool isRowAxis, unsigned autoRepeatTracksCount) + : m_orderedNamedGridLines(isRowAxis ? style.orderedNamedGridColumnLines() : style.orderedNamedGridRowLines()) + , m_orderedNamedAutoRepeatGridLines(isRowAxis ? style.autoRepeatOrderedNamedGridColumnLines() : style.autoRepeatOrderedNamedGridRowLines()) + , m_insertionPoint(isRowAxis ? style.gridAutoRepeatColumnsInsertionPoint() : style.gridAutoRepeatRowsInsertionPoint()) + , m_autoRepeatTotalTracks(autoRepeatTracksCount) + , m_autoRepeatTrackListLength(isRowAxis ? style.gridAutoRepeatColumns().size() : style.gridAutoRepeatRows().size()) + { + } + + bool isEmpty() const { return m_orderedNamedGridLines.isEmpty() && m_orderedNamedAutoRepeatGridLines.isEmpty(); } + void collectLineNamesForIndex(CSSGridLineNamesValue&, unsigned index) const; + +private: + + enum NamedLinesType { NamedLines, AutoRepeatNamedLines }; + void appendLines(CSSGridLineNamesValue&, unsigned index, NamedLinesType) const; + + const OrderedNamedGridLinesMap& m_orderedNamedGridLines; + const OrderedNamedGridLinesMap& m_orderedNamedAutoRepeatGridLines; + unsigned m_insertionPoint; + unsigned m_autoRepeatTotalTracks; + unsigned m_autoRepeatTrackListLength; +}; + +void OrderedNamedLinesCollector::appendLines(CSSGridLineNamesValue& lineNamesValue, unsigned index, NamedLinesType type) const { - // Note that this won't return the results in the order specified in the style sheet, - // which is probably fine as we still *do* return all the expected values. - NamedGridLinesMap::const_iterator it = namedGridLines.begin(); - NamedGridLinesMap::const_iterator end = namedGridLines.end(); - for (; it != end; ++it) { - const Vector<size_t>& linesIndexes = it->value; - for (size_t j = 0; j < linesIndexes.size(); ++j) { - if (linesIndexes[j] != i) - continue; + auto iter = type == NamedLines ? m_orderedNamedGridLines.find(index) : m_orderedNamedAutoRepeatGridLines.find(index); + auto endIter = type == NamedLines ? m_orderedNamedGridLines.end() : m_orderedNamedAutoRepeatGridLines.end(); + if (iter == endIter) + return; - list.append(cssValuePool().createValue(it->key, CSSPrimitiveValue::CSS_STRING)); - break; - } + auto& cssValuePool = CSSValuePool::singleton(); + for (auto lineName : iter->value) + lineNamesValue.append(cssValuePool.createValue(lineName, CSSPrimitiveValue::CSS_STRING)); +} + +void OrderedNamedLinesCollector::collectLineNamesForIndex(CSSGridLineNamesValue& lineNamesValue, unsigned i) const +{ + ASSERT(!isEmpty()); + if (m_orderedNamedAutoRepeatGridLines.isEmpty() || i < m_insertionPoint) { + appendLines(lineNamesValue, i, NamedLines); + return; + } + + ASSERT(m_autoRepeatTotalTracks); + + if (i > m_insertionPoint + m_autoRepeatTotalTracks) { + appendLines(lineNamesValue, i - (m_autoRepeatTotalTracks - 1), NamedLines); + return; + } + + if (i == m_insertionPoint) { + appendLines(lineNamesValue, i, NamedLines); + appendLines(lineNamesValue, 0, AutoRepeatNamedLines); + return; + } + + if (i == m_insertionPoint + m_autoRepeatTotalTracks) { + appendLines(lineNamesValue, m_autoRepeatTrackListLength, AutoRepeatNamedLines); + appendLines(lineNamesValue, m_insertionPoint + 1, NamedLines); + return; } + + unsigned autoRepeatIndexInFirstRepetition = (i - m_insertionPoint) % m_autoRepeatTrackListLength; + if (!autoRepeatIndexInFirstRepetition && i > m_insertionPoint) + appendLines(lineNamesValue, m_autoRepeatTrackListLength, AutoRepeatNamedLines); + appendLines(lineNamesValue, autoRepeatIndexInFirstRepetition, AutoRepeatNamedLines); } -static PassRef<CSSValue> valueForGridTrackList(const Vector<GridTrackSize>& trackSizes, const NamedGridLinesMap& namedGridLines, const RenderStyle* style, RenderView* renderView) +static void addValuesForNamedGridLinesAtIndex(OrderedNamedLinesCollector& collector, unsigned i, CSSValueList& list) { - // Handle the 'none' case here. - if (!trackSizes.size()) { - ASSERT(namedGridLines.isEmpty()); - return cssValuePool().createIdentifierValue(CSSValueNone); + if (collector.isEmpty()) + return; + + auto lineNames = CSSGridLineNamesValue::create(); + collector.collectLineNamesForIndex(lineNames.get(), i); + if (lineNames->length()) + list.append(WTFMove(lineNames)); +} + +static Ref<CSSValueList> valueForGridTrackSizeList(GridTrackSizingDirection direction, const RenderStyle& style) +{ + auto& autoTrackSizes = direction == ForColumns ? style.gridAutoColumns() : style.gridAutoRows(); + + auto list = CSSValueList::createSpaceSeparated(); + for (auto& trackSize : autoTrackSizes) + list->append(specifiedValueForGridTrackSize(trackSize, style)); + return list; +} + +static Ref<CSSValue> valueForGridTrackList(GridTrackSizingDirection direction, RenderObject* renderer, const RenderStyle& style) +{ + bool isRowAxis = direction == ForColumns; + bool isRenderGrid = is<RenderGrid>(renderer); + auto& trackSizes = isRowAxis ? style.gridColumns() : style.gridRows(); + auto& autoRepeatTrackSizes = isRowAxis ? style.gridAutoRepeatColumns() : style.gridAutoRepeatRows(); + + // Handle the 'none' case. + bool trackListIsEmpty = trackSizes.isEmpty() && autoRepeatTrackSizes.isEmpty(); + if (isRenderGrid && trackListIsEmpty) { + // For grids we should consider every listed track, whether implicitly or explicitly + // created. Empty grids have a sole grid line per axis. + auto& grid = downcast<RenderGrid>(*renderer); + auto& positions = isRowAxis ? grid.columnPositions() : grid.rowPositions(); + trackListIsEmpty = positions.size() == 1; } + if (trackListIsEmpty) + return CSSValuePool::singleton().createIdentifierValue(CSSValueNone); + + unsigned autoRepeatTotalTracks = isRenderGrid ? downcast<RenderGrid>(renderer)->autoRepeatCountForDirection(direction) : 0; + OrderedNamedLinesCollector collector(style, isRowAxis, autoRepeatTotalTracks); auto list = CSSValueList::createSpaceSeparated(); - for (size_t i = 0; i < trackSizes.size(); ++i) { - addValuesForNamedGridLinesAtIndex(namedGridLines, i, list.get()); - list.get().append(valueForGridTrackSize(trackSizes[i], style, renderView)); + unsigned insertionIndex; + if (isRenderGrid) { + auto computedTrackSizes = downcast<RenderGrid>(*renderer).trackSizesForComputedStyle(direction); + unsigned numTracks = computedTrackSizes.size(); + + for (unsigned i = 0; i < numTracks; ++i) { + addValuesForNamedGridLinesAtIndex(collector, i, list.get()); + list->append(zoomAdjustedPixelValue(computedTrackSizes[i], style)); + } + addValuesForNamedGridLinesAtIndex(collector, numTracks + 1, list.get()); + insertionIndex = numTracks; + } else { + for (unsigned i = 0; i < trackSizes.size(); ++i) { + addValuesForNamedGridLinesAtIndex(collector, i, list.get()); + list->append(specifiedValueForGridTrackSize(trackSizes[i], style)); + } + insertionIndex = trackSizes.size(); } - // Those are the trailing <string>* allowed in the syntax. - addValuesForNamedGridLinesAtIndex(namedGridLines, trackSizes.size(), list.get()); - return std::move(list); + + // Those are the trailing <ident>* allowed in the syntax. + addValuesForNamedGridLinesAtIndex(collector, insertionIndex, list.get()); + return WTFMove(list); } -static PassRef<CSSValue> valueForGridPosition(const GridPosition& position) +static Ref<CSSValue> valueForGridPosition(const GridPosition& position) { + auto& cssValuePool = CSSValuePool::singleton(); if (position.isAuto()) - return cssValuePool().createIdentifierValue(CSSValueAuto); + return cssValuePool.createIdentifierValue(CSSValueAuto); if (position.isNamedGridArea()) - return cssValuePool().createValue(position.namedGridLine(), CSSPrimitiveValue::CSS_STRING); + return cssValuePool.createValue(position.namedGridLine(), CSSPrimitiveValue::CSS_STRING); auto list = CSSValueList::createSpaceSeparated(); if (position.isSpan()) { - list.get().append(cssValuePool().createIdentifierValue(CSSValueSpan)); - list.get().append(cssValuePool().createValue(position.spanPosition(), CSSPrimitiveValue::CSS_NUMBER)); + list->append(cssValuePool.createIdentifierValue(CSSValueSpan)); + list->append(cssValuePool.createValue(position.spanPosition(), CSSPrimitiveValue::CSS_NUMBER)); } else - list.get().append(cssValuePool().createValue(position.integerPosition(), CSSPrimitiveValue::CSS_NUMBER)); + list->append(cssValuePool.createValue(position.integerPosition(), CSSPrimitiveValue::CSS_NUMBER)); if (!position.namedGridLine().isNull()) - list.get().append(cssValuePool().createValue(position.namedGridLine(), CSSPrimitiveValue::CSS_STRING)); - return std::move(list); + list->append(cssValuePool.createValue(position.namedGridLine(), CSSPrimitiveValue::CSS_STRING)); + return WTFMove(list); } -static PassRef<CSSValue> createTransitionPropertyValue(const Animation& animation) +static Ref<CSSValue> createTransitionPropertyValue(const Animation& animation) { - if (animation.animationMode() == Animation::AnimateNone) - return cssValuePool().createIdentifierValue(CSSValueNone); - if (animation.animationMode() == Animation::AnimateAll) - return cssValuePool().createIdentifierValue(CSSValueAll); - return cssValuePool().createValue(getPropertyNameString(animation.property()), CSSPrimitiveValue::CSS_STRING); + switch (animation.animationMode()) { + case Animation::AnimateNone: + return CSSValuePool::singleton().createIdentifierValue(CSSValueNone); + case Animation::AnimateAll: + return CSSValuePool::singleton().createIdentifierValue(CSSValueAll); + case Animation::AnimateSingleProperty: + return CSSValuePool::singleton().createValue(getPropertyNameString(animation.property()), CSSPrimitiveValue::CSS_STRING); + case Animation::AnimateUnknownProperty: + return CSSValuePool::singleton().createValue(animation.unknownProperty(), CSSPrimitiveValue::CSS_STRING); + } + ASSERT_NOT_REACHED(); + return CSSValuePool::singleton().createIdentifierValue(CSSValueNone); } -static PassRef<CSSValueList> getTransitionPropertyValue(const AnimationList* animList) +static Ref<CSSValueList> transitionPropertyValue(const AnimationList* animationList) { auto list = CSSValueList::createCommaSeparated(); - if (animList) { - for (size_t i = 0; i < animList->size(); ++i) - list.get().append(createTransitionPropertyValue(animList->animation(i))); + if (animationList) { + for (size_t i = 0; i < animationList->size(); ++i) + list->append(createTransitionPropertyValue(animationList->animation(i))); } else - list.get().append(cssValuePool().createIdentifierValue(CSSValueAll)); + list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueAll)); return list; } -static PassRef<CSSValueList> getDelayValue(const AnimationList* animList) +#if ENABLE(CSS_SCROLL_SNAP) + +static Ref<CSSValueList> valueForScrollSnapType(const ScrollSnapType& type) +{ + auto value = CSSValueList::createSpaceSeparated(); + if (type.strictness == ScrollSnapStrictness::None) + value->append(CSSValuePool::singleton().createValue(CSSValueNone)); + else { + value->append(CSSPrimitiveValue::create(type.axis)); + value->append(CSSPrimitiveValue::create(type.strictness)); + } + return value; +} + +static Ref<CSSValueList> valueForScrollSnapAlignment(const ScrollSnapAlign& alignment) +{ + auto value = CSSValueList::createSpaceSeparated(); + value->append(CSSPrimitiveValue::create(alignment.x)); + value->append(CSSPrimitiveValue::create(alignment.y)); + return value; +} + +#endif + +static Ref<CSSValue> willChangePropertyValue(const WillChangeData* willChangeData) +{ + auto& cssValuePool = CSSValuePool::singleton(); + if (!willChangeData || !willChangeData->numFeatures()) + return cssValuePool.createIdentifierValue(CSSValueAuto); + + auto list = CSSValueList::createCommaSeparated(); + for (size_t i = 0; i < willChangeData->numFeatures(); ++i) { + WillChangeData::FeaturePropertyPair feature = willChangeData->featureAt(i); + switch (feature.first) { + case WillChangeData::ScrollPosition: + list->append(cssValuePool.createIdentifierValue(CSSValueScrollPosition)); + break; + case WillChangeData::Contents: + list->append(cssValuePool.createIdentifierValue(CSSValueContents)); + break; + case WillChangeData::Property: + list->append(cssValuePool.createIdentifierValue(feature.second)); + break; + case WillChangeData::Invalid: + ASSERT_NOT_REACHED(); + break; + } + } + + return WTFMove(list); +} + +static inline void appendLigaturesValue(CSSValueList& list, FontVariantLigatures value, CSSValueID yesValue, CSSValueID noValue) +{ + switch (value) { + case FontVariantLigatures::Normal: + return; + case FontVariantLigatures::No: + list.append(CSSValuePool::singleton().createIdentifierValue(noValue)); + return; + case FontVariantLigatures::Yes: + list.append(CSSValuePool::singleton().createIdentifierValue(yesValue)); + return; + } + ASSERT_NOT_REACHED(); +} + +static Ref<CSSValue> fontVariantLigaturesPropertyValue(FontVariantLigatures common, FontVariantLigatures discretionary, FontVariantLigatures historical, FontVariantLigatures contextualAlternates) +{ + auto& cssValuePool = CSSValuePool::singleton(); + if (common == FontVariantLigatures::No && discretionary == FontVariantLigatures::No && historical == FontVariantLigatures::No && contextualAlternates == FontVariantLigatures::No) + return cssValuePool.createIdentifierValue(CSSValueNone); + if (common == FontVariantLigatures::Normal && discretionary == FontVariantLigatures::Normal && historical == FontVariantLigatures::Normal && contextualAlternates == FontVariantLigatures::Normal) + return cssValuePool.createIdentifierValue(CSSValueNormal); + + auto valueList = CSSValueList::createSpaceSeparated(); + appendLigaturesValue(valueList, common, CSSValueCommonLigatures, CSSValueNoCommonLigatures); + appendLigaturesValue(valueList, discretionary, CSSValueDiscretionaryLigatures, CSSValueNoDiscretionaryLigatures); + appendLigaturesValue(valueList, historical, CSSValueHistoricalLigatures, CSSValueNoHistoricalLigatures); + appendLigaturesValue(valueList, contextualAlternates, CSSValueContextual, CSSValueNoContextual); + return WTFMove(valueList); +} + +static Ref<CSSValue> fontVariantPositionPropertyValue(FontVariantPosition position) +{ + auto& cssValuePool = CSSValuePool::singleton(); + CSSValueID valueID = CSSValueNormal; + switch (position) { + case FontVariantPosition::Normal: + break; + case FontVariantPosition::Subscript: + valueID = CSSValueSub; + break; + case FontVariantPosition::Superscript: + valueID = CSSValueSuper; + break; + } + return cssValuePool.createIdentifierValue(valueID); +} + +static Ref<CSSValue> fontVariantCapsPropertyValue(FontVariantCaps caps) +{ + auto& cssValuePool = CSSValuePool::singleton(); + CSSValueID valueID = CSSValueNormal; + switch (caps) { + case FontVariantCaps::Normal: + break; + case FontVariantCaps::Small: + valueID = CSSValueSmallCaps; + break; + case FontVariantCaps::AllSmall: + valueID = CSSValueAllSmallCaps; + break; + case FontVariantCaps::Petite: + valueID = CSSValuePetiteCaps; + break; + case FontVariantCaps::AllPetite: + valueID = CSSValueAllPetiteCaps; + break; + case FontVariantCaps::Unicase: + valueID = CSSValueUnicase; + break; + case FontVariantCaps::Titling: + valueID = CSSValueTitlingCaps; + break; + } + return cssValuePool.createIdentifierValue(valueID); +} + +static Ref<CSSValue> fontVariantNumericPropertyValue(FontVariantNumericFigure figure, FontVariantNumericSpacing spacing, FontVariantNumericFraction fraction, FontVariantNumericOrdinal ordinal, FontVariantNumericSlashedZero slashedZero) +{ + auto& cssValuePool = CSSValuePool::singleton(); + if (figure == FontVariantNumericFigure::Normal && spacing == FontVariantNumericSpacing::Normal && fraction == FontVariantNumericFraction::Normal && ordinal == FontVariantNumericOrdinal::Normal && slashedZero == FontVariantNumericSlashedZero::Normal) + return cssValuePool.createIdentifierValue(CSSValueNormal); + + auto valueList = CSSValueList::createSpaceSeparated(); + switch (figure) { + case FontVariantNumericFigure::Normal: + break; + case FontVariantNumericFigure::LiningNumbers: + valueList->append(cssValuePool.createIdentifierValue(CSSValueLiningNums)); + break; + case FontVariantNumericFigure::OldStyleNumbers: + valueList->append(cssValuePool.createIdentifierValue(CSSValueOldstyleNums)); + break; + } + + switch (spacing) { + case FontVariantNumericSpacing::Normal: + break; + case FontVariantNumericSpacing::ProportionalNumbers: + valueList->append(cssValuePool.createIdentifierValue(CSSValueProportionalNums)); + break; + case FontVariantNumericSpacing::TabularNumbers: + valueList->append(cssValuePool.createIdentifierValue(CSSValueTabularNums)); + break; + } + + switch (fraction) { + case FontVariantNumericFraction::Normal: + break; + case FontVariantNumericFraction::DiagonalFractions: + valueList->append(cssValuePool.createIdentifierValue(CSSValueDiagonalFractions)); + break; + case FontVariantNumericFraction::StackedFractions: + valueList->append(cssValuePool.createIdentifierValue(CSSValueStackedFractions)); + break; + } + + if (ordinal == FontVariantNumericOrdinal::Yes) + valueList->append(cssValuePool.createIdentifierValue(CSSValueOrdinal)); + if (slashedZero == FontVariantNumericSlashedZero::Yes) + valueList->append(cssValuePool.createIdentifierValue(CSSValueSlashedZero)); + + return WTFMove(valueList); +} + +static Ref<CSSValue> fontVariantAlternatesPropertyValue(FontVariantAlternates alternates) { + auto& cssValuePool = CSSValuePool::singleton(); + CSSValueID valueID = CSSValueNormal; + switch (alternates) { + case FontVariantAlternates::Normal: + break; + case FontVariantAlternates::HistoricalForms: + valueID = CSSValueHistoricalForms; + break; + } + return cssValuePool.createIdentifierValue(valueID); +} + +static Ref<CSSValue> fontVariantEastAsianPropertyValue(FontVariantEastAsianVariant variant, FontVariantEastAsianWidth width, FontVariantEastAsianRuby ruby) +{ + auto& cssValuePool = CSSValuePool::singleton(); + if (variant == FontVariantEastAsianVariant::Normal && width == FontVariantEastAsianWidth::Normal && ruby == FontVariantEastAsianRuby::Normal) + return cssValuePool.createIdentifierValue(CSSValueNormal); + + auto valueList = CSSValueList::createSpaceSeparated(); + switch (variant) { + case FontVariantEastAsianVariant::Normal: + break; + case FontVariantEastAsianVariant::Jis78: + valueList->append(cssValuePool.createIdentifierValue(CSSValueJis78)); + break; + case FontVariantEastAsianVariant::Jis83: + valueList->append(cssValuePool.createIdentifierValue(CSSValueJis83)); + break; + case FontVariantEastAsianVariant::Jis90: + valueList->append(cssValuePool.createIdentifierValue(CSSValueJis90)); + break; + case FontVariantEastAsianVariant::Jis04: + valueList->append(cssValuePool.createIdentifierValue(CSSValueJis04)); + break; + case FontVariantEastAsianVariant::Simplified: + valueList->append(cssValuePool.createIdentifierValue(CSSValueSimplified)); + break; + case FontVariantEastAsianVariant::Traditional: + valueList->append(cssValuePool.createIdentifierValue(CSSValueTraditional)); + break; + } + + switch (width) { + case FontVariantEastAsianWidth::Normal: + break; + case FontVariantEastAsianWidth::Full: + valueList->append(cssValuePool.createIdentifierValue(CSSValueFullWidth)); + break; + case FontVariantEastAsianWidth::Proportional: + valueList->append(cssValuePool.createIdentifierValue(CSSValueProportionalWidth)); + break; + } + + if (ruby == FontVariantEastAsianRuby::Yes) + valueList->append(cssValuePool.createIdentifierValue(CSSValueRuby)); + + return WTFMove(valueList); +} + +static Ref<CSSValueList> delayValue(const AnimationList* animationList) +{ + auto& cssValuePool = CSSValuePool::singleton(); auto list = CSSValueList::createCommaSeparated(); - if (animList) { - for (size_t i = 0; i < animList->size(); ++i) - list.get().append(cssValuePool().createValue(animList->animation(i).delay(), CSSPrimitiveValue::CSS_S)); + if (animationList) { + for (size_t i = 0; i < animationList->size(); ++i) + list->append(cssValuePool.createValue(animationList->animation(i).delay(), CSSPrimitiveValue::CSS_S)); } else { // Note that initialAnimationDelay() is used for both transitions and animations - list.get().append(cssValuePool().createValue(Animation::initialAnimationDelay(), CSSPrimitiveValue::CSS_S)); + list->append(cssValuePool.createValue(Animation::initialDelay(), CSSPrimitiveValue::CSS_S)); } return list; } -static PassRef<CSSValueList> getDurationValue(const AnimationList* animList) +static Ref<CSSValueList> durationValue(const AnimationList* animationList) { + auto& cssValuePool = CSSValuePool::singleton(); auto list = CSSValueList::createCommaSeparated(); - if (animList) { - for (size_t i = 0; i < animList->size(); ++i) - list.get().append(cssValuePool().createValue(animList->animation(i).duration(), CSSPrimitiveValue::CSS_S)); + if (animationList) { + for (size_t i = 0; i < animationList->size(); ++i) + list->append(cssValuePool.createValue(animationList->animation(i).duration(), CSSPrimitiveValue::CSS_S)); } else { // Note that initialAnimationDuration() is used for both transitions and animations - list.get().append(cssValuePool().createValue(Animation::initialAnimationDuration(), CSSPrimitiveValue::CSS_S)); + list->append(cssValuePool.createValue(Animation::initialDuration(), CSSPrimitiveValue::CSS_S)); } return list; } -static PassRefPtr<CSSValue> createTimingFunctionValue(const TimingFunction* timingFunction) +static Ref<CSSValue> createTimingFunctionValue(const TimingFunction& timingFunction) { - switch (timingFunction->type()) { + switch (timingFunction.type()) { case TimingFunction::CubicBezierFunction: { - const CubicBezierTimingFunction* bezierTimingFunction = static_cast<const CubicBezierTimingFunction*>(timingFunction); - if (bezierTimingFunction->timingFunctionPreset() != CubicBezierTimingFunction::Custom) { + auto& function = static_cast<const CubicBezierTimingFunction&>(timingFunction); + if (function.timingFunctionPreset() != CubicBezierTimingFunction::Custom) { CSSValueID valueId = CSSValueInvalid; - switch (bezierTimingFunction->timingFunctionPreset()) { + switch (function.timingFunctionPreset()) { case CubicBezierTimingFunction::Ease: valueId = CSSValueEase; break; @@ -1101,63 +1498,110 @@ static PassRefPtr<CSSValue> createTimingFunctionValue(const TimingFunction* timi case CubicBezierTimingFunction::EaseOut: valueId = CSSValueEaseOut; break; - case CubicBezierTimingFunction::EaseInOut: + default: + ASSERT(function.timingFunctionPreset() == CubicBezierTimingFunction::EaseInOut); valueId = CSSValueEaseInOut; break; - default: - ASSERT_NOT_REACHED(); - return 0; } - return cssValuePool().createIdentifierValue(valueId); + return CSSValuePool::singleton().createIdentifierValue(valueId); } - return CSSCubicBezierTimingFunctionValue::create(bezierTimingFunction->x1(), bezierTimingFunction->y1(), bezierTimingFunction->x2(), bezierTimingFunction->y2()); + return CSSCubicBezierTimingFunctionValue::create(function.x1(), function.y1(), function.x2(), function.y2()); } case TimingFunction::StepsFunction: { - const StepsTimingFunction* stepsTimingFunction = static_cast<const StepsTimingFunction*>(timingFunction); - return CSSStepsTimingFunctionValue::create(stepsTimingFunction->numberOfSteps(), stepsTimingFunction->stepAtStart()); + auto& function = static_cast<const StepsTimingFunction&>(timingFunction); + return CSSStepsTimingFunctionValue::create(function.numberOfSteps(), function.stepAtStart()); } - case TimingFunction::LinearFunction: - return cssValuePool().createIdentifierValue(CSSValueLinear); + case TimingFunction::SpringFunction: { + auto& function = static_cast<const SpringTimingFunction&>(timingFunction); + return CSSSpringTimingFunctionValue::create(function.mass(), function.stiffness(), function.damping(), function.initialVelocity()); + } + default: + ASSERT(timingFunction.type() == TimingFunction::LinearFunction); + return CSSValuePool::singleton().createIdentifierValue(CSSValueLinear); } - ASSERT_NOT_REACHED(); - return 0; } -static PassRef<CSSValueList> getTimingFunctionValue(const AnimationList* animList) +static Ref<CSSValueList> timingFunctionValue(const AnimationList* animationList) { auto list = CSSValueList::createCommaSeparated(); - if (animList) { - for (size_t i = 0; i < animList->size(); ++i) - list.get().append(createTimingFunctionValue(animList->animation(i).timingFunction().get())); + if (animationList) { + for (size_t i = 0; i < animationList->size(); ++i) + list->append(createTimingFunctionValue(*animationList->animation(i).timingFunction())); } else // Note that initialAnimationTimingFunction() is used for both transitions and animations - list.get().append(createTimingFunctionValue(Animation::initialAnimationTimingFunction().get())); + list->append(createTimingFunctionValue(Animation::initialTimingFunction())); return list; } -static PassRef<CSSValue> createLineBoxContainValue(unsigned lineBoxContain) +#if ENABLE(CSS_ANIMATIONS_LEVEL_2) + +static Ref<CSSValue> createAnimationTriggerValue(const AnimationTrigger& trigger, const RenderStyle& style) +{ + switch (trigger.type()) { + case AnimationTrigger::AnimationTriggerType::ScrollAnimationTriggerType: { + auto& scrollAnimationTrigger = downcast<ScrollAnimationTrigger>(trigger); + if (scrollAnimationTrigger.endValue().isAuto()) + return CSSAnimationTriggerScrollValue::create(zoomAdjustedPixelValueForLength(scrollAnimationTrigger.startValue(), style)); + return CSSAnimationTriggerScrollValue::create(zoomAdjustedPixelValueForLength(scrollAnimationTrigger.startValue(), style), + zoomAdjustedPixelValueForLength(scrollAnimationTrigger.endValue(), style)); + } + default: + ASSERT(trigger.type() == AnimationTrigger::AnimationTriggerType::AutoAnimationTriggerType); + return CSSValuePool::singleton().createIdentifierValue(CSSValueAuto); + } +} + +static Ref<CSSValueList> animationTriggerValue(const AnimationList* animationList, const RenderStyle& style) +{ + auto list = CSSValueList::createCommaSeparated(); + if (animationList) { + for (size_t i = 0; i < animationList->size(); ++i) + list->append(createAnimationTriggerValue(*animationList->animation(i).trigger(), style)); + } else + list->append(createAnimationTriggerValue(Animation::initialTrigger().get(), style)); + return list; +} + +#endif + +static Ref<CSSValue> createLineBoxContainValue(unsigned lineBoxContain) { if (!lineBoxContain) - return cssValuePool().createIdentifierValue(CSSValueNone); + return CSSValuePool::singleton().createIdentifierValue(CSSValueNone); return CSSLineBoxContainValue::create(lineBoxContain); } -ComputedStyleExtractor::ComputedStyleExtractor(PassRefPtr<Node> node, bool allowVisitedStyle, PseudoId pseudoElementSpecifier) - : m_node(node) +static Element* styleElementForNode(Node* node) +{ + if (!node) + return nullptr; + if (is<Element>(*node)) + return downcast<Element>(node); + return composedTreeAncestors(*node).first(); +} + +ComputedStyleExtractor::ComputedStyleExtractor(Node* node, bool allowVisitedStyle, PseudoId pseudoElementSpecifier) + : m_element(styleElementForNode(node)) , m_pseudoElementSpecifier(pseudoElementSpecifier) , m_allowVisitedStyle(allowVisitedStyle) { } +ComputedStyleExtractor::ComputedStyleExtractor(Element* element, bool allowVisitedStyle, PseudoId pseudoElementSpecifier) + : m_element(element) + , m_pseudoElementSpecifier(pseudoElementSpecifier) + , m_allowVisitedStyle(allowVisitedStyle) +{ +} -CSSComputedStyleDeclaration::CSSComputedStyleDeclaration(PassRefPtr<Node> n, bool allowVisitedStyle, const String& pseudoElementName) - : m_node(n) +CSSComputedStyleDeclaration::CSSComputedStyleDeclaration(Element& element, bool allowVisitedStyle, const String& pseudoElementName) + : m_element(element) , m_allowVisitedStyle(allowVisitedStyle) , m_refCount(1) { unsigned nameWithoutColonsStart = pseudoElementName[0] == ':' ? (pseudoElementName[1] == ':' ? 2 : 1) : 0; - m_pseudoElementSpecifier = CSSSelector::pseudoId(CSSSelector::parsePseudoType( - AtomicString(pseudoElementName.substring(nameWithoutColonsStart)))); + m_pseudoElementSpecifier = CSSSelector::pseudoId(CSSSelector::parsePseudoElementType( + (pseudoElementName.substringSharingImpl(nameWithoutColonsStart)))); } CSSComputedStyleDeclaration::~CSSComputedStyleDeclaration() @@ -1184,7 +1628,7 @@ String CSSComputedStyleDeclaration::cssText() const if (i) result.append(' '); result.append(getPropertyName(computedProperties[i])); - result.append(": ", 2); + result.appendLiteral(": "); result.append(getPropertyValue(computedProperties[i])); result.append(';'); } @@ -1192,41 +1636,33 @@ String CSSComputedStyleDeclaration::cssText() const return result.toString(); } -void CSSComputedStyleDeclaration::setCssText(const String&, ExceptionCode& ec) +ExceptionOr<void> CSSComputedStyleDeclaration::setCssText(const String&) { - ec = NO_MODIFICATION_ALLOWED_ERR; + return Exception { NO_MODIFICATION_ALLOWED_ERR }; } -static CSSValueID cssIdentifierForFontSizeKeyword(int keywordSize) +RefPtr<CSSPrimitiveValue> ComputedStyleExtractor::getFontSizeCSSValuePreferringKeyword() { - ASSERT_ARG(keywordSize, keywordSize); - ASSERT_ARG(keywordSize, keywordSize <= 8); - return static_cast<CSSValueID>(CSSValueXxSmall + keywordSize - 1); -} - -PassRefPtr<CSSPrimitiveValue> ComputedStyleExtractor::getFontSizeCSSValuePreferringKeyword() const -{ - if (!m_node) - return 0; + if (!m_element) + return nullptr; - m_node->document().updateLayoutIgnorePendingStylesheets(); + m_element->document().updateLayoutIgnorePendingStylesheets(); - RefPtr<RenderStyle> style = m_node->computedStyle(m_pseudoElementSpecifier); + auto* style = m_element->computedStyle(m_pseudoElementSpecifier); if (!style) - return 0; + return nullptr; - if (int keywordSize = style->fontDescription().keywordSize()) - return cssValuePool().createIdentifierValue(cssIdentifierForFontSizeKeyword(keywordSize)); + if (CSSValueID sizeIdentifier = style->fontDescription().keywordSizeAsIdentifier()) + return CSSValuePool::singleton().createIdentifierValue(sizeIdentifier); - return zoomAdjustedPixelValue(style->fontDescription().computedPixelSize(), style.get()); + return zoomAdjustedPixelValue(style->fontDescription().computedSize(), *style); } -bool ComputedStyleExtractor::useFixedFontDefaultSize() const +bool ComputedStyleExtractor::useFixedFontDefaultSize() { - if (!m_node) + if (!m_element) return false; - - RefPtr<RenderStyle> style = m_node->computedStyle(m_pseudoElementSpecifier); + auto* style = m_element->computedStyle(m_pseudoElementSpecifier); if (!style) return false; @@ -1251,277 +1687,549 @@ static CSSValueID identifierForFamily(const AtomicString& family) return CSSValueInvalid; } -static PassRef<CSSPrimitiveValue> valueForFamily(const AtomicString& family) +static Ref<CSSPrimitiveValue> valueForFamily(const AtomicString& family) { if (CSSValueID familyIdentifier = identifierForFamily(family)) - return cssValuePool().createIdentifierValue(familyIdentifier); - return cssValuePool().createValue(family.string(), CSSPrimitiveValue::CSS_STRING); + return CSSValuePool::singleton().createIdentifierValue(familyIdentifier); + return CSSValuePool::singleton().createFontFamilyValue(family); } -static PassRef<CSSValue> renderTextDecorationFlagsToCSSValue(int textDecoration) +static Ref<CSSValue> renderTextDecorationFlagsToCSSValue(int textDecoration) { + auto& cssValuePool = CSSValuePool::singleton(); // Blink value is ignored. - RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); + auto list = CSSValueList::createSpaceSeparated(); if (textDecoration & TextDecorationUnderline) - list->append(cssValuePool().createIdentifierValue(CSSValueUnderline)); + list->append(cssValuePool.createIdentifierValue(CSSValueUnderline)); if (textDecoration & TextDecorationOverline) - list->append(cssValuePool().createIdentifierValue(CSSValueOverline)); + list->append(cssValuePool.createIdentifierValue(CSSValueOverline)); if (textDecoration & TextDecorationLineThrough) - list->append(cssValuePool().createIdentifierValue(CSSValueLineThrough)); + list->append(cssValuePool.createIdentifierValue(CSSValueLineThrough)); #if ENABLE(LETTERPRESS) if (textDecoration & TextDecorationLetterpress) - list->append(cssValuePool().createIdentifierValue(CSSValueWebkitLetterpress)); + list->append(cssValuePool.createIdentifierValue(CSSValueWebkitLetterpress)); #endif if (!list->length()) - return cssValuePool().createIdentifierValue(CSSValueNone); - return list.releaseNonNull(); + return cssValuePool.createIdentifierValue(CSSValueNone); + return WTFMove(list); } -static PassRef<CSSValue> renderTextDecorationStyleFlagsToCSSValue(TextDecorationStyle textDecorationStyle) +static Ref<CSSValue> renderTextDecorationStyleFlagsToCSSValue(TextDecorationStyle textDecorationStyle) { switch (textDecorationStyle) { case TextDecorationStyleSolid: - return cssValuePool().createIdentifierValue(CSSValueSolid); + return CSSValuePool::singleton().createIdentifierValue(CSSValueSolid); case TextDecorationStyleDouble: - return cssValuePool().createIdentifierValue(CSSValueDouble); + return CSSValuePool::singleton().createIdentifierValue(CSSValueDouble); case TextDecorationStyleDotted: - return cssValuePool().createIdentifierValue(CSSValueDotted); + return CSSValuePool::singleton().createIdentifierValue(CSSValueDotted); case TextDecorationStyleDashed: - return cssValuePool().createIdentifierValue(CSSValueDashed); + return CSSValuePool::singleton().createIdentifierValue(CSSValueDashed); case TextDecorationStyleWavy: - return cssValuePool().createIdentifierValue(CSSValueWavy); + return CSSValuePool::singleton().createIdentifierValue(CSSValueWavy); } ASSERT_NOT_REACHED(); - return cssValuePool().createExplicitInitialValue(); + return CSSValuePool::singleton().createExplicitInitialValue(); } -static PassRef<CSSValue> renderTextDecorationSkipFlagsToCSSValue(TextDecorationSkip textDecorationSkip) +static Ref<CSSValue> renderTextDecorationSkipFlagsToCSSValue(TextDecorationSkip textDecorationSkip) { switch (textDecorationSkip) { + case TextDecorationSkipAuto: + return CSSValuePool::singleton().createIdentifierValue(CSSValueAuto); case TextDecorationSkipNone: - return cssValuePool().createExplicitInitialValue(); + return CSSValuePool::singleton().createIdentifierValue(CSSValueNone); case TextDecorationSkipInk: - return cssValuePool().createIdentifierValue(CSSValueInk); + return CSSValuePool::singleton().createIdentifierValue(CSSValueInk); + case TextDecorationSkipObjects: + return CSSValuePool::singleton().createIdentifierValue(CSSValueObjects); } ASSERT_NOT_REACHED(); - return cssValuePool().createExplicitInitialValue(); + return CSSValuePool::singleton().createExplicitInitialValue(); } -static PassRef<CSSValue> renderEmphasisPositionFlagsToCSSValue(TextEmphasisPosition textEmphasisPosition) +static Ref<CSSValue> renderEmphasisPositionFlagsToCSSValue(TextEmphasisPosition textEmphasisPosition) { ASSERT(!((textEmphasisPosition & TextEmphasisPositionOver) && (textEmphasisPosition & TextEmphasisPositionUnder))); ASSERT(!((textEmphasisPosition & TextEmphasisPositionLeft) && (textEmphasisPosition & TextEmphasisPositionRight))); - RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); + auto& cssValuePool = CSSValuePool::singleton(); + auto list = CSSValueList::createSpaceSeparated(); if (textEmphasisPosition & TextEmphasisPositionOver) - list->append(cssValuePool().createIdentifierValue(CSSValueOver)); + list->append(cssValuePool.createIdentifierValue(CSSValueOver)); if (textEmphasisPosition & TextEmphasisPositionUnder) - list->append(cssValuePool().createIdentifierValue(CSSValueUnder)); + list->append(cssValuePool.createIdentifierValue(CSSValueUnder)); if (textEmphasisPosition & TextEmphasisPositionLeft) - list->append(cssValuePool().createIdentifierValue(CSSValueLeft)); + list->append(cssValuePool.createIdentifierValue(CSSValueLeft)); if (textEmphasisPosition & TextEmphasisPositionRight) - list->append(cssValuePool().createIdentifierValue(CSSValueRight)); - + list->append(cssValuePool.createIdentifierValue(CSSValueRight)); if (!list->length()) - return cssValuePool().createIdentifierValue(CSSValueNone); - return list.releaseNonNull(); + return cssValuePool.createIdentifierValue(CSSValueNone); + return WTFMove(list); } -static PassRef<CSSValue> fillRepeatToCSSValue(EFillRepeat xRepeat, EFillRepeat yRepeat) +static Ref<CSSValue> hangingPunctuationToCSSValue(HangingPunctuation hangingPunctuation) +{ + auto& cssValuePool = CSSValuePool::singleton(); + auto list = CSSValueList::createSpaceSeparated(); + if (hangingPunctuation & FirstHangingPunctuation) + list->append(cssValuePool.createIdentifierValue(CSSValueFirst)); + if (hangingPunctuation & AllowEndHangingPunctuation) + list->append(cssValuePool.createIdentifierValue(CSSValueAllowEnd)); + if (hangingPunctuation & ForceEndHangingPunctuation) + list->append(cssValuePool.createIdentifierValue(CSSValueForceEnd)); + if (hangingPunctuation & LastHangingPunctuation) + list->append(cssValuePool.createIdentifierValue(CSSValueLast)); + if (!list->length()) + return cssValuePool.createIdentifierValue(CSSValueNone); + return WTFMove(list); +} + +static Ref<CSSValue> fillRepeatToCSSValue(EFillRepeat xRepeat, EFillRepeat yRepeat) { // For backwards compatibility, if both values are equal, just return one of them. And // if the two values are equivalent to repeat-x or repeat-y, just return the shorthand. + auto& cssValuePool = CSSValuePool::singleton(); if (xRepeat == yRepeat) - return cssValuePool().createValue(xRepeat); + return cssValuePool.createValue(xRepeat); if (xRepeat == RepeatFill && yRepeat == NoRepeatFill) - return cssValuePool().createIdentifierValue(CSSValueRepeatX); + return cssValuePool.createIdentifierValue(CSSValueRepeatX); if (xRepeat == NoRepeatFill && yRepeat == RepeatFill) - return cssValuePool().createIdentifierValue(CSSValueRepeatY); + return cssValuePool.createIdentifierValue(CSSValueRepeatY); auto list = CSSValueList::createSpaceSeparated(); - list.get().append(cssValuePool().createValue(xRepeat)); - list.get().append(cssValuePool().createValue(yRepeat)); - return std::move(list); + list->append(cssValuePool.createValue(xRepeat)); + list->append(cssValuePool.createValue(yRepeat)); + return WTFMove(list); } -static PassRefPtr<CSSValue> fillSourceTypeToCSSValue(EMaskSourceType type) +static Ref<CSSValue> fillSourceTypeToCSSValue(EMaskSourceType type) { switch (type) { case MaskAlpha: - return cssValuePool().createValue(CSSValueAlpha); - case MaskLuminance: - return cssValuePool().createValue(CSSValueLuminance); + return CSSValuePool::singleton().createValue(CSSValueAlpha); + default: + ASSERT(type == MaskLuminance); + return CSSValuePool::singleton().createValue(CSSValueLuminance); } - - ASSERT_NOT_REACHED(); - - return 0; } -static PassRef<CSSValue> fillSizeToCSSValue(const FillSize& fillSize, const RenderStyle* style) + +static Ref<CSSValue> fillSizeToCSSValue(const FillSize& fillSize, const RenderStyle& style) { if (fillSize.type == Contain) - return cssValuePool().createIdentifierValue(CSSValueContain); + return CSSValuePool::singleton().createIdentifierValue(CSSValueContain); if (fillSize.type == Cover) - return cssValuePool().createIdentifierValue(CSSValueCover); + return CSSValuePool::singleton().createIdentifierValue(CSSValueCover); - if (fillSize.size.height().isAuto()) - return zoomAdjustedPixelValueForLength(fillSize.size.width(), style); + if (fillSize.size.height.isAuto()) + return zoomAdjustedPixelValueForLength(fillSize.size.width, style); auto list = CSSValueList::createSpaceSeparated(); - list.get().append(zoomAdjustedPixelValueForLength(fillSize.size.width(), style)); - list.get().append(zoomAdjustedPixelValueForLength(fillSize.size.height(), style)); - return std::move(list); + list->append(zoomAdjustedPixelValueForLength(fillSize.size.width, style)); + list->append(zoomAdjustedPixelValueForLength(fillSize.size.height, style)); + return WTFMove(list); } -static PassRef<CSSValue> altTextToCSSValue(const RenderStyle* style) +static Ref<CSSValue> altTextToCSSValue(const RenderStyle& style) { - return cssValuePool().createValue(style->contentAltText(), CSSPrimitiveValue::CSS_STRING); + return CSSValuePool::singleton().createValue(style.contentAltText(), CSSPrimitiveValue::CSS_STRING); } -static PassRef<CSSValueList> contentToCSSValue(const RenderStyle* style) +static Ref<CSSValueList> contentToCSSValue(const RenderStyle& style) { + auto& cssValuePool = CSSValuePool::singleton(); auto list = CSSValueList::createSpaceSeparated(); - for (const ContentData* contentData = style->contentData(); contentData; contentData = contentData->next()) { - if (contentData->isCounter()) { - const CounterContent* counter = static_cast<const CounterContentData*>(contentData)->counter(); - ASSERT(counter); - list.get().append(cssValuePool().createValue(counter->identifier(), CSSPrimitiveValue::CSS_COUNTER_NAME)); - } else if (contentData->isImage()) { - const StyleImage* image = static_cast<const ImageContentData*>(contentData)->image(); - ASSERT(image); - list.get().append(image->cssValue()); - } else if (contentData->isText()) - list.get().append(cssValuePool().createValue(static_cast<const TextContentData*>(contentData)->text(), CSSPrimitiveValue::CSS_STRING)); - } - if (style->hasFlowFrom()) - list.get().append(cssValuePool().createValue(style->regionThread(), CSSPrimitiveValue::CSS_STRING)); + for (auto* contentData = style.contentData(); contentData; contentData = contentData->next()) { + if (is<CounterContentData>(*contentData)) + list->append(cssValuePool.createValue(downcast<CounterContentData>(*contentData).counter().identifier(), CSSPrimitiveValue::CSS_COUNTER_NAME)); + else if (is<ImageContentData>(*contentData)) + list->append(downcast<ImageContentData>(*contentData).image().cssValue()); + else if (is<TextContentData>(*contentData)) + list->append(cssValuePool.createValue(downcast<TextContentData>(*contentData).text(), CSSPrimitiveValue::CSS_STRING)); + } + if (style.hasFlowFrom()) + list->append(cssValuePool.createValue(style.regionThread(), CSSPrimitiveValue::CSS_STRING)); return list; } -static PassRefPtr<CSSValue> counterToCSSValue(const RenderStyle* style, CSSPropertyID propertyID) +static Ref<CSSValue> counterToCSSValue(const RenderStyle& style, CSSPropertyID propertyID) { - const CounterDirectiveMap* map = style->counterDirectives(); + auto* map = style.counterDirectives(); if (!map) - return 0; + return CSSValuePool::singleton().createIdentifierValue(CSSValueNone); - RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); + auto& cssValuePool = CSSValuePool::singleton(); + auto list = CSSValueList::createSpaceSeparated(); for (CounterDirectiveMap::const_iterator it = map->begin(); it != map->end(); ++it) { - list->append(cssValuePool().createValue(it->key, CSSPrimitiveValue::CSS_STRING)); + list->append(cssValuePool.createValue(it->key, CSSPrimitiveValue::CSS_STRING)); short number = propertyID == CSSPropertyCounterIncrement ? it->value.incrementValue() : it->value.resetValue(); - list->append(cssValuePool().createValue((double)number, CSSPrimitiveValue::CSS_NUMBER)); + list->append(cssValuePool.createValue((double)number, CSSPrimitiveValue::CSS_NUMBER)); } - return list.release(); + return WTFMove(list); } static void logUnimplementedPropertyID(CSSPropertyID propertyID) { - DEFINE_STATIC_LOCAL(HashSet<CSSPropertyID>, propertyIDSet, ()); - if (!propertyIDSet.add(propertyID).isNewEntry) + static NeverDestroyed<HashSet<CSSPropertyID>> propertyIDSet; + if (!propertyIDSet.get().add(propertyID).isNewEntry) return; LOG_ERROR("WebKit does not yet implement getComputedStyle for '%s'.", getPropertyName(propertyID)); } -static PassRef<CSSValueList> fontFamilyFromStyle(RenderStyle* style) +static Ref<CSSValueList> fontFamilyListFromStyle(const RenderStyle& style) { auto list = CSSValueList::createCommaSeparated(); - for (unsigned i = 0; i < style->font().familyCount(); ++i) - list.get().append(valueForFamily(style->font().familyAt(i))); + for (unsigned i = 0; i < style.fontCascade().familyCount(); ++i) + list->append(valueForFamily(style.fontCascade().familyAt(i))); return list; } -static PassRef<CSSPrimitiveValue> lineHeightFromStyle(RenderStyle* style, RenderView* renderView) +static Ref<CSSValue> fontFamilyFromStyle(const RenderStyle& style) { - Length length = style->lineHeight(); - if (length.isNegative()) - return cssValuePool().createIdentifierValue(CSSValueNormal); - if (length.isPercent()) + if (style.fontCascade().familyCount() == 1) + return valueForFamily(style.fontCascade().familyAt(0)); + return fontFamilyListFromStyle(style); +} + +static Ref<CSSPrimitiveValue> lineHeightFromStyle(const RenderStyle& style) +{ + Length length = style.lineHeight(); + if (length.isNegative()) // If true, line-height not set; use the font's line spacing. + return zoomAdjustedPixelValue(style.fontMetrics().floatLineSpacing(), style); + if (length.isPercent()) { // This is imperfect, because it doesn't include the zoom factor and the real computation // for how high to be in pixels does include things like minimum font size and the zoom factor. // On the other hand, since font-size doesn't include the zoom factor, we really can't do // that here either. - return zoomAdjustedPixelValue(static_cast<int>(length.percent() * style->fontDescription().specifiedSize()) / 100, style); - return zoomAdjustedPixelValue(floatValueForLength(length, 0, renderView), style); + return zoomAdjustedPixelValue(static_cast<int>(length.percent() * style.fontDescription().specifiedSize()) / 100, style); + } + return zoomAdjustedPixelValue(floatValueForLength(length, 0), style); } -static PassRef<CSSPrimitiveValue> fontSizeFromStyle(RenderStyle* style) +static Ref<CSSPrimitiveValue> fontSizeFromStyle(const RenderStyle& style) { - return zoomAdjustedPixelValue(style->fontDescription().computedPixelSize(), style); + return zoomAdjustedPixelValue(style.fontDescription().computedSize(), style); } -static PassRef<CSSPrimitiveValue> fontStyleFromStyle(RenderStyle* style) +static Ref<CSSPrimitiveValue> fontStyleFromStyle(const RenderStyle& style) { - if (style->fontDescription().italic()) - return cssValuePool().createIdentifierValue(CSSValueItalic); - return cssValuePool().createIdentifierValue(CSSValueNormal); + if (style.fontDescription().italic()) + return CSSValuePool::singleton().createIdentifierValue(CSSValueItalic); + return CSSValuePool::singleton().createIdentifierValue(CSSValueNormal); } -static PassRef<CSSPrimitiveValue> fontVariantFromStyle(RenderStyle* style) +static Ref<CSSValue> fontVariantFromStyle(const RenderStyle& style) { - if (style->fontDescription().smallCaps()) - return cssValuePool().createIdentifierValue(CSSValueSmallCaps); - return cssValuePool().createIdentifierValue(CSSValueNormal); + if (style.fontDescription().variantSettings().isAllNormal()) + return CSSValuePool::singleton().createIdentifierValue(CSSValueNormal); + + auto list = CSSValueList::createSpaceSeparated(); + + switch (style.fontDescription().variantCommonLigatures()) { + case FontVariantLigatures::Normal: + break; + case FontVariantLigatures::Yes: + list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueCommonLigatures)); + break; + case FontVariantLigatures::No: + list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueNoCommonLigatures)); + break; + } + + switch (style.fontDescription().variantDiscretionaryLigatures()) { + case FontVariantLigatures::Normal: + break; + case FontVariantLigatures::Yes: + list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueDiscretionaryLigatures)); + break; + case FontVariantLigatures::No: + list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueNoDiscretionaryLigatures)); + break; + } + + switch (style.fontDescription().variantHistoricalLigatures()) { + case FontVariantLigatures::Normal: + break; + case FontVariantLigatures::Yes: + list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueHistoricalLigatures)); + break; + case FontVariantLigatures::No: + list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueNoHistoricalLigatures)); + break; + } + + switch (style.fontDescription().variantContextualAlternates()) { + case FontVariantLigatures::Normal: + break; + case FontVariantLigatures::Yes: + list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueContextual)); + break; + case FontVariantLigatures::No: + list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueNoContextual)); + break; + } + + switch (style.fontDescription().variantPosition()) { + case FontVariantPosition::Normal: + break; + case FontVariantPosition::Subscript: + list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueSub)); + break; + case FontVariantPosition::Superscript: + list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueSuper)); + break; + } + + switch (style.fontDescription().variantCaps()) { + case FontVariantCaps::Normal: + break; + case FontVariantCaps::Small: + list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueSmallCaps)); + break; + case FontVariantCaps::AllSmall: + list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueAllSmallCaps)); + break; + case FontVariantCaps::Petite: + list->append(CSSValuePool::singleton().createIdentifierValue(CSSValuePetiteCaps)); + break; + case FontVariantCaps::AllPetite: + list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueAllPetiteCaps)); + break; + case FontVariantCaps::Unicase: + list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueUnicase)); + break; + case FontVariantCaps::Titling: + list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueTitlingCaps)); + break; + } + + switch (style.fontDescription().variantNumericFigure()) { + case FontVariantNumericFigure::Normal: + break; + case FontVariantNumericFigure::LiningNumbers: + list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueLiningNums)); + break; + case FontVariantNumericFigure::OldStyleNumbers: + list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueOldstyleNums)); + break; + } + + switch (style.fontDescription().variantNumericSpacing()) { + case FontVariantNumericSpacing::Normal: + break; + case FontVariantNumericSpacing::ProportionalNumbers: + list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueProportionalNums)); + break; + case FontVariantNumericSpacing::TabularNumbers: + list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueTabularNums)); + break; + } + + switch (style.fontDescription().variantNumericFraction()) { + case FontVariantNumericFraction::Normal: + break; + case FontVariantNumericFraction::DiagonalFractions: + list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueDiagonalFractions)); + break; + case FontVariantNumericFraction::StackedFractions: + list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueStackedFractions)); + break; + } + + switch (style.fontDescription().variantNumericOrdinal()) { + case FontVariantNumericOrdinal::Normal: + break; + case FontVariantNumericOrdinal::Yes: + list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueOrdinal)); + break; + } + + switch (style.fontDescription().variantNumericSlashedZero()) { + case FontVariantNumericSlashedZero::Normal: + break; + case FontVariantNumericSlashedZero::Yes: + list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueSlashedZero)); + break; + } + + switch (style.fontDescription().variantAlternates()) { + case FontVariantAlternates::Normal: + break; + case FontVariantAlternates::HistoricalForms: + list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueHistoricalForms)); + break; + } + + switch (style.fontDescription().variantEastAsianVariant()) { + case FontVariantEastAsianVariant::Normal: + break; + case FontVariantEastAsianVariant::Jis78: + list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueJis78)); + break; + case FontVariantEastAsianVariant::Jis83: + list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueJis83)); + break; + case FontVariantEastAsianVariant::Jis90: + list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueJis90)); + break; + case FontVariantEastAsianVariant::Jis04: + list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueJis04)); + break; + case FontVariantEastAsianVariant::Simplified: + list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueSimplified)); + break; + case FontVariantEastAsianVariant::Traditional: + list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueTraditional)); + break; + } + + switch (style.fontDescription().variantEastAsianWidth()) { + case FontVariantEastAsianWidth::Normal: + break; + case FontVariantEastAsianWidth::Full: + list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueFullWidth)); + break; + case FontVariantEastAsianWidth::Proportional: + list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueProportionalWidth)); + break; + } + + switch (style.fontDescription().variantEastAsianRuby()) { + case FontVariantEastAsianRuby::Normal: + break; + case FontVariantEastAsianRuby::Yes: + list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueRuby)); + break; + } + + return WTFMove(list); } -static PassRef<CSSPrimitiveValue> fontWeightFromStyle(RenderStyle* style) +static Ref<CSSPrimitiveValue> fontWeightFromStyle(const RenderStyle& style) { - switch (style->fontDescription().weight()) { + switch (style.fontDescription().weight()) { case FontWeight100: - return cssValuePool().createIdentifierValue(CSSValue100); + return CSSValuePool::singleton().createIdentifierValue(CSSValue100); case FontWeight200: - return cssValuePool().createIdentifierValue(CSSValue200); + return CSSValuePool::singleton().createIdentifierValue(CSSValue200); case FontWeight300: - return cssValuePool().createIdentifierValue(CSSValue300); + return CSSValuePool::singleton().createIdentifierValue(CSSValue300); case FontWeightNormal: - return cssValuePool().createIdentifierValue(CSSValueNormal); + return CSSValuePool::singleton().createIdentifierValue(CSSValueNormal); case FontWeight500: - return cssValuePool().createIdentifierValue(CSSValue500); + return CSSValuePool::singleton().createIdentifierValue(CSSValue500); case FontWeight600: - return cssValuePool().createIdentifierValue(CSSValue600); + return CSSValuePool::singleton().createIdentifierValue(CSSValue600); case FontWeightBold: - return cssValuePool().createIdentifierValue(CSSValueBold); + return CSSValuePool::singleton().createIdentifierValue(CSSValueBold); case FontWeight800: - return cssValuePool().createIdentifierValue(CSSValue800); + return CSSValuePool::singleton().createIdentifierValue(CSSValue800); case FontWeight900: - return cssValuePool().createIdentifierValue(CSSValue900); + return CSSValuePool::singleton().createIdentifierValue(CSSValue900); } ASSERT_NOT_REACHED(); - return cssValuePool().createIdentifierValue(CSSValueNormal); + return CSSValuePool::singleton().createIdentifierValue(CSSValueNormal); +} + +static Ref<CSSValue> fontSynthesisFromStyle(const RenderStyle& style) +{ + if (style.fontDescription().fontSynthesis() == FontSynthesisNone) + return CSSValuePool::singleton().createIdentifierValue(CSSValueNone); + + auto list = CSSValueList::createSpaceSeparated(); + if (style.fontDescription().fontSynthesis() & FontSynthesisStyle) + list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueStyle)); + if (style.fontDescription().fontSynthesis() & FontSynthesisWeight) + list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueWeight)); + if (style.fontDescription().fontSynthesis() & FontSynthesisSmallCaps) + list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueSmallCaps)); + return WTFMove(list); } typedef const Length& (RenderStyle::*RenderStyleLengthGetter)() const; typedef LayoutUnit (RenderBoxModelObject::*RenderBoxComputedCSSValueGetter)() const; template<RenderStyleLengthGetter lengthGetter, RenderBoxComputedCSSValueGetter computedCSSValueGetter> -inline PassRefPtr<CSSValue> zoomAdjustedPaddingOrMarginPixelValue(RenderStyle* style, RenderObject* renderer) +static RefPtr<CSSValue> zoomAdjustedPaddingOrMarginPixelValue(const RenderStyle& style, RenderObject* renderer) { - Length unzoomzedLength = (style->*lengthGetter)(); - if (!renderer || !renderer->isBox() || unzoomzedLength.isFixed()) + Length unzoomzedLength = (style.*lengthGetter)(); + if (!is<RenderBox>(renderer) || unzoomzedLength.isFixed()) return zoomAdjustedPixelValueForLength(unzoomzedLength, style); - return zoomAdjustedPixelValue((toRenderBox(renderer)->*computedCSSValueGetter)(), style); + return zoomAdjustedPixelValue((downcast<RenderBox>(*renderer).*computedCSSValueGetter)(), style); } template<RenderStyleLengthGetter lengthGetter> -inline bool paddingOrMarginIsRendererDependent(RenderStyle* style, RenderObject* renderer) +static bool paddingOrMarginIsRendererDependent(const RenderStyle* style, RenderObject* renderer) { - if (!renderer || !renderer->isBox()) - return false; - return !(style && (style->*lengthGetter)().isFixed()); + return renderer && style && renderer->isBox() && !(style->*lengthGetter)().isFixed(); } -static bool isLayoutDependent(CSSPropertyID propertyID, RenderStyle* style, RenderObject* renderer) +static CSSValueID convertToPageBreak(BreakBetween value) +{ + if (value == PageBreakBetween || value == LeftPageBreakBetween || value == RightPageBreakBetween + || value == RectoPageBreakBetween || value == VersoPageBreakBetween) + return CSSValueAlways; // CSS 2.1 allows us to map these to always. + if (value == AvoidBreakBetween || value == AvoidPageBreakBetween) + return CSSValueAvoid; + return CSSValueAuto; +} + +static CSSValueID convertToColumnBreak(BreakBetween value) +{ + if (value == ColumnBreakBetween) + return CSSValueAlways; + if (value == AvoidBreakBetween || value == AvoidColumnBreakBetween) + return CSSValueAvoid; + return CSSValueAuto; +} + +static CSSValueID convertToPageBreak(BreakInside value) +{ + if (value == AvoidBreakInside || value == AvoidPageBreakInside) + return CSSValueAvoid; + return CSSValueAuto; +} + +static CSSValueID convertToColumnBreak(BreakInside value) +{ + if (value == AvoidBreakInside || value == AvoidColumnBreakInside) + return CSSValueAvoid; + return CSSValueAuto; +} + +#if ENABLE(CSS_REGIONS) +static CSSValueID convertToRegionBreak(BreakBetween value) +{ + if (value == RegionBreakBetween) + return CSSValueAlways; + if (value == AvoidBreakBetween || value == AvoidRegionBreakBetween) + return CSSValueAvoid; + return CSSValueAuto; +} + +static CSSValueID convertToRegionBreak(BreakInside value) +{ + if (value == AvoidBreakInside || value == AvoidRegionBreakInside) + return CSSValueAvoid; + return CSSValueAuto; +} +#endif + +static bool isLayoutDependent(CSSPropertyID propertyID, const RenderStyle* style, RenderObject* renderer) { switch (propertyID) { case CSSPropertyWidth: case CSSPropertyHeight: - case CSSPropertyWebkitPerspectiveOrigin: - case CSSPropertyWebkitTransformOrigin: - case CSSPropertyWebkitTransform: -#if ENABLE(CSS_FILTERS) - case CSSPropertyWebkitFilter: + case CSSPropertyPerspectiveOrigin: + case CSSPropertyTransformOrigin: + case CSSPropertyTransform: + case CSSPropertyFilter: +#if ENABLE(FILTERS_LEVEL_2) + case CSSPropertyWebkitBackdropFilter: #endif return true; case CSSPropertyMargin: { @@ -1552,136 +2260,325 @@ static bool isLayoutDependent(CSSPropertyID propertyID, RenderStyle* style, Rend return paddingOrMarginIsRendererDependent<&RenderStyle::paddingBottom>(style, renderer); case CSSPropertyPaddingLeft: return paddingOrMarginIsRendererDependent<&RenderStyle::paddingLeft>(style, renderer); + case CSSPropertyGridTemplateColumns: + case CSSPropertyGridTemplateRows: + case CSSPropertyGridTemplate: + case CSSPropertyGrid: + return renderer && renderer->isRenderGrid(); default: return false; } } -Node* ComputedStyleExtractor::styledNode() const +Element* ComputedStyleExtractor::styledElement() { - if (!m_node) - return 0; - if (!m_node->isElementNode()) - return m_node.get(); - Element* element = toElement(m_node.get()); + if (!m_element) + return nullptr; PseudoElement* pseudoElement; - if (m_pseudoElementSpecifier == BEFORE && (pseudoElement = element->beforePseudoElement())) + if (m_pseudoElementSpecifier == BEFORE && (pseudoElement = m_element->beforePseudoElement())) return pseudoElement; - if (m_pseudoElementSpecifier == AFTER && (pseudoElement = element->afterPseudoElement())) + if (m_pseudoElementSpecifier == AFTER && (pseudoElement = m_element->afterPseudoElement())) return pseudoElement; - return element; + return m_element.get(); } -PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropertyID propertyID, EUpdateLayout updateLayout) const +static StyleSelfAlignmentData resolveLegacyJustifyItems(const StyleSelfAlignmentData& data) { - return ComputedStyleExtractor(m_node, m_allowVisitedStyle, m_pseudoElementSpecifier).propertyValue(propertyID, updateLayout); + if (data.positionType() == LegacyPosition) + return { data.position(), OverflowAlignmentDefault }; + return data; } -PassRef<MutableStyleProperties> CSSComputedStyleDeclaration::copyProperties() const +static StyleSelfAlignmentData resolveJustifyItemsAuto(const StyleSelfAlignmentData& data, Node* parent) { - return ComputedStyleExtractor(m_node, m_allowVisitedStyle, m_pseudoElementSpecifier).copyProperties(); + if (data.position() != ItemPositionAuto) + return data; + + // If the inherited value of justify-items includes the 'legacy' keyword, 'auto' computes to the inherited value. + const auto& inheritedValue = (!parent || !parent->computedStyle()) ? RenderStyle::initialDefaultAlignment() : parent->computedStyle()->justifyItems(); + if (inheritedValue.positionType() == LegacyPosition) + return inheritedValue; + if (inheritedValue.position() == ItemPositionAuto) + return resolveJustifyItemsAuto(inheritedValue, parent->parentNode()); + return { ItemPositionNormal, OverflowAlignmentDefault }; } -static inline bool nodeOrItsAncestorNeedsStyleRecalc(Node* styledNode) +static StyleSelfAlignmentData resolveJustifySelfAuto(const StyleSelfAlignmentData& data, Node* parent) { - if (styledNode->document().hasPendingForcedStyleRecalc()) + if (data.position() != ItemPositionAuto) + return data; + + // The 'auto' keyword computes to the computed value of justify-items on the parent or 'normal' if the box has no parent. + if (!parent || !parent->computedStyle()) + return { ItemPositionNormal, OverflowAlignmentDefault }; + return resolveLegacyJustifyItems(resolveJustifyItemsAuto(parent->computedStyle()->justifyItems(), parent->parentNode())); +} + +static StyleSelfAlignmentData resolveAlignSelfAuto(const StyleSelfAlignmentData& data, Node* parent) +{ + if (data.position() != ItemPositionAuto) + return data; + + // The 'auto' keyword computes to the computed value of align-items on the parent or 'normal' if the box has no parent. + if (!parent || !parent->computedStyle()) + return { ItemPositionNormal, OverflowAlignmentDefault }; + return parent->computedStyle()->alignItems(); +} + +static bool isImplicitlyInheritedGridOrFlexProperty(CSSPropertyID propertyID) +{ + // It would be nice if grid and flex worked within normal CSS mechanisms and not invented their own inheritance system. + switch (propertyID) { + case CSSPropertyAlignSelf: + case CSSPropertyJustifySelf: + case CSSPropertyJustifyItems: + // FIXME: In StyleResolver::adjustRenderStyle z-index is adjusted based on the parent display property for grid/flex. + case CSSPropertyZIndex: return true; - for (Node* n = styledNode; n; n = n->parentNode()) {// FIXME: Call parentOrShadowHostNode() instead - if (n->needsStyleRecalc()) - return true; + default: + return false; } - return false; } -static inline PassRefPtr<RenderStyle> computeRenderStyleForProperty(Node* styledNode, PseudoId pseudoElementSpecifier, CSSPropertyID propertyID) +RefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropertyID propertyID, EUpdateLayout updateLayout) const +{ + return ComputedStyleExtractor(m_element.ptr(), m_allowVisitedStyle, m_pseudoElementSpecifier).propertyValue(propertyID, updateLayout); +} + +Ref<MutableStyleProperties> CSSComputedStyleDeclaration::copyProperties() const +{ + return ComputedStyleExtractor(m_element.ptr(), m_allowVisitedStyle, m_pseudoElementSpecifier).copyProperties(); +} + +static inline bool hasValidStyleForProperty(Element& element, CSSPropertyID propertyID) +{ + if (element.styleValidity() != Style::Validity::Valid) + return false; + if (element.document().hasPendingForcedStyleRecalc()) + return false; + if (!element.document().childNeedsStyleRecalc()) + return true; + + bool isInherited = CSSProperty::isInheritedProperty(propertyID) || isImplicitlyInheritedGridOrFlexProperty(propertyID); + bool maybeExplicitlyInherited = !isInherited; + + const auto* currentElement = &element; + for (auto& ancestor : composedTreeAncestors(element)) { + if (ancestor.styleValidity() >= Style::Validity::SubtreeInvalid) + return false; + + if (maybeExplicitlyInherited) { + auto* style = currentElement->renderStyle(); + maybeExplicitlyInherited = !style || style->hasExplicitlyInheritedProperties(); + } + + if ((isInherited || maybeExplicitlyInherited) && ancestor.styleValidity() == Style::Validity::ElementInvalid) + return false; + + if (ancestor.directChildNeedsStyleRecalc() && currentElement->styleIsAffectedByPreviousSibling()) + return false; + + currentElement = &ancestor; + } + + return true; +} + +static bool updateStyleIfNeededForProperty(Element& element, CSSPropertyID propertyID) +{ + auto& document = element.document(); + + document.styleScope().flushPendingUpdate(); + + if (hasValidStyleForProperty(element, propertyID)) + return false; + + document.updateStyleIfNeeded(); + return true; +} + +static inline const RenderStyle* computeRenderStyleForProperty(Element& element, PseudoId pseudoElementSpecifier, CSSPropertyID propertyID, std::unique_ptr<RenderStyle>& ownedStyle) { - RenderObject* renderer = styledNode->renderer(); + auto* renderer = element.renderer(); - if (renderer && renderer->isComposited() && AnimationController::supportsAcceleratedAnimationOfProperty(propertyID)) { - AnimationUpdateBlock animationUpdateBlock(&renderer->animation()); - RefPtr<RenderStyle> style = renderer->animation().getAnimatedStyleForRenderer(toRenderElement(renderer)); - if (pseudoElementSpecifier && !styledNode->isPseudoElement()) { + if (renderer && renderer->isComposited() && CSSAnimationController::supportsAcceleratedAnimationOfProperty(propertyID)) { + ownedStyle = renderer->animation().getAnimatedStyleForRenderer(*renderer); + if (pseudoElementSpecifier && !element.isPseudoElement()) { // FIXME: This cached pseudo style will only exist if the animation has been run at least once. - return style->getCachedPseudoStyle(pseudoElementSpecifier); + return ownedStyle->getCachedPseudoStyle(pseudoElementSpecifier); } - return style.release(); + return ownedStyle.get(); } - return styledNode->computedStyle(styledNode->isPseudoElement() ? NOPSEUDO : pseudoElementSpecifier); + return element.computedStyle(element.isPseudoElement() ? NOPSEUDO : pseudoElementSpecifier); } -#if ENABLE(CSS_SHAPES) -static PassRefPtr<CSSValue> shapePropertyValue(const RenderStyle* style, const ShapeValue* shapeValue) +static Ref<CSSValue> shapePropertyValue(const RenderStyle& style, const ShapeValue* shapeValue) { if (!shapeValue) - return cssValuePool().createIdentifierValue(CSSValueNone); + return CSSValuePool::singleton().createIdentifierValue(CSSValueNone); - if (shapeValue->type() == ShapeValue::Outside) - return cssValuePool().createIdentifierValue(CSSValueOutsideShape); + if (shapeValue->type() == ShapeValue::Type::Box) + return CSSValuePool::singleton().createValue(shapeValue->cssBox()); - if (shapeValue->type() == ShapeValue::Box) - return cssValuePool().createValue(shapeValue->layoutBox()); + if (shapeValue->type() == ShapeValue::Type::Image) { + if (shapeValue->image()) + return shapeValue->image()->cssValue(); + return CSSValuePool::singleton().createIdentifierValue(CSSValueNone); + } - if (shapeValue->type() == ShapeValue::Image) - return shapeValue->image() ? shapeValue->image()->cssValue() : cssValuePool().createIdentifierValue(CSSValueNone); + ASSERT(shapeValue->type() == ShapeValue::Type::Shape); - ASSERT(shapeValue->type() == ShapeValue::Shape); + auto list = CSSValueList::createSpaceSeparated(); + list->append(valueForBasicShape(style, *shapeValue->shape())); + if (shapeValue->cssBox() != BoxMissing) + list->append(CSSValuePool::singleton().createValue(shapeValue->cssBox())); + return WTFMove(list); +} - RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); - list->append(valueForBasicShape(style, shapeValue->shape())); - if (shapeValue->layoutBox() != BoxMissing) - list->append(cssValuePool().createValue(shapeValue->layoutBox())); - return list.release(); +static Ref<CSSValueList> valueForItemPositionWithOverflowAlignment(const StyleSelfAlignmentData& data) +{ + auto& cssValuePool = CSSValuePool::singleton(); + auto result = CSSValueList::createSpaceSeparated(); + if (data.positionType() == LegacyPosition) + result->append(cssValuePool.createIdentifierValue(CSSValueLegacy)); + result->append(cssValuePool.createValue(data.position())); + if (data.position() >= ItemPositionCenter && data.overflow() != OverflowAlignmentDefault) + result->append(cssValuePool.createValue(data.overflow())); + ASSERT(result->length() <= 2); + return result; } -#endif -PassRefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID, EUpdateLayout updateLayout) const +static Ref<CSSValueList> valueForContentPositionAndDistributionWithOverflowAlignment(const StyleContentAlignmentData& data, CSSValueID normalBehaviorValueID) { - Node* styledNode = this->styledNode(); - if (!styledNode) - return 0; + auto& cssValuePool = CSSValuePool::singleton(); + auto result = CSSValueList::createSpaceSeparated(); + if (data.distribution() != ContentDistributionDefault) + result->append(cssValuePool.createValue(data.distribution())); + if (data.distribution() == ContentDistributionDefault || data.position() != ContentPositionNormal) { + bool gridEnabled = false; + gridEnabled = RuntimeEnabledFeatures::sharedFeatures().isCSSGridLayoutEnabled(); + if (data.position() != ContentPositionNormal || gridEnabled) + result->append(cssValuePool.createValue(data.position())); + else + result->append(cssValuePool.createIdentifierValue(normalBehaviorValueID)); + } + if ((data.position() >= ContentPositionCenter || data.distribution() != ContentDistributionDefault) && data.overflow() != OverflowAlignmentDefault) + result->append(cssValuePool.createValue(data.overflow())); + ASSERT(result->length() > 0); + ASSERT(result->length() <= 3); + return result; +} + +static Ref<CSSValue> paintOrder(PaintOrder paintOrder) +{ + if (paintOrder == PaintOrderNormal) + return CSSPrimitiveValue::createIdentifier(CSSValueNormal); + + auto paintOrderList = CSSValueList::createSpaceSeparated(); + switch (paintOrder) { + case PaintOrderNormal: + ASSERT_NOT_REACHED(); + break; + case PaintOrderFill: + paintOrderList->append(CSSPrimitiveValue::createIdentifier(CSSValueFill)); + break; + case PaintOrderFillMarkers: + paintOrderList->append(CSSPrimitiveValue::createIdentifier(CSSValueFill)); + paintOrderList->append(CSSPrimitiveValue::createIdentifier(CSSValueMarkers)); + break; + case PaintOrderStroke: + paintOrderList->append(CSSPrimitiveValue::createIdentifier(CSSValueStroke)); + break; + case PaintOrderStrokeMarkers: + paintOrderList->append(CSSPrimitiveValue::createIdentifier(CSSValueStroke)); + paintOrderList->append(CSSPrimitiveValue::createIdentifier(CSSValueMarkers)); + break; + case PaintOrderMarkers: + paintOrderList->append(CSSPrimitiveValue::createIdentifier(CSSValueMarkers)); + break; + case PaintOrderMarkersStroke: + paintOrderList->append(CSSPrimitiveValue::createIdentifier(CSSValueMarkers)); + paintOrderList->append(CSSPrimitiveValue::createIdentifier(CSSValueStroke)); + break; + } + return WTFMove(paintOrderList); +} + +inline static bool isFlexOrGrid(ContainerNode* element) +{ + return element && element->computedStyle() && element->computedStyle()->isDisplayFlexibleOrGridBox(); +} + +RefPtr<CSSValue> ComputedStyleExtractor::customPropertyValue(const String& propertyName) +{ + Element* styledElement = this->styledElement(); + if (!styledElement) + return nullptr; + + if (updateStyleIfNeededForProperty(*styledElement, CSSPropertyCustom)) { + // Style update may change styledElement() to PseudoElement or back. + styledElement = this->styledElement(); + } + + std::unique_ptr<RenderStyle> ownedStyle; + auto* style = computeRenderStyleForProperty(*styledElement, m_pseudoElementSpecifier, CSSPropertyCustom, ownedStyle); + if (!style) + return nullptr; + + return style->customProperties().get(propertyName); +} + +String ComputedStyleExtractor::customPropertyText(const String& propertyName) +{ + RefPtr<CSSValue> propertyValue = customPropertyValue(propertyName); + return propertyValue ? propertyValue->cssText() : emptyString(); +} + +RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID, EUpdateLayout updateLayout) +{ + auto* styledElement = this->styledElement(); + if (!styledElement) + return nullptr; - RefPtr<RenderStyle> style; - RenderObject* renderer = 0; + std::unique_ptr<RenderStyle> ownedStyle; + const RenderStyle* style = nullptr; + RenderObject* renderer = nullptr; bool forceFullLayout = false; if (updateLayout) { - Document& document = styledNode->document(); + Document& document = m_element->document(); - if (nodeOrItsAncestorNeedsStyleRecalc(styledNode)) { - document.updateStyleIfNeeded(); - // The style recalc could have caused the styled node to be discarded or replaced - // if it was a PseudoElement so we need to update it. - styledNode = this->styledNode(); + if (updateStyleIfNeededForProperty(*styledElement, propertyID)) { + // Style update may change styledElement() to PseudoElement or back. + styledElement = this->styledElement(); } + renderer = styledElement->renderer(); - renderer = styledNode->renderer(); - -#if ENABLE(SVG) - if (propertyID == CSSPropertyDisplay && !renderer && isSVGElement(*styledNode) && !toSVGElement(*styledNode).isValid()) + if (propertyID == CSSPropertyDisplay && !renderer && is<SVGElement>(*styledElement) && !downcast<SVGElement>(*styledElement).isValid()) return nullptr; -#endif - style = computeRenderStyleForProperty(styledNode, m_pseudoElementSpecifier, propertyID); + + style = computeRenderStyleForProperty(*styledElement, m_pseudoElementSpecifier, propertyID, ownedStyle); // FIXME: Some of these cases could be narrowed down or optimized better. - forceFullLayout = isLayoutDependent(propertyID, style.get(), renderer) - || styledNode->isInShadowTree() - || (document.styleResolverIfExists() && document.styleResolverIfExists()->hasViewportDependentMediaQueries() && document.ownerElement()) - || document.seamlessParentIFrame(); + forceFullLayout = isLayoutDependent(propertyID, style, renderer) + || styledElement->isInShadowTree() + || (document.styleScope().resolverIfExists() && document.styleScope().resolverIfExists()->hasViewportDependentMediaQueries() && document.ownerElement()); if (forceFullLayout) { document.updateLayoutIgnorePendingStylesheets(); - styledNode = this->styledNode(); + styledElement = this->styledElement(); } } if (!updateLayout || forceFullLayout) { - style = computeRenderStyleForProperty(styledNode, m_pseudoElementSpecifier, propertyID); - renderer = styledNode->renderer(); + style = computeRenderStyleForProperty(*styledElement, m_pseudoElementSpecifier, propertyID, ownedStyle); + renderer = styledElement->renderer(); } if (!style) - return 0; + return nullptr; + auto& cssValuePool = CSSValuePool::singleton(); propertyID = CSSProperty::resolveDirectionAwareProperty(propertyID, style->direction(), style->writingMode()); switch (propertyID) { @@ -1689,91 +2586,72 @@ PassRefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propert break; case CSSPropertyBackgroundColor: - return cssValuePool().createColorValue(m_allowVisitedStyle? style->visitedDependentColor(CSSPropertyBackgroundColor).rgb() : style->backgroundColor().rgb()); + return cssValuePool.createColorValue(m_allowVisitedStyle? style->visitedDependentColor(CSSPropertyBackgroundColor) : style->backgroundColor()); case CSSPropertyBackgroundImage: case CSSPropertyWebkitMaskImage: { - const FillLayer* layers = propertyID == CSSPropertyWebkitMaskImage ? style->maskLayers() : style->backgroundLayers(); - if (!layers) - return cssValuePool().createIdentifierValue(CSSValueNone); - - if (!layers->next()) { - if (layers->image()) - return layers->image()->cssValue(); - - return cssValuePool().createIdentifierValue(CSSValueNone); + auto& layers = propertyID == CSSPropertyWebkitMaskImage ? style->maskLayers() : style->backgroundLayers(); + if (!layers.next()) { + if (layers.image()) + return layers.image()->cssValue(); + return cssValuePool.createIdentifierValue(CSSValueNone); } - - RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); - for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) { + auto list = CSSValueList::createCommaSeparated(); + for (auto* currLayer = &layers; currLayer; currLayer = currLayer->next()) { if (currLayer->image()) list->append(currLayer->image()->cssValue()); else - list->append(cssValuePool().createIdentifierValue(CSSValueNone)); + list->append(cssValuePool.createIdentifierValue(CSSValueNone)); } - return list.release(); + return WTFMove(list); } case CSSPropertyBackgroundSize: case CSSPropertyWebkitBackgroundSize: case CSSPropertyWebkitMaskSize: { - const FillLayer* layers = propertyID == CSSPropertyWebkitMaskSize ? style->maskLayers() : style->backgroundLayers(); - if (!layers->next()) - return fillSizeToCSSValue(layers->size(), style.get()); - - RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); - for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) - list->append(fillSizeToCSSValue(currLayer->size(), style.get())); - - return list.release(); + auto& layers = propertyID == CSSPropertyWebkitMaskSize ? style->maskLayers() : style->backgroundLayers(); + if (!layers.next()) + return fillSizeToCSSValue(layers.size(), *style); + auto list = CSSValueList::createCommaSeparated(); + for (auto* currLayer = &layers; currLayer; currLayer = currLayer->next()) + list->append(fillSizeToCSSValue(currLayer->size(), *style)); + return WTFMove(list); } case CSSPropertyBackgroundRepeat: case CSSPropertyWebkitMaskRepeat: { - const FillLayer* layers = propertyID == CSSPropertyWebkitMaskRepeat ? style->maskLayers() : style->backgroundLayers(); - if (!layers->next()) - return fillRepeatToCSSValue(layers->repeatX(), layers->repeatY()); - - RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); - for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) + auto& layers = propertyID == CSSPropertyWebkitMaskRepeat ? style->maskLayers() : style->backgroundLayers(); + if (!layers.next()) + return fillRepeatToCSSValue(layers.repeatX(), layers.repeatY()); + auto list = CSSValueList::createCommaSeparated(); + for (auto* currLayer = &layers; currLayer; currLayer = currLayer->next()) list->append(fillRepeatToCSSValue(currLayer->repeatX(), currLayer->repeatY())); - - return list.release(); + return WTFMove(list); } case CSSPropertyWebkitMaskSourceType: { - const FillLayer* layers = style->maskLayers(); - - if (!layers) - return cssValuePool().createIdentifierValue(CSSValueNone); - - if (!layers->next()) - return fillSourceTypeToCSSValue(layers->maskSourceType()); - - RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); - for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) + auto& layers = style->maskLayers(); + if (!layers.next()) + return fillSourceTypeToCSSValue(layers.maskSourceType()); + auto list = CSSValueList::createCommaSeparated(); + for (auto* currLayer = &layers; currLayer; currLayer = currLayer->next()) list->append(fillSourceTypeToCSSValue(currLayer->maskSourceType())); - - return list.release(); + return WTFMove(list); } case CSSPropertyWebkitBackgroundComposite: case CSSPropertyWebkitMaskComposite: { - const FillLayer* layers = propertyID == CSSPropertyWebkitMaskComposite ? style->maskLayers() : style->backgroundLayers(); - if (!layers->next()) - return cssValuePool().createValue(layers->composite()); - - RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); - for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) - list->append(cssValuePool().createValue(currLayer->composite())); - - return list.release(); + auto& layers = propertyID == CSSPropertyWebkitMaskComposite ? style->maskLayers() : style->backgroundLayers(); + if (!layers.next()) + return cssValuePool.createValue(layers.composite()); + auto list = CSSValueList::createCommaSeparated(); + for (auto* currLayer = &layers; currLayer; currLayer = currLayer->next()) + list->append(cssValuePool.createValue(currLayer->composite())); + return WTFMove(list); } case CSSPropertyBackgroundAttachment: { - const FillLayer* layers = style->backgroundLayers(); - if (!layers->next()) - return cssValuePool().createValue(layers->attachment()); - - RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); - for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) - list->append(cssValuePool().createValue(currLayer->attachment())); - - return list.release(); + auto& layers = style->backgroundLayers(); + if (!layers.next()) + return cssValuePool.createValue(layers.attachment()); + auto list = CSSValueList::createCommaSeparated(); + for (auto* currLayer = &layers; currLayer; currLayer = currLayer->next()) + list->append(cssValuePool.createValue(currLayer->attachment())); + return WTFMove(list); } case CSSPropertyBackgroundClip: case CSSPropertyBackgroundOrigin: @@ -1781,327 +2659,348 @@ PassRefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propert case CSSPropertyWebkitBackgroundOrigin: case CSSPropertyWebkitMaskClip: case CSSPropertyWebkitMaskOrigin: { - const FillLayer* layers = (propertyID == CSSPropertyWebkitMaskClip || propertyID == CSSPropertyWebkitMaskOrigin) ? style->maskLayers() : style->backgroundLayers(); + auto& layers = (propertyID == CSSPropertyWebkitMaskClip || propertyID == CSSPropertyWebkitMaskOrigin) ? style->maskLayers() : style->backgroundLayers(); bool isClip = propertyID == CSSPropertyBackgroundClip || propertyID == CSSPropertyWebkitBackgroundClip || propertyID == CSSPropertyWebkitMaskClip; - if (!layers->next()) { - EFillBox box = isClip ? layers->clip() : layers->origin(); - return cssValuePool().createValue(box); - } - - RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); - for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) { - EFillBox box = isClip ? currLayer->clip() : currLayer->origin(); - list->append(cssValuePool().createValue(box)); - } - - return list.release(); + if (!layers.next()) + return cssValuePool.createValue(isClip ? layers.clip() : layers.origin()); + auto list = CSSValueList::createCommaSeparated(); + for (auto* currLayer = &layers; currLayer; currLayer = currLayer->next()) + list->append(cssValuePool.createValue(isClip ? currLayer->clip() : currLayer->origin())); + return WTFMove(list); } case CSSPropertyBackgroundPosition: case CSSPropertyWebkitMaskPosition: { - const FillLayer* layers = propertyID == CSSPropertyWebkitMaskPosition ? style->maskLayers() : style->backgroundLayers(); - if (!layers->next()) - return createPositionListForLayer(propertyID, layers, style.get()); - - RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); - for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) - list->append(createPositionListForLayer(propertyID, currLayer, style.get())); - return list.release(); + auto& layers = propertyID == CSSPropertyWebkitMaskPosition ? style->maskLayers() : style->backgroundLayers(); + if (!layers.next()) + return createPositionListForLayer(propertyID, layers, *style); + + auto list = CSSValueList::createCommaSeparated(); + for (auto* currLayer = &layers; currLayer; currLayer = currLayer->next()) + list->append(createPositionListForLayer(propertyID, *currLayer, *style)); + return WTFMove(list); } case CSSPropertyBackgroundPositionX: case CSSPropertyWebkitMaskPositionX: { - const FillLayer* layers = propertyID == CSSPropertyWebkitMaskPositionX ? style->maskLayers() : style->backgroundLayers(); - if (!layers->next()) - return cssValuePool().createValue(layers->xPosition()); + auto& layers = propertyID == CSSPropertyWebkitMaskPositionX ? style->maskLayers() : style->backgroundLayers(); + if (!layers.next()) + return cssValuePool.createValue(layers.xPosition()); - RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); - for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) - list->append(cssValuePool().createValue(currLayer->xPosition())); + auto list = CSSValueList::createCommaSeparated(); + for (auto* currLayer = &layers; currLayer; currLayer = currLayer->next()) + list->append(cssValuePool.createValue(currLayer->xPosition())); - return list.release(); + return WTFMove(list); } case CSSPropertyBackgroundPositionY: case CSSPropertyWebkitMaskPositionY: { - const FillLayer* layers = propertyID == CSSPropertyWebkitMaskPositionY ? style->maskLayers() : style->backgroundLayers(); - if (!layers->next()) - return cssValuePool().createValue(layers->yPosition()); + auto& layers = propertyID == CSSPropertyWebkitMaskPositionY ? style->maskLayers() : style->backgroundLayers(); + if (!layers.next()) + return cssValuePool.createValue(layers.yPosition()); - RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); - for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) - list->append(cssValuePool().createValue(currLayer->yPosition())); + auto list = CSSValueList::createCommaSeparated(); + for (auto* currLayer = &layers; currLayer; currLayer = currLayer->next()) + list->append(cssValuePool.createValue(currLayer->yPosition())); - return list.release(); + return WTFMove(list); } case CSSPropertyBorderCollapse: if (style->borderCollapse()) - return cssValuePool().createIdentifierValue(CSSValueCollapse); - return cssValuePool().createIdentifierValue(CSSValueSeparate); + return cssValuePool.createIdentifierValue(CSSValueCollapse); + return cssValuePool.createIdentifierValue(CSSValueSeparate); case CSSPropertyBorderSpacing: { - RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); - list->append(zoomAdjustedPixelValue(style->horizontalBorderSpacing(), style.get())); - list->append(zoomAdjustedPixelValue(style->verticalBorderSpacing(), style.get())); - return list.release(); + auto list = CSSValueList::createSpaceSeparated(); + list->append(zoomAdjustedPixelValue(style->horizontalBorderSpacing(), *style)); + list->append(zoomAdjustedPixelValue(style->verticalBorderSpacing(), *style)); + return WTFMove(list); } case CSSPropertyWebkitBorderHorizontalSpacing: - return zoomAdjustedPixelValue(style->horizontalBorderSpacing(), style.get()); + return zoomAdjustedPixelValue(style->horizontalBorderSpacing(), *style); case CSSPropertyWebkitBorderVerticalSpacing: - return zoomAdjustedPixelValue(style->verticalBorderSpacing(), style.get()); + return zoomAdjustedPixelValue(style->verticalBorderSpacing(), *style); case CSSPropertyBorderImageSource: if (style->borderImageSource()) return style->borderImageSource()->cssValue(); - return cssValuePool().createIdentifierValue(CSSValueNone); + return cssValuePool.createIdentifierValue(CSSValueNone); case CSSPropertyBorderTopColor: - return m_allowVisitedStyle ? cssValuePool().createColorValue(style->visitedDependentColor(CSSPropertyBorderTopColor).rgb()) : currentColorOrValidColor(style.get(), style->borderTopColor()); + return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyBorderTopColor)) : currentColorOrValidColor(style, style->borderTopColor()); case CSSPropertyBorderRightColor: - return m_allowVisitedStyle ? cssValuePool().createColorValue(style->visitedDependentColor(CSSPropertyBorderRightColor).rgb()) : currentColorOrValidColor(style.get(), style->borderRightColor()); + return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyBorderRightColor)) : currentColorOrValidColor(style, style->borderRightColor()); case CSSPropertyBorderBottomColor: - return m_allowVisitedStyle ? cssValuePool().createColorValue(style->visitedDependentColor(CSSPropertyBorderBottomColor).rgb()) : currentColorOrValidColor(style.get(), style->borderBottomColor()); + return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyBorderBottomColor)) : currentColorOrValidColor(style, style->borderBottomColor()); case CSSPropertyBorderLeftColor: - return m_allowVisitedStyle ? cssValuePool().createColorValue(style->visitedDependentColor(CSSPropertyBorderLeftColor).rgb()) : currentColorOrValidColor(style.get(), style->borderLeftColor()); + return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyBorderLeftColor)) : currentColorOrValidColor(style, style->borderLeftColor()); case CSSPropertyBorderTopStyle: - return cssValuePool().createValue(style->borderTopStyle()); + return cssValuePool.createValue(style->borderTopStyle()); case CSSPropertyBorderRightStyle: - return cssValuePool().createValue(style->borderRightStyle()); + return cssValuePool.createValue(style->borderRightStyle()); case CSSPropertyBorderBottomStyle: - return cssValuePool().createValue(style->borderBottomStyle()); + return cssValuePool.createValue(style->borderBottomStyle()); case CSSPropertyBorderLeftStyle: - return cssValuePool().createValue(style->borderLeftStyle()); + return cssValuePool.createValue(style->borderLeftStyle()); case CSSPropertyBorderTopWidth: - return zoomAdjustedPixelValue(style->borderTopWidth(), style.get()); + return zoomAdjustedPixelValue(style->borderTopWidth(), *style); case CSSPropertyBorderRightWidth: - return zoomAdjustedPixelValue(style->borderRightWidth(), style.get()); + return zoomAdjustedPixelValue(style->borderRightWidth(), *style); case CSSPropertyBorderBottomWidth: - return zoomAdjustedPixelValue(style->borderBottomWidth(), style.get()); + return zoomAdjustedPixelValue(style->borderBottomWidth(), *style); case CSSPropertyBorderLeftWidth: - return zoomAdjustedPixelValue(style->borderLeftWidth(), style.get()); + return zoomAdjustedPixelValue(style->borderLeftWidth(), *style); case CSSPropertyBottom: - return getPositionOffsetValue(style.get(), CSSPropertyBottom, m_node->document().renderView()); + return positionOffsetValue(*style, CSSPropertyBottom); case CSSPropertyWebkitBoxAlign: - return cssValuePool().createValue(style->boxAlign()); + return cssValuePool.createValue(style->boxAlign()); #if ENABLE(CSS_BOX_DECORATION_BREAK) case CSSPropertyWebkitBoxDecorationBreak: if (style->boxDecorationBreak() == DSLICE) - return cssValuePool().createIdentifierValue(CSSValueSlice); - return cssValuePool().createIdentifierValue(CSSValueClone); + return cssValuePool.createIdentifierValue(CSSValueSlice); + return cssValuePool.createIdentifierValue(CSSValueClone); #endif case CSSPropertyWebkitBoxDirection: - return cssValuePool().createValue(style->boxDirection()); + return cssValuePool.createValue(style->boxDirection()); case CSSPropertyWebkitBoxFlex: - return cssValuePool().createValue(style->boxFlex(), CSSPrimitiveValue::CSS_NUMBER); + return cssValuePool.createValue(style->boxFlex(), CSSPrimitiveValue::CSS_NUMBER); case CSSPropertyWebkitBoxFlexGroup: - return cssValuePool().createValue(style->boxFlexGroup(), CSSPrimitiveValue::CSS_NUMBER); + return cssValuePool.createValue(style->boxFlexGroup(), CSSPrimitiveValue::CSS_NUMBER); case CSSPropertyWebkitBoxLines: - return cssValuePool().createValue(style->boxLines()); + return cssValuePool.createValue(style->boxLines()); case CSSPropertyWebkitBoxOrdinalGroup: - return cssValuePool().createValue(style->boxOrdinalGroup(), CSSPrimitiveValue::CSS_NUMBER); + return cssValuePool.createValue(style->boxOrdinalGroup(), CSSPrimitiveValue::CSS_NUMBER); case CSSPropertyWebkitBoxOrient: - return cssValuePool().createValue(style->boxOrient()); + return cssValuePool.createValue(style->boxOrient()); case CSSPropertyWebkitBoxPack: - return cssValuePool().createValue(style->boxPack()); + return cssValuePool.createValue(style->boxPack()); case CSSPropertyWebkitBoxReflect: - return valueForReflection(style->boxReflect(), style.get()); + return valueForReflection(style->boxReflect(), *style); case CSSPropertyBoxShadow: case CSSPropertyWebkitBoxShadow: - return valueForShadow(style->boxShadow(), propertyID, style.get()); + return valueForShadow(style->boxShadow(), propertyID, *style); case CSSPropertyCaptionSide: - return cssValuePool().createValue(style->captionSide()); + return cssValuePool.createValue(style->captionSide()); case CSSPropertyClear: - return cssValuePool().createValue(style->clear()); + return cssValuePool.createValue(style->clear()); case CSSPropertyColor: - return cssValuePool().createColorValue(m_allowVisitedStyle ? style->visitedDependentColor(CSSPropertyColor).rgb() : style->color().rgb()); + return cssValuePool.createColorValue(m_allowVisitedStyle ? style->visitedDependentColor(CSSPropertyColor) : style->color()); case CSSPropertyWebkitPrintColorAdjust: - return cssValuePool().createValue(style->printColorAdjust()); + return cssValuePool.createValue(style->printColorAdjust()); case CSSPropertyWebkitColumnAxis: - return cssValuePool().createValue(style->columnAxis()); - case CSSPropertyWebkitColumnCount: + return cssValuePool.createValue(style->columnAxis()); + case CSSPropertyColumnCount: if (style->hasAutoColumnCount()) - return cssValuePool().createIdentifierValue(CSSValueAuto); - return cssValuePool().createValue(style->columnCount(), CSSPrimitiveValue::CSS_NUMBER); - case CSSPropertyWebkitColumnFill: - return cssValuePool().createValue(style->columnFill()); - case CSSPropertyWebkitColumnGap: + return cssValuePool.createIdentifierValue(CSSValueAuto); + return cssValuePool.createValue(style->columnCount(), CSSPrimitiveValue::CSS_NUMBER); + case CSSPropertyColumnFill: + return cssValuePool.createValue(style->columnFill()); + case CSSPropertyColumnGap: if (style->hasNormalColumnGap()) - return cssValuePool().createIdentifierValue(CSSValueNormal); - return zoomAdjustedPixelValue(style->columnGap(), style.get()); + return cssValuePool.createIdentifierValue(CSSValueNormal); + return zoomAdjustedPixelValue(style->columnGap(), *style); case CSSPropertyWebkitColumnProgression: - return cssValuePool().createValue(style->columnProgression()); - case CSSPropertyWebkitColumnRuleColor: - return m_allowVisitedStyle ? cssValuePool().createColorValue(style->visitedDependentColor(CSSPropertyOutlineColor).rgb()) : currentColorOrValidColor(style.get(), style->columnRuleColor()); - case CSSPropertyWebkitColumnRuleStyle: - return cssValuePool().createValue(style->columnRuleStyle()); - case CSSPropertyWebkitColumnRuleWidth: - return zoomAdjustedPixelValue(style->columnRuleWidth(), style.get()); - case CSSPropertyWebkitColumnSpan: - return cssValuePool().createIdentifierValue(style->columnSpan() ? CSSValueAll : CSSValueNone); + return cssValuePool.createValue(style->columnProgression()); + case CSSPropertyColumnRuleColor: + return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyOutlineColor)) : currentColorOrValidColor(style, style->columnRuleColor()); + case CSSPropertyColumnRuleStyle: + return cssValuePool.createValue(style->columnRuleStyle()); + case CSSPropertyColumnRuleWidth: + return zoomAdjustedPixelValue(style->columnRuleWidth(), *style); + case CSSPropertyColumnSpan: + return cssValuePool.createIdentifierValue(style->columnSpan() ? CSSValueAll : CSSValueNone); case CSSPropertyWebkitColumnBreakAfter: - return cssValuePool().createValue(style->columnBreakAfter()); + return cssValuePool.createValue(convertToColumnBreak(style->breakAfter())); case CSSPropertyWebkitColumnBreakBefore: - return cssValuePool().createValue(style->columnBreakBefore()); + return cssValuePool.createValue(convertToColumnBreak(style->breakBefore())); case CSSPropertyWebkitColumnBreakInside: - return cssValuePool().createValue(style->columnBreakInside()); - case CSSPropertyWebkitColumnWidth: + return cssValuePool.createValue(convertToColumnBreak(style->breakInside())); + case CSSPropertyColumnWidth: if (style->hasAutoColumnWidth()) - return cssValuePool().createIdentifierValue(CSSValueAuto); - return zoomAdjustedPixelValue(style->columnWidth(), style.get()); + return cssValuePool.createIdentifierValue(CSSValueAuto); + return zoomAdjustedPixelValue(style->columnWidth(), *style); case CSSPropertyTabSize: - return cssValuePool().createValue(style->tabSize(), CSSPrimitiveValue::CSS_NUMBER); + return cssValuePool.createValue(style->tabSize(), CSSPrimitiveValue::CSS_NUMBER); #if ENABLE(CSS_REGIONS) case CSSPropertyWebkitRegionBreakAfter: - return cssValuePool().createValue(style->regionBreakAfter()); + return cssValuePool.createValue(convertToRegionBreak(style->breakAfter())); case CSSPropertyWebkitRegionBreakBefore: - return cssValuePool().createValue(style->regionBreakBefore()); + return cssValuePool.createValue(convertToRegionBreak(style->breakBefore())); case CSSPropertyWebkitRegionBreakInside: - return cssValuePool().createValue(style->regionBreakInside()); + return cssValuePool.createValue(convertToRegionBreak(style->breakInside())); #endif case CSSPropertyCursor: { RefPtr<CSSValueList> list; - CursorList* cursors = style->cursors(); + auto* cursors = style->cursors(); if (cursors && cursors->size() > 0) { list = CSSValueList::createCommaSeparated(); for (unsigned i = 0; i < cursors->size(); ++i) if (StyleImage* image = cursors->at(i).image()) list->append(image->cssValue()); } - RefPtr<CSSValue> value = cssValuePool().createValue(style->cursor()); + auto value = cssValuePool.createValue(style->cursor()); if (list) { - list->append(value.release()); - return list.release(); + list->append(WTFMove(value)); + return list; } - return value.release(); + return WTFMove(value); } #if ENABLE(CURSOR_VISIBILITY) case CSSPropertyWebkitCursorVisibility: - return cssValuePool().createValue(style->cursorVisibility()); + return cssValuePool.createValue(style->cursorVisibility()); #endif case CSSPropertyDirection: - return cssValuePool().createValue(style->direction()); + return cssValuePool.createValue(style->direction()); case CSSPropertyDisplay: - return cssValuePool().createValue(style->display()); + return cssValuePool.createValue(style->display()); case CSSPropertyEmptyCells: - return cssValuePool().createValue(style->emptyCells()); - case CSSPropertyWebkitAlignContent: - return cssValuePool().createValue(style->alignContent()); - case CSSPropertyWebkitAlignItems: - return cssValuePool().createValue(style->alignItems()); - case CSSPropertyWebkitAlignSelf: - if (style->alignSelf() == AlignAuto) { - Node* parent = styledNode->parentNode(); - if (parent && parent->computedStyle()) - return cssValuePool().createValue(parent->computedStyle()->alignItems()); - return cssValuePool().createValue(AlignStretch); - } - return cssValuePool().createValue(style->alignSelf()); - case CSSPropertyWebkitFlex: - return getCSSPropertyValuesForShorthandProperties(webkitFlexShorthand()); - case CSSPropertyWebkitFlexBasis: - return cssValuePool().createValue(style->flexBasis()); - case CSSPropertyWebkitFlexDirection: - return cssValuePool().createValue(style->flexDirection()); - case CSSPropertyWebkitFlexFlow: - return getCSSPropertyValuesForShorthandProperties(webkitFlexFlowShorthand()); - case CSSPropertyWebkitFlexGrow: - return cssValuePool().createValue(style->flexGrow()); - case CSSPropertyWebkitFlexShrink: - return cssValuePool().createValue(style->flexShrink()); - case CSSPropertyWebkitFlexWrap: - return cssValuePool().createValue(style->flexWrap()); - case CSSPropertyWebkitJustifyContent: - return cssValuePool().createValue(style->justifyContent()); - case CSSPropertyWebkitOrder: - return cssValuePool().createValue(style->order(), CSSPrimitiveValue::CSS_NUMBER); + return cssValuePool.createValue(style->emptyCells()); + case CSSPropertyAlignContent: + return valueForContentPositionAndDistributionWithOverflowAlignment(style->alignContent(), CSSValueStretch); + case CSSPropertyAlignItems: + return valueForItemPositionWithOverflowAlignment(style->alignItems()); + case CSSPropertyAlignSelf: + return valueForItemPositionWithOverflowAlignment(resolveAlignSelfAuto(style->alignSelf(), styledElement->parentNode())); + case CSSPropertyFlex: + return getCSSPropertyValuesForShorthandProperties(flexShorthand()); + case CSSPropertyFlexBasis: + return cssValuePool.createValue(style->flexBasis()); + case CSSPropertyFlexDirection: + return cssValuePool.createValue(style->flexDirection()); + case CSSPropertyFlexFlow: + return getCSSPropertyValuesForShorthandProperties(flexFlowShorthand()); + case CSSPropertyFlexGrow: + return cssValuePool.createValue(style->flexGrow()); + case CSSPropertyFlexShrink: + return cssValuePool.createValue(style->flexShrink()); + case CSSPropertyFlexWrap: + return cssValuePool.createValue(style->flexWrap()); + case CSSPropertyJustifyContent: + return valueForContentPositionAndDistributionWithOverflowAlignment(style->justifyContent(), CSSValueFlexStart); + case CSSPropertyJustifyItems: + return valueForItemPositionWithOverflowAlignment(resolveJustifyItemsAuto(style->justifyItems(), styledElement->parentNode())); + case CSSPropertyJustifySelf: + return valueForItemPositionWithOverflowAlignment(resolveJustifySelfAuto(style->justifySelf(), styledElement->parentNode())); + case CSSPropertyOrder: + return cssValuePool.createValue(style->order(), CSSPrimitiveValue::CSS_NUMBER); case CSSPropertyFloat: if (style->display() != NONE && style->hasOutOfFlowPosition()) - return cssValuePool().createIdentifierValue(CSSValueNone); - return cssValuePool().createValue(style->floating()); + return cssValuePool.createIdentifierValue(CSSValueNone); + return cssValuePool.createValue(style->floating()); case CSSPropertyFont: { - RefPtr<CSSFontValue> computedFont = CSSFontValue::create(); - computedFont->style = fontStyleFromStyle(style.get()); - computedFont->variant = fontVariantFromStyle(style.get()); - computedFont->weight = fontWeightFromStyle(style.get()); - computedFont->size = fontSizeFromStyle(style.get()); - computedFont->lineHeight = lineHeightFromStyle(style.get(), m_node->document().renderView()); - computedFont->family = fontFamilyFromStyle(style.get()); - return computedFont.release(); - } - case CSSPropertyFontFamily: { - RefPtr<CSSValueList> fontFamilyList = fontFamilyFromStyle(style.get()); - // If there's only a single family, return that as a CSSPrimitiveValue. - // NOTE: Gecko always returns this as a comma-separated CSSPrimitiveValue string. - if (fontFamilyList->length() == 1) - return fontFamilyList->item(0); - return fontFamilyList.release(); + auto computedFont = CSSFontValue::create(); + computedFont->style = fontStyleFromStyle(*style); + if (style->fontDescription().variantCaps() == FontVariantCaps::Small) + computedFont->variant = CSSValuePool::singleton().createIdentifierValue(CSSValueSmallCaps); + else + computedFont->variant = CSSValuePool::singleton().createIdentifierValue(CSSValueNormal); + computedFont->weight = fontWeightFromStyle(*style); + computedFont->size = fontSizeFromStyle(*style); + computedFont->lineHeight = lineHeightFromStyle(*style); + computedFont->family = fontFamilyListFromStyle(*style); + return WTFMove(computedFont); } + case CSSPropertyFontFamily: + return fontFamilyFromStyle(*style); case CSSPropertyFontSize: - return fontSizeFromStyle(style.get()); + return fontSizeFromStyle(*style); case CSSPropertyFontStyle: - return fontStyleFromStyle(style.get()); + return fontStyleFromStyle(*style); case CSSPropertyFontVariant: - return fontVariantFromStyle(style.get()); + return fontVariantFromStyle(*style); case CSSPropertyFontWeight: - return fontWeightFromStyle(style.get()); - case CSSPropertyWebkitFontFeatureSettings: { - const FontFeatureSettings* featureSettings = style->fontDescription().featureSettings(); - if (!featureSettings || !featureSettings->size()) - return cssValuePool().createIdentifierValue(CSSValueNormal); - RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); - for (unsigned i = 0; i < featureSettings->size(); ++i) { - const FontFeature& feature = featureSettings->at(i); - list->append(CSSFontFeatureValue::create(feature.tag(), feature.value())); - } - return list.release(); + return fontWeightFromStyle(*style); + case CSSPropertyFontSynthesis: + return fontSynthesisFromStyle(*style); + case CSSPropertyFontFeatureSettings: { + const FontFeatureSettings& featureSettings = style->fontDescription().featureSettings(); + if (!featureSettings.size()) + return cssValuePool.createIdentifierValue(CSSValueNormal); + auto list = CSSValueList::createCommaSeparated(); + for (auto& feature : featureSettings) + list->append(CSSFontFeatureValue::create(FontTag(feature.tag()), feature.value())); + return WTFMove(list); } - case CSSPropertyWebkitGridAutoColumns: - return valueForGridTrackSize(style->gridAutoColumns(), style.get(), m_node->document().renderView()); - case CSSPropertyWebkitGridAutoFlow: - return cssValuePool().createValue(style->gridAutoFlow()); - case CSSPropertyWebkitGridAutoRows: - return valueForGridTrackSize(style->gridAutoRows(), style.get(), m_node->document().renderView()); - case CSSPropertyWebkitGridDefinitionColumns: - return valueForGridTrackList(style->gridColumns(), style->namedGridColumnLines(), style.get(), m_node->document().renderView()); - case CSSPropertyWebkitGridDefinitionRows: - return valueForGridTrackList(style->gridRows(), style->namedGridRowLines(), style.get(), m_node->document().renderView()); - - case CSSPropertyWebkitGridColumnStart: +#if ENABLE(VARIATION_FONTS) + case CSSPropertyFontVariationSettings: { + const FontVariationSettings& variationSettings = style->fontDescription().variationSettings(); + if (variationSettings.isEmpty()) + return cssValuePool.createIdentifierValue(CSSValueNormal); + auto list = CSSValueList::createCommaSeparated(); + for (auto& feature : variationSettings) + list->append(CSSFontVariationValue::create(feature.tag(), feature.value())); + return WTFMove(list); + } +#endif + case CSSPropertyGridAutoFlow: { + auto list = CSSValueList::createSpaceSeparated(); + ASSERT(style->isGridAutoFlowDirectionRow() || style->isGridAutoFlowDirectionColumn()); + if (style->isGridAutoFlowDirectionRow()) + list->append(cssValuePool.createIdentifierValue(CSSValueRow)); + else + list->append(cssValuePool.createIdentifierValue(CSSValueColumn)); + + if (style->isGridAutoFlowAlgorithmDense()) + list->append(cssValuePool.createIdentifierValue(CSSValueDense)); + + return WTFMove(list); + } + + // Specs mention that getComputedStyle() should return the used value of the property instead of the computed + // one for grid-template-{rows|columns} but not for the grid-auto-{rows|columns} as things like + // grid-auto-columns: 2fr; cannot be resolved to a value in pixels as the '2fr' means very different things + // depending on the size of the explicit grid or the number of implicit tracks added to the grid. See + // http://lists.w3.org/Archives/Public/www-style/2013Nov/0014.html + case CSSPropertyGridAutoColumns: + return valueForGridTrackSizeList(ForColumns, *style); + case CSSPropertyGridAutoRows: + return valueForGridTrackSizeList(ForRows, *style); + + case CSSPropertyGridTemplateColumns: + return valueForGridTrackList(ForColumns, renderer, *style); + case CSSPropertyGridTemplateRows: + return valueForGridTrackList(ForRows, renderer, *style); + + case CSSPropertyGridColumnStart: return valueForGridPosition(style->gridItemColumnStart()); - case CSSPropertyWebkitGridColumnEnd: + case CSSPropertyGridColumnEnd: return valueForGridPosition(style->gridItemColumnEnd()); - case CSSPropertyWebkitGridRowStart: + case CSSPropertyGridRowStart: return valueForGridPosition(style->gridItemRowStart()); - case CSSPropertyWebkitGridRowEnd: + case CSSPropertyGridRowEnd: return valueForGridPosition(style->gridItemRowEnd()); - case CSSPropertyWebkitGridArea: - return getCSSPropertyValuesForGridShorthand(webkitGridAreaShorthand()); - case CSSPropertyWebkitGridColumn: - return getCSSPropertyValuesForGridShorthand(webkitGridColumnShorthand()); - case CSSPropertyWebkitGridRow: - return getCSSPropertyValuesForGridShorthand(webkitGridRowShorthand()); - - case CSSPropertyWebkitGridTemplate: + case CSSPropertyGridArea: + return getCSSPropertyValuesForGridShorthand(gridAreaShorthand()); + case CSSPropertyGridTemplate: + return getCSSPropertyValuesForGridShorthand(gridTemplateShorthand()); + case CSSPropertyGrid: + return getCSSPropertyValuesForGridShorthand(gridShorthand()); + case CSSPropertyGridColumn: + return getCSSPropertyValuesForGridShorthand(gridColumnShorthand()); + case CSSPropertyGridRow: + return getCSSPropertyValuesForGridShorthand(gridRowShorthand()); + case CSSPropertyGridTemplateAreas: if (!style->namedGridAreaRowCount()) { ASSERT(!style->namedGridAreaColumnCount()); - return cssValuePool().createIdentifierValue(CSSValueNone); + return cssValuePool.createIdentifierValue(CSSValueNone); } - - return CSSGridTemplateValue::create(style->namedGridArea(), style->namedGridAreaRowCount(), style->namedGridAreaColumnCount()); - + return CSSGridTemplateAreasValue::create(style->namedGridArea(), style->namedGridAreaRowCount(), style->namedGridAreaColumnCount()); + case CSSPropertyGridColumnGap: + return zoomAdjustedPixelValueForLength(style->gridColumnGap(), *style); + case CSSPropertyGridRowGap: + return zoomAdjustedPixelValueForLength(style->gridRowGap(), *style); + case CSSPropertyGridGap: + return getCSSPropertyValuesForGridShorthand(gridGapShorthand()); case CSSPropertyHeight: - if (renderer) { + if (renderer && !renderer->isRenderSVGModelObject()) { // According to http://www.w3.org/TR/CSS2/visudet.html#the-height-property, // the "height" property does not apply for non-replaced inline elements. if (!renderer->isReplaced() && renderer->isInline()) - return cssValuePool().createIdentifierValue(CSSValueAuto); - return zoomAdjustedPixelValue(sizingBox(renderer).height(), style.get()); + return cssValuePool.createIdentifierValue(CSSValueAuto); + return zoomAdjustedPixelValue(sizingBox(*renderer).height(), *style); } - return zoomAdjustedPixelValueForLength(style->height(), style.get()); - case CSSPropertyWebkitHighlight: - if (style->highlight() == nullAtom) - return cssValuePool().createIdentifierValue(CSSValueNone); - return cssValuePool().createValue(style->highlight(), CSSPrimitiveValue::CSS_STRING); + return zoomAdjustedPixelValueForLength(style->height(), *style); case CSSPropertyWebkitHyphens: - return cssValuePool().createValue(style->hyphens()); + return cssValuePool.createValue(style->hyphens()); case CSSPropertyWebkitHyphenateCharacter: if (style->hyphenationString().isNull()) - return cssValuePool().createIdentifierValue(CSSValueAuto); - return cssValuePool().createValue(style->hyphenationString(), CSSPrimitiveValue::CSS_STRING); + return cssValuePool.createIdentifierValue(CSSValueAuto); + return cssValuePool.createValue(style->hyphenationString(), CSSPrimitiveValue::CSS_STRING); case CSSPropertyWebkitHyphenateLimitAfter: if (style->hyphenationLimitAfter() < 0) return CSSPrimitiveValue::createIdentifier(CSSValueAuto); @@ -2116,158 +3015,171 @@ PassRefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propert return CSSPrimitiveValue::create(style->hyphenationLimitLines(), CSSPrimitiveValue::CSS_NUMBER); case CSSPropertyWebkitBorderFit: if (style->borderFit() == BorderFitBorder) - return cssValuePool().createIdentifierValue(CSSValueBorder); - return cssValuePool().createIdentifierValue(CSSValueLines); + return cssValuePool.createIdentifierValue(CSSValueBorder); + return cssValuePool.createIdentifierValue(CSSValueLines); #if ENABLE(CSS_IMAGE_ORIENTATION) case CSSPropertyImageOrientation: - return cssValuePool().createValue(style->imageOrientation()); + return cssValuePool.createValue(style->imageOrientation()); #endif case CSSPropertyImageRendering: return CSSPrimitiveValue::create(style->imageRendering()); #if ENABLE(CSS_IMAGE_RESOLUTION) case CSSPropertyImageResolution: - return cssValuePool().createValue(style->imageResolution(), CSSPrimitiveValue::CSS_DPPX); + return cssValuePool.createValue(style->imageResolution(), CSSPrimitiveValue::CSS_DPPX); #endif case CSSPropertyLeft: - return getPositionOffsetValue(style.get(), CSSPropertyLeft, m_node->document().renderView()); + return positionOffsetValue(*style, CSSPropertyLeft); case CSSPropertyLetterSpacing: if (!style->letterSpacing()) - return cssValuePool().createIdentifierValue(CSSValueNormal); - return zoomAdjustedPixelValue(style->letterSpacing(), style.get()); + return cssValuePool.createIdentifierValue(CSSValueNormal); + return zoomAdjustedPixelValue(style->letterSpacing(), *style); case CSSPropertyWebkitLineClamp: if (style->lineClamp().isNone()) - return cssValuePool().createIdentifierValue(CSSValueNone); - return cssValuePool().createValue(style->lineClamp().value(), style->lineClamp().isPercentage() ? CSSPrimitiveValue::CSS_PERCENTAGE : CSSPrimitiveValue::CSS_NUMBER); + return cssValuePool.createIdentifierValue(CSSValueNone); + return cssValuePool.createValue(style->lineClamp().value(), style->lineClamp().isPercentage() ? CSSPrimitiveValue::CSS_PERCENTAGE : CSSPrimitiveValue::CSS_NUMBER); case CSSPropertyLineHeight: - return lineHeightFromStyle(style.get(), m_node->document().renderView()); + return lineHeightFromStyle(*style); case CSSPropertyListStyleImage: if (style->listStyleImage()) return style->listStyleImage()->cssValue(); - return cssValuePool().createIdentifierValue(CSSValueNone); + return cssValuePool.createIdentifierValue(CSSValueNone); case CSSPropertyListStylePosition: - return cssValuePool().createValue(style->listStylePosition()); + return cssValuePool.createValue(style->listStylePosition()); case CSSPropertyListStyleType: - return cssValuePool().createValue(style->listStyleType()); + return cssValuePool.createValue(style->listStyleType()); case CSSPropertyWebkitLocale: if (style->locale().isNull()) - return cssValuePool().createIdentifierValue(CSSValueAuto); - return cssValuePool().createValue(style->locale(), CSSPrimitiveValue::CSS_STRING); + return cssValuePool.createIdentifierValue(CSSValueAuto); + return cssValuePool.createValue(style->locale(), CSSPrimitiveValue::CSS_STRING); case CSSPropertyMarginTop: - return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::marginTop, &RenderBoxModelObject::marginTop>(style.get(), renderer); + return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::marginTop, &RenderBoxModelObject::marginTop>(*style, renderer); case CSSPropertyMarginRight: { Length marginRight = style->marginRight(); - if (marginRight.isFixed() || !renderer || !renderer->isBox()) - return zoomAdjustedPixelValueForLength(marginRight, style.get()); + if (marginRight.isFixed() || !is<RenderBox>(renderer)) + return zoomAdjustedPixelValueForLength(marginRight, *style); float value; - if (marginRight.isPercent() || marginRight.isViewportPercentage()) + if (marginRight.isPercentOrCalculated()) { // RenderBox gives a marginRight() that is the distance between the right-edge of the child box // and the right-edge of the containing box, when display == BLOCK. Let's calculate the absolute // value of the specified margin-right % instead of relying on RenderBox's marginRight() value. - value = minimumValueForLength(marginRight, toRenderBox(renderer)->containingBlockLogicalWidthForContent(), m_node->document().renderView()); - else - value = toRenderBox(renderer)->marginRight(); - return zoomAdjustedPixelValue(value, style.get()); + value = minimumValueForLength(marginRight, downcast<RenderBox>(*renderer).containingBlockLogicalWidthForContent()); + } else + value = downcast<RenderBox>(*renderer).marginRight(); + return zoomAdjustedPixelValue(value, *style); } case CSSPropertyMarginBottom: - return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::marginBottom, &RenderBoxModelObject::marginBottom>(style.get(), renderer); + return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::marginBottom, &RenderBoxModelObject::marginBottom>(*style, renderer); case CSSPropertyMarginLeft: - return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::marginLeft, &RenderBoxModelObject::marginLeft>(style.get(), renderer); + return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::marginLeft, &RenderBoxModelObject::marginLeft>(*style, renderer); case CSSPropertyWebkitMarqueeDirection: - return cssValuePool().createValue(style->marqueeDirection()); + return cssValuePool.createValue(style->marqueeDirection()); case CSSPropertyWebkitMarqueeIncrement: - return cssValuePool().createValue(style->marqueeIncrement()); + return cssValuePool.createValue(style->marqueeIncrement()); case CSSPropertyWebkitMarqueeRepetition: if (style->marqueeLoopCount() < 0) - return cssValuePool().createIdentifierValue(CSSValueInfinite); - return cssValuePool().createValue(style->marqueeLoopCount(), CSSPrimitiveValue::CSS_NUMBER); + return cssValuePool.createIdentifierValue(CSSValueInfinite); + return cssValuePool.createValue(style->marqueeLoopCount(), CSSPrimitiveValue::CSS_NUMBER); case CSSPropertyWebkitMarqueeStyle: - return cssValuePool().createValue(style->marqueeBehavior()); + return cssValuePool.createValue(style->marqueeBehavior()); case CSSPropertyWebkitUserModify: - return cssValuePool().createValue(style->userModify()); + return cssValuePool.createValue(style->userModify()); case CSSPropertyMaxHeight: { const Length& maxHeight = style->maxHeight(); if (maxHeight.isUndefined()) - return cssValuePool().createIdentifierValue(CSSValueNone); - return zoomAdjustedPixelValueForLength(maxHeight, style.get()); + return cssValuePool.createIdentifierValue(CSSValueNone); + return zoomAdjustedPixelValueForLength(maxHeight, *style); } case CSSPropertyMaxWidth: { const Length& maxWidth = style->maxWidth(); if (maxWidth.isUndefined()) - return cssValuePool().createIdentifierValue(CSSValueNone); - return zoomAdjustedPixelValueForLength(maxWidth, style.get()); + return cssValuePool.createIdentifierValue(CSSValueNone); + return zoomAdjustedPixelValueForLength(maxWidth, *style); } case CSSPropertyMinHeight: - // FIXME: For flex-items, min-height:auto should compute to min-content. - if (style->minHeight().isAuto()) - return zoomAdjustedPixelValue(0, style.get()); - return zoomAdjustedPixelValueForLength(style->minHeight(), style.get()); + if (style->minHeight().isAuto()) { + if (isFlexOrGrid(styledElement->parentNode())) + return cssValuePool.createIdentifierValue(CSSValueAuto); + return zoomAdjustedPixelValue(0, *style); + } + return zoomAdjustedPixelValueForLength(style->minHeight(), *style); case CSSPropertyMinWidth: - // FIXME: For flex-items, min-width:auto should compute to min-content. - if (style->minWidth().isAuto()) - return zoomAdjustedPixelValue(0, style.get()); - return zoomAdjustedPixelValueForLength(style->minWidth(), style.get()); + if (style->minWidth().isAuto()) { + if (isFlexOrGrid(styledElement->parentNode())) + return cssValuePool.createIdentifierValue(CSSValueAuto); + return zoomAdjustedPixelValue(0, *style); + } + return zoomAdjustedPixelValueForLength(style->minWidth(), *style); case CSSPropertyObjectFit: - return cssValuePool().createValue(style->objectFit()); + return cssValuePool.createValue(style->objectFit()); + case CSSPropertyObjectPosition: { + auto list = CSSValueList::createSpaceSeparated(); + list->append(zoomAdjustedPixelValueForLength(style->objectPosition().x(), *style)); + list->append(zoomAdjustedPixelValueForLength(style->objectPosition().y(), *style)); + return WTFMove(list); + } case CSSPropertyOpacity: - return cssValuePool().createValue(style->opacity(), CSSPrimitiveValue::CSS_NUMBER); + return cssValuePool.createValue(style->opacity(), CSSPrimitiveValue::CSS_NUMBER); case CSSPropertyOrphans: if (style->hasAutoOrphans()) - return cssValuePool().createIdentifierValue(CSSValueAuto); - return cssValuePool().createValue(style->orphans(), CSSPrimitiveValue::CSS_NUMBER); + return cssValuePool.createIdentifierValue(CSSValueAuto); + return cssValuePool.createValue(style->orphans(), CSSPrimitiveValue::CSS_NUMBER); case CSSPropertyOutlineColor: - return m_allowVisitedStyle ? cssValuePool().createColorValue(style->visitedDependentColor(CSSPropertyOutlineColor).rgb()) : currentColorOrValidColor(style.get(), style->outlineColor()); + return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyOutlineColor)) : currentColorOrValidColor(style, style->outlineColor()); case CSSPropertyOutlineOffset: - return zoomAdjustedPixelValue(style->outlineOffset(), style.get()); + return zoomAdjustedPixelValue(style->outlineOffset(), *style); case CSSPropertyOutlineStyle: if (style->outlineStyleIsAuto()) - return cssValuePool().createIdentifierValue(CSSValueAuto); - return cssValuePool().createValue(style->outlineStyle()); + return cssValuePool.createIdentifierValue(CSSValueAuto); + return cssValuePool.createValue(style->outlineStyle()); case CSSPropertyOutlineWidth: - return zoomAdjustedPixelValue(style->outlineWidth(), style.get()); + return zoomAdjustedPixelValue(style->outlineWidth(), *style); case CSSPropertyOverflow: - return cssValuePool().createValue(std::max(style->overflowX(), style->overflowY())); + return cssValuePool.createValue(std::max(style->overflowX(), style->overflowY())); case CSSPropertyOverflowWrap: - return cssValuePool().createValue(style->overflowWrap()); + return cssValuePool.createValue(style->overflowWrap()); case CSSPropertyOverflowX: - return cssValuePool().createValue(style->overflowX()); + return cssValuePool.createValue(style->overflowX()); case CSSPropertyOverflowY: - return cssValuePool().createValue(style->overflowY()); + return cssValuePool.createValue(style->overflowY()); case CSSPropertyPaddingTop: - return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::paddingTop, &RenderBoxModelObject::computedCSSPaddingTop>(style.get(), renderer); + return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::paddingTop, &RenderBoxModelObject::computedCSSPaddingTop>(*style, renderer); case CSSPropertyPaddingRight: - return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::paddingRight, &RenderBoxModelObject::computedCSSPaddingRight>(style.get(), renderer); + return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::paddingRight, &RenderBoxModelObject::computedCSSPaddingRight>(*style, renderer); case CSSPropertyPaddingBottom: - return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::paddingBottom, &RenderBoxModelObject::computedCSSPaddingBottom>(style.get(), renderer); + return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::paddingBottom, &RenderBoxModelObject::computedCSSPaddingBottom>(*style, renderer); case CSSPropertyPaddingLeft: - return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::paddingLeft, &RenderBoxModelObject::computedCSSPaddingLeft>(style.get(), renderer); + return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::paddingLeft, &RenderBoxModelObject::computedCSSPaddingLeft>(*style, renderer); case CSSPropertyPageBreakAfter: - return cssValuePool().createValue(style->pageBreakAfter()); + return cssValuePool.createValue(convertToPageBreak(style->breakAfter())); case CSSPropertyPageBreakBefore: - return cssValuePool().createValue(style->pageBreakBefore()); - case CSSPropertyPageBreakInside: { - EPageBreak pageBreak = style->pageBreakInside(); - ASSERT(pageBreak != PBALWAYS); - if (pageBreak == PBALWAYS) - return 0; - return cssValuePool().createValue(style->pageBreakInside()); - } + return cssValuePool.createValue(convertToPageBreak(style->breakBefore())); + case CSSPropertyPageBreakInside: + return cssValuePool.createValue(convertToPageBreak(style->breakInside())); + case CSSPropertyBreakAfter: + return cssValuePool.createValue(style->breakAfter()); + case CSSPropertyBreakBefore: + return cssValuePool.createValue(style->breakBefore()); + case CSSPropertyBreakInside: + return cssValuePool.createValue(style->breakInside()); + case CSSPropertyHangingPunctuation: + return hangingPunctuationToCSSValue(style->hangingPunctuation()); case CSSPropertyPosition: - return cssValuePool().createValue(style->position()); + return cssValuePool.createValue(style->position()); case CSSPropertyRight: - return getPositionOffsetValue(style.get(), CSSPropertyRight, m_node->document().renderView()); + return positionOffsetValue(*style, CSSPropertyRight); case CSSPropertyWebkitRubyPosition: - return cssValuePool().createValue(style->rubyPosition()); + return cssValuePool.createValue(style->rubyPosition()); case CSSPropertyTableLayout: - return cssValuePool().createValue(style->tableLayout()); + return cssValuePool.createValue(style->tableLayout()); case CSSPropertyTextAlign: - return cssValuePool().createValue(style->textAlign()); + return cssValuePool.createValue(style->textAlign()); case CSSPropertyTextDecoration: return renderTextDecorationFlagsToCSSValue(style->textDecoration()); #if ENABLE(CSS3_TEXT) case CSSPropertyWebkitTextAlignLast: - return cssValuePool().createValue(style->textAlignLast()); + return cssValuePool.createValue(style->textAlignLast()); case CSSPropertyWebkitTextJustify: - return cssValuePool().createValue(style->textJustify()); + return cssValuePool.createValue(style->textJustify()); #endif // CSS3_TEXT case CSSPropertyWebkitTextDecoration: return getCSSPropertyValuesForShorthandProperties(webkitTextDecorationShorthand()); @@ -2276,25 +3188,25 @@ PassRefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propert case CSSPropertyWebkitTextDecorationStyle: return renderTextDecorationStyleFlagsToCSSValue(style->textDecorationStyle()); case CSSPropertyWebkitTextDecorationColor: - return currentColorOrValidColor(style.get(), style->textDecorationColor()); + return currentColorOrValidColor(style, style->textDecorationColor()); case CSSPropertyWebkitTextDecorationSkip: return renderTextDecorationSkipFlagsToCSSValue(style->textDecorationSkip()); case CSSPropertyWebkitTextUnderlinePosition: - return cssValuePool().createValue(style->textUnderlinePosition()); + return cssValuePool.createValue(style->textUnderlinePosition()); case CSSPropertyWebkitTextDecorationsInEffect: return renderTextDecorationFlagsToCSSValue(style->textDecorationsInEffect()); case CSSPropertyWebkitTextFillColor: - return currentColorOrValidColor(style.get(), style->textFillColor()); + return currentColorOrValidColor(style, style->textFillColor()); case CSSPropertyWebkitTextEmphasisColor: - return currentColorOrValidColor(style.get(), style->textEmphasisColor()); + return currentColorOrValidColor(style, style->textEmphasisColor()); case CSSPropertyWebkitTextEmphasisPosition: return renderEmphasisPositionFlagsToCSSValue(style->textEmphasisPosition()); case CSSPropertyWebkitTextEmphasisStyle: switch (style->textEmphasisMark()) { case TextEmphasisMarkNone: - return cssValuePool().createIdentifierValue(CSSValueNone); + return cssValuePool.createIdentifierValue(CSSValueNone); case TextEmphasisMarkCustom: - return cssValuePool().createValue(style->textEmphasisCustomMark(), CSSPrimitiveValue::CSS_STRING); + return cssValuePool.createValue(style->textEmphasisCustomMark(), CSSPrimitiveValue::CSS_STRING); case TextEmphasisMarkAuto: ASSERT_NOT_REACHED(); #if ASSERT_DISABLED @@ -2304,269 +3216,283 @@ PassRefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propert case TextEmphasisMarkCircle: case TextEmphasisMarkDoubleCircle: case TextEmphasisMarkTriangle: - case TextEmphasisMarkSesame: { - RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); - list->append(cssValuePool().createValue(style->textEmphasisFill())); - list->append(cssValuePool().createValue(style->textEmphasisMark())); - return list.release(); - } + case TextEmphasisMarkSesame: + auto list = CSSValueList::createSpaceSeparated(); + list->append(cssValuePool.createValue(style->textEmphasisFill())); + list->append(cssValuePool.createValue(style->textEmphasisMark())); + return WTFMove(list); } case CSSPropertyTextIndent: { // If CSS3_TEXT is disabled or text-indent has only one value(<length> | <percentage>), // getPropertyCSSValue() returns CSSValue. - RefPtr<CSSValue> textIndent = zoomAdjustedPixelValueForLength(style->textIndent(), style.get()); + auto textIndent = zoomAdjustedPixelValueForLength(style->textIndent(), *style); #if ENABLE(CSS3_TEXT) // If CSS3_TEXT is enabled and text-indent has -webkit-each-line or -webkit-hanging, // getPropertyCSSValue() returns CSSValueList. if (style->textIndentLine() == TextIndentEachLine || style->textIndentType() == TextIndentHanging) { - RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); - list->append(textIndent.release()); + auto list = CSSValueList::createSpaceSeparated(); + list->append(WTFMove(textIndent)); if (style->textIndentLine() == TextIndentEachLine) - list->append(cssValuePool().createIdentifierValue(CSSValueWebkitEachLine)); + list->append(cssValuePool.createIdentifierValue(CSSValueWebkitEachLine)); if (style->textIndentType() == TextIndentHanging) - list->append(cssValuePool().createIdentifierValue(CSSValueWebkitHanging)); - return list.release(); + list->append(cssValuePool.createIdentifierValue(CSSValueWebkitHanging)); + return WTFMove(list); } #endif - return textIndent.release(); + return WTFMove(textIndent); } case CSSPropertyTextShadow: - return valueForShadow(style->textShadow(), propertyID, style.get()); + return valueForShadow(style->textShadow(), propertyID, *style); case CSSPropertyTextRendering: - return cssValuePool().createValue(style->fontDescription().textRenderingMode()); + return cssValuePool.createValue(style->fontDescription().textRenderingMode()); case CSSPropertyTextOverflow: if (style->textOverflow()) - return cssValuePool().createIdentifierValue(CSSValueEllipsis); - return cssValuePool().createIdentifierValue(CSSValueClip); + return cssValuePool.createIdentifierValue(CSSValueEllipsis); + return cssValuePool.createIdentifierValue(CSSValueClip); case CSSPropertyWebkitTextSecurity: - return cssValuePool().createValue(style->textSecurity()); -#if ENABLE(IOS_TEXT_AUTOSIZING) + return cssValuePool.createValue(style->textSecurity()); +#if ENABLE(TEXT_AUTOSIZING) case CSSPropertyWebkitTextSizeAdjust: if (style->textSizeAdjust().isAuto()) - return cssValuePool().createIdentifierValue(CSSValueAuto); + return cssValuePool.createIdentifierValue(CSSValueAuto); if (style->textSizeAdjust().isNone()) - return cssValuePool().createIdentifierValue(CSSValueNone); + return cssValuePool.createIdentifierValue(CSSValueNone); return CSSPrimitiveValue::create(style->textSizeAdjust().percentage(), CSSPrimitiveValue::CSS_PERCENTAGE); #endif case CSSPropertyWebkitTextStrokeColor: - return currentColorOrValidColor(style.get(), style->textStrokeColor()); + return currentColorOrValidColor(style, style->textStrokeColor()); case CSSPropertyWebkitTextStrokeWidth: - return zoomAdjustedPixelValue(style->textStrokeWidth(), style.get()); + return zoomAdjustedPixelValue(style->textStrokeWidth(), *style); case CSSPropertyTextTransform: - return cssValuePool().createValue(style->textTransform()); + return cssValuePool.createValue(style->textTransform()); case CSSPropertyTop: - return getPositionOffsetValue(style.get(), CSSPropertyTop, m_node->document().renderView()); + return positionOffsetValue(*style, CSSPropertyTop); case CSSPropertyUnicodeBidi: - return cssValuePool().createValue(style->unicodeBidi()); + return cssValuePool.createValue(style->unicodeBidi()); case CSSPropertyVerticalAlign: switch (style->verticalAlign()) { case BASELINE: - return cssValuePool().createIdentifierValue(CSSValueBaseline); + return cssValuePool.createIdentifierValue(CSSValueBaseline); case MIDDLE: - return cssValuePool().createIdentifierValue(CSSValueMiddle); + return cssValuePool.createIdentifierValue(CSSValueMiddle); case SUB: - return cssValuePool().createIdentifierValue(CSSValueSub); + return cssValuePool.createIdentifierValue(CSSValueSub); case SUPER: - return cssValuePool().createIdentifierValue(CSSValueSuper); + return cssValuePool.createIdentifierValue(CSSValueSuper); case TEXT_TOP: - return cssValuePool().createIdentifierValue(CSSValueTextTop); + return cssValuePool.createIdentifierValue(CSSValueTextTop); case TEXT_BOTTOM: - return cssValuePool().createIdentifierValue(CSSValueTextBottom); + return cssValuePool.createIdentifierValue(CSSValueTextBottom); case TOP: - return cssValuePool().createIdentifierValue(CSSValueTop); + return cssValuePool.createIdentifierValue(CSSValueTop); case BOTTOM: - return cssValuePool().createIdentifierValue(CSSValueBottom); + return cssValuePool.createIdentifierValue(CSSValueBottom); case BASELINE_MIDDLE: - return cssValuePool().createIdentifierValue(CSSValueWebkitBaselineMiddle); + return cssValuePool.createIdentifierValue(CSSValueWebkitBaselineMiddle); case LENGTH: - return cssValuePool().createValue(style->verticalAlignLength()); + return cssValuePool.createValue(style->verticalAlignLength()); } ASSERT_NOT_REACHED(); - return 0; + return nullptr; case CSSPropertyVisibility: - return cssValuePool().createValue(style->visibility()); + return cssValuePool.createValue(style->visibility()); case CSSPropertyWhiteSpace: - return cssValuePool().createValue(style->whiteSpace()); + return cssValuePool.createValue(style->whiteSpace()); case CSSPropertyWidows: if (style->hasAutoWidows()) - return cssValuePool().createIdentifierValue(CSSValueAuto); - return cssValuePool().createValue(style->widows(), CSSPrimitiveValue::CSS_NUMBER); + return cssValuePool.createIdentifierValue(CSSValueAuto); + return cssValuePool.createValue(style->widows(), CSSPrimitiveValue::CSS_NUMBER); case CSSPropertyWidth: - if (renderer) { + if (renderer && !renderer->isRenderSVGModelObject()) { // According to http://www.w3.org/TR/CSS2/visudet.html#the-width-property, // the "width" property does not apply for non-replaced inline elements. if (!renderer->isReplaced() && renderer->isInline()) - return cssValuePool().createIdentifierValue(CSSValueAuto); - return zoomAdjustedPixelValue(sizingBox(renderer).width(), style.get()); + return cssValuePool.createIdentifierValue(CSSValueAuto); + return zoomAdjustedPixelValue(sizingBox(*renderer).width(), *style); } - return zoomAdjustedPixelValueForLength(style->width(), style.get()); + return zoomAdjustedPixelValueForLength(style->width(), *style); + case CSSPropertyWillChange: + return willChangePropertyValue(style->willChange()); case CSSPropertyWordBreak: - return cssValuePool().createValue(style->wordBreak()); + return cssValuePool.createValue(style->wordBreak()); case CSSPropertyWordSpacing: - return zoomAdjustedPixelValue(style->font().wordSpacing(), style.get()); + return zoomAdjustedPixelValue(style->fontCascade().wordSpacing(), *style); case CSSPropertyWordWrap: - return cssValuePool().createValue(style->overflowWrap()); + return cssValuePool.createValue(style->overflowWrap()); case CSSPropertyWebkitLineBreak: - return cssValuePool().createValue(style->lineBreak()); + return cssValuePool.createValue(style->lineBreak()); case CSSPropertyWebkitNbspMode: - return cssValuePool().createValue(style->nbspMode()); + return cssValuePool.createValue(style->nbspMode()); case CSSPropertyResize: - return cssValuePool().createValue(style->resize()); + return cssValuePool.createValue(style->resize()); case CSSPropertyWebkitFontKerning: - return cssValuePool().createValue(style->fontDescription().kerning()); + return cssValuePool.createValue(style->fontDescription().kerning()); case CSSPropertyWebkitFontSmoothing: - return cssValuePool().createValue(style->fontDescription().fontSmoothing()); - case CSSPropertyWebkitFontVariantLigatures: { - FontDescription::LigaturesState commonLigaturesState = style->fontDescription().commonLigaturesState(); - FontDescription::LigaturesState discretionaryLigaturesState = style->fontDescription().discretionaryLigaturesState(); - FontDescription::LigaturesState historicalLigaturesState = style->fontDescription().historicalLigaturesState(); - if (commonLigaturesState == FontDescription::NormalLigaturesState && discretionaryLigaturesState == FontDescription::NormalLigaturesState - && historicalLigaturesState == FontDescription::NormalLigaturesState) - return cssValuePool().createIdentifierValue(CSSValueNormal); - - RefPtr<CSSValueList> valueList = CSSValueList::createSpaceSeparated(); - if (commonLigaturesState != FontDescription::NormalLigaturesState) - valueList->append(cssValuePool().createIdentifierValue(commonLigaturesState == FontDescription::DisabledLigaturesState ? CSSValueNoCommonLigatures : CSSValueCommonLigatures)); - if (discretionaryLigaturesState != FontDescription::NormalLigaturesState) - valueList->append(cssValuePool().createIdentifierValue(discretionaryLigaturesState == FontDescription::DisabledLigaturesState ? CSSValueNoDiscretionaryLigatures : CSSValueDiscretionaryLigatures)); - if (historicalLigaturesState != FontDescription::NormalLigaturesState) - valueList->append(cssValuePool().createIdentifierValue(historicalLigaturesState == FontDescription::DisabledLigaturesState ? CSSValueNoHistoricalLigatures : CSSValueHistoricalLigatures)); - return valueList; - } + return cssValuePool.createValue(style->fontDescription().fontSmoothing()); + case CSSPropertyFontVariantLigatures: + return fontVariantLigaturesPropertyValue(style->fontDescription().variantCommonLigatures(), style->fontDescription().variantDiscretionaryLigatures(), style->fontDescription().variantHistoricalLigatures(), style->fontDescription().variantContextualAlternates()); + case CSSPropertyFontVariantPosition: + return fontVariantPositionPropertyValue(style->fontDescription().variantPosition()); + case CSSPropertyFontVariantCaps: + return fontVariantCapsPropertyValue(style->fontDescription().variantCaps()); + case CSSPropertyFontVariantNumeric: + return fontVariantNumericPropertyValue(style->fontDescription().variantNumericFigure(), style->fontDescription().variantNumericSpacing(), style->fontDescription().variantNumericFraction(), style->fontDescription().variantNumericOrdinal(), style->fontDescription().variantNumericSlashedZero()); + case CSSPropertyFontVariantAlternates: + return fontVariantAlternatesPropertyValue(style->fontDescription().variantAlternates()); + case CSSPropertyFontVariantEastAsian: + return fontVariantEastAsianPropertyValue(style->fontDescription().variantEastAsianVariant(), style->fontDescription().variantEastAsianWidth(), style->fontDescription().variantEastAsianRuby()); case CSSPropertyZIndex: if (style->hasAutoZIndex()) - return cssValuePool().createIdentifierValue(CSSValueAuto); - return cssValuePool().createValue(style->zIndex(), CSSPrimitiveValue::CSS_NUMBER); + return cssValuePool.createIdentifierValue(CSSValueAuto); + return cssValuePool.createValue(style->zIndex(), CSSPrimitiveValue::CSS_NUMBER); case CSSPropertyZoom: - return cssValuePool().createValue(style->zoom(), CSSPrimitiveValue::CSS_NUMBER); + return cssValuePool.createValue(style->zoom(), CSSPrimitiveValue::CSS_NUMBER); case CSSPropertyBoxSizing: if (style->boxSizing() == CONTENT_BOX) - return cssValuePool().createIdentifierValue(CSSValueContentBox); - return cssValuePool().createIdentifierValue(CSSValueBorderBox); + return cssValuePool.createIdentifierValue(CSSValueContentBox); + return cssValuePool.createIdentifierValue(CSSValueBorderBox); #if ENABLE(DASHBOARD_SUPPORT) case CSSPropertyWebkitDashboardRegion: { const Vector<StyleDashboardRegion>& regions = style->dashboardRegions(); unsigned count = regions.size(); if (count == 1 && regions[0].type == StyleDashboardRegion::None) - return cssValuePool().createIdentifierValue(CSSValueNone); + return cssValuePool.createIdentifierValue(CSSValueNone); RefPtr<DashboardRegion> firstRegion; - DashboardRegion* previousRegion = 0; + DashboardRegion* previousRegion = nullptr; for (unsigned i = 0; i < count; i++) { - RefPtr<DashboardRegion> region = DashboardRegion::create(); + auto region = DashboardRegion::create(); StyleDashboardRegion styleRegion = regions[i]; region->m_label = styleRegion.label; LengthBox offset = styleRegion.offset; - region->setTop(zoomAdjustedPixelValue(offset.top().value(), style.get())); - region->setRight(zoomAdjustedPixelValue(offset.right().value(), style.get())); - region->setBottom(zoomAdjustedPixelValue(offset.bottom().value(), style.get())); - region->setLeft(zoomAdjustedPixelValue(offset.left().value(), style.get())); + region->setTop(zoomAdjustedPixelValue(offset.top().value(), *style)); + region->setRight(zoomAdjustedPixelValue(offset.right().value(), *style)); + region->setBottom(zoomAdjustedPixelValue(offset.bottom().value(), *style)); + region->setLeft(zoomAdjustedPixelValue(offset.left().value(), *style)); region->m_isRectangle = (styleRegion.type == StyleDashboardRegion::Rectangle); region->m_isCircle = (styleRegion.type == StyleDashboardRegion::Circle); if (previousRegion) - previousRegion->m_next = region; + previousRegion->m_next = region.copyRef(); else - firstRegion = region; - previousRegion = region.get(); + firstRegion = region.copyRef(); + previousRegion = region.ptr(); } - return cssValuePool().createValue(firstRegion.release()); + return cssValuePool.createValue(WTFMove(firstRegion)); } #endif - case CSSPropertyWebkitAnimationDelay: - return getDelayValue(style->animations()); - case CSSPropertyWebkitAnimationDirection: { - RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); + case CSSPropertyAnimationDelay: + return delayValue(style->animations()); + case CSSPropertyAnimationDirection: { + auto list = CSSValueList::createCommaSeparated(); const AnimationList* t = style->animations(); if (t) { for (size_t i = 0; i < t->size(); ++i) { - if (t->animation(i).direction()) - list->append(cssValuePool().createIdentifierValue(CSSValueAlternate)); - else - list->append(cssValuePool().createIdentifierValue(CSSValueNormal)); + switch (t->animation(i).direction()) { + case Animation::AnimationDirectionNormal: + list->append(cssValuePool.createIdentifierValue(CSSValueNormal)); + break; + case Animation::AnimationDirectionAlternate: + list->append(cssValuePool.createIdentifierValue(CSSValueAlternate)); + break; + case Animation::AnimationDirectionReverse: + list->append(cssValuePool.createIdentifierValue(CSSValueReverse)); + break; + case Animation::AnimationDirectionAlternateReverse: + list->append(cssValuePool.createIdentifierValue(CSSValueAlternateReverse)); + break; + } } } else - list->append(cssValuePool().createIdentifierValue(CSSValueNormal)); - return list.release(); + list->append(cssValuePool.createIdentifierValue(CSSValueNormal)); + return WTFMove(list); } - case CSSPropertyWebkitAnimationDuration: - return getDurationValue(style->animations()); - case CSSPropertyWebkitAnimationFillMode: { - RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); + case CSSPropertyAnimationDuration: + return durationValue(style->animations()); + case CSSPropertyAnimationFillMode: { + auto list = CSSValueList::createCommaSeparated(); const AnimationList* t = style->animations(); if (t) { for (size_t i = 0; i < t->size(); ++i) { switch (t->animation(i).fillMode()) { case AnimationFillModeNone: - list->append(cssValuePool().createIdentifierValue(CSSValueNone)); + list->append(cssValuePool.createIdentifierValue(CSSValueNone)); break; case AnimationFillModeForwards: - list->append(cssValuePool().createIdentifierValue(CSSValueForwards)); + list->append(cssValuePool.createIdentifierValue(CSSValueForwards)); break; case AnimationFillModeBackwards: - list->append(cssValuePool().createIdentifierValue(CSSValueBackwards)); + list->append(cssValuePool.createIdentifierValue(CSSValueBackwards)); break; case AnimationFillModeBoth: - list->append(cssValuePool().createIdentifierValue(CSSValueBoth)); + list->append(cssValuePool.createIdentifierValue(CSSValueBoth)); break; } } } else - list->append(cssValuePool().createIdentifierValue(CSSValueNone)); - return list.release(); + list->append(cssValuePool.createIdentifierValue(CSSValueNone)); + return WTFMove(list); } - case CSSPropertyWebkitAnimationIterationCount: { - RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); + case CSSPropertyAnimationIterationCount: { + auto list = CSSValueList::createCommaSeparated(); const AnimationList* t = style->animations(); if (t) { for (size_t i = 0; i < t->size(); ++i) { double iterationCount = t->animation(i).iterationCount(); if (iterationCount == Animation::IterationCountInfinite) - list->append(cssValuePool().createIdentifierValue(CSSValueInfinite)); + list->append(cssValuePool.createIdentifierValue(CSSValueInfinite)); else - list->append(cssValuePool().createValue(iterationCount, CSSPrimitiveValue::CSS_NUMBER)); + list->append(cssValuePool.createValue(iterationCount, CSSPrimitiveValue::CSS_NUMBER)); } } else - list->append(cssValuePool().createValue(Animation::initialAnimationIterationCount(), CSSPrimitiveValue::CSS_NUMBER)); - return list.release(); + list->append(cssValuePool.createValue(Animation::initialIterationCount(), CSSPrimitiveValue::CSS_NUMBER)); + return WTFMove(list); } - case CSSPropertyWebkitAnimationName: { - RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); + case CSSPropertyAnimationName: { + auto list = CSSValueList::createCommaSeparated(); const AnimationList* t = style->animations(); if (t) { for (size_t i = 0; i < t->size(); ++i) - list->append(cssValuePool().createValue(t->animation(i).name(), CSSPrimitiveValue::CSS_STRING)); + list->append(cssValuePool.createValue(t->animation(i).name(), CSSPrimitiveValue::CSS_STRING)); } else - list->append(cssValuePool().createIdentifierValue(CSSValueNone)); - return list.release(); + list->append(cssValuePool.createIdentifierValue(CSSValueNone)); + return WTFMove(list); } - case CSSPropertyWebkitAnimationPlayState: { - RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); + case CSSPropertyAnimationPlayState: { + auto list = CSSValueList::createCommaSeparated(); const AnimationList* t = style->animations(); if (t) { for (size_t i = 0; i < t->size(); ++i) { int prop = t->animation(i).playState(); if (prop == AnimPlayStatePlaying) - list->append(cssValuePool().createIdentifierValue(CSSValueRunning)); + list->append(cssValuePool.createIdentifierValue(CSSValueRunning)); else - list->append(cssValuePool().createIdentifierValue(CSSValuePaused)); + list->append(cssValuePool.createIdentifierValue(CSSValuePaused)); } } else - list->append(cssValuePool().createIdentifierValue(CSSValueRunning)); - return list.release(); + list->append(cssValuePool.createIdentifierValue(CSSValueRunning)); + return WTFMove(list); } - case CSSPropertyWebkitAnimationTimingFunction: - return getTimingFunctionValue(style->animations()); + case CSSPropertyAnimationTimingFunction: + return timingFunctionValue(style->animations()); +#if ENABLE(CSS_ANIMATIONS_LEVEL_2) + case CSSPropertyWebkitAnimationTrigger: + return animationTriggerValue(style->animations(), *style); +#endif case CSSPropertyWebkitAppearance: - return cssValuePool().createValue(style->appearance()); + return cssValuePool.createValue(style->appearance()); case CSSPropertyWebkitAspectRatio: - if (!style->hasAspectRatio()) - return cssValuePool().createIdentifierValue(CSSValueNone); + if (style->aspectRatioType() == AspectRatioAuto) + return cssValuePool.createIdentifierValue(CSSValueAuto); + if (style->aspectRatioType() == AspectRatioFromDimensions) + return cssValuePool.createIdentifierValue(CSSValueFromDimensions); + if (style->aspectRatioType() == AspectRatioFromIntrinsic) + return cssValuePool.createIdentifierValue(CSSValueFromIntrinsic); return CSSAspectRatioValue::create(style->aspectRatioNumerator(), style->aspectRatioDenominator()); case CSSPropertyWebkitBackfaceVisibility: - return cssValuePool().createIdentifierValue((style->backfaceVisibility() == BackfaceVisibilityHidden) ? CSSValueHidden : CSSValueVisible); + return cssValuePool.createIdentifierValue((style->backfaceVisibility() == BackfaceVisibilityHidden) ? CSSValueHidden : CSSValueVisible); case CSSPropertyWebkitBorderImage: return valueForNinePieceImage(style->borderImage()); case CSSPropertyBorderImageOutset: @@ -2590,256 +3516,231 @@ PassRefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propert case CSSPropertyWebkitMaskBoxImageSource: if (style->maskBoxImageSource()) return style->maskBoxImageSource()->cssValue(); - return cssValuePool().createIdentifierValue(CSSValueNone); + return cssValuePool.createIdentifierValue(CSSValueNone); case CSSPropertyWebkitFontSizeDelta: // Not a real style property -- used by the editing engine -- so has no computed value. break; + case CSSPropertyWebkitInitialLetter: { + auto drop = !style->initialLetterDrop() ? cssValuePool.createIdentifierValue(CSSValueNormal) : cssValuePool.createValue(style->initialLetterDrop(), CSSPrimitiveValue::CSS_NUMBER); + auto size = !style->initialLetterHeight() ? cssValuePool.createIdentifierValue(CSSValueNormal) : cssValuePool.createValue(style->initialLetterHeight(), CSSPrimitiveValue::CSS_NUMBER); + return cssValuePool.createValue(Pair::create(WTFMove(drop), WTFMove(size))); + } case CSSPropertyWebkitMarginBottomCollapse: case CSSPropertyWebkitMarginAfterCollapse: - return cssValuePool().createValue(style->marginAfterCollapse()); + return cssValuePool.createValue(style->marginAfterCollapse()); case CSSPropertyWebkitMarginTopCollapse: case CSSPropertyWebkitMarginBeforeCollapse: - return cssValuePool().createValue(style->marginBeforeCollapse()); + return cssValuePool.createValue(style->marginBeforeCollapse()); #if ENABLE(ACCELERATED_OVERFLOW_SCROLLING) case CSSPropertyWebkitOverflowScrolling: if (!style->useTouchOverflowScrolling()) - return cssValuePool().createIdentifierValue(CSSValueAuto); - return cssValuePool().createIdentifierValue(CSSValueTouch); + return cssValuePool.createIdentifierValue(CSSValueAuto); + return cssValuePool.createIdentifierValue(CSSValueTouch); #endif - case CSSPropertyWebkitPerspective: + case CSSPropertyPerspective: if (!style->hasPerspective()) - return cssValuePool().createIdentifierValue(CSSValueNone); - return zoomAdjustedPixelValue(style->perspective(), style.get()); - case CSSPropertyWebkitPerspectiveOrigin: { - RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); + return cssValuePool.createIdentifierValue(CSSValueNone); + return zoomAdjustedPixelValue(style->perspective(), *style); + case CSSPropertyPerspectiveOrigin: { + auto list = CSSValueList::createSpaceSeparated(); if (renderer) { LayoutRect box; - if (renderer->isBox()) - box = toRenderBox(renderer)->borderBoxRect(); + if (is<RenderBox>(*renderer)) + box = downcast<RenderBox>(*renderer).borderBoxRect(); - RenderView* renderView = m_node->document().renderView(); - list->append(zoomAdjustedPixelValue(minimumValueForLength(style->perspectiveOriginX(), box.width(), renderView), style.get())); - list->append(zoomAdjustedPixelValue(minimumValueForLength(style->perspectiveOriginY(), box.height(), renderView), style.get())); + list->append(zoomAdjustedPixelValue(minimumValueForLength(style->perspectiveOriginX(), box.width()), *style)); + list->append(zoomAdjustedPixelValue(minimumValueForLength(style->perspectiveOriginY(), box.height()), *style)); } else { - list->append(zoomAdjustedPixelValueForLength(style->perspectiveOriginX(), style.get())); - list->append(zoomAdjustedPixelValueForLength(style->perspectiveOriginY(), style.get())); + list->append(zoomAdjustedPixelValueForLength(style->perspectiveOriginX(), *style)); + list->append(zoomAdjustedPixelValueForLength(style->perspectiveOriginY(), *style)); } - return list.release(); + return WTFMove(list); } case CSSPropertyWebkitRtlOrdering: - return cssValuePool().createIdentifierValue(style->rtlOrdering() ? CSSValueVisual : CSSValueLogical); -#if PLATFORM(IOS) - // FIXME: This property shouldn't be iOS-specific. Once we fix up its usage in InlineTextBox::paintCompositionBackground() - // we should remove the PLATFORM(IOS)-guard. See <https://bugs.webkit.org/show_bug.cgi?id=126296>. - case CSSPropertyWebkitCompositionFillColor: - return currentColorOrValidColor(style.get(), style->compositionFillColor()); -#endif + return cssValuePool.createIdentifierValue(style->rtlOrdering() ? CSSValueVisual : CSSValueLogical); #if ENABLE(TOUCH_EVENTS) case CSSPropertyWebkitTapHighlightColor: - return currentColorOrValidColor(style.get(), style->tapHighlightColor()); + return currentColorOrValidColor(style, style->tapHighlightColor()); + case CSSPropertyTouchAction: + return cssValuePool.createValue(style->touchAction()); #endif #if PLATFORM(IOS) case CSSPropertyWebkitTouchCallout: - return cssValuePool().createIdentifierValue(style->touchCalloutEnabled() ? CSSValueDefault : CSSValueNone); + return cssValuePool.createIdentifierValue(style->touchCalloutEnabled() ? CSSValueDefault : CSSValueNone); #endif case CSSPropertyWebkitUserDrag: - return cssValuePool().createValue(style->userDrag()); + return cssValuePool.createValue(style->userDrag()); case CSSPropertyWebkitUserSelect: - return cssValuePool().createValue(style->userSelect()); + return cssValuePool.createValue(style->userSelect()); case CSSPropertyBorderBottomLeftRadius: - return getBorderRadiusCornerValue(style->borderBottomLeftRadius(), style.get(), m_node->document().renderView()); + return borderRadiusCornerValue(style->borderBottomLeftRadius(), *style); case CSSPropertyBorderBottomRightRadius: - return getBorderRadiusCornerValue(style->borderBottomRightRadius(), style.get(), m_node->document().renderView()); + return borderRadiusCornerValue(style->borderBottomRightRadius(), *style); case CSSPropertyBorderTopLeftRadius: - return getBorderRadiusCornerValue(style->borderTopLeftRadius(), style.get(), m_node->document().renderView()); + return borderRadiusCornerValue(style->borderTopLeftRadius(), *style); case CSSPropertyBorderTopRightRadius: - return getBorderRadiusCornerValue(style->borderTopRightRadius(), style.get(), m_node->document().renderView()); + return borderRadiusCornerValue(style->borderTopRightRadius(), *style); case CSSPropertyClip: { if (!style->hasClip()) - return cssValuePool().createIdentifierValue(CSSValueAuto); - RefPtr<Rect> rect = Rect::create(); - rect->setTop(zoomAdjustedPixelValue(style->clip().top().value(), style.get())); - rect->setRight(zoomAdjustedPixelValue(style->clip().right().value(), style.get())); - rect->setBottom(zoomAdjustedPixelValue(style->clip().bottom().value(), style.get())); - rect->setLeft(zoomAdjustedPixelValue(style->clip().left().value(), style.get())); - return cssValuePool().createValue(rect.release()); + return cssValuePool.createIdentifierValue(CSSValueAuto); + auto rect = Rect::create(); + rect->setTop(autoOrZoomAdjustedValue(style->clip().top(), *style)); + rect->setRight(autoOrZoomAdjustedValue(style->clip().right(), *style)); + rect->setBottom(autoOrZoomAdjustedValue(style->clip().bottom(), *style)); + rect->setLeft(autoOrZoomAdjustedValue(style->clip().left(), *style)); + return cssValuePool.createValue(WTFMove(rect)); } case CSSPropertySpeak: - return cssValuePool().createValue(style->speak()); - case CSSPropertyWebkitTransform: - return computedTransform(renderer, style.get()); - case CSSPropertyWebkitTransformOrigin: { - RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); + return cssValuePool.createValue(style->speak()); + case CSSPropertyTransform: + return computedTransform(renderer, *style); + case CSSPropertyTransformOrigin: { + auto list = CSSValueList::createSpaceSeparated(); if (renderer) { LayoutRect box; - if (renderer->isBox()) - box = toRenderBox(renderer)->borderBoxRect(); + if (is<RenderBox>(*renderer)) + box = downcast<RenderBox>(*renderer).borderBoxRect(); - RenderView* renderView = m_node->document().renderView(); - list->append(zoomAdjustedPixelValue(minimumValueForLength(style->transformOriginX(), box.width(), renderView), style.get())); - list->append(zoomAdjustedPixelValue(minimumValueForLength(style->transformOriginY(), box.height(), renderView), style.get())); + list->append(zoomAdjustedPixelValue(minimumValueForLength(style->transformOriginX(), box.width()), *style)); + list->append(zoomAdjustedPixelValue(minimumValueForLength(style->transformOriginY(), box.height()), *style)); if (style->transformOriginZ() != 0) - list->append(zoomAdjustedPixelValue(style->transformOriginZ(), style.get())); + list->append(zoomAdjustedPixelValue(style->transformOriginZ(), *style)); } else { - list->append(zoomAdjustedPixelValueForLength(style->transformOriginX(), style.get())); - list->append(zoomAdjustedPixelValueForLength(style->transformOriginY(), style.get())); + list->append(zoomAdjustedPixelValueForLength(style->transformOriginX(), *style)); + list->append(zoomAdjustedPixelValueForLength(style->transformOriginY(), *style)); if (style->transformOriginZ() != 0) - list->append(zoomAdjustedPixelValue(style->transformOriginZ(), style.get())); + list->append(zoomAdjustedPixelValue(style->transformOriginZ(), *style)); } - return list.release(); + return WTFMove(list); } + case CSSPropertyTransformStyle: case CSSPropertyWebkitTransformStyle: - return cssValuePool().createIdentifierValue((style->transformStyle3D() == TransformStyle3DPreserve3D) ? CSSValuePreserve3d : CSSValueFlat); + return cssValuePool.createIdentifierValue((style->transformStyle3D() == TransformStyle3DPreserve3D) ? CSSValuePreserve3d : CSSValueFlat); case CSSPropertyTransitionDelay: - case CSSPropertyWebkitTransitionDelay: - return getDelayValue(style->transitions()); + return delayValue(style->transitions()); case CSSPropertyTransitionDuration: - case CSSPropertyWebkitTransitionDuration: - return getDurationValue(style->transitions()); + return durationValue(style->transitions()); case CSSPropertyTransitionProperty: - case CSSPropertyWebkitTransitionProperty: - return getTransitionPropertyValue(style->transitions()); + return transitionPropertyValue(style->transitions()); case CSSPropertyTransitionTimingFunction: - case CSSPropertyWebkitTransitionTimingFunction: - return getTimingFunctionValue(style->transitions()); - case CSSPropertyTransition: - case CSSPropertyWebkitTransition: { - const AnimationList* animList = style->transitions(); - if (animList) { - RefPtr<CSSValueList> transitionsList = CSSValueList::createCommaSeparated(); - for (size_t i = 0; i < animList->size(); ++i) { - RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); - const Animation& animation = animList->animation(i); + return timingFunctionValue(style->transitions()); + case CSSPropertyTransition: { + if (auto* animationList = style->transitions()) { + auto transitionsList = CSSValueList::createCommaSeparated(); + for (size_t i = 0; i < animationList->size(); ++i) { + auto list = CSSValueList::createSpaceSeparated(); + auto& animation = animationList->animation(i); list->append(createTransitionPropertyValue(animation)); - list->append(cssValuePool().createValue(animation.duration(), CSSPrimitiveValue::CSS_S)); - list->append(createTimingFunctionValue(animation.timingFunction().get())); - list->append(cssValuePool().createValue(animation.delay(), CSSPrimitiveValue::CSS_S)); - transitionsList->append(list); + list->append(cssValuePool.createValue(animation.duration(), CSSPrimitiveValue::CSS_S)); + list->append(createTimingFunctionValue(*animation.timingFunction())); + list->append(cssValuePool.createValue(animation.delay(), CSSPrimitiveValue::CSS_S)); + transitionsList->append(WTFMove(list)); } - return transitionsList.release(); + return WTFMove(transitionsList); } - RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); + auto list = CSSValueList::createSpaceSeparated(); // transition-property default value. - list->append(cssValuePool().createIdentifierValue(CSSValueAll)); - list->append(cssValuePool().createValue(Animation::initialAnimationDuration(), CSSPrimitiveValue::CSS_S)); - list->append(createTimingFunctionValue(Animation::initialAnimationTimingFunction().get())); - list->append(cssValuePool().createValue(Animation::initialAnimationDelay(), CSSPrimitiveValue::CSS_S)); - return list.release(); + list->append(cssValuePool.createIdentifierValue(CSSValueAll)); + list->append(cssValuePool.createValue(Animation::initialDuration(), CSSPrimitiveValue::CSS_S)); + list->append(createTimingFunctionValue(Animation::initialTimingFunction())); + list->append(cssValuePool.createValue(Animation::initialDelay(), CSSPrimitiveValue::CSS_S)); + return WTFMove(list); } case CSSPropertyPointerEvents: - return cssValuePool().createValue(style->pointerEvents()); - case CSSPropertyWebkitColorCorrection: - return cssValuePool().createValue(style->colorSpace()); + return cssValuePool.createValue(style->pointerEvents()); case CSSPropertyWebkitLineGrid: if (style->lineGrid().isNull()) - return cssValuePool().createIdentifierValue(CSSValueNone); - return cssValuePool().createValue(style->lineGrid(), CSSPrimitiveValue::CSS_STRING); + return cssValuePool.createIdentifierValue(CSSValueNone); + return cssValuePool.createValue(style->lineGrid(), CSSPrimitiveValue::CSS_STRING); case CSSPropertyWebkitLineSnap: return CSSPrimitiveValue::create(style->lineSnap()); case CSSPropertyWebkitLineAlign: return CSSPrimitiveValue::create(style->lineAlign()); - case CSSPropertyWebkitWritingMode: - return cssValuePool().createValue(style->writingMode()); + case CSSPropertyWritingMode: + return cssValuePool.createValue(style->writingMode()); case CSSPropertyWebkitTextCombine: - return cssValuePool().createValue(style->textCombine()); + return cssValuePool.createValue(style->textCombine()); case CSSPropertyWebkitTextOrientation: return CSSPrimitiveValue::create(style->textOrientation()); case CSSPropertyWebkitLineBoxContain: return createLineBoxContainValue(style->lineBoxContain()); - case CSSPropertyWebkitAlt: - return altTextToCSSValue(style.get()); + case CSSPropertyAlt: + return altTextToCSSValue(*style); case CSSPropertyContent: - return contentToCSSValue(style.get()); + return contentToCSSValue(*style); case CSSPropertyCounterIncrement: - return counterToCSSValue(style.get(), propertyID); + return counterToCSSValue(*style, propertyID); case CSSPropertyCounterReset: - return counterToCSSValue(style.get(), propertyID); + return counterToCSSValue(*style, propertyID); case CSSPropertyWebkitClipPath: { - ClipPathOperation* operation = style->clipPath(); + auto* operation = style->clipPath(); if (!operation) - return cssValuePool().createIdentifierValue(CSSValueNone); -#if ENABLE(SVG) - if (operation->type() == ClipPathOperation::Reference) { - ReferenceClipPathOperation& referenceOperation = toReferenceClipPathOperation(*operation); - return CSSPrimitiveValue::create(referenceOperation.url(), CSSPrimitiveValue::CSS_URI); - } -#endif - RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); - if (operation->type() == ClipPathOperation::Shape) { - ShapeClipPathOperation& shapeOperation = toShapeClipPathOperation(*operation); - list->append(valueForBasicShape(style.get(), shapeOperation.basicShape())); + return cssValuePool.createIdentifierValue(CSSValueNone); + if (is<ReferenceClipPathOperation>(*operation)) + return CSSPrimitiveValue::create(downcast<ReferenceClipPathOperation>(*operation).url(), CSSPrimitiveValue::CSS_URI); + auto list = CSSValueList::createSpaceSeparated(); + if (is<ShapeClipPathOperation>(*operation)) { + auto& shapeOperation = downcast<ShapeClipPathOperation>(*operation); + list->append(valueForBasicShape(*style, shapeOperation.basicShape())); if (shapeOperation.referenceBox() != BoxMissing) - list->append(cssValuePool().createValue(shapeOperation.referenceBox())); - } - if (operation->type() == ClipPathOperation::Box) { - BoxClipPathOperation& boxOperation = toBoxClipPathOperation(*operation); - list->append(cssValuePool().createValue(boxOperation.referenceBox())); + list->append(cssValuePool.createValue(shapeOperation.referenceBox())); } - return list.release(); + if (is<BoxClipPathOperation>(*operation)) + list->append(cssValuePool.createValue(downcast<BoxClipPathOperation>(*operation).referenceBox())); + return WTFMove(list); } #if ENABLE(CSS_REGIONS) case CSSPropertyWebkitFlowInto: - if (style->flowThread().isNull()) - return cssValuePool().createIdentifierValue(CSSValueNone); - return cssValuePool().createValue(style->flowThread(), CSSPrimitiveValue::CSS_STRING); + if (!style->hasFlowInto()) + return cssValuePool.createIdentifierValue(CSSValueNone); + return cssValuePool.createValue(style->flowThread(), CSSPrimitiveValue::CSS_STRING); case CSSPropertyWebkitFlowFrom: if (!style->hasFlowFrom()) - return cssValuePool().createIdentifierValue(CSSValueNone); - return cssValuePool().createValue(style->regionThread(), CSSPrimitiveValue::CSS_STRING); + return cssValuePool.createIdentifierValue(CSSValueNone); + return cssValuePool.createValue(style->regionThread(), CSSPrimitiveValue::CSS_STRING); case CSSPropertyWebkitRegionFragment: - return cssValuePool().createValue(style->regionFragment()); -#endif -#if ENABLE(CSS_EXCLUSIONS) - case CSSPropertyWebkitWrapFlow: - return cssValuePool().createValue(style->wrapFlow()); - case CSSPropertyWebkitWrapThrough: - return cssValuePool().createValue(style->wrapThrough()); -#endif -#if ENABLE(CSS_SHAPES) - case CSSPropertyWebkitShapeMargin: - return cssValuePool().createValue(style->shapeMargin()); - case CSSPropertyWebkitShapePadding: - return cssValuePool().createValue(style->shapePadding()); - case CSSPropertyWebkitShapeImageThreshold: - return cssValuePool().createValue(style->shapeImageThreshold(), CSSPrimitiveValue::CSS_NUMBER); - case CSSPropertyWebkitShapeInside: - return shapePropertyValue(style.get(), style->shapeInside()); - case CSSPropertyWebkitShapeOutside: - return shapePropertyValue(style.get(), style->shapeOutside()); + return cssValuePool.createValue(style->regionFragment()); #endif -#if ENABLE(CSS_FILTERS) - case CSSPropertyWebkitFilter: - return valueForFilter(style.get(), style->filter()); + case CSSPropertyShapeMargin: + return cssValuePool.createValue(style->shapeMargin(), *style); + case CSSPropertyShapeImageThreshold: + return cssValuePool.createValue(style->shapeImageThreshold(), CSSPrimitiveValue::CSS_NUMBER); + case CSSPropertyShapeOutside: + return shapePropertyValue(*style, style->shapeOutside()); + case CSSPropertyFilter: + return valueForFilter(*style, style->filter()); +#if ENABLE(FILTERS_LEVEL_2) + case CSSPropertyWebkitBackdropFilter: + return valueForFilter(*style, style->backdropFilter()); #endif #if ENABLE(CSS_COMPOSITING) - case CSSPropertyWebkitBlendMode: - return cssValuePool().createValue(style->blendMode()); + case CSSPropertyMixBlendMode: + return cssValuePool.createValue(style->blendMode()); + case CSSPropertyIsolation: + return cssValuePool.createValue(style->isolation()); #endif - case CSSPropertyWebkitBackgroundBlendMode: { - const FillLayer* layers = style->backgroundLayers(); - if (!layers->next()) - return cssValuePool().createValue(layers->blendMode()); - - RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); - for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) - list->append(cssValuePool().createValue(currLayer->blendMode())); - - return list.release(); + case CSSPropertyBackgroundBlendMode: { + auto& layers = style->backgroundLayers(); + if (!layers.next()) + return cssValuePool.createValue(layers.blendMode()); + auto list = CSSValueList::createCommaSeparated(); + for (auto* currLayer = &layers; currLayer; currLayer = currLayer->next()) + list->append(cssValuePool.createValue(currLayer->blendMode())); + return WTFMove(list); } case CSSPropertyBackground: return getBackgroundShorthandValue(); case CSSPropertyBorder: { - RefPtr<CSSValue> value = propertyValue(CSSPropertyBorderTop, DoNotUpdateLayout); - const CSSPropertyID properties[3] = { CSSPropertyBorderRight, CSSPropertyBorderBottom, - CSSPropertyBorderLeft }; - for (size_t i = 0; i < WTF_ARRAY_LENGTH(properties); ++i) { - if (!compareCSSValuePtr<CSSValue>(value, propertyValue(properties[i], DoNotUpdateLayout))) - return 0; + auto value = propertyValue(CSSPropertyBorderTop, DoNotUpdateLayout); + const CSSPropertyID properties[3] = { CSSPropertyBorderRight, CSSPropertyBorderBottom, CSSPropertyBorderLeft }; + for (auto& property : properties) { + if (!compareCSSValuePtr<CSSValue>(value, propertyValue(property, DoNotUpdateLayout))) + return nullptr; } - return value.release(); + return value; } case CSSPropertyBorderBottom: return getCSSPropertyValuesForShorthandProperties(borderBottomShorthand()); @@ -2850,7 +3751,7 @@ PassRefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propert case CSSPropertyBorderImage: return valueForNinePieceImage(style->borderImage()); case CSSPropertyBorderRadius: - return getBorderRadiusShorthandValue(style.get(), m_node->document().renderView()); + return borderRadiusShorthandValue(*style); case CSSPropertyBorderRight: return getCSSPropertyValuesForShorthandProperties(borderRightShorthand()); case CSSPropertyBorderStyle: @@ -2859,10 +3760,10 @@ PassRefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propert return getCSSPropertyValuesForShorthandProperties(borderTopShorthand()); case CSSPropertyBorderWidth: return getCSSPropertyValuesForSidesShorthand(borderWidthShorthand()); - case CSSPropertyWebkitColumnRule: - return getCSSPropertyValuesForShorthandProperties(webkitColumnRuleShorthand()); - case CSSPropertyWebkitColumns: - return getCSSPropertyValuesForShorthandProperties(webkitColumnsShorthand()); + case CSSPropertyColumnRule: + return getCSSPropertyValuesForShorthandProperties(columnRuleShorthand()); + case CSSPropertyColumns: + return getCSSPropertyValuesForShorthandProperties(columnsShorthand()); case CSSPropertyListStyle: return getCSSPropertyValuesForShorthandProperties(listStyleShorthand()); case CSSPropertyMargin: @@ -2871,12 +3772,83 @@ PassRefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propert return getCSSPropertyValuesForShorthandProperties(outlineShorthand()); case CSSPropertyPadding: return getCSSPropertyValuesForSidesShorthand(paddingShorthand()); + +#if ENABLE(CSS_SCROLL_SNAP) + case CSSPropertyScrollSnapMargin: + return getCSSPropertyValuesForSidesShorthand(scrollSnapMarginShorthand()); + case CSSPropertyScrollSnapMarginBottom: + return zoomAdjustedPixelValueForLength(style->scrollSnapMarginBottom(), *style); + case CSSPropertyScrollSnapMarginTop: + return zoomAdjustedPixelValueForLength(style->scrollSnapMarginTop(), *style); + case CSSPropertyScrollSnapMarginRight: + return zoomAdjustedPixelValueForLength(style->scrollSnapMarginRight(), *style); + case CSSPropertyScrollSnapMarginLeft: + return zoomAdjustedPixelValueForLength(style->scrollSnapMarginLeft(), *style); + case CSSPropertyScrollPadding: + return getCSSPropertyValuesForSidesShorthand(scrollPaddingShorthand()); + case CSSPropertyScrollPaddingBottom: + return zoomAdjustedPixelValueForLength(style->scrollPaddingBottom(), *style); + case CSSPropertyScrollPaddingTop: + return zoomAdjustedPixelValueForLength(style->scrollPaddingTop(), *style); + case CSSPropertyScrollPaddingRight: + return zoomAdjustedPixelValueForLength(style->scrollPaddingRight(), *style); + case CSSPropertyScrollPaddingLeft: + return zoomAdjustedPixelValueForLength(style->scrollPaddingLeft(), *style); + case CSSPropertyScrollSnapType: + return valueForScrollSnapType(style->scrollSnapType()); + case CSSPropertyScrollSnapAlign: + return valueForScrollSnapAlignment(style->scrollSnapAlign()); +#endif + +#if ENABLE(CSS_TRAILING_WORD) + case CSSPropertyAppleTrailingWord: + return cssValuePool.createValue(style->trailingWord()); +#endif + +#if ENABLE(APPLE_PAY) + case CSSPropertyApplePayButtonStyle: + return cssValuePool.createValue(style->applePayButtonStyle()); + case CSSPropertyApplePayButtonType: + return cssValuePool.createValue(style->applePayButtonType()); +#endif + /* Individual properties not part of the spec */ case CSSPropertyBackgroundRepeatX: case CSSPropertyBackgroundRepeatY: break; + // Length properties for SVG. + case CSSPropertyCx: + return zoomAdjustedPixelValueForLength(style->svgStyle().cx(), *style); + case CSSPropertyCy: + return zoomAdjustedPixelValueForLength(style->svgStyle().cy(), *style); + case CSSPropertyR: + return zoomAdjustedPixelValueForLength(style->svgStyle().r(), *style); + case CSSPropertyRx: + return zoomAdjustedPixelValueForLength(style->svgStyle().rx(), *style); + case CSSPropertyRy: + return zoomAdjustedPixelValueForLength(style->svgStyle().ry(), *style); + case CSSPropertyStrokeDashoffset: + return zoomAdjustedPixelValueForLength(style->svgStyle().strokeDashOffset(), *style); + case CSSPropertyX: + return zoomAdjustedPixelValueForLength(style->svgStyle().x(), *style); + case CSSPropertyY: + return zoomAdjustedPixelValueForLength(style->svgStyle().y(), *style); + case CSSPropertyWebkitTextZoom: + return cssValuePool.createValue(style->textZoom()); + + case CSSPropertyPaintOrder: + return paintOrder(style->paintOrder()); + case CSSPropertyStrokeLinecap: + return CSSPrimitiveValue::create(style->capStyle()); + case CSSPropertyStrokeLinejoin: + return CSSPrimitiveValue::create(style->joinStyle()); + case CSSPropertyStrokeWidth: + return zoomAdjustedPixelValueForLength(style->strokeWidth(), *style); + /* Unimplemented CSS 3 properties (including CSS3 shorthand properties) */ + case CSSPropertyAll: + case CSSPropertyAnimation: case CSSPropertyWebkitTextEmphasis: case CSSPropertyTextLineThrough: case CSSPropertyTextLineThroughColor: @@ -2942,7 +3914,6 @@ PassRefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propert break; /* Unimplemented -webkit- properties */ - case CSSPropertyWebkitAnimation: case CSSPropertyWebkitBorderRadius: case CSSPropertyWebkitMarginCollapse: case CSSPropertyWebkitMarquee: @@ -2950,12 +3921,12 @@ PassRefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propert case CSSPropertyWebkitMask: case CSSPropertyWebkitMaskRepeatX: case CSSPropertyWebkitMaskRepeatY: - case CSSPropertyWebkitPerspectiveOriginX: - case CSSPropertyWebkitPerspectiveOriginY: + case CSSPropertyPerspectiveOriginX: + case CSSPropertyPerspectiveOriginY: case CSSPropertyWebkitTextStroke: - case CSSPropertyWebkitTransformOriginX: - case CSSPropertyWebkitTransformOriginY: - case CSSPropertyWebkitTransformOriginZ: + case CSSPropertyTransformOriginX: + case CSSPropertyTransformOriginY: + case CSSPropertyTransformOriginZ: break; #if ENABLE(CSS_DEVICE_ADAPTATION) @@ -2966,13 +3937,11 @@ PassRefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propert break; #endif -#if ENABLE(SVG) case CSSPropertyBufferedRendering: case CSSPropertyClipPath: case CSSPropertyClipRule: case CSSPropertyMask: case CSSPropertyEnableBackground: - case CSSPropertyFilter: case CSSPropertyFloodColor: case CSSPropertyFloodOpacity: case CSSPropertyLightingColor: @@ -2993,12 +3962,8 @@ PassRefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propert case CSSPropertyShapeRendering: case CSSPropertyStroke: case CSSPropertyStrokeDasharray: - case CSSPropertyStrokeDashoffset: - case CSSPropertyStrokeLinecap: - case CSSPropertyStrokeLinejoin: case CSSPropertyStrokeMiterlimit: case CSSPropertyStrokeOpacity: - case CSSPropertyStrokeWidth: case CSSPropertyAlignmentBaseline: case CSSPropertyBaselineShift: case CSSPropertyDominantBaseline: @@ -3007,142 +3972,166 @@ PassRefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propert case CSSPropertyKerning: case CSSPropertyTextAnchor: case CSSPropertyVectorEffect: - case CSSPropertyWritingMode: case CSSPropertyWebkitSvgShadow: return svgPropertyValue(propertyID, DoNotUpdateLayout); -#endif + case CSSPropertyCustom: + ASSERT_NOT_REACHED(); + return nullptr; } logUnimplementedPropertyID(propertyID); - return 0; + return nullptr; } String CSSComputedStyleDeclaration::getPropertyValue(CSSPropertyID propertyID) const { - RefPtr<CSSValue> value = getPropertyCSSValue(propertyID); - if (value) - return value->cssText(); - return ""; + auto value = getPropertyCSSValue(propertyID); + if (!value) + return emptyString(); // FIXME: Should this be null instead, as it is in StyleProperties::getPropertyValue? + return value->cssText(); } unsigned CSSComputedStyleDeclaration::length() const { - Node* node = m_node.get(); - if (!node) - return 0; + updateStyleIfNeededForProperty(m_element.get(), CSSPropertyCustom); - RenderStyle* style = node->computedStyle(m_pseudoElementSpecifier); + auto* style = m_element->computedStyle(m_pseudoElementSpecifier); if (!style) return 0; - return numComputedProperties; + return numComputedProperties + style->customProperties().size(); } String CSSComputedStyleDeclaration::item(unsigned i) const { if (i >= length()) - return ""; - - return getPropertyNameString(computedProperties[i]); + return String(); + + if (i < numComputedProperties) + return getPropertyNameString(computedProperties[i]); + + auto* style = m_element->computedStyle(m_pseudoElementSpecifier); + if (!style) + return String(); + + unsigned index = i - numComputedProperties; + + const auto& customProperties = style->customProperties(); + if (index >= customProperties.size()) + return String(); + + Vector<String, 4> results; + copyKeysToVector(customProperties, results); + return results.at(index); } -bool ComputedStyleExtractor::propertyMatches(CSSPropertyID propertyID, const CSSValue* value) const +bool ComputedStyleExtractor::propertyMatches(CSSPropertyID propertyID, const CSSValue* value) { - if (propertyID == CSSPropertyFontSize && value->isPrimitiveValue() && m_node) { - m_node->document().updateLayoutIgnorePendingStylesheets(); - RenderStyle* style = m_node->computedStyle(m_pseudoElementSpecifier); - if (style && style->fontDescription().keywordSize()) { - CSSValueID sizeValue = cssIdentifierForFontSizeKeyword(style->fontDescription().keywordSize()); - const CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); - if (primitiveValue->isValueID() && primitiveValue->getValueID() == sizeValue) - return true; + if (!m_element) + return false; + if (propertyID == CSSPropertyFontSize && is<CSSPrimitiveValue>(*value)) { + m_element->document().updateLayoutIgnorePendingStylesheets(); + if (auto* style = m_element->computedStyle(m_pseudoElementSpecifier)) { + if (CSSValueID sizeIdentifier = style->fontDescription().keywordSizeAsIdentifier()) { + auto& primitiveValue = downcast<CSSPrimitiveValue>(*value); + if (primitiveValue.isValueID() && primitiveValue.valueID() == sizeIdentifier) + return true; + } } } RefPtr<CSSValue> computedValue = propertyValue(propertyID); return computedValue && value && computedValue->equals(*value); } -PassRef<MutableStyleProperties> ComputedStyleExtractor::copyProperties() const +Ref<MutableStyleProperties> ComputedStyleExtractor::copyProperties() { return copyPropertiesInSet(computedProperties, numComputedProperties); } -PassRefPtr<CSSValueList> ComputedStyleExtractor::getCSSPropertyValuesForShorthandProperties(const StylePropertyShorthand& shorthand) const +RefPtr<CSSValueList> ComputedStyleExtractor::getCSSPropertyValuesForShorthandProperties(const StylePropertyShorthand& shorthand) { - RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); - for (size_t i = 0; i < shorthand.length(); ++i) { - RefPtr<CSSValue> value = propertyValue(shorthand.properties()[i], DoNotUpdateLayout); - list->append(value); - } - return list.release(); + auto list = CSSValueList::createSpaceSeparated(); + for (size_t i = 0; i < shorthand.length(); ++i) + list->append(propertyValue(shorthand.properties()[i], DoNotUpdateLayout).releaseNonNull()); + return WTFMove(list); } -PassRefPtr<CSSValueList> ComputedStyleExtractor::getCSSPropertyValuesForSidesShorthand(const StylePropertyShorthand& shorthand) const +RefPtr<CSSValueList> ComputedStyleExtractor::getCSSPropertyValuesForSidesShorthand(const StylePropertyShorthand& shorthand) { - RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); + auto list = CSSValueList::createSpaceSeparated(); + // Assume the properties are in the usual order top, right, bottom, left. - RefPtr<CSSValue> topValue = propertyValue(shorthand.properties()[0], DoNotUpdateLayout); - RefPtr<CSSValue> rightValue = propertyValue(shorthand.properties()[1], DoNotUpdateLayout); - RefPtr<CSSValue> bottomValue = propertyValue(shorthand.properties()[2], DoNotUpdateLayout); - RefPtr<CSSValue> leftValue = propertyValue(shorthand.properties()[3], DoNotUpdateLayout); + auto topValue = propertyValue(shorthand.properties()[0], DoNotUpdateLayout); + auto rightValue = propertyValue(shorthand.properties()[1], DoNotUpdateLayout); + auto bottomValue = propertyValue(shorthand.properties()[2], DoNotUpdateLayout); + auto leftValue = propertyValue(shorthand.properties()[3], DoNotUpdateLayout); // All 4 properties must be specified. if (!topValue || !rightValue || !bottomValue || !leftValue) - return 0; + return nullptr; bool showLeft = !compareCSSValuePtr(rightValue, leftValue); bool showBottom = !compareCSSValuePtr(topValue, bottomValue) || showLeft; bool showRight = !compareCSSValuePtr(topValue, rightValue) || showBottom; - list->append(topValue.release()); + list->append(topValue.releaseNonNull()); if (showRight) - list->append(rightValue.release()); + list->append(rightValue.releaseNonNull()); if (showBottom) - list->append(bottomValue.release()); + list->append(bottomValue.releaseNonNull()); if (showLeft) - list->append(leftValue.release()); + list->append(leftValue.releaseNonNull()); - return list.release(); + return WTFMove(list); } -PassRefPtr<CSSValueList> ComputedStyleExtractor::getCSSPropertyValuesForGridShorthand(const StylePropertyShorthand& shorthand) const +RefPtr<CSSValueList> ComputedStyleExtractor::getCSSPropertyValuesForGridShorthand(const StylePropertyShorthand& shorthand) { - RefPtr<CSSValueList> list = CSSValueList::createSlashSeparated(); - for (size_t i = 0; i < shorthand.length(); ++i) { - RefPtr<CSSValue> value = propertyValue(shorthand.properties()[i], DoNotUpdateLayout); - list->append(value.release()); - } - return list.release(); + auto list = CSSValueList::createSlashSeparated(); + for (size_t i = 0; i < shorthand.length(); ++i) + list->append(propertyValue(shorthand.properties()[i], DoNotUpdateLayout).releaseNonNull()); + return WTFMove(list); } -PassRef<MutableStyleProperties> ComputedStyleExtractor::copyPropertiesInSet(const CSSPropertyID* set, unsigned length) const +Ref<MutableStyleProperties> ComputedStyleExtractor::copyPropertiesInSet(const CSSPropertyID* set, unsigned length) { Vector<CSSProperty, 256> list; list.reserveInitialCapacity(length); for (unsigned i = 0; i < length; ++i) { - RefPtr<CSSValue> value = propertyValue(set[i]); - if (value) - list.append(CSSProperty(set[i], value.release(), false)); + if (auto value = propertyValue(set[i])) + list.append(CSSProperty(set[i], WTFMove(value), false)); } return MutableStyleProperties::create(list.data(), list.size()); } CSSRule* CSSComputedStyleDeclaration::parentRule() const { - return 0; + return nullptr; } -PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(const String& propertyName) +RefPtr<DeprecatedCSSOMValue> CSSComputedStyleDeclaration::getPropertyCSSValue(const String& propertyName) { + if (isCustomPropertyName(propertyName)) { + auto value = ComputedStyleExtractor(m_element.ptr(), m_allowVisitedStyle, m_pseudoElementSpecifier).customPropertyValue(propertyName); + if (!value) + return nullptr; + return value->createDeprecatedCSSOMWrapper(); + } + CSSPropertyID propertyID = cssPropertyID(propertyName); if (!propertyID) - return 0; - RefPtr<CSSValue> value = getPropertyCSSValue(propertyID); - return value ? value->cloneForCSSOM() : 0; + return nullptr; + auto value = getPropertyCSSValue(propertyID); + if (!value) + return nullptr; + return value->createDeprecatedCSSOMWrapper(); } String CSSComputedStyleDeclaration::getPropertyValue(const String &propertyName) { + if (isCustomPropertyName(propertyName)) + return ComputedStyleExtractor(m_element.ptr(), m_allowVisitedStyle, m_pseudoElementSpecifier).customPropertyText(propertyName); + CSSPropertyID propertyID = cssPropertyID(propertyName); if (!propertyID) return String(); @@ -3152,12 +4141,12 @@ String CSSComputedStyleDeclaration::getPropertyValue(const String &propertyName) String CSSComputedStyleDeclaration::getPropertyPriority(const String&) { // All computed styles have a priority of not "important". - return ""; + return emptyString(); // FIXME: Should this sometimes be null instead of empty, to match a normal style declaration? } String CSSComputedStyleDeclaration::getPropertyShorthand(const String&) { - return ""; + return emptyString(); // FIXME: Should this sometimes be null instead of empty, to match a normal style declaration? } bool CSSComputedStyleDeclaration::isPropertyImplicit(const String&) @@ -3165,18 +4154,17 @@ bool CSSComputedStyleDeclaration::isPropertyImplicit(const String&) return false; } -void CSSComputedStyleDeclaration::setProperty(const String&, const String&, const String&, ExceptionCode& ec) +ExceptionOr<void> CSSComputedStyleDeclaration::setProperty(const String&, const String&, const String&) { - ec = NO_MODIFICATION_ALLOWED_ERR; + return Exception { NO_MODIFICATION_ALLOWED_ERR }; } -String CSSComputedStyleDeclaration::removeProperty(const String&, ExceptionCode& ec) +ExceptionOr<String> CSSComputedStyleDeclaration::removeProperty(const String&) { - ec = NO_MODIFICATION_ALLOWED_ERR; - return String(); + return Exception { NO_MODIFICATION_ALLOWED_ERR }; } -PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValueInternal(CSSPropertyID propertyID) +RefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValueInternal(CSSPropertyID propertyID) { return getPropertyCSSValue(propertyID); } @@ -3186,23 +4174,20 @@ String CSSComputedStyleDeclaration::getPropertyValueInternal(CSSPropertyID prope return getPropertyValue(propertyID); } -void CSSComputedStyleDeclaration::setPropertyInternal(CSSPropertyID, const String&, bool, ExceptionCode& ec) +ExceptionOr<bool> CSSComputedStyleDeclaration::setPropertyInternal(CSSPropertyID, const String&, bool) { - ec = NO_MODIFICATION_ALLOWED_ERR; + return Exception { NO_MODIFICATION_ALLOWED_ERR }; } -PassRefPtr<CSSValueList> ComputedStyleExtractor::getBackgroundShorthandValue() const +Ref<CSSValueList> ComputedStyleExtractor::getBackgroundShorthandValue() { - static const CSSPropertyID propertiesBeforeSlashSeperator[5] = { CSSPropertyBackgroundColor, CSSPropertyBackgroundImage, - CSSPropertyBackgroundRepeat, CSSPropertyBackgroundAttachment, - CSSPropertyBackgroundPosition }; - static const CSSPropertyID propertiesAfterSlashSeperator[3] = { CSSPropertyBackgroundSize, CSSPropertyBackgroundOrigin, - CSSPropertyBackgroundClip }; + static const CSSPropertyID propertiesBeforeSlashSeperator[5] = { CSSPropertyBackgroundColor, CSSPropertyBackgroundImage, CSSPropertyBackgroundRepeat, CSSPropertyBackgroundAttachment, CSSPropertyBackgroundPosition }; + static const CSSPropertyID propertiesAfterSlashSeperator[3] = { CSSPropertyBackgroundSize, CSSPropertyBackgroundOrigin, CSSPropertyBackgroundClip }; - RefPtr<CSSValueList> list = CSSValueList::createSlashSeparated(); - list->append(getCSSPropertyValuesForShorthandProperties(StylePropertyShorthand(CSSPropertyBackground, propertiesBeforeSlashSeperator, WTF_ARRAY_LENGTH(propertiesBeforeSlashSeperator)))); - list->append(getCSSPropertyValuesForShorthandProperties(StylePropertyShorthand(CSSPropertyBackground, propertiesAfterSlashSeperator, WTF_ARRAY_LENGTH(propertiesAfterSlashSeperator)))); - return list.release(); + auto list = CSSValueList::createSlashSeparated(); + list->append(*getCSSPropertyValuesForShorthandProperties(StylePropertyShorthand(CSSPropertyBackground, propertiesBeforeSlashSeperator))); + list->append(*getCSSPropertyValuesForShorthandProperties(StylePropertyShorthand(CSSPropertyBackground, propertiesAfterSlashSeperator))); + return list; } } // namespace WebCore |