REGRESSION (Safari 10.1): When 'transition' contains -ms-transform, transform-origin...
[WebKit-https.git] / Source / WebCore / css / CSSComputedStyleDeclaration.cpp
index 929bbef..c05cc3c 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2004 Zack Rusin <zack@kde.org>
- * Copyright (C) 2004-2014 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.
 #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 "CSSFontStyleValue.h"
 #include "CSSFontValue.h"
+#include "CSSFontVariationValue.h"
 #include "CSSFunctionValue.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 "FontSelectionValueInlines.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 "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 "WebKitCSSFilterValue.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_GRID_LAYOUT)
 #include "CSSGridLineNamesValue.h"
 #include "CSSGridTemplateAreasValue.h"
 #include "RenderGrid.h"
-#endif
-
-#if ENABLE(CSS_SHAPES)
-#include "ShapeValue.h"
-#endif
 
 #if ENABLE(DASHBOARD_SUPPORT)
 #include "DashboardRegion.h"
 #endif
 
-#if ENABLE(CSS_SCROLL_SNAP)
-#include "LengthRepeat.h"
-#include "StyleScrollSnapPoints.h"
-#endif
-
 #if ENABLE(CSS_ANIMATIONS_LEVEL_2)
 #include "AnimationTrigger.h"
 #endif
@@ -146,6 +147,8 @@ static const CSSPropertyID computedProperties[] = {
     CSSPropertyClear,
     CSSPropertyClip,
     CSSPropertyColor,
+    CSSPropertyCounterIncrement,
+    CSSPropertyCounterReset,
     CSSPropertyContent,
     CSSPropertyCursor,
     CSSPropertyDirection,
@@ -154,10 +157,15 @@ static const CSSPropertyID computedProperties[] = {
     CSSPropertyFloat,
     CSSPropertyFontFamily,
     CSSPropertyFontSize,
+    CSSPropertyFontStretch,
     CSSPropertyFontStyle,
     CSSPropertyFontSynthesis,
     CSSPropertyFontVariant,
     CSSPropertyFontWeight,
+#if ENABLE(VARIATION_FONTS)
+    CSSPropertyFontOpticalSizing,
+#endif
+    CSSPropertyHangingPunctuation,
     CSSPropertyHeight,
 #if ENABLE(CSS_IMAGE_ORIENTATION)
     CSSPropertyImageOrientation,
@@ -180,6 +188,8 @@ static const CSSPropertyID computedProperties[] = {
     CSSPropertyMaxWidth,
     CSSPropertyMinHeight,
     CSSPropertyMinWidth,
+    CSSPropertyObjectFit,
+    CSSPropertyObjectPosition,
     CSSPropertyOpacity,
     CSSPropertyOrphans,
     CSSPropertyOutlineColor,
@@ -233,26 +243,26 @@ static const CSSPropertyID computedProperties[] = {
     CSSPropertyWhiteSpace,
     CSSPropertyWidows,
     CSSPropertyWidth,
+    CSSPropertyWillChange,
     CSSPropertyWordBreak,
     CSSPropertyWordSpacing,
     CSSPropertyWordWrap,
 #if ENABLE(CSS_SCROLL_SNAP)
-    CSSPropertyWebkitScrollSnapType,
-    CSSPropertyWebkitScrollSnapPointsX,
-    CSSPropertyWebkitScrollSnapPointsY,
-    CSSPropertyWebkitScrollSnapDestination,
-    CSSPropertyWebkitScrollSnapCoordinate,
+    CSSPropertyScrollSnapMargin,
+    CSSPropertyScrollSnapMarginLeft,
+    CSSPropertyScrollSnapMarginTop,
+    CSSPropertyScrollSnapMarginRight,
+    CSSPropertyScrollSnapMarginBottom,
+    CSSPropertyScrollPadding,
+    CSSPropertyScrollPaddingLeft,
+    CSSPropertyScrollPaddingTop,
+    CSSPropertyScrollPaddingRight,
+    CSSPropertyScrollPaddingBottom,
+    CSSPropertyScrollSnapType,
+    CSSPropertyScrollSnapAlign,
 #endif
     CSSPropertyZIndex,
     CSSPropertyZoom,
-    CSSPropertyWebkitAnimationDelay,
-    CSSPropertyWebkitAnimationDirection,
-    CSSPropertyWebkitAnimationDuration,
-    CSSPropertyWebkitAnimationFillMode,
-    CSSPropertyWebkitAnimationIterationCount,
-    CSSPropertyWebkitAnimationName,
-    CSSPropertyWebkitAnimationPlayState,
-    CSSPropertyWebkitAnimationTimingFunction,
 #if ENABLE(CSS_ANIMATIONS_LEVEL_2)
     CSSPropertyWebkitAnimationTrigger,
 #endif
@@ -291,7 +301,7 @@ static const CSSPropertyID computedProperties[] = {
     CSSPropertyColumnCount,
     CSSPropertyColumnFill,
     CSSPropertyColumnGap,
-    CSSPropertyColumnProgression,
+    CSSPropertyWebkitColumnProgression,
     CSSPropertyColumnRuleColor,
     CSSPropertyColumnRuleStyle,
     CSSPropertyColumnRuleWidth,
@@ -308,13 +318,16 @@ static const CSSPropertyID computedProperties[] = {
     CSSPropertyAlignSelf,
     CSSPropertyFilter,
     CSSPropertyFlexBasis,
+    CSSPropertyFlexDirection,
+    CSSPropertyFlexFlow,
     CSSPropertyFlexGrow,
     CSSPropertyFlexShrink,
-    CSSPropertyFlexDirection,
     CSSPropertyFlexWrap,
     CSSPropertyJustifyContent,
     CSSPropertyJustifySelf,
     CSSPropertyJustifyItems,
+    CSSPropertyPlaceContent,
+    CSSPropertyPlaceItems,
 #if ENABLE(FILTERS_LEVEL_2)
     CSSPropertyWebkitBackdropFilter,
 #endif
@@ -326,18 +339,21 @@ static const CSSPropertyID computedProperties[] = {
     CSSPropertyFontVariantNumeric,
     CSSPropertyFontVariantAlternates,
     CSSPropertyFontVariantEastAsian,
-#if ENABLE(CSS_GRID_LAYOUT)
-    CSSPropertyWebkitGridAutoColumns,
-    CSSPropertyWebkitGridAutoFlow,
-    CSSPropertyWebkitGridAutoRows,
-    CSSPropertyWebkitGridColumnEnd,
-    CSSPropertyWebkitGridColumnStart,
-    CSSPropertyWebkitGridTemplateAreas,
-    CSSPropertyWebkitGridTemplateColumns,
-    CSSPropertyWebkitGridTemplateRows,
-    CSSPropertyWebkitGridRowEnd,
-    CSSPropertyWebkitGridRowStart,
+#if ENABLE(VARIATION_FONTS)
+    CSSPropertyFontVariationSettings,
 #endif
+    CSSPropertyGridAutoColumns,
+    CSSPropertyGridAutoFlow,
+    CSSPropertyGridAutoRows,
+    CSSPropertyGridColumnEnd,
+    CSSPropertyGridColumnStart,
+    CSSPropertyGridTemplateAreas,
+    CSSPropertyGridTemplateColumns,
+    CSSPropertyGridTemplateRows,
+    CSSPropertyGridRowEnd,
+    CSSPropertyGridRowStart,
+    CSSPropertyGridColumnGap,
+    CSSPropertyGridRowGap,
     CSSPropertyWebkitHyphenateCharacter,
     CSSPropertyWebkitHyphenateLimitAfter,
     CSSPropertyWebkitHyphenateLimitBefore,
@@ -346,7 +362,7 @@ static const CSSPropertyID computedProperties[] = {
     CSSPropertyWebkitInitialLetter,
     CSSPropertyWebkitLineAlign,
     CSSPropertyWebkitLineBoxContain,
-    CSSPropertyWebkitLineBreak,
+    CSSPropertyLineBreak,
     CSSPropertyWebkitLineClamp,
     CSSPropertyWebkitLineGrid,
     CSSPropertyWebkitLineSnap,
@@ -383,9 +399,7 @@ static const CSSPropertyID computedProperties[] = {
 #if PLATFORM(IOS)
     CSSPropertyWebkitTouchCallout,
 #endif
-#if ENABLE(CSS_SHAPES)
-    CSSPropertyWebkitShapeOutside,
-#endif
+    CSSPropertyShapeOutside,
 #if ENABLE(TOUCH_EVENTS)
     CSSPropertyWebkitTapHighlightColor,
 #endif
@@ -397,21 +411,16 @@ static const CSSPropertyID computedProperties[] = {
     CSSPropertyWebkitTextFillColor,
     CSSPropertyWebkitTextOrientation,
     CSSPropertyWebkitTextSecurity,
-#if ENABLE(IOS_TEXT_AUTOSIZING)
+#if ENABLE(TEXT_AUTOSIZING)
     CSSPropertyWebkitTextSizeAdjust,
 #endif
     CSSPropertyWebkitTextStrokeColor,
     CSSPropertyWebkitTextStrokeWidth,
     CSSPropertyWebkitTextZoom,
     CSSPropertyWebkitTransformStyle,
-    CSSPropertyWebkitTransitionDelay,
-    CSSPropertyWebkitTransitionDuration,
-    CSSPropertyWebkitTransitionProperty,
-    CSSPropertyWebkitTransitionTimingFunction,
     CSSPropertyWebkitUserDrag,
     CSSPropertyWebkitUserModify,
     CSSPropertyWebkitUserSelect,
-    CSSPropertyWebkitWritingMode,
 #if ENABLE(CSS_REGIONS)
     CSSPropertyWebkitFlowInto,
     CSSPropertyWebkitFlowFrom,
@@ -420,16 +429,17 @@ static const CSSPropertyID computedProperties[] = {
     CSSPropertyWebkitRegionBreakInside,
     CSSPropertyWebkitRegionFragment,
 #endif
-#if ENABLE(CSS_SHAPES)
-    CSSPropertyWebkitShapeMargin,
-    CSSPropertyWebkitShapeImageThreshold,
-#endif
+    CSSPropertyShapeImageThreshold,
+    CSSPropertyShapeMargin,
+    CSSPropertyShapeOutside,
+    CSSPropertyShapeRendering,
     CSSPropertyBufferedRendering,
     CSSPropertyClipPath,
     CSSPropertyClipRule,
     CSSPropertyCx,
     CSSPropertyCy,
     CSSPropertyMask,
+    CSSPropertyMaskType,
     CSSPropertyFilter,
     CSSPropertyFloodColor,
     CSSPropertyFloodOpacity,
@@ -445,13 +455,12 @@ static const CSSPropertyID computedProperties[] = {
     CSSPropertyMarkerEnd,
     CSSPropertyMarkerMid,
     CSSPropertyMarkerStart,
-    CSSPropertyMaskType,
     CSSPropertyPaintOrder,
     CSSPropertyR,
     CSSPropertyRx,
     CSSPropertyRy,
-    CSSPropertyShapeRendering,
     CSSPropertyStroke,
+    CSSPropertyStrokeColor,
     CSSPropertyStrokeDasharray,
     CSSPropertyStrokeDashoffset,
     CSSPropertyStrokeLinecap,
@@ -536,12 +545,12 @@ static Ref<CSSBorderImageSliceValue> valueForNinePieceImageSlice(const NinePiece
     }
 
     auto quad = Quad::create();
-    quad->setTop(top.release());
-    quad->setRight(right.release());
-    quad->setBottom(bottom.release());
-    quad->setLeft(left.release());
+    quad->setTop(WTFMove(top));
+    quad->setRight(WTFMove(right));
+    quad->setBottom(WTFMove(bottom));
+    quad->setLeft(WTFMove(left));
 
-    return CSSBorderImageSliceValue::create(CSSValuePool::singleton().createValue(WTF::move(quad)), image.fill());
+    return CSSBorderImageSliceValue::create(CSSValuePool::singleton().createValue(WTFMove(quad)), image.fill());
 }
 
 static Ref<CSSPrimitiveValue> valueForNinePieceImageQuad(const LengthBox& box)
@@ -589,25 +598,24 @@ static Ref<CSSPrimitiveValue> valueForNinePieceImageQuad(const LengthBox& box)
     }
 
     auto quad = Quad::create();
-    quad->setTop(top);
-    quad->setRight(right);
-    quad->setBottom(bottom);
-    quad->setLeft(left);
+    quad->setTop(WTFMove(top));
+    quad->setRight(WTFMove(right));
+    quad->setBottom(WTFMove(bottom));
+    quad->setLeft(WTFMove(left));
 
-    return cssValuePool.createValue(WTF::move(quad));
+    return cssValuePool.createValue(WTFMove(quad));
 }
 
 static Ref<CSSValue> valueForNinePieceImageRepeat(const NinePieceImage& image)
 {
     auto& cssValuePool = CSSValuePool::singleton();
-    RefPtr<CSSPrimitiveValue> horizontalRepeat = cssValuePool.createIdentifierValue(valueForRepeatRule(image.horizontalRule()));
-
+    auto horizontalRepeat = cssValuePool.createIdentifierValue(valueForRepeatRule(image.horizontalRule()));
     RefPtr<CSSPrimitiveValue> verticalRepeat;
     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()));
+    return cssValuePool.createValue(Pair::create(WTFMove(horizontalRepeat), WTFMove(verticalRepeat)));
 }
 
 static Ref<CSSValue> valueForNinePieceImage(const NinePieceImage& image)
@@ -632,7 +640,7 @@ static Ref<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 Ref<CSSPrimitiveValue> zoomAdjustedPixelValue(double value, const RenderStyle& style)
@@ -679,26 +687,26 @@ static Ref<CSSValue> valueForReflection(const StyleReflection* reflection, const
         break;
     }
 
-    return CSSReflectValue::create(direction.release(), offset.release(), valueForNinePieceImage(reflection->mask()));
+    return CSSReflectValue::create(direction.releaseNonNull(), offset.releaseNonNull(), valueForNinePieceImage(reflection->mask()));
 }
 
-static Ref<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::singleton().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::singleton().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 RefPtr<CSSValue> positionOffsetValue(RenderStyle& style, CSSPropertyID propertyID)
+static RefPtr<CSSValue> positionOffsetValue(const RenderStyle& style, CSSPropertyID propertyID)
 {
     Length length;
     switch (propertyID) {
@@ -735,12 +743,12 @@ static RefPtr<CSSValue> positionOffsetValue(RenderStyle& style, CSSPropertyID pr
     return CSSValuePool::singleton().createIdentifierValue(CSSValueAuto);
 }
 
-RefPtr<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::singleton().createColorValue(style->color().rgb());
-    return CSSValuePool::singleton().createColorValue(color.rgb());
+        return CSSValuePool::singleton().createColorValue(style->color());
+    return CSSValuePool::singleton().createColorValue(color);
 }
 
 static Ref<CSSPrimitiveValue> percentageOrZoomAdjustedValue(Length length, const RenderStyle& style)
@@ -759,39 +767,38 @@ static Ref<CSSPrimitiveValue> autoOrZoomAdjustedValue(Length length, const Rende
     return zoomAdjustedPixelValue(valueForLength(length, 0), style);
 }
 
-static Ref<CSSValueList> getBorderRadiusCornerValues(const LengthSize& radius, const RenderStyle& style)
+static Ref<CSSValueList> borderRadiusCornerValues(const LengthSize& radius, const RenderStyle& style)
 {
     auto list = CSSValueList::createSpaceSeparated();
-    list.get().append(percentageOrZoomAdjustedValue(radius.width(), style));
-    list.get().append(percentageOrZoomAdjustedValue(radius.height(), style));
+    list->append(percentageOrZoomAdjustedValue(radius.width, style));
+    list->append(percentageOrZoomAdjustedValue(radius.height, style));
     return list;
 }
 
-static Ref<CSSValue> getBorderRadiusCornerValue(const LengthSize& radius, const RenderStyle& style)
+static Ref<CSSValue> borderRadiusCornerValue(const LengthSize& radius, const RenderStyle& style)
 {
-    if (radius.width() == radius.height())
-        return percentageOrZoomAdjustedValue(radius.width(), style);
-
-    return getBorderRadiusCornerValues(radius, style);
+    if (radius.width == radius.height)
+        return percentageOrZoomAdjustedValue(radius.width, style);
+    return borderRadiusCornerValues(radius, style);
 }
 
-static Ref<CSSValueList> getBorderRadiusShorthandValue(const RenderStyle& style)
+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);
-    RefPtr<CSSValueList> topRightRadius = getBorderRadiusCornerValues(style.borderTopRightRadius(), style);
-    RefPtr<CSSValueList> bottomRightRadius = getBorderRadiusCornerValues(style.borderBottomRightRadius(), style);
-    RefPtr<CSSValueList> bottomLeftRadius = getBorderRadiusCornerValues(style.borderBottomLeftRadius(), style);
+    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();
+    auto horizontalRadii = CSSValueList::createSpaceSeparated();
     horizontalRadii->append(*topLeftRadius->item(0));
     if (showHorizontalTopRight)
         horizontalRadii->append(*topRightRadius->item(0));
@@ -800,9 +807,9 @@ static Ref<CSSValueList> getBorderRadiusShorthandValue(const RenderStyle& style)
     if (showHorizontalBottomLeft)
         horizontalRadii->append(*bottomLeftRadius->item(0));
 
-    list.get().append(horizontalRadii.releaseNonNull());
+    list->append(WTFMove(horizontalRadii));
 
-    RefPtr<CSSValueList> verticalRadiiList = CSSValueList::createSpaceSeparated();
+    auto verticalRadiiList = CSSValueList::createSpaceSeparated();
     verticalRadiiList->append(*topLeftRadius->item(1));
     if (showVerticalTopRight)
         verticalRadiiList->append(*topRightRadius->item(1));
@@ -811,8 +818,8 @@ static Ref<CSSValueList> getBorderRadiusShorthandValue(const RenderStyle& style)
     if (showVerticalBottomLeft)
         verticalRadiiList->append(*bottomLeftRadius->item(1));
 
-    if (!verticalRadiiList->equals(downcast<CSSValueList>(*list.get().item(0))))
-        list.get().append(verticalRadiiList.releaseNonNull());
+    if (!verticalRadiiList->equals(downcast<CSSValueList>(*list->item(0))))
+        list->append(WTFMove(verticalRadiiList));
 
     return list;
 }
@@ -826,12 +833,12 @@ static LayoutRect sizingBox(RenderObject& renderer)
     return box.style().boxSizing() == BORDER_BOX ? box.borderBoxRect() : box.computedCSSContentBoxRect();
 }
 
-static Ref<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));
@@ -840,7 +847,7 @@ static Ref<WebKitCSSTransformValue> matrixTransformValue(const TransformationMat
         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));
@@ -881,8 +888,8 @@ static Ref<CSSValue> computedTransform(RenderObject* renderer, const RenderStyle
 
     // 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 WTF::move(list);
+    list->append(matrixTransformValue(transform, style));
+    return WTFMove(list);
 }
 
 static inline Ref<CSSPrimitiveValue> adjustLengthForZoom(double length, const RenderStyle& style, AdjustPixelValuesForComputedStyle adjust)
@@ -903,15 +910,15 @@ Ref<CSSValue> ComputedStyleExtractor::valueForShadow(const ShadowData* shadow, C
 
     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.get().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 WTF::move(list);
+    return WTFMove(list);
 }
 
 Ref<CSSValue> ComputedStyleExtractor::valueForFilter(const RenderStyle& style, const FilterOperations& filterOperations, AdjustPixelValuesForComputedStyle adjust)
@@ -922,91 +929,80 @@ Ref<CSSValue> ComputedStyleExtractor::valueForFilter(const RenderStyle& style, c
 
     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;
-        switch (filterOperation.type()) {
-        case FilterOperation::REFERENCE: {
+
+        if (filterOperation.type() == FilterOperation::REFERENCE) {
             ReferenceFilterOperation& referenceOperation = downcast<ReferenceFilterOperation>(filterOperation);
-            filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::ReferenceFilterOperation);
-            filterValue->append(cssValuePool.createValue(referenceOperation.url(), CSSPrimitiveValue::CSS_URI));
-            break;
-        }
-        case FilterOperation::GRAYSCALE: {
-            BasicColorMatrixFilterOperation& colorMatrixOperation = downcast<BasicColorMatrixFilterOperation>(filterOperation);
-            filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::GrayscaleFilterOperation);
-            filterValue->append(cssValuePool.createValue(colorMatrixOperation.amount(), CSSPrimitiveValue::CSS_NUMBER));
-            break;
-        }
-        case FilterOperation::SEPIA: {
-            BasicColorMatrixFilterOperation& colorMatrixOperation = downcast<BasicColorMatrixFilterOperation>(filterOperation);
-            filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::SepiaFilterOperation);
-            filterValue->append(cssValuePool.createValue(colorMatrixOperation.amount(), CSSPrimitiveValue::CSS_NUMBER));
-            break;
-        }
-        case FilterOperation::SATURATE: {
-            BasicColorMatrixFilterOperation& colorMatrixOperation = downcast<BasicColorMatrixFilterOperation>(filterOperation);
-            filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::SaturateFilterOperation);
-            filterValue->append(cssValuePool.createValue(colorMatrixOperation.amount(), CSSPrimitiveValue::CSS_NUMBER));
-            break;
-        }
-        case FilterOperation::HUE_ROTATE: {
-            BasicColorMatrixFilterOperation& colorMatrixOperation = downcast<BasicColorMatrixFilterOperation>(filterOperation);
-            filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::HueRotateFilterOperation);
-            filterValue->append(cssValuePool.createValue(colorMatrixOperation.amount(), CSSPrimitiveValue::CSS_DEG));
-            break;
-        }
-        case FilterOperation::INVERT: {
-            BasicComponentTransferFilterOperation& componentTransferOperation = downcast<BasicComponentTransferFilterOperation>(filterOperation);
-            filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::InvertFilterOperation);
-            filterValue->append(cssValuePool.createValue(componentTransferOperation.amount(), CSSPrimitiveValue::CSS_NUMBER));
-            break;
-        }
-        case FilterOperation::OPACITY: {
-            BasicComponentTransferFilterOperation& componentTransferOperation = downcast<BasicComponentTransferFilterOperation>(filterOperation);
-            filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::OpacityFilterOperation);
-            filterValue->append(cssValuePool.createValue(componentTransferOperation.amount(), CSSPrimitiveValue::CSS_NUMBER));
-            break;
-        }
-        case FilterOperation::BRIGHTNESS: {
-            BasicComponentTransferFilterOperation& brightnessOperation = downcast<BasicComponentTransferFilterOperation>(filterOperation);
-            filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::BrightnessFilterOperation);
-            filterValue->append(cssValuePool.createValue(brightnessOperation.amount(), CSSPrimitiveValue::CSS_NUMBER));
-            break;
-        }
-        case FilterOperation::CONTRAST: {
-            BasicComponentTransferFilterOperation& contrastOperation = downcast<BasicComponentTransferFilterOperation>(filterOperation);
-            filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::ContrastFilterOperation);
-            filterValue->append(cssValuePool.createValue(contrastOperation.amount(), CSSPrimitiveValue::CSS_NUMBER));
-            break;
-        }
-        case FilterOperation::BLUR: {
-            BlurFilterOperation& blurOperation = downcast<BlurFilterOperation>(filterOperation);
-            filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::BlurFilterOperation);
-            filterValue->append(adjustLengthForZoom(blurOperation.stdDeviation(), style, adjust));
-            break;
-        }
-        case FilterOperation::DROP_SHADOW: {
-            DropShadowFilterOperation& dropShadowOperation = downcast<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;
+            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.releaseNonNull());
     }
-
-    return WTF::move(list);
+    return WTFMove(list);
 }
 
-#if ENABLE(CSS_GRID_LAYOUT)
 static Ref<CSSValue> specifiedValueForGridTrackBreadth(const GridLength& trackBreadth, const RenderStyle& style)
 {
     if (!trackBreadth.isLength())
@@ -1022,73 +1018,162 @@ static Ref<CSSValue> specifiedValueForGridTrackSize(const GridTrackSize& trackSi
 {
     switch (trackSize.type()) {
     case LengthTrackSizing:
-        return specifiedValueForGridTrackBreadth(trackSize.length(), style);
+        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);
-        RefPtr<CSSValueList> minMaxTrackBreadths = CSSValueList::createCommaSeparated();
+        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 CSSFunctionValue::create("minmax(", minMaxTrackBreadths);
+        return WTFMove(minMaxTrackBreadths);
     }
 }
 
-static void addValuesForNamedGridLinesAtIndex(const OrderedNamedGridLinesMap& orderedNamedGridLines, 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
 {
-    const Vector<String>& namedGridLines = orderedNamedGridLines.get(i);
-    if (namedGridLines.isEmpty())
+    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;
 
     auto& cssValuePool = CSSValuePool::singleton();
-    RefPtr<CSSGridLineNamesValue> lineNames = CSSGridLineNamesValue::create();
-    for (auto& name : namedGridLines)
-        lineNames->append(cssValuePool.createValue(name, CSSPrimitiveValue::CSS_STRING));
-    list.append(lineNames.releaseNonNull());
+    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 void addValuesForNamedGridLinesAtIndex(OrderedNamedLinesCollector& collector, unsigned i, CSSValueList& list)
+{
+    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)
 {
-    const Vector<GridTrackSize>& trackSizes = direction == ForColumns ? style.gridColumns() : style.gridRows();
-    const OrderedNamedGridLinesMap& orderedNamedGridLines = direction == ForColumns ? style.orderedNamedGridColumnLines() : style.orderedNamedGridRowLines();
+    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();
+    bool trackListIsEmpty = trackSizes.isEmpty() && autoRepeatTrackSizes.isEmpty();
     if (isRenderGrid && trackListIsEmpty) {
-        // For grids we should consider every listed track, whether implicitly or explicitly created. If we don't have
-        // any explicit track and there are no children then there are no implicit tracks. We cannot simply check the
-        // number of rows/columns in our internal grid representation because it's always at least 1x1 (see r143331).
-        trackListIsEmpty = !downcast<RenderBlock>(*renderer).firstChild();
+        // 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) {
-        ASSERT(orderedNamedGridLines.isEmpty());
+    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();
     unsigned insertionIndex;
     if (isRenderGrid) {
-        const Vector<LayoutUnit>& trackPositions = direction == ForColumns ? downcast<RenderGrid>(*renderer).columnPositions() : downcast<RenderGrid>(*renderer).rowPositions();
-        // There are at least #tracks + 1 grid lines (trackPositions). Apart from that, the grid container can generate implicit grid tracks,
-        // so we'll have more trackPositions than trackSizes as the latter only contain the explicit grid.
-        ASSERT(trackPositions.size() - 1 >= trackSizes.size());
-
-        for (unsigned i = 0; i < trackPositions.size() - 1; ++i) {
-            addValuesForNamedGridLinesAtIndex(orderedNamedGridLines, i, list.get());
-            list.get().append(zoomAdjustedPixelValue(trackPositions[i + 1] - trackPositions[i], style));
+        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));
         }
-        insertionIndex = trackPositions.size() - 1;
+        addValuesForNamedGridLinesAtIndex(collector, numTracks + 1, list.get());
+        insertionIndex = numTracks;
     } else {
         for (unsigned i = 0; i < trackSizes.size(); ++i) {
-            addValuesForNamedGridLinesAtIndex(orderedNamedGridLines, i, list.get());
-            list.get().append(specifiedValueForGridTrackSize(trackSizes[i], style));
+            addValuesForNamedGridLinesAtIndex(collector, i, list.get());
+            list->append(specifiedValueForGridTrackSize(trackSizes[i], style));
         }
         insertionIndex = trackSizes.size();
     }
 
     // Those are the trailing <ident>* allowed in the syntax.
-    addValuesForNamedGridLinesAtIndex(orderedNamedGridLines, insertionIndex, list.get());
-    return WTF::move(list);
+    addValuesForNamedGridLinesAtIndex(collector, insertionIndex, list.get());
+    return WTFMove(list);
 }
 
 static Ref<CSSValue> valueForGridPosition(const GridPosition& position)
@@ -1102,80 +1187,68 @@ static Ref<CSSValue> valueForGridPosition(const GridPosition& position)
 
     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 WTF::move(list);
+        list->append(cssValuePool.createValue(position.namedGridLine(), CSSPrimitiveValue::CSS_STRING));
+    return WTFMove(list);
 }
-#endif
 
 static Ref<CSSValue> createTransitionPropertyValue(const Animation& animation)
 {
-    if (animation.animationMode() == Animation::AnimateNone)
+    switch (animation.animationMode()) {
+    case Animation::AnimateNone:
         return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
-    if (animation.animationMode() == Animation::AnimateAll)
+    case Animation::AnimateAll:
         return CSSValuePool::singleton().createIdentifierValue(CSSValueAll);
-    return CSSValuePool::singleton().createValue(getPropertyNameString(animation.property()), CSSPrimitiveValue::CSS_STRING);
+    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 Ref<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::singleton().createIdentifierValue(CSSValueAll));
+        list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueAll));
     return list;
 }
 
 #if ENABLE(CSS_SCROLL_SNAP)
-static Ref<CSSValueList> scrollSnapDestination(RenderStyle& style, const LengthSize& destination)
-{
-    auto list = CSSValueList::createSpaceSeparated();
-    list.get().append(zoomAdjustedPixelValueForLength(destination.width(), style));
-    list.get().append(zoomAdjustedPixelValueForLength(destination.height(), style));
-    return list;
-}
 
-static Ref<CSSValue> scrollSnapPoints(RenderStyle& style, const ScrollSnapPoints* points)
+static Ref<CSSValueList> valueForScrollSnapType(const ScrollSnapType& type)
 {
-    if (!points)
-        return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
-
-    if (points->usesElements)
-        return CSSValuePool::singleton().createIdentifierValue(CSSValueElements);
-    auto list = CSSValueList::createSpaceSeparated();
-    for (auto& point : points->offsets)
-        list.get().append(zoomAdjustedPixelValueForLength(point, style));
-    if (points->hasRepeat)
-        list.get().append(CSSValuePool::singleton().createValue(LengthRepeat::create(zoomAdjustedPixelValueForLength(points->repeatOffset, style))));
-    return WTF::move(list);
+    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<CSSValue> scrollSnapCoordinates(RenderStyle& style, const Vector<LengthSize>& coordinates)
+static Ref<CSSValueList> valueForScrollSnapAlignment(const ScrollSnapAlign& alignment)
 {
-    if (coordinates.isEmpty())
-        return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
-
-    auto list = CSSValueList::createCommaSeparated();
-
-    for (auto& coordinate : coordinates) {
-        auto pair = CSSValueList::createSpaceSeparated();
-        pair.get().append(zoomAdjustedPixelValueForLength(coordinate.width(), style));
-        pair.get().append(zoomAdjustedPixelValueForLength(coordinate.height(), style));
-        list.get().append(WTF::move(pair));
-    }
-
-    return WTF::move(list);
+    auto value = CSSValueList::createSpaceSeparated();
+    value->append(CSSPrimitiveValue::create(alignment.x));
+    value->append(CSSPrimitiveValue::create(alignment.y));
+    return value;
 }
+
 #endif
 
-static Ref<CSSValue> getWillChangePropertyValue(const WillChangeData* willChangeData)
+static Ref<CSSValue> willChangePropertyValue(const WillChangeData* willChangeData)
 {
     auto& cssValuePool = CSSValuePool::singleton();
     if (!willChangeData || !willChangeData->numFeatures())
@@ -1186,13 +1259,13 @@ static Ref<CSSValue> getWillChangePropertyValue(const WillChangeData* willChange
         WillChangeData::FeaturePropertyPair feature = willChangeData->featureAt(i);
         switch (feature.first) {
         case WillChangeData::ScrollPosition:
-            list.get().append(cssValuePool.createIdentifierValue(CSSValueScrollPosition));
+            list->append(cssValuePool.createIdentifierValue(CSSValueScrollPosition));
             break;
         case WillChangeData::Contents:
-            list.get().append(cssValuePool.createIdentifierValue(CSSValueContents));
+            list->append(cssValuePool.createIdentifierValue(CSSValueContents));
             break;
         case WillChangeData::Property:
-            list.get().append(cssValuePool.createIdentifierValue(feature.second));
+            list->append(cssValuePool.createIdentifierValue(feature.second));
             break;
         case WillChangeData::Invalid:
             ASSERT_NOT_REACHED();
@@ -1200,7 +1273,7 @@ static Ref<CSSValue> getWillChangePropertyValue(const WillChangeData* willChange
         }
     }
 
-    return WTF::move(list);
+    return WTFMove(list);
 }
 
 static inline void appendLigaturesValue(CSSValueList& list, FontVariantLigatures value, CSSValueID yesValue, CSSValueID noValue)
@@ -1231,7 +1304,7 @@ static Ref<CSSValue> fontVariantLigaturesPropertyValue(FontVariantLigatures comm
     appendLigaturesValue(valueList, discretionary, CSSValueDiscretionaryLigatures, CSSValueNoDiscretionaryLigatures);
     appendLigaturesValue(valueList, historical, CSSValueHistoricalLigatures, CSSValueNoHistoricalLigatures);
     appendLigaturesValue(valueList, contextualAlternates, CSSValueContextual, CSSValueNoContextual);
-    return WTF::move(valueList);
+    return WTFMove(valueList);
 }
 
 static Ref<CSSValue> fontVariantPositionPropertyValue(FontVariantPosition position)
@@ -1325,7 +1398,7 @@ static Ref<CSSValue> fontVariantNumericPropertyValue(FontVariantNumericFigure fi
     if (slashedZero == FontVariantNumericSlashedZero::Yes)
         valueList->append(cssValuePool.createIdentifierValue(CSSValueSlashedZero));
 
-    return WTF::move(valueList);
+    return WTFMove(valueList);
 }
 
 static Ref<CSSValue> fontVariantAlternatesPropertyValue(FontVariantAlternates alternates)
@@ -1375,10 +1448,10 @@ static Ref<CSSValue> fontVariantEastAsianPropertyValue(FontVariantEastAsianVaria
     switch (width) {
     case FontVariantEastAsianWidth::Normal:
         break;
-    case FontVariantEastAsianWidth::FullWidth:
+    case FontVariantEastAsianWidth::Full:
         valueList->append(cssValuePool.createIdentifierValue(CSSValueFullWidth));
         break;
-    case FontVariantEastAsianWidth::ProportionalWidth:
+    case FontVariantEastAsianWidth::Proportional:
         valueList->append(cssValuePool.createIdentifierValue(CSSValueProportionalWidth));
         break;
     }
@@ -1386,45 +1459,45 @@ static Ref<CSSValue> fontVariantEastAsianPropertyValue(FontVariantEastAsianVaria
     if (ruby == FontVariantEastAsianRuby::Yes)
         valueList->append(cssValuePool.createIdentifierValue(CSSValueRuby));
 
-    return WTF::move(valueList);
+    return WTFMove(valueList);
 }
 
-static Ref<CSSValueList> getDelayValue(const AnimationList* animList)
+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::initialDelay(), CSSPrimitiveValue::CSS_S));
+        list->append(cssValuePool.createValue(Animation::initialDelay(), CSSPrimitiveValue::CSS_S));
     }
     return list;
 }
 
-static Ref<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::initialDuration(), CSSPrimitiveValue::CSS_S));
+        list->append(cssValuePool.createValue(Animation::initialDuration(), CSSPrimitiveValue::CSS_S));
     }
     return list;
 }
 
-static Ref<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;
@@ -1435,64 +1508,69 @@ static Ref<CSSValue> createTimingFunctionValue(const TimingFunction* timingFunct
                 valueId = CSSValueEaseOut;
                 break;
             default:
-                ASSERT(bezierTimingFunction->timingFunctionPreset() == CubicBezierTimingFunction::EaseInOut);
+                ASSERT(function.timingFunctionPreset() == CubicBezierTimingFunction::EaseInOut);
                 valueId = CSSValueEaseInOut;
                 break;
             }
             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::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);
+        ASSERT(timingFunction.type() == TimingFunction::LinearFunction);
         return CSSValuePool::singleton().createIdentifierValue(CSSValueLinear);
     }
 }
 
-static Ref<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::initialTimingFunction().get()));
+        list->append(createTimingFunctionValue(Animation::initialTimingFunction()));
     return list;
 }
 
 #if ENABLE(CSS_ANIMATIONS_LEVEL_2)
-static Ref<CSSValue> createAnimationTriggerValue(const AnimationTrigger* trigger, const RenderStyle& style)
+
+static Ref<CSSValue> createAnimationTriggerValue(const AnimationTrigger& trigger, const RenderStyle& style)
 {
-    switch (trigger->type()) {
+    switch (trigger.type()) {
     case AnimationTrigger::AnimationTriggerType::ScrollAnimationTriggerType: {
-        auto& scrollAnimationTrigger = downcast<ScrollAnimationTrigger>(*trigger);
+        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);
+        ASSERT(trigger.type() == AnimationTrigger::AnimationTriggerType::AutoAnimationTriggerType);
         return CSSValuePool::singleton().createIdentifierValue(CSSValueAuto);
     }
 }
 
-static Ref<CSSValueList> getAnimationTriggerValue(const AnimationList* animList, const RenderStyle& style)
+static Ref<CSSValueList> animationTriggerValue(const AnimationList* animationList, const RenderStyle& style)
 {
     auto list = CSSValueList::createCommaSeparated();
-    if (animList) {
-        for (size_t i = 0; i < animList->size(); ++i)
-            list.get().append(createAnimationTriggerValue(animList->animation(i).trigger().get(), style));
+    if (animationList) {
+        for (size_t i = 0; i < animationList->size(); ++i)
+            list->append(createAnimationTriggerValue(*animationList->animation(i).trigger(), style));
     } else
-        list.get().append(createAnimationTriggerValue(Animation::initialTrigger().get(), style));
-
+        list->append(createAnimationTriggerValue(Animation::initialTrigger().get(), style));
     return list;
 }
+
 #endif
 
 static Ref<CSSValue> createLineBoxContainValue(unsigned lineBoxContain)
@@ -1502,16 +1580,31 @@ static Ref<CSSValue> createLineBoxContainValue(unsigned lineBoxContain)
     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)
 {
@@ -1552,34 +1645,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 };
 }
 
-RefPtr<CSSPrimitiveValue> ComputedStyleExtractor::getFontSizeCSSValuePreferringKeyword() const
+RefPtr<CSSPrimitiveValue> ComputedStyleExtractor::getFontSizeCSSValuePreferringKeyword()
 {
-    if (!m_node)
+    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 nullptr;
 
     if (CSSValueID sizeIdentifier = style->fontDescription().keywordSizeAsIdentifier())
         return CSSValuePool::singleton().createIdentifierValue(sizeIdentifier);
 
-    return zoomAdjustedPixelValue(style->fontDescription().computedPixelSize(), *style);
+    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;
 
@@ -1601,6 +1693,8 @@ static CSSValueID identifierForFamily(const AtomicString& family)
         return CSSValueSansSerif;
     if (family == serifFamily)
         return CSSValueSerif;
+    if (family == systemUiFamily)
+        return CSSValueSystemUi;
     return CSSValueInvalid;
 }
 
@@ -1615,7 +1709,7 @@ 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));
     if (textDecoration & TextDecorationOverline)
@@ -1629,7 +1723,7 @@ static Ref<CSSValue> renderTextDecorationFlagsToCSSValue(int textDecoration)
 
     if (!list->length())
         return cssValuePool.createIdentifierValue(CSSValueNone);
-    return list.releaseNonNull();
+    return WTFMove(list);
 }
 
 static Ref<CSSValue> renderTextDecorationStyleFlagsToCSSValue(TextDecorationStyle textDecorationStyle)
@@ -1673,7 +1767,7 @@ static Ref<CSSValue> renderEmphasisPositionFlagsToCSSValue(TextEmphasisPosition
     ASSERT(!((textEmphasisPosition & TextEmphasisPositionOver) && (textEmphasisPosition & TextEmphasisPositionUnder)));
     ASSERT(!((textEmphasisPosition & TextEmphasisPositionLeft) && (textEmphasisPosition & TextEmphasisPositionRight)));
     auto& cssValuePool = CSSValuePool::singleton();
-    RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
+    auto list = CSSValueList::createSpaceSeparated();
     if (textEmphasisPosition & TextEmphasisPositionOver)
         list->append(cssValuePool.createIdentifierValue(CSSValueOver));
     if (textEmphasisPosition & TextEmphasisPositionUnder)
@@ -1682,12 +1776,28 @@ static Ref<CSSValue> renderEmphasisPositionFlagsToCSSValue(TextEmphasisPosition
         list->append(cssValuePool.createIdentifierValue(CSSValueLeft));
     if (textEmphasisPosition & TextEmphasisPositionRight)
         list->append(cssValuePool.createIdentifierValue(CSSValueRight));
-
     if (!list->length())
         return cssValuePool.createIdentifierValue(CSSValueNone);
-    return list.releaseNonNull();
+    return WTFMove(list);
 }
 
+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
@@ -1701,9 +1811,9 @@ static Ref<CSSValue> fillRepeatToCSSValue(EFillRepeat xRepeat, EFillRepeat yRepe
         return cssValuePool.createIdentifierValue(CSSValueRepeatY);
 
     auto list = CSSValueList::createSpaceSeparated();
-    list.get().append(cssValuePool.createValue(xRepeat));
-    list.get().append(cssValuePool.createValue(yRepeat));
-    return WTF::move(list);
+    list->append(cssValuePool.createValue(xRepeat));
+    list->append(cssValuePool.createValue(yRepeat));
+    return WTFMove(list);
 }
 
 static Ref<CSSValue> fillSourceTypeToCSSValue(EMaskSourceType type)
@@ -1725,51 +1835,51 @@ static Ref<CSSValue> fillSizeToCSSValue(const FillSize& fillSize, const RenderSt
     if (fillSize.type == Cover)
         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 WTF::move(list);
+    list->append(zoomAdjustedPixelValueForLength(fillSize.size.width, style));
+    list->append(zoomAdjustedPixelValueForLength(fillSize.size.height, style));
+    return WTFMove(list);
 }
 
-static Ref<CSSValue> altTextToCSSValue(const RenderStyle* style)
+static Ref<CSSValue> altTextToCSSValue(const RenderStyle& style)
 {
-    return CSSValuePool::singleton().createValue(style->contentAltText(), CSSPrimitiveValue::CSS_STRING);
+    return CSSValuePool::singleton().createValue(style.contentAltText(), CSSPrimitiveValue::CSS_STRING);
 }
     
-static Ref<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()) {
+    for (auto* contentData = style.contentData(); contentData; contentData = contentData->next()) {
         if (is<CounterContentData>(*contentData))
-            list.get().append(cssValuePool.createValue(downcast<CounterContentData>(*contentData).counter().identifier(), CSSPrimitiveValue::CSS_COUNTER_NAME));
+            list->append(cssValuePool.createValue(downcast<CounterContentData>(*contentData).counter().identifier(), CSSPrimitiveValue::CSS_COUNTER_NAME));
         else if (is<ImageContentData>(*contentData))
-            list.get().append(*downcast<ImageContentData>(*contentData).image().cssValue());
+            list->append(downcast<ImageContentData>(*contentData).image().cssValue());
         else if (is<TextContentData>(*contentData))
-            list.get().append(cssValuePool.createValue(downcast<TextContentData>(*contentData).text(), CSSPrimitiveValue::CSS_STRING));
+            list->append(cssValuePool.createValue(downcast<TextContentData>(*contentData).text(), CSSPrimitiveValue::CSS_STRING));
     }
-    if (style->hasFlowFrom())
-        list.get().append(cssValuePool.createValue(style->regionThread(), CSSPrimitiveValue::CSS_STRING));
+    if (style.hasFlowFrom())
+        list->append(cssValuePool.createValue(style.regionThread(), CSSPrimitiveValue::CSS_STRING));
     return list;
 }
 
-static RefPtr<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 nullptr;
+        return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
 
     auto& cssValuePool = CSSValuePool::singleton();
-    RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
+    auto list = CSSValueList::createSpaceSeparated();
     for (CounterDirectiveMap::const_iterator it = map->begin(); it != map->end(); ++it) {
         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));
     }
-    return list.release();
+    return WTFMove(list);
 }
 
 static void logUnimplementedPropertyID(CSSPropertyID propertyID)
@@ -1781,15 +1891,22 @@ static void logUnimplementedPropertyID(CSSPropertyID propertyID)
     LOG_ERROR("WebKit does not yet implement getComputedStyle for '%s'.", getPropertyName(propertyID));
 }
 
-static Ref<CSSValueList> fontFamilyFromStyle(RenderStyle* style)
+static Ref<CSSValueList> fontFamilyListFromStyle(const RenderStyle& style)
 {
     auto list = CSSValueList::createCommaSeparated();
-    for (unsigned i = 0; i < style->fontCascade().familyCount(); ++i)
-        list.get().append(valueForFamily(style->fontCascade().familyAt(i)));
+    for (unsigned i = 0; i < style.fontCascade().familyCount(); ++i)
+        list->append(valueForFamily(style.fontCascade().familyAt(i)));
     return list;
 }
 
-static Ref<CSSPrimitiveValue> lineHeightFromStyle(RenderStyle& style)
+static Ref<CSSValue> fontFamilyFromStyle(const RenderStyle& style)
+{
+    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.
@@ -1804,69 +1921,269 @@ static Ref<CSSPrimitiveValue> lineHeightFromStyle(RenderStyle& style)
     return zoomAdjustedPixelValue(floatValueForLength(length, 0), style);
 }
 
-static Ref<CSSPrimitiveValue> fontSizeFromStyle(RenderStyle& style)
+static Ref<CSSPrimitiveValue> fontSizeFromStyle(const RenderStyle& style)
+{
+    return zoomAdjustedPixelValue(style.fontDescription().computedSize(), style);
+}
+
+Ref<CSSPrimitiveValue> ComputedStyleExtractor::fontNonKeywordWeightFromStyleValue(FontSelectionValue weight)
+{
+    return CSSValuePool::singleton().createValue(static_cast<float>(weight), CSSPrimitiveValue::CSS_NUMBER);
+}
+
+Ref<CSSPrimitiveValue> ComputedStyleExtractor::fontWeightFromStyleValue(FontSelectionValue weight)
+{
+    if (auto value = fontWeightKeyword(weight))
+        return CSSValuePool::singleton().createIdentifierValue(value.value());
+    return fontNonKeywordWeightFromStyleValue(weight);
+}
+
+static Ref<CSSPrimitiveValue> fontWeightFromStyle(const RenderStyle& style)
+{
+    return ComputedStyleExtractor::fontWeightFromStyleValue(style.fontDescription().weight());
+}
+
+Ref<CSSPrimitiveValue> ComputedStyleExtractor::fontNonKeywordStretchFromStyleValue(FontSelectionValue stretch)
+{
+    return CSSValuePool::singleton().createValue(static_cast<float>(stretch), CSSPrimitiveValue::CSS_PERCENTAGE);
+}
+
+Ref<CSSPrimitiveValue> ComputedStyleExtractor::fontStretchFromStyleValue(FontSelectionValue stretch)
 {
-    return zoomAdjustedPixelValue(style.fontDescription().computedPixelSize(), style);
+    if (auto keyword = fontStretchKeyword(stretch))
+        return CSSValuePool::singleton().createIdentifierValue(keyword.value());
+    return fontNonKeywordStretchFromStyleValue(stretch);
 }
 
-static Ref<CSSPrimitiveValue> fontStyleFromStyle(RenderStyle* style)
+static Ref<CSSPrimitiveValue> fontStretchFromStyle(const RenderStyle& style)
 {
-    if (style->fontDescription().italic())
-        return CSSValuePool::singleton().createIdentifierValue(CSSValueItalic);
-    return CSSValuePool::singleton().createIdentifierValue(CSSValueNormal);
+    return ComputedStyleExtractor::fontStretchFromStyleValue(style.fontDescription().stretch());
 }
 
-static Ref<CSSPrimitiveValue> fontVariantFromStyle(RenderStyle* style)
+Ref<CSSFontStyleValue> ComputedStyleExtractor::fontNonKeywordStyleFromStyleValue(FontSelectionValue italic)
 {
-    if (style->fontDescription().smallCaps())
-        return CSSValuePool::singleton().createIdentifierValue(CSSValueSmallCaps);
-    return CSSValuePool::singleton().createIdentifierValue(CSSValueNormal);
+    return CSSFontStyleValue::create(CSSValuePool::singleton().createIdentifierValue(CSSValueOblique), CSSValuePool::singleton().createValue(static_cast<float>(italic), CSSPrimitiveValue::CSS_DEG));
 }
 
-static Ref<CSSPrimitiveValue> fontWeightFromStyle(RenderStyle* style)
+Ref<CSSFontStyleValue> ComputedStyleExtractor::fontStyleFromStyleValue(FontSelectionValue italic)
 {
-    switch (style->fontDescription().weight()) {
-    case FontWeight100:
-        return CSSValuePool::singleton().createIdentifierValue(CSSValue100);
-    case FontWeight200:
-        return CSSValuePool::singleton().createIdentifierValue(CSSValue200);
-    case FontWeight300:
-        return CSSValuePool::singleton().createIdentifierValue(CSSValue300);
-    case FontWeightNormal:
+    if (auto keyword = fontStyleKeyword(italic))
+        return CSSFontStyleValue::create(CSSValuePool::singleton().createIdentifierValue(keyword.value()));
+    return fontNonKeywordStyleFromStyleValue(italic);
+}
+
+static Ref<CSSFontStyleValue> fontStyleFromStyle(const RenderStyle& style)
+{
+    return ComputedStyleExtractor::fontStyleFromStyleValue(style.fontDescription().italic());
+}
+
+static Ref<CSSValue> fontVariantFromStyle(const RenderStyle& style)
+{
+    if (style.fontDescription().variantSettings().isAllNormal())
         return CSSValuePool::singleton().createIdentifierValue(CSSValueNormal);
-    case FontWeight500:
-        return CSSValuePool::singleton().createIdentifierValue(CSSValue500);
-    case FontWeight600:
-        return CSSValuePool::singleton().createIdentifierValue(CSSValue600);
-    case FontWeightBold:
-        return CSSValuePool::singleton().createIdentifierValue(CSSValueBold);
-    case FontWeight800:
-        return CSSValuePool::singleton().createIdentifierValue(CSSValue800);
-    case FontWeight900:
-        return CSSValuePool::singleton().createIdentifierValue(CSSValue900);
+
+    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;
     }
-    ASSERT_NOT_REACHED();
-    return CSSValuePool::singleton().createIdentifierValue(CSSValueNormal);
+
+    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 Ref<CSSValue> fontSynthesisFromStyle(RenderStyle& style)
+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.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueStyle));
+        list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueStyle));
     if (style.fontDescription().fontSynthesis() & FontSynthesisWeight)
-        list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueWeight));
-    return Ref<CSSValue>(list.get());
+        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 RefPtr<CSSValue> zoomAdjustedPaddingOrMarginPixelValue(RenderStyle& style, RenderObject* renderer)
+static RefPtr<CSSValue> zoomAdjustedPaddingOrMarginPixelValue(const RenderStyle& style, RenderObject* renderer)
 {
     Length unzoomzedLength = (style.*lengthGetter)();
     if (!is<RenderBox>(renderer) || unzoomzedLength.isFixed())
@@ -1875,14 +2192,63 @@ inline RefPtr<CSSValue> zoomAdjustedPaddingOrMarginPixelValue(RenderStyle& 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 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 bool isLayoutDependent(CSSPropertyID propertyID, RenderStyle* style, RenderObject* renderer)
+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:
@@ -1923,123 +2289,159 @@ static bool isLayoutDependent(CSSPropertyID propertyID, RenderStyle* style, Rend
         return paddingOrMarginIsRendererDependent<&RenderStyle::paddingBottom>(style, renderer);
     case CSSPropertyPaddingLeft:
         return paddingOrMarginIsRendererDependent<&RenderStyle::paddingLeft>(style, renderer); 
-#if ENABLE(CSS_GRID_LAYOUT)
-    case CSSPropertyWebkitGridTemplateColumns:
-    case CSSPropertyWebkitGridTemplateRows:
-    case CSSPropertyWebkitGridTemplate:
-    case CSSPropertyWebkitGrid:
+    case CSSPropertyGridTemplateColumns:
+    case CSSPropertyGridTemplateRows:
+    case CSSPropertyGridTemplate:
+    case CSSPropertyGrid:
         return renderer && renderer->isRenderGrid();
-#endif
     default:
         return false;
     }
 }
 
-Node* ComputedStyleExtractor::styledNode() const
+Element* ComputedStyleExtractor::styledElement()
 {
-    if (!m_node)
+    if (!m_element)
         return nullptr;
-    if (!is<Element>(*m_node))
-        return m_node.get();
-    Element& element = downcast<Element>(*m_node);
     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();
 }
 
-static ItemPosition resolveContainerAlignmentAuto(ItemPosition position, RenderObject* element)
+static StyleSelfAlignmentData resolveLegacyJustifyItems(const StyleSelfAlignmentData& data)
 {
-    if (position != ItemPositionAuto || !element)
-        return position;
-
-    return element->style().isDisplayFlexibleOrGridBox() ? ItemPositionStretch : ItemPositionStart;
+    if (data.positionType() == LegacyPosition)
+        return { data.position(), OverflowAlignmentDefault };
+    return data;
 }
 
-static ItemPosition resolveSelfAlignmentAuto(ItemPosition position, OverflowAlignment& overflow, RenderObject* element)
+static StyleSelfAlignmentData resolveJustifyItemsAuto(const StyleSelfAlignmentData& data, Node* parent)
 {
-    if (position != ItemPositionAuto || !element || element->isOutOfFlowPositioned())
-        return position;
+    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 };
+}
 
-    RenderBlock* parent = element->containingBlock();
-    if (!parent)
-        return ItemPositionStart;
+static StyleSelfAlignmentData resolveJustifySelfAuto(const StyleSelfAlignmentData& data, Node* parent)
+{
+    if (data.position() != ItemPositionAuto)
+        return data;
 
-    overflow = parent->style().alignItemsOverflowAlignment();
-    return resolveContainerAlignmentAuto(parent->style().alignItemsPosition(), parent);
+    // 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 void resolveContentAlignmentAuto(ContentPosition& position, ContentDistributionType& distribution, RenderObject* element)
+static StyleSelfAlignmentData resolveAlignSelfAuto(const StyleSelfAlignmentData& data, Node* parent)
 {
-    if (position != ContentPositionAuto || distribution != ContentDistributionDefault || !element)
-        return;
+    if (data.position() != ItemPositionAuto)
+        return data;
 
-    // Even that both align-content and justify-content 'auto' values are resolved to 'stretch'
-    // in case of flexbox containers, 'stretch' value in justify-content will behave like 'flex-start'. 
-    if (element->style().isDisplayFlexibleBox())
-        distribution = ContentDistributionStretch;
-    else
-        position = ContentPositionStart;
+    // 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;
+    default:
+        return false;
+    }
 }
 
 RefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropertyID propertyID, EUpdateLayout updateLayout) const
 {
-    return ComputedStyleExtractor(m_node, m_allowVisitedStyle, m_pseudoElementSpecifier).propertyValue(propertyID, updateLayout);
+    return ComputedStyleExtractor(m_element.ptr(), m_allowVisitedStyle, m_pseudoElementSpecifier).propertyValue(propertyID, updateLayout);
 }
 
 Ref<MutableStyleProperties> CSSComputedStyleDeclaration::copyProperties() const
 {
-    return ComputedStyleExtractor(m_node, m_allowVisitedStyle, m_pseudoElementSpecifier).copyProperties();
+    return ComputedStyleExtractor(m_element.ptr(), m_allowVisitedStyle, m_pseudoElementSpecifier).copyProperties();
 }
 
-static inline bool nodeOrItsAncestorNeedsStyleRecalc(const Node& node)
+static inline bool hasValidStyleForProperty(Element& element, CSSPropertyID propertyID)
 {
-    if (node.needsStyleRecalc())
+    if (element.styleValidity() != Style::Validity::Valid)
+        return false;
+    if (element.document().hasPendingForcedStyleRecalc())
+        return false;
+    if (!element.document().childNeedsStyleRecalc())
         return true;
 
-    const Node* currentNode = &node;
-    const Element* ancestor = currentNode->parentOrShadowHostElement();
-    while (ancestor) {
-        if (ancestor->needsStyleRecalc())
-            return true;
+    bool isInherited = CSSProperty::isInheritedProperty(propertyID) || isImplicitlyInheritedGridOrFlexProperty(propertyID);
+    bool maybeExplicitlyInherited = !isInherited;
 
-        if (ancestor->directChildNeedsStyleRecalc() && currentNode->styleIsAffectedByPreviousSibling())
-            return true;
+    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;
 
-        currentNode = ancestor;
-        ancestor = currentNode->parentOrShadowHostElement();
+        currentElement = &ancestor;
     }
-    return false;
+
+    return true;
 }
 
-static inline bool updateStyleIfNeededForNode(const Node& node)
+static bool updateStyleIfNeededForProperty(Element& element, CSSPropertyID propertyID)
 {
-    Document& document = node.document();
-    if (!document.hasPendingForcedStyleRecalc() && !(document.childNeedsStyleRecalc() && nodeOrItsAncestorNeedsStyleRecalc(node)))
+    auto& document = element.document();
+
+    document.styleScope().flushPendingUpdate();
+
+    if (hasValidStyleForProperty(element, propertyID))
         return false;
+
     document.updateStyleIfNeeded();
     return true;
 }
 
-static inline RefPtr<RenderStyle> computeRenderStyleForProperty(Node* styledNode, PseudoId pseudoElementSpecifier, CSSPropertyID propertyID)
+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)) {
-        RefPtr<RenderStyle> style = renderer->animation().getAnimatedStyleForRenderer(downcast<RenderElement>(*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;
+        return ownedStyle.get();
     }
 
-    return styledNode->computedStyle(styledNode->isPseudoElement() ? NOPSEUDO : pseudoElementSpecifier);
+    return element.computedStyle(element.isPseudoElement() ? NOPSEUDO : pseudoElementSpecifier);
 }
 
-#if ENABLE(CSS_SHAPES)
 static Ref<CSSValue> shapePropertyValue(const RenderStyle& style, const ShapeValue* shapeValue)
 {
     if (!shapeValue)
@@ -2050,105 +2452,208 @@ static Ref<CSSValue> shapePropertyValue(const RenderStyle& style, const ShapeVal
 
     if (shapeValue->type() == ShapeValue::Type::Image) {
         if (shapeValue->image())
-            return *shapeValue->image()->cssValue();
+            return shapeValue->image()->cssValue();
         return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
     }
 
     ASSERT(shapeValue->type() == ShapeValue::Type::Shape);
 
-    RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
+    auto list = CSSValueList::createSpaceSeparated();
     list->append(valueForBasicShape(style, *shapeValue->shape()));
     if (shapeValue->cssBox() != BoxMissing)
         list->append(CSSValuePool::singleton().createValue(shapeValue->cssBox()));
-    return list.releaseNonNull();
+    return WTFMove(list);
 }
-#endif
 
-static RefPtr<CSSValueList> valueForItemPositionWithOverflowAlignment(ItemPosition itemPosition, OverflowAlignment overflowAlignment, ItemPositionType positionType)
+static Ref<CSSValueList> valueForItemPositionWithOverflowAlignment(const StyleSelfAlignmentData& data)
 {
     auto& cssValuePool = CSSValuePool::singleton();
-    RefPtr<CSSValueList> result = CSSValueList::createSpaceSeparated();
-    if (positionType == LegacyPosition)
-        result->append(CSSPrimitiveValue::createIdentifier(CSSValueLegacy));
-    result->append(cssValuePool.createValue(itemPosition));
-    if (overflowAlignment != OverflowAlignmentDefault)
-        result->append(cssValuePool.createValue(overflowAlignment));
+    auto result = CSSValueList::createSpaceSeparated();
+    if (data.positionType() == LegacyPosition)
+        result->append(cssValuePool.createIdentifierValue(CSSValueLegacy));
+    if (data.position() == ItemPositionBaseline)
+        result->append(cssValuePool.createIdentifierValue(CSSValueBaseline));
+    else if (data.position() == ItemPositionLastBaseline) {
+        result->append(cssValuePool.createIdentifierValue(CSSValueLast));
+        result->append(cssValuePool.createIdentifierValue(CSSValueBaseline));
+    } else
+        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;
 }
 
-static RefPtr<CSSValueList> valueForContentPositionAndDistributionWithOverflowAlignment(ContentPosition position, ContentDistributionType distribution, OverflowAlignment overflowAlignment)
+static Ref<CSSValueList> valueForContentPositionAndDistributionWithOverflowAlignment(const StyleContentAlignmentData& data, CSSValueID normalBehaviorValueID)
 {
-    RefPtr<CSSValueList> result = CSSValueList::createSpaceSeparated();
-    if (distribution != ContentDistributionDefault)
-        result->append(CSSPrimitiveValue::create(distribution));
-    if (distribution == ContentDistributionDefault || position != ContentPositionAuto)
-        result->append(CSSPrimitiveValue::create(position));
-    if ((position >= ContentPositionCenter || distribution != ContentDistributionDefault) && overflowAlignment != OverflowAlignmentDefault)
-        result->append(CSSPrimitiveValue::create(overflowAlignment));
+    auto& cssValuePool = CSSValuePool::singleton();
+    auto result = CSSValueList::createSpaceSeparated();
+    // Handle content-distribution values
+    if (data.distribution() != ContentDistributionDefault)
+        result->append(cssValuePool.createValue(data.distribution()));
+
+    bool gridEnabled = false;
+    gridEnabled = RuntimeEnabledFeatures::sharedFeatures().isCSSGridLayoutEnabled();
+
+    // Handle content-position values (either as fallback or actual value)
+    switch (data.position()) {
+    case ContentPositionNormal:
+        // Handle 'normal' value, not valid as content-distribution fallback.
+        if (data.distribution() == ContentDistributionDefault)
+            result->append(cssValuePool.createIdentifierValue(gridEnabled ? CSSValueNormal : normalBehaviorValueID));
+        break;
+    case ContentPositionLastBaseline:
+        result->append(cssValuePool.createIdentifierValue(CSSValueLast));
+        result->append(cssValuePool.createIdentifierValue(CSSValueBaseline));
+        break;
+    default:
+        result->append(cssValuePool.createValue(data.position()));
+    }
+
+    // Handle overflow-alignment (only allowed for content-position values)
+    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 == PaintOrder::Normal)
+        return CSSPrimitiveValue::createIdentifier(CSSValueNormal);
+    
+    auto paintOrderList = CSSValueList::createSpaceSeparated();
+    switch (paintOrder) {
+    case PaintOrder::Normal:
+        ASSERT_NOT_REACHED();
+        break;
+    case PaintOrder::Fill:
+        paintOrderList->append(CSSPrimitiveValue::createIdentifier(CSSValueFill));
+        break;
+    case PaintOrder::FillMarkers:
+        paintOrderList->append(CSSPrimitiveValue::createIdentifier(CSSValueFill));
+        paintOrderList->append(CSSPrimitiveValue::createIdentifier(CSSValueMarkers));
+        break;
+    case PaintOrder::Stroke:
+        paintOrderList->append(CSSPrimitiveValue::createIdentifier(CSSValueStroke));
+        break;
+    case PaintOrder::StrokeMarkers:
+        paintOrderList->append(CSSPrimitiveValue::createIdentifier(CSSValueStroke));
+        paintOrderList->append(CSSPrimitiveValue::createIdentifier(CSSValueMarkers));
+        break;
+    case PaintOrder::Markers:
+        paintOrderList->append(CSSPrimitiveValue::createIdentifier(CSSValueMarkers));
+        break;
+    case PaintOrder::MarkersStroke:
+        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) const
+RefPtr<CSSValue> ComputedStyleExtractor::customPropertyValue(const String& propertyName)
 {
-    Node* styledNode = this->styledNode();
-    if (!styledNode)
+    Element* styledElement = this->styledElement();
+    if (!styledElement)
         return nullptr;
+    
+    if (updateStyleIfNeededForProperty(*styledElement, CSSPropertyCustom)) {
+        // Style update may change styledElement() to PseudoElement or back.
+        styledElement = this->styledElement();
+    }
 
-    RefPtr<RenderStyle> style = computeRenderStyleForProperty(styledNode, m_pseudoElementSpecifier, CSSPropertyCustom);
-    if (!style || !style->hasCustomProperty(propertyName))
+    std::unique_ptr<RenderStyle> ownedStyle;
+    auto* style = computeRenderStyleForProperty(*styledElement, m_pseudoElementSpecifier, CSSPropertyCustom, ownedStyle);
+    if (!style)
         return nullptr;
 
-    String result = style->getCustomPropertyValue(propertyName);
-    return CSSCustomPropertyValue::create(propertyName, result);
+    return style->customProperties().get(propertyName);
 }
 
-RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID, EUpdateLayout updateLayout) const
+String ComputedStyleExtractor::customPropertyText(const String& propertyName)
 {
-    Node* styledNode = this->styledNode();
-    if (!styledNode)
+    RefPtr<CSSValue> propertyValue = customPropertyValue(propertyName);
+    return propertyValue ? propertyValue->cssText() : emptyString();
+}
+
+static Ref<CSSFontValue> fontShorthandValueForSelectionProperties(const FontDescription& fontDescription)
+{
+    auto computedFont = CSSFontValue::create();
+
+    auto variantCaps = fontDescription.variantCaps();
+    if (variantCaps == FontVariantCaps::Small)
+        computedFont->variant = CSSValuePool::singleton().createIdentifierValue(CSSValueSmallCaps);
+    else if (variantCaps == FontVariantCaps::Normal)
+        computedFont->variant = CSSValuePool::singleton().createIdentifierValue(CSSValueNormal);
+    else
+        return CSSFontValue::create();
+
+    auto weight = fontDescription.weight();
+    if (auto value = fontWeightKeyword(weight))
+        computedFont->weight = CSSValuePool::singleton().createIdentifierValue(value.value());
+    else if (isCSS21Weight(weight))
+        computedFont->weight = CSSValuePool::singleton().createValue(static_cast<float>(weight), CSSPrimitiveValue::CSS_NUMBER);
+    else
+        return CSSFontValue::create();
+
+    if (auto keyword = fontStretchKeyword(fontDescription.stretch()))
+        computedFont->stretch = CSSValuePool::singleton().createIdentifierValue(keyword.value());
+    else
+        return CSSFontValue::create();
+
+    if (auto italic = fontStyleKeyword(fontDescription.italic()))
+        computedFont->style = CSSFontStyleValue::create(CSSValuePool::singleton().createIdentifierValue(italic.value()));
+    else
+        return CSSFontValue::create();
+
+    return computedFont;
+}
+
+RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID, EUpdateLayout updateLayout)
+{
+    auto* styledElement = this->styledElement();
+    if (!styledElement)
         return nullptr;
 
-    RefPtr<RenderStyle> style;
+    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 (updateStyleIfNeededForNode(*styledNode)) {
-            // 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 (propertyID == CSSPropertyDisplay && !renderer && is<SVGElement>(*styledNode) && !downcast<SVGElement>(*styledNode).isValid())
+        if (propertyID == CSSPropertyDisplay && !renderer && is<SVGElement>(*styledElement) && !downcast<SVGElement>(*styledElement).isValid())
             return nullptr;
 
-        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());
+        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)
@@ -2162,91 +2667,72 @@ RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
             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();
-
+            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());
+                    list->append(currLayer->image()->cssValue());
                 else
                     list->append(cssValuePool.createIdentifierValue(CSSValueNone));
             }
-            return list;
+            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);
-
-            RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
-            for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
+            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 list;
+            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;
+            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;
+            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())
+            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 list;
+            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())
+            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 list;
+            return WTFMove(list);
         }
         case CSSPropertyBackgroundClip:
         case CSSPropertyBackgroundOrigin:
@@ -2254,65 +2740,59 @@ RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
         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;
+            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())
+            auto& layers = propertyID == CSSPropertyWebkitMaskPosition ? style->maskLayers() : style->backgroundLayers();
+            if (!layers.next())
                 return createPositionListForLayer(propertyID, layers, *style);
 
-            RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
-            for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
-                list->append(createPositionListForLayer(propertyID, currLayer, *style));
-            return list;
+            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())
+            auto list = CSSValueList::createCommaSeparated();
+            for (auto* currLayer = &layers; currLayer; currLayer = currLayer->next())
                 list->append(cssValuePool.createValue(currLayer->xPosition()));
 
-            return list;
+            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())
+            auto list = CSSValueList::createCommaSeparated();
+            for (auto* currLayer = &layers; currLayer; currLayer = currLayer->next())
                 list->append(cssValuePool.createValue(currLayer->yPosition()));
 
-            return list;
+            return WTFMove(list);
         }
         case CSSPropertyBorderCollapse:
             if (style->borderCollapse())
                 return cssValuePool.createIdentifierValue(CSSValueCollapse);
             return cssValuePool.createIdentifierValue(CSSValueSeparate);
         case CSSPropertyBorderSpacing: {
-            RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
+            auto list = CSSValueList::createSpaceSeparated();
             list->append(zoomAdjustedPixelValue(style->horizontalBorderSpacing(), *style));
             list->append(zoomAdjustedPixelValue(style->verticalBorderSpacing(), *style));
-            return list;
+            return WTFMove(list);
         }
         case CSSPropertyWebkitBorderHorizontalSpacing:
             return zoomAdjustedPixelValue(style->horizontalBorderSpacing(), *style);
@@ -2323,13 +2803,13 @@ RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
                 return style->borderImageSource()->cssValue();
             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());
         case CSSPropertyBorderRightStyle:
@@ -2380,7 +2860,7 @@ RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
         case CSSPropertyClear:
             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());
         case CSSPropertyWebkitColumnAxis:
@@ -2395,10 +2875,10 @@ RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
             if (style->hasNormalColumnGap())
                 return cssValuePool.createIdentifierValue(CSSValueNormal);
             return zoomAdjustedPixelValue(style->columnGap(), *style);
-        case CSSPropertyColumnProgression:
+        case CSSPropertyWebkitColumnProgression:
             return cssValuePool.createValue(style->columnProgression());
         case CSSPropertyColumnRuleColor:
-            return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyOutlineColor).rgb()) : currentColorOrValidColor(style.get(), style->columnRuleColor());
+            return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyOutlineColor)) : currentColorOrValidColor(style, style->columnRuleColor());
         case CSSPropertyColumnRuleStyle:
             return cssValuePool.createValue(style->columnRuleStyle());
         case CSSPropertyColumnRuleWidth:
@@ -2406,11 +2886,11 @@ RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
         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());
+            return cssValuePool.createValue(convertToColumnBreak(style->breakInside()));
         case CSSPropertyColumnWidth:
             if (style->hasAutoColumnWidth())
                 return cssValuePool.createIdentifierValue(CSSValueAuto);
@@ -2419,27 +2899,27 @@ RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
             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());
+                        list->append(image->cssValue());
             }
             auto value = cssValuePool.createValue(style->cursor());
             if (list) {
-                list->append(WTF::move(value));
+                list->append(WTFMove(value));
                 return list;
             }
-            return WTF::move(value);
+            return WTFMove(value);
         }
 #if ENABLE(CURSOR_VISIBILITY)
         case CSSPropertyWebkitCursorVisibility:
@@ -2451,23 +2931,16 @@ RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
             return cssValuePool.createValue(style->display());
         case CSSPropertyEmptyCells:
             return cssValuePool.createValue(style->emptyCells());
-        case CSSPropertyAlignContent: {
-            ContentPosition position = style->alignContentPosition();
-            ContentDistributionType distribution = style->alignContentDistribution();
-            resolveContentAlignmentAuto(position, distribution, renderer);
-            return valueForContentPositionAndDistributionWithOverflowAlignment(position, distribution, style->alignContentOverflowAlignment());
-        }
+        case CSSPropertyAlignContent:
+            return valueForContentPositionAndDistributionWithOverflowAlignment(style->alignContent(), CSSValueStretch);
         case CSSPropertyAlignItems:
-            return valueForItemPositionWithOverflowAlignment(resolveContainerAlignmentAuto(style->alignItemsPosition(), renderer), style->alignItemsOverflowAlignment(), NonLegacyPosition);
-        case CSSPropertyAlignSelf: {
-            OverflowAlignment overflow = style->alignSelfOverflowAlignment();
-            ItemPosition alignSelf = resolveSelfAlignmentAuto(style->alignSelfPosition(), overflow, renderer);
-            return valueForItemPositionWithOverflowAlignment(alignSelf, overflow, NonLegacyPosition);
-        }
+            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());
+            return cssValuePool.createValue(style->flexBasis(), *style);
         case CSSPropertyFlexDirection:
             return cssValuePool.createValue(style->flexDirection());
         case CSSPropertyFlexFlow:
@@ -2478,19 +2951,16 @@ RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
             return cssValuePool.createValue(style->flexShrink());
         case CSSPropertyFlexWrap:
             return cssValuePool.createValue(style->flexWrap());
-        case CSSPropertyJustifyContent: {
-            ContentPosition position = style->justifyContentPosition();
-            ContentDistributionType distribution = style->justifyContentDistribution();
-            resolveContentAlignmentAuto(position, distribution, renderer);
-            return valueForContentPositionAndDistributionWithOverflowAlignment(position, distribution, style->justifyContentOverflowAlignment());
-        }
+        case CSSPropertyJustifyContent:
+            return valueForContentPositionAndDistributionWithOverflowAlignment(style->justifyContent(), CSSValueFlexStart);
         case CSSPropertyJustifyItems:
-            return valueForItemPositionWithOverflowAlignment(resolveContainerAlignmentAuto(style->justifyItemsPosition(), renderer), style->justifyItemsOverflowAlignment(), style->justifyItemsPositionType());
-        case CSSPropertyJustifySelf: {
-            OverflowAlignment overflow = style->justifySelfOverflowAlignment();
-            ItemPosition justifySelf = resolveSelfAlignmentAuto(style->justifySelfPosition(), overflow, renderer);
-            return valueForItemPositionWithOverflowAlignment(justifySelf, overflow, NonLegacyPosition);
-        }
+            return valueForItemPositionWithOverflowAlignment(resolveJustifyItemsAuto(style->justifyItems(), styledElement->parentNode()));
+        case CSSPropertyJustifySelf:
+            return valueForItemPositionWithOverflowAlignment(resolveJustifySelfAuto(style->justifySelf(), styledElement->parentNode()));
+        case CSSPropertyPlaceContent:
+            return getCSSPropertyValuesForShorthandProperties(placeContentShorthand());
+        case CSSPropertyPlaceItems:
+            return getCSSPropertyValuesForShorthandProperties(placeItemsShorthand());
         case CSSPropertyOrder:
             return cssValuePool.createValue(style->order(), CSSPrimitiveValue::CSS_NUMBER);
         case CSSPropertyFloat:
@@ -2498,45 +2968,50 @@ RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
                 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());
+            auto computedFont = fontShorthandValueForSelectionProperties(style->fontDescription());
             computedFont->size = fontSizeFromStyle(*style);
             computedFont->lineHeight = lineHeightFromStyle(*style);
-            computedFont->family = fontFamilyFromStyle(style.get());
-            return computedFont;
-        }
-        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;
+            computedFont->family = fontFamilyListFromStyle(*style);
+            return WTFMove(computedFont);
         }
+        case CSSPropertyFontFamily:
+            return fontFamilyFromStyle(*style);
         case CSSPropertyFontSize:
             return fontSizeFromStyle(*style);
         case CSSPropertyFontStyle:
-            return fontStyleFromStyle(style.get());
+            return fontStyleFromStyle(*style);
+        case CSSPropertyFontStretch:
+            return fontStretchFromStyle(*style);
         case CSSPropertyFontVariant:
-            return fontVariantFromStyle(style.get());
+            return fontVariantFromStyle(*style);
         case CSSPropertyFontWeight:
-            return fontWeightFromStyle(style.get());
+            return fontWeightFromStyle(*style);
         case CSSPropertyFontSynthesis:
             return fontSynthesisFromStyle(*style);
-        case CSSPropertyWebkitFontFeatureSettings: {
+        case CSSPropertyFontFeatureSettings: {
             const FontFeatureSettings& featureSettings = style->fontDescription().featureSettings();
             if (!featureSettings.size())
                 return cssValuePool.createIdentifierValue(CSSValueNormal);
-            RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
+            auto list = CSSValueList::createCommaSeparated();
             for (auto& feature : featureSettings)
-                list->append(CSSFontFeatureValue::create(FontFeatureTag(feature.tag()), feature.value()));
-            return list;
+                list->append(CSSFontFeatureValue::create(FontTag(feature.tag()), feature.value()));
+            return WTFMove(list);
         }
-#if ENABLE(CSS_GRID_LAYOUT)
-        case CSSPropertyWebkitGridAutoFlow: {
-            RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
+#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);
+        }
+        case CSSPropertyFontOpticalSizing:
+            return cssValuePool.createValue(style->fontDescription().opticalSizing());
+#endif
+        case CSSPropertyGridAutoFlow: {
+            auto list = CSSValueList::createSpaceSeparated();
             ASSERT(style->isGridAutoFlowDirectionRow() || style->isGridAutoFlowDirectionColumn());
             if (style->isGridAutoFlowDirectionRow())
                 list->append(cssValuePool.createIdentifierValue(CSSValueRow));
@@ -2546,51 +3021,54 @@ RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
             if (style->isGridAutoFlowAlgorithmDense())
                 list->append(cssValuePool.createIdentifierValue(CSSValueDense));
 
-            return list;
+            return WTFMove(list);
         }
 
         // Specs mention that getComputedStyle() should return the used value of the property instead of the computed
-        // one for grid-definition-{rows|columns} but not for the grid-auto-{rows|columns} as things like
+        // 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 CSSPropertyWebkitGridAutoColumns:
-            return specifiedValueForGridTrackSize(style->gridAutoColumns(), *style);
-        case CSSPropertyWebkitGridAutoRows:
-            return specifiedValueForGridTrackSize(style->gridAutoRows(), *style);
+        case CSSPropertyGridAutoColumns:
+            return valueForGridTrackSizeList(ForColumns, *style);
+        case CSSPropertyGridAutoRows:
+            return valueForGridTrackSizeList(ForRows, *style);
 
-        case CSSPropertyWebkitGridTemplateColumns:
+        case CSSPropertyGridTemplateColumns:
             return valueForGridTrackList(ForColumns, renderer, *style);
-        case CSSPropertyWebkitGridTemplateRows:
+        case CSSPropertyGridTemplateRows:
             return valueForGridTrackList(ForRows, renderer, *style);
 
-        case CSSPropertyWebkitGridColumnStart:
+        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 CSSPropertyWebkitGridTemplate:
-            return getCSSPropertyValuesForGridShorthand(webkitGridTemplateShorthand());
-        case CSSPropertyWebkitGrid:
-            return getCSSPropertyValuesForGridShorthand(webkitGridShorthand());
-        case CSSPropertyWebkitGridColumn:
-            return getCSSPropertyValuesForGridShorthand(webkitGridColumnShorthand());
-        case CSSPropertyWebkitGridRow:
-            return getCSSPropertyValuesForGridShorthand(webkitGridRowShorthand());
-
-        case CSSPropertyWebkitGridTemplateAreas:
+        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 CSSGridTemplateAreasValue::create(style->namedGridArea(), style->namedGridAreaRowCount(), style->namedGridAreaColumnCount());
-#endif /* ENABLE(CSS_GRID_LAYOUT) */
+        case CSSPropertyGridColumnGap:
+            return zoomAdjustedPixelValueForLength(style->gridColumnGap(), *style);
+        case CSSPropertyGridRowGap:
+            return zoomAdjustedPixelValueForLength(style->gridRowGap(), *style);
+        case CSSPropertyGridGap:
+            return getCSSPropertyValuesForGridShorthand(gridGapShorthand());
         case CSSPropertyHeight:
             if (renderer && !renderer->isRenderSVGModelObject()) {
                 // According to http://www.w3.org/TR/CSS2/visudet.html#the-height-property,
@@ -2702,20 +3180,26 @@ RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
         }
         case CSSPropertyMinHeight:
             if (style->minHeight().isAuto()) {
-                if (isFlexOrGrid(styledNode->parentNode()))
+                if (isFlexOrGrid(styledElement->parentNode()))
                     return cssValuePool.createIdentifierValue(CSSValueAuto);
                 return zoomAdjustedPixelValue(0, *style);
             }
             return zoomAdjustedPixelValueForLength(style->minHeight(), *style);
         case CSSPropertyMinWidth:
             if (style->minWidth().isAuto()) {
-                if (isFlexOrGrid(styledNode->parentNode()))
+                if (isFlexOrGrid(styledElement->parentNode()))
                     return cssValuePool.createIdentifierValue(CSSValueAuto);
                 return zoomAdjustedPixelValue(0, *style);
             }
             return zoomAdjustedPixelValueForLength(style->minWidth(), *style);
         case CSSPropertyObjectFit:
             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);
         case CSSPropertyOrphans:
@@ -2723,7 +3207,7 @@ RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
                 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);
         case CSSPropertyOutlineStyle:
@@ -2749,16 +3233,19 @@ RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
         case CSSPropertyPaddingLeft:
             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 nullptr;
-            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());
         case CSSPropertyRight:
@@ -2784,7 +3271,7 @@ RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
         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:
@@ -2792,9 +3279,9 @@ RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
         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:
@@ -2812,31 +3299,30 @@ RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
             case TextEmphasisMarkCircle:
             case TextEmphasisMarkDoubleCircle:
             case TextEmphasisMarkTriangle:
-            case TextEmphasisMarkSesame: {
-                RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
+            case TextEmphasisMarkSesame:
+                auto list = CSSValueList::createSpaceSeparated();
                 list->append(cssValuePool.createValue(style->textEmphasisFill()));
                 list->append(cssValuePool.createValue(style->textEmphasisMark()));
-                return list;
-            }
+                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);
+            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.releaseNonNull());
+                auto list = CSSValueList::createSpaceSeparated();
+                list->append(WTFMove(textIndent));
                 if (style->textIndentLine() == TextIndentEachLine)
                     list->append(cssValuePool.createIdentifierValue(CSSValueWebkitEachLine));
                 if (style->textIndentType() == TextIndentHanging)
                     list->append(cssValuePool.createIdentifierValue(CSSValueWebkitHanging));
-                return list;
+                return WTFMove(list);
             }
 #endif
-            return textIndent;
+            return WTFMove(textIndent);
         }
         case CSSPropertyTextShadow:
             return valueForShadow(style->textShadow(), propertyID, *style);
@@ -2848,7 +3334,7 @@ RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
             return cssValuePool.createIdentifierValue(CSSValueClip);
         case CSSPropertyWebkitTextSecurity:
             return cssValuePool.createValue(style->textSecurity());
-#if ENABLE(IOS_TEXT_AUTOSIZING)
+#if ENABLE(TEXT_AUTOSIZING)
         case CSSPropertyWebkitTextSizeAdjust:
             if (style->textSizeAdjust().isAuto())
                 return cssValuePool.createIdentifierValue(CSSValueAuto);
@@ -2857,7 +3343,7 @@ RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
             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);
         case CSSPropertyTextTransform:
@@ -2909,15 +3395,14 @@ RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
             }
             return zoomAdjustedPixelValueForLength(style->width(), *style);
         case CSSPropertyWillChange:
-            return getWillChangePropertyValue(style->willChange());
-            break;
+            return willChangePropertyValue(style->willChange());
         case CSSPropertyWordBreak:
             return cssValuePool.createValue(style->wordBreak());
         case CSSPropertyWordSpacing:
             return zoomAdjustedPixelValue(style->fontCascade().wordSpacing(), *style);
         case CSSPropertyWordWrap:
             return cssValuePool.createValue(style->overflowWrap());
-        case CSSPropertyWebkitLineBreak:
+        case CSSPropertyLineBreak:
             return cssValuePool.createValue(style->lineBreak());
         case CSSPropertyWebkitNbspMode:
             return cssValuePool.createValue(style->nbspMode());
@@ -2978,15 +3463,13 @@ RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
                     firstRegion = region.copyRef();
                 previousRegion = region.ptr();
             }
-            return cssValuePool.createValue(WTF::move(firstRegion));
+            return cssValuePool.createValue(WTFMove(firstRegion));
         }
 #endif
         case CSSPropertyAnimationDelay:
-        case CSSPropertyWebkitAnimationDelay:
-            return getDelayValue(style->animations());
-        case CSSPropertyAnimationDirection:
-        case CSSPropertyWebkitAnimationDirection: {
-            RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
+            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) {
@@ -3007,14 +3490,12 @@ RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
                 }
             } else
                 list->append(cssValuePool.createIdentifierValue(CSSValueNormal));
-            return list;
+            return WTFMove(list);
         }
         case CSSPropertyAnimationDuration:
-        case CSSPropertyWebkitAnimationDuration:
-            return getDurationValue(style->animations());
-        case CSSPropertyAnimationFillMode:
-        case CSSPropertyWebkitAnimationFillMode: {
-            RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
+            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) {
@@ -3035,11 +3516,10 @@ RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
                 }
             } else
                 list->append(cssValuePool.createIdentifierValue(CSSValueNone));
-            return list;
+            return WTFMove(list);
         }
-        case CSSPropertyAnimationIterationCount:
-        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) {
@@ -3051,22 +3531,20 @@ RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
                 }
             } else
                 list->append(cssValuePool.createValue(Animation::initialIterationCount(), CSSPrimitiveValue::CSS_NUMBER));
-            return list;
+            return WTFMove(list);
         }
-        case CSSPropertyAnimationName:
-        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));
             } else
                 list->append(cssValuePool.createIdentifierValue(CSSValueNone));
-            return list;
+            return WTFMove(list);
         }
-        case CSSPropertyAnimationPlayState:
-        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) {
@@ -3078,14 +3556,13 @@ RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
                 }
             } else
                 list->append(cssValuePool.createIdentifierValue(CSSValueRunning));
-            return list;
+            return WTFMove(list);
         }
         case CSSPropertyAnimationTimingFunction:
-        case CSSPropertyWebkitAnimationTimingFunction:
-            return getTimingFunctionValue(style->animations());
+            return timingFunctionValue(style->animations());
 #if ENABLE(CSS_ANIMATIONS_LEVEL_2)
         case CSSPropertyWebkitAnimationTrigger:
-            return getAnimationTriggerValue(style->animations(), *style);
+            return animationTriggerValue(style->animations(), *style);
 #endif
         case CSSPropertyWebkitAppearance:
             return cssValuePool.createValue(style->appearance());
@@ -3127,9 +3604,9 @@ RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
             // Not a real style property -- used by the editing engine -- so has no computed value.
             break;
         case CSSPropertyWebkitInitialLetter: {
-            RefPtr<CSSPrimitiveValue> drop = !style->initialLetterDrop() ? cssValuePool.createIdentifierValue(CSSValueNormal) : cssValuePool.createValue(style->initialLetterDrop(), CSSPrimitiveValue::CSS_NUMBER);
-            RefPtr<CSSPrimitiveValue> size = !style->initialLetterHeight() ? cssValuePool.createIdentifierValue(CSSValueNormal) : cssValuePool.createValue(style->initialLetterHeight(), CSSPrimitiveValue::CSS_NUMBER);
-            return cssValuePool.createValue(Pair::create(drop.release(), size.release()));
+            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:
@@ -3148,7 +3625,7 @@ RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
                 return cssValuePool.createIdentifierValue(CSSValueNone);
             return zoomAdjustedPixelValue(style->perspective(), *style);
         case CSSPropertyPerspectiveOrigin: {
-            RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
+            auto list = CSSValueList::createSpaceSeparated();
             if (renderer) {
                 LayoutRect box;
                 if (is<RenderBox>(*renderer))
@@ -3162,13 +3639,15 @@ RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
                 list->append(zoomAdjustedPixelValueForLength(style->perspectiveOriginY(), *style));
 
             }
-            return list;
+            return WTFMove(list);
         }
         case CSSPropertyWebkitRtlOrdering:
             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:
@@ -3179,13 +3658,13 @@ RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
         case CSSPropertyWebkitUserSelect:
             return cssValuePool.createValue(style->userSelect());
         case CSSPropertyBorderBottomLeftRadius:
-            return getBorderRadiusCornerValue(style->borderBottomLeftRadius(), *style);
+            return borderRadiusCornerValue(style->borderBottomLeftRadius(), *style);
         case CSSPropertyBorderBottomRightRadius:
-            return getBorderRadiusCornerValue(style->borderBottomRightRadius(), *style);
+            return borderRadiusCornerValue(style->borderBottomRightRadius(), *style);
         case CSSPropertyBorderTopLeftRadius:
-            return getBorderRadiusCornerValue(style->borderTopLeftRadius(), *style);
+            return borderRadiusCornerValue(style->borderTopLeftRadius(), *style);
         case CSSPropertyBorderTopRightRadius:
-            return getBorderRadiusCornerValue(style->borderTopRightRadius(), *style);
+            return borderRadiusCornerValue(style->borderTopRightRadius(), *style);
         case CSSPropertyClip: {
             if (!style->hasClip())
                 return cssValuePool.createIdentifierValue(CSSValueAuto);
@@ -3194,14 +3673,14 @@ RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
             rect->setRight(autoOrZoomAdjustedValue(style->clip().right(), *style));
             rect->setBottom(autoOrZoomAdjustedValue(style->clip().bottom(), *style));
             rect->setLeft(autoOrZoomAdjustedValue(style->clip().left(), *style));
-            return cssValuePool.createValue(WTF::move(rect));
+            return cssValuePool.createValue(WTFMove(rect));
         }
         case CSSPropertySpeak:
             return cssValuePool.createValue(style->speak());
         case CSSPropertyTransform:
             return computedTransform(renderer, *style);
         case CSSPropertyTransformOrigin: {
-            RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
+            auto list = CSSValueList::createSpaceSeparated();
             if (renderer) {
                 LayoutRect box;
                 if (is<RenderBox>(*renderer))
@@ -3217,47 +3696,41 @@ RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
                 if (style->transformOriginZ() != 0)
                     list->append(zoomAdjustedPixelValue(style->transformOriginZ(), *style));
             }
-            return list;
+            return WTFMove(list);
         }
         case CSSPropertyTransformStyle:
         case CSSPropertyWebkitTransformStyle:
             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(createTimingFunctionValue(*animation.timingFunction()));
                     list->append(cssValuePool.createValue(animation.delay(), CSSPrimitiveValue::CSS_S));
-                    transitionsList->append(list.releaseNonNull());
+                    transitionsList->append(WTFMove(list));
                 }
-                return transitionsList;
+                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::initialDuration(), CSSPrimitiveValue::CSS_S));
-            list->append(createTimingFunctionValue(Animation::initialTimingFunction().get()));
+            list->append(createTimingFunctionValue(Animation::initialTimingFunction()));
             list->append(cssValuePool.createValue(Animation::initialDelay(), CSSPrimitiveValue::CSS_S));
-            return list;
+            return WTFMove(list);
         }
         case CSSPropertyPointerEvents:
             return cssValuePool.createValue(style->pointerEvents());
@@ -3269,7 +3742,7 @@ RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
             return CSSPrimitiveValue::create(style->lineSnap());
         case CSSPropertyWebkitLineAlign:
             return CSSPrimitiveValue::create(style->lineAlign());
-        case CSSPropertyWebkitWritingMode:
+        case CSSPropertyWritingMode:
             return cssValuePool.createValue(style->writingMode());
         case CSSPropertyWebkitTextCombine:
             return cssValuePool.createValue(style->textCombine());
@@ -3278,33 +3751,29 @@ RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
         case CSSPropertyWebkitLineBoxContain:
             return createLineBoxContainValue(style->lineBoxContain());
         case CSSPropertyAlt:
-            return altTextToCSSValue(style.get());
+            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 (is<ReferenceClipPathOperation>(*operation)) {
-                const auto& referenceOperation = downcast<ReferenceClipPathOperation>(*operation);
-                return CSSPrimitiveValue::create(referenceOperation.url(), CSSPrimitiveValue::CSS_URI);
-            }
-            RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
+            if (is<ReferenceClipPathOperation>(*operation))
+                return CSSPrimitiveValue::create(downcast<ReferenceClipPathOperation>(*operation).url(), CSSPrimitiveValue::CSS_URI);
+            auto list = CSSValueList::createSpaceSeparated();
             if (is<ShapeClipPathOperation>(*operation)) {
-                const auto& shapeOperation = downcast<ShapeClipPathOperation>(*operation);
+                auto& shapeOperation = downcast<ShapeClipPathOperation>(*operation);
                 list->append(valueForBasicShape(*style, shapeOperation.basicShape()));
                 if (shapeOperation.referenceBox() != BoxMissing)
                     list->append(cssValuePool.createValue(shapeOperation.referenceBox()));
             }
-            if (is<BoxClipPathOperation>(*operation)) {
-                const auto& boxOperation = downcast<BoxClipPathOperation>(*operation);
-                list->append(cssValuePool.createValue(boxOperation.referenceBox()));
-            }
-            return list;
+            if (is<BoxClipPathOperation>(*operation))
+                list->append(cssValuePool.createValue(downcast<BoxClipPathOperation>(*operation).referenceBox()));
+            return WTFMove(list);
         }
 #if ENABLE(CSS_REGIONS)
         case CSSPropertyWebkitFlowInto:
@@ -3318,14 +3787,12 @@ RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
         case CSSPropertyWebkitRegionFragment:
             return cssValuePool.createValue(style->regionFragment());
 #endif
-#if ENABLE(CSS_SHAPES)
-        case CSSPropertyWebkitShapeMargin:
+        case CSSPropertyShapeMargin:
             return cssValuePool.createValue(style->shapeMargin(), *style);
-        case CSSPropertyWebkitShapeImageThreshold:
+        case CSSPropertyShapeImageThreshold:
             return cssValuePool.createValue(style->shapeImageThreshold(), CSSPrimitiveValue::CSS_NUMBER);
-        case CSSPropertyWebkitShapeOutside:
+        case CSSPropertyShapeOutside:
             return shapePropertyValue(*style, style->shapeOutside());
-#endif
         case CSSPropertyFilter:
             return valueForFilter(*style, style->filter());
 #if ENABLE(FILTERS_LEVEL_2)
@@ -3339,20 +3806,18 @@ RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
             return cssValuePool.createValue(style->isolation());
 #endif
         case CSSPropertyBackgroundBlendMode: {
-            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())
+            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 list.release();
+            return WTFMove(list);
         }
         case CSSPropertyBackground:
             return getBackgroundShorthandValue();
         case CSSPropertyBorder: {
-            RefPtr<CSSValue> value = propertyValue(CSSPropertyBorderTop, DoNotUpdateLayout);
+            auto value = propertyValue(CSSPropertyBorderTop, DoNotUpdateLayout);
             const CSSPropertyID properties[3] = { CSSPropertyBorderRight, CSSPropertyBorderBottom, CSSPropertyBorderLeft };
             for (auto& property : properties) {
                 if (!compareCSSValuePtr<CSSValue>(value, propertyValue(property, DoNotUpdateLayout)))
@@ -3369,7 +3834,7 @@ RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
         case CSSPropertyBorderImage:
             return valueForNinePieceImage(style->borderImage());
         case CSSPropertyBorderRadius:
-            return getBorderRadiusShorthandValue(*style);
+            return borderRadiusShorthandValue(*style);
         case CSSPropertyBorderRight:
             return getCSSPropertyValuesForShorthandProperties(borderRightShorthand());
         case CSSPropertyBorderStyle:
@@ -3392,16 +3857,30 @@ RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
             return getCSSPropertyValuesForSidesShorthand(paddingShorthand());
 
 #if ENABLE(CSS_SCROLL_SNAP)
-        case CSSPropertyWebkitScrollSnapType:
-            return cssValuePool.createValue(style->scrollSnapType());
-        case CSSPropertyWebkitScrollSnapDestination:
-            return scrollSnapDestination(*style, style->scrollSnapDestination());
-        case CSSPropertyWebkitScrollSnapPointsX:
-            return scrollSnapPoints(*style, style->scrollSnapPointsX());
-        case CSSPropertyWebkitScrollSnapPointsY:
-            return scrollSnapPoints(*style, style->scrollSnapPointsY());
-        case CSSPropertyWebkitScrollSnapCoordinate:
-            return scrollSnapCoordinates(*style, style->scrollSnapCoordinates());
+        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)
@@ -3409,6 +3888,13 @@ RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
             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:
@@ -3425,8 +3911,6 @@ RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
             return zoomAdjustedPixelValueForLength(style->svgStyle().rx(), *style);
         case CSSPropertyRy:
             return zoomAdjustedPixelValueForLength(style->svgStyle().ry(), *style);
-        case CSSPropertyStrokeWidth:
-            return zoomAdjustedPixelValueForLength(style->svgStyle().strokeWidth(), *style);
         case CSSPropertyStrokeDashoffset:
             return zoomAdjustedPixelValueForLength(style->svgStyle().strokeDashOffset(), *style);
         case CSSPropertyX:
@@ -3436,24 +3920,23 @@ RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
         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);
+        case CSSPropertyStrokeColor:
+            return currentColorOrValidColor(style, style->strokeColor());
+        case CSSPropertyStrokeMiterlimit:
+            return CSSPrimitiveValue::create(style->strokeMiterLimit(), CSSPrimitiveValue::CSS_NUMBER);
+
         /* Unimplemented CSS 3 properties (including CSS3 shorthand properties) */
+        case CSSPropertyAll:
         case CSSPropertyAnimation:
         case CSSPropertyWebkitTextEmphasis:
-        case CSSPropertyTextLineThrough:
-        case CSSPropertyTextLineThroughColor:
-        case CSSPropertyTextLineThroughMode:
-        case CSSPropertyTextLineThroughStyle:
-        case CSSPropertyTextLineThroughWidth:
-        case CSSPropertyTextOverline:
-        case CSSPropertyTextOverlineColor:
-        case CSSPropertyTextOverlineMode:
-        case CSSPropertyTextOverlineStyle:
-        case CSSPropertyTextOverlineWidth:
-        case CSSPropertyTextUnderline:
-        case CSSPropertyTextUnderlineColor:
-        case CSSPropertyTextUnderlineMode:
-        case CSSPropertyTextUnderlineStyle:
-        case CSSPropertyTextUnderlineWidth:
             break;
 
         /* Directional properties are resolved by resolveDirectionAwareProperty() before the switch. */
@@ -3491,7 +3974,6 @@ RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
             break;
 
         /* Unimplemented @font-face properties */
-        case CSSPropertyFontStretch:
         case CSSPropertySrc:
         case CSSPropertyUnicodeRange:
             break;
@@ -3503,7 +3985,6 @@ RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
             break;
 
         /* Unimplemented -webkit- properties */
-        case CSSPropertyWebkitAnimation:
         case CSSPropertyWebkitBorderRadius:
         case CSSPropertyWebkitMarginCollapse:
         case CSSPropertyWebkitMarquee:
@@ -3549,13 +4030,9 @@ RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
         case CSSPropertyMarkerMid:
         case CSSPropertyMarkerStart:
         case CSSPropertyMaskType:
-        case CSSPropertyPaintOrder:
         case CSSPropertyShapeRendering:
         case CSSPropertyStroke:
         case CSSPropertyStrokeDasharray:
-        case CSSPropertyStrokeLinecap:
-        case CSSPropertyStrokeLinejoin:
-        case CSSPropertyStrokeMiterlimit:
         case CSSPropertyStrokeOpacity:
         case CSSPropertyAlignmentBaseline:
         case CSSPropertyBaselineShift:
@@ -3565,7 +4042,6 @@ RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
         case CSSPropertyKerning:
         case CSSPropertyTextAnchor:
         case CSSPropertyVectorEffect:
-        case CSSPropertyWritingMode:
         case CSSPropertyWebkitSvgShadow:
             return svgPropertyValue(propertyID, DoNotUpdateLayout);
         case CSSPropertyCustom:
@@ -3579,7 +4055,7 @@ RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
 
 String CSSComputedStyleDeclaration::getPropertyValue(CSSPropertyID propertyID) const
 {
-    RefPtr<CSSValue> value = getPropertyCSSValue(propertyID);
+    auto value = getPropertyCSSValue(propertyID);
     if (!value)
         return emptyString(); // FIXME: Should this be null instead, as it is in StyleProperties::getPropertyValue?
     return value->cssText();
@@ -3587,53 +4063,48 @@ String CSSComputedStyleDeclaration::getPropertyValue(CSSPropertyID propertyID) c
 
 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;
 
-    const HashMap<AtomicString, String>* customProperties = style->customProperties();
-    return numComputedProperties + (customProperties ? customProperties->size() : 0);
+    return numComputedProperties + style->customProperties().size();
 }
 
 String CSSComputedStyleDeclaration::item(unsigned i) const
 {
     if (i >= length())
-        return emptyString();
+        return String();
     
     if (i < numComputedProperties)
         return getPropertyNameString(computedProperties[i]);
     
-    Node* node = m_node.get();
-    if (!node)
-        return emptyString();
-
-    RenderStyle* style = node->computedStyle(m_pseudoElementSpecifier);
+    auto* style = m_element->computedStyle(m_pseudoElementSpecifier);
     if (!style)
-        return emptyString();
+        return String();
     
     unsigned index = i - numComputedProperties;
     
-    const auto* customProperties = style->customProperties();
-    if (!customProperties || index >= customProperties->size())
-        return emptyString();
+    const auto& customProperties = style->customProperties();
+    if (index >= customProperties.size())
+        return String();
     
     Vector<String, 4> results;
-    copyKeysToVector(*customProperties, 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 && is<CSSPrimitiveValue>(*value) && m_node) {
-        m_node->document().updateLayoutIgnorePendingStylesheets();
-        if (RenderStyle* style = m_node->computedStyle(m_pseudoElementSpecifier)) {
+    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.getValueID() == sizeIdentifier)
+                if (primitiveValue.isValueID() && primitiveValue.valueID() == sizeIdentifier)
                     return true;
             }
         }
@@ -3642,29 +4113,28 @@ bool ComputedStyleExtractor::propertyMatches(CSSPropertyID propertyID, const CSS
     return computedValue && value && computedValue->equals(*value);
 }
 
-Ref<MutableStyleProperties> ComputedStyleExtractor::copyProperties() const
+Ref<MutableStyleProperties> ComputedStyleExtractor::copyProperties()
 {
     return copyPropertiesInSet(computedProperties, numComputedProperties);
 }
 
-RefPtr<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.releaseNonNull());
-    }
-    return list;
+    auto list = CSSValueList::createSpaceSeparated();
+    for (size_t i = 0; i < shorthand.length(); ++i)
+        list->append(propertyValue(shorthand.properties()[i], DoNotUpdateLayout).releaseNonNull());
+    return WTFMove(list);
 }
 
-RefPtr<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)
@@ -3682,44 +4152,25 @@ RefPtr<CSSValueList> ComputedStyleExtractor::getCSSPropertyValuesForSidesShortha
     if (showLeft)
         list->append(leftValue.releaseNonNull());
 
-    return list;
+    return WTFMove(list);
 }
 
-RefPtr<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.releaseNonNull());
-    }
-    return list;
+    auto list = CSSValueList::createSlashSeparated();
+    for (size_t i = 0; i < shorthand.length(); ++i)
+        list->append(propertyValue(shorthand.properties()[i], DoNotUpdateLayout).releaseNonNull());
+    return WTFMove(list);
 }
 
-Ref<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));
     }
-    
-    auto* styledNode = this->styledNode();
-    if (styledNode) {
-        RefPtr<RenderStyle> style = computeRenderStyleForProperty(styledNode, m_pseudoElementSpecifier, CSSPropertyCustom);
-        if (style) {
-            const auto* customProperties = style->customProperties();
-            if (customProperties) {
-                HashMap<AtomicString, String>::const_iterator end = customProperties->end();
-                for (HashMap<AtomicString, String>::const_iterator it = customProperties->begin(); it != end; ++it) {
-                    RefPtr<CSSCustomPropertyValue> value = CSSCustomPropertyValue::create(it->key, it->value);
-                    list.append(CSSProperty(CSSPropertyCustom, value.release(), false));
-                }
-            }
-        }
-    }
-    
     return MutableStyleProperties::create(list.data(), list.size());
 }
 
@@ -3728,28 +4179,28 @@ CSSRule* CSSComputedStyleDeclaration::parentRule() const
     return nullptr;
 }
 
-RefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(const String& propertyName)
+RefPtr<DeprecatedCSSOMValue> CSSComputedStyleDeclaration::getPropertyCSSValue(const String& propertyName)
 {
     if (isCustomPropertyName(propertyName)) {
-        RefPtr<CSSValue> value = ComputedStyleExtractor(m_node, m_allowVisitedStyle, m_pseudoElementSpecifier).customPropertyValue(propertyName);
-        return value ? value->cloneForCSSOM() : nullptr;
+        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 nullptr;
-    RefPtr<CSSValue> value = getPropertyCSSValue(propertyID);
-    return value ? value->cloneForCSSOM() : nullptr;
+    auto value = getPropertyCSSValue(propertyID);
+    if (!value)
+        return nullptr;
+    return value->createDeprecatedCSSOMWrapper();
 }
 
 String CSSComputedStyleDeclaration::getPropertyValue(const String &propertyName)
 {
-    if (isCustomPropertyName(propertyName)) {
-        RefPtr<CSSValue> value = ComputedStyleExtractor(m_node, m_allowVisitedStyle, m_pseudoElementSpecifier).customPropertyValue(propertyName);
-        if (!value)
-            return String();
-        return value->cssText();
-    }
+    if (isCustomPropertyName(propertyName))
+        return ComputedStyleExtractor(m_element.ptr(), m_allowVisitedStyle, m_pseudoElementSpecifier).customPropertyText(propertyName);
 
     CSSPropertyID propertyID = cssPropertyID(propertyName);
     if (!propertyID)
@@ -3773,15 +4224,14 @@ 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 };
 }
     
 RefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValueInternal(CSSPropertyID propertyID)
@@ -3794,21 +4244,17 @@ String CSSComputedStyleDeclaration::getPropertyValueInternal(CSSPropertyID prope
     return getPropertyValue(propertyID);
 }
 
-bool CSSComputedStyleDeclaration::setPropertyInternal(CSSPropertyID, const String&, bool, ExceptionCode& ec)
+ExceptionOr<bool> CSSComputedStyleDeclaration::setPropertyInternal(CSSPropertyID, const String&, bool)
 {
-    ec = NO_MODIFICATION_ALLOWED_ERR;
-    return false;
+    return Exception { NO_MODIFICATION_ALLOWED_ERR };
 }
 
-RefPtr<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();
+    auto list = CSSValueList::createSlashSeparated();
     list->append(*getCSSPropertyValuesForShorthandProperties(StylePropertyShorthand(CSSPropertyBackground, propertiesBeforeSlashSeperator)));
     list->append(*getCSSPropertyValuesForShorthandProperties(StylePropertyShorthand(CSSPropertyBackground, propertiesAfterSlashSeperator)));
     return list;