/*
 * Copyright (C) 2004 Zack Rusin <zack@kde.org>
 * Copyright (C) 2004-2021 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.
 * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301  USA
 */

#include "config.h"
#include "CSSComputedStyleDeclaration.h"

#include "BasicShapeFunctions.h"
#include "CSSBasicShapes.h"
#include "CSSBorderImage.h"
#include "CSSBorderImageSliceValue.h"
#include "CSSFontFeatureValue.h"
#include "CSSFontStyleValue.h"
#include "CSSFontValue.h"
#include "CSSFontVariationValue.h"
#include "CSSFunctionValue.h"
#include "CSSGridAutoRepeatValue.h"
#include "CSSLineBoxContainValue.h"
#include "CSSPrimitiveValue.h"
#include "CSSPrimitiveValueMappings.h"
#include "CSSPropertyAnimation.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 "CursorList.h"
#include "DeprecatedCSSOMValue.h"
#include "Document.h"
#include "DocumentTimeline.h"
#include "FontCascade.h"
#include "FontSelectionValueInlines.h"
#include "FontTaggedSettings.h"
#include "NodeRenderStyle.h"
#include "Pair.h"
#include "QuotesData.h"
#include "Rect.h"
#include "RenderBlock.h"
#include "RenderBox.h"
#include "RenderInline.h"
#include "RenderStyle.h"
#include "SVGElement.h"
#include "SVGRenderSupport.h"
#include "Settings.h"
#include "ShapeValue.h"
#include "StyleProperties.h"
#include "StylePropertyShorthand.h"
#include "StylePropertyShorthandFunctions.h"
#include "StyleResolver.h"
#include "StyleScope.h"
#include "StyleScrollSnapPoints.h"
#include "TouchAction.h"
#include "WebKitFontFamilyNames.h"
#include "WillChangeData.h"
#include <wtf/IsoMallocInlines.h>
#include <wtf/NeverDestroyed.h>
#include <wtf/text/StringBuilder.h>

#include "CSSGridLineNamesValue.h"
#include "CSSGridTemplateAreasValue.h"
#include "RenderGrid.h"

namespace WebCore {

WTF_MAKE_ISO_ALLOCATED_IMPL(CSSComputedStyleDeclaration);

static CSSValueID valueForRepeatRule(NinePieceImageRule rule)
{
    switch (rule) {
    case NinePieceImageRule::Repeat:
        return CSSValueRepeat;
    case NinePieceImageRule::Round:
        return CSSValueRound;
    case NinePieceImageRule::Space:
        return CSSValueSpace;
    default:
        return CSSValueStretch;
    }
}

static Ref<CSSPrimitiveValue> valueForImageSliceSide(const Length& length)
{
    // These values can be percentages, numbers, or while an animation of mixed types is in progress,
    // a calculation that combines a percentage and a number.
    if (length.isPercent())
        return CSSValuePool::singleton().createValue(length.percent(), CSSUnitType::CSS_PERCENTAGE);
    if (length.isAuto() || length.isFixed())
        return CSSValuePool::singleton().createValue(length.value(), CSSUnitType::CSS_NUMBER);

    // Calculating the actual length currently in use would require most of the code from RenderBoxModelObject::paintNinePieceImage.
    // And even if we could do that, it's not clear if that's exactly what we'd want during animation.
    // FIXME: For now, just return 0.
    ASSERT(length.isCalculated());
    return CSSValuePool::singleton().createValue(0, CSSUnitType::CSS_NUMBER);
}

static Ref<CSSBorderImageSliceValue> valueForNinePieceImageSlice(const NinePieceImage& image)
{
    auto& slices = image.imageSlices();

    RefPtr<CSSPrimitiveValue> top = valueForImageSliceSide(slices.top());

    RefPtr<CSSPrimitiveValue> right;
    RefPtr<CSSPrimitiveValue> bottom;
    RefPtr<CSSPrimitiveValue> left;

    if (slices.right() == slices.top() && slices.bottom() == slices.top() && slices.left() == slices.top()) {
        right = top;
        bottom = top;
        left = top;
    } else {
        right = valueForImageSliceSide(slices.right());

        if (slices.bottom() == slices.top() && slices.right() == slices.left()) {
            bottom = top;
            left = right;
        } else {
            bottom = valueForImageSliceSide(slices.bottom());

            if (slices.left() == slices.right())
                left = right;
            else
                left = valueForImageSliceSide(slices.left());
        }
    }

    auto quad = Quad::create();
    quad->setTop(WTFMove(top));
    quad->setRight(WTFMove(right));
    quad->setBottom(WTFMove(bottom));
    quad->setLeft(WTFMove(left));

    return CSSBorderImageSliceValue::create(CSSValuePool::singleton().createValue(WTFMove(quad)), image.fill());
}

static Ref<CSSPrimitiveValue> valueForNinePieceImageQuad(const LengthBox& box, const RenderStyle& style)
{
    RefPtr<CSSPrimitiveValue> top;
    RefPtr<CSSPrimitiveValue> right;
    RefPtr<CSSPrimitiveValue> bottom;
    RefPtr<CSSPrimitiveValue> left;

    auto& cssValuePool = CSSValuePool::singleton();

    if (box.top().isRelative())
        top = cssValuePool.createValue(box.top().value(), CSSUnitType::CSS_NUMBER);
    else
        top = cssValuePool.createValue(box.top(), style);

    if (box.right() == box.top() && box.bottom() == box.top() && box.left() == box.top()) {
        right = top;
        bottom = top;
        left = top;
    } else {
        if (box.right().isRelative())
            right = cssValuePool.createValue(box.right().value(), CSSUnitType::CSS_NUMBER);
        else
            right = cssValuePool.createValue(box.right(), style);

        if (box.bottom() == box.top() && box.right() == box.left()) {
            bottom = top;
            left = right;
        } else {
            if (box.bottom().isRelative())
                bottom = cssValuePool.createValue(box.bottom().value(), CSSUnitType::CSS_NUMBER);
            else
                bottom = cssValuePool.createValue(box.bottom(), style);

            if (box.left() == box.right())
                left = right;
            else {
                if (box.left().isRelative())
                    left = cssValuePool.createValue(box.left().value(), CSSUnitType::CSS_NUMBER);
                else
                    left = cssValuePool.createValue(box.left(), style);
            }
        }
    }

    auto quad = Quad::create();
    quad->setTop(WTFMove(top));
    quad->setRight(WTFMove(right));
    quad->setBottom(WTFMove(bottom));
    quad->setLeft(WTFMove(left));

    return cssValuePool.createValue(WTFMove(quad));
}

static Ref<CSSValue> valueForNinePieceImageRepeat(const NinePieceImage& image)
{
    auto& cssValuePool = CSSValuePool::singleton();
    auto horizontalRepeat = cssValuePool.createIdentifierValue(valueForRepeatRule(image.horizontalRule()));
    RefPtr<CSSPrimitiveValue> verticalRepeat;
    if (image.horizontalRule() == image.verticalRule())
        verticalRepeat = horizontalRepeat.copyRef();
    else
        verticalRepeat = cssValuePool.createIdentifierValue(valueForRepeatRule(image.verticalRule()));
    return cssValuePool.createValue(Pair::create(WTFMove(horizontalRepeat), WTFMove(verticalRepeat)));
}

static Ref<CSSValue> valueForNinePieceImage(const NinePieceImage& image, const RenderStyle& style)
{
    if (!image.hasImage())
        return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);

    RefPtr<CSSValue> imageValue;
    if (image.image())
        imageValue = image.image()->cssValue();

    auto imageSlices = valueForNinePieceImageSlice(image);
    auto borderSlices = valueForNinePieceImageQuad(image.borderSlices(), style);
    auto outset = valueForNinePieceImageQuad(image.outset(), style);
    auto repeat = valueForNinePieceImageRepeat(image);
    return createBorderImageValue(WTFMove(imageValue), WTFMove(imageSlices), WTFMove(borderSlices), WTFMove(outset), WTFMove(repeat));
}

inline static Ref<CSSPrimitiveValue> zoomAdjustedPixelValue(double value, const RenderStyle& style)
{
    return CSSValuePool::singleton().createValue(adjustFloatForAbsoluteZoom(value, style), CSSUnitType::CSS_PX);
}

inline static Ref<CSSPrimitiveValue> zoomAdjustedNumberValue(double value, const RenderStyle& style)
{
    return CSSValuePool::singleton().createValue(value / style.effectiveZoom(), CSSUnitType::CSS_NUMBER);
}

static Ref<CSSPrimitiveValue> zoomAdjustedPixelValueForLength(const Length& length, const RenderStyle& style)
{
    if (length.isFixed())
        return zoomAdjustedPixelValue(length.value(), style);
    return CSSValuePool::singleton().createValue(length, style);
}

static Ref<CSSValue> valueForReflection(const StyleReflection* reflection, const RenderStyle& style)
{
    if (!reflection)
        return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);

    RefPtr<CSSPrimitiveValue> offset;
    if (reflection->offset().isPercentOrCalculated())
        offset = CSSValuePool::singleton().createValue(reflection->offset().percent(), CSSUnitType::CSS_PERCENTAGE);
    else
        offset = zoomAdjustedPixelValue(reflection->offset().value(), style);

    RefPtr<CSSPrimitiveValue> direction;
    switch (reflection->direction()) {
    case ReflectionDirection::Below:
        direction = CSSValuePool::singleton().createIdentifierValue(CSSValueBelow);
        break;
    case ReflectionDirection::Above:
        direction = CSSValuePool::singleton().createIdentifierValue(CSSValueAbove);
        break;
    case ReflectionDirection::Left:
        direction = CSSValuePool::singleton().createIdentifierValue(CSSValueLeft);
        break;
    case ReflectionDirection::Right:
        direction = CSSValuePool::singleton().createIdentifierValue(CSSValueRight);
        break;
    }

    return CSSReflectValue::create(direction.releaseNonNull(), offset.releaseNonNull(), valueForNinePieceImage(reflection->mask(), style));
}

static Ref<CSSValueList> createPositionListForLayer(CSSPropertyID propertyID, const FillLayer& layer, const RenderStyle& style)
{
    auto list = CSSValueList::createSpaceSeparated();
    if (layer.isBackgroundXOriginSet() && layer.backgroundXOrigin() != Edge::Left) {
        ASSERT_UNUSED(propertyID, propertyID == CSSPropertyBackgroundPosition || propertyID == CSSPropertyWebkitMaskPosition);
        list->append(CSSValuePool::singleton().createValue(layer.backgroundXOrigin()));
    }
    list->append(zoomAdjustedPixelValueForLength(layer.xPosition(), style));
    if (layer.isBackgroundYOriginSet() && layer.backgroundYOrigin() != Edge::Top) {
        ASSERT(propertyID == CSSPropertyBackgroundPosition || propertyID == CSSPropertyWebkitMaskPosition);
        list->append(CSSValuePool::singleton().createValue(layer.backgroundYOrigin()));
    }
    list->append(zoomAdjustedPixelValueForLength(layer.yPosition(), style));
    return list;
}

static Ref<CSSValue> createSingleAxisPositionValueForLayer(CSSPropertyID propertyID, const FillLayer& layer, const RenderStyle& style)
{
    if (propertyID == CSSPropertyBackgroundPositionX || propertyID == CSSPropertyWebkitMaskPositionX) {
        if (!layer.isBackgroundXOriginSet() || layer.backgroundXOrigin() == Edge::Left)
            return zoomAdjustedPixelValueForLength(layer.xPosition(), style);

        auto list = CSSValueList::createSpaceSeparated();
        list->append(CSSValuePool::singleton().createValue(layer.backgroundXOrigin()));
        list->append(zoomAdjustedPixelValueForLength(layer.xPosition(), style));
        return list;
    }

    if (!layer.isBackgroundYOriginSet() || layer.backgroundYOrigin() == Edge::Top)
        return zoomAdjustedPixelValueForLength(layer.yPosition(), style);

    auto list = CSSValueList::createSpaceSeparated();
    list->append(CSSValuePool::singleton().createValue(layer.backgroundYOrigin()));
    list->append(zoomAdjustedPixelValueForLength(layer.yPosition(), style));
    return list;
}

static Length getOffsetComputedLength(const RenderStyle& style, CSSPropertyID propertyID)
{
    // If specified as a length, the corresponding absolute length; if specified as
    // a percentage, the specified value; otherwise, 'auto'. Hence, we can just
    // return the value in the style.
    //
    // See http://www.w3.org/TR/CSS21/cascade.html#computed-value
    switch (propertyID) {
    case CSSPropertyLeft:
        return style.left();
    case CSSPropertyRight:
        return style.right();
    case CSSPropertyTop:
        return style.top();
    case CSSPropertyBottom:
        return style.bottom();
    default:
        ASSERT_NOT_REACHED();
    }

    return { };
}

static LayoutUnit getOffsetUsedStyleRelative(RenderBox& box, CSSPropertyID propertyID)
{
    // For relatively positioned boxes, the offset is with respect to the top edges
    // of the box itself. This ties together top/bottom and left/right to be
    // opposites of each other.
    //
    // See http://www.w3.org/TR/CSS2/visuren.html#relative-positioning
    //
    // Specifically;
    //   Since boxes are not split or stretched as a result of 'left' or
    //   'right', the used values are always: left = -right.
    // and
    //   Since boxes are not split or stretched as a result of 'top' or
    //   'bottom', the used values are always: top = -bottom.
    switch (propertyID) {
    case CSSPropertyTop:
        return box.relativePositionOffset().height();
    case CSSPropertyBottom:
        return -(box.relativePositionOffset().height());
    case CSSPropertyLeft:
        return box.relativePositionOffset().width();
    case CSSPropertyRight:
        return -(box.relativePositionOffset().width());
    default:
        ASSERT_NOT_REACHED();
    }

    return 0;
}

static LayoutUnit getOffsetUsedStyleOutOfFlowPositioned(RenderBlock& container, RenderBox& box, CSSPropertyID propertyID)
{
    // For out-of-flow positioned boxes, the offset is how far an box's margin
    // edge is offset below the edge of the box's containing block.
    // See http://www.w3.org/TR/CSS2/visuren.html#position-props

    // Margins are included in offsetTop/offsetLeft so we need to remove them here.
    switch (propertyID) {
    case CSSPropertyTop:
        return box.offsetTop() - box.marginTop();
    case CSSPropertyBottom:
        return container.clientHeight() - (box.offsetTop() + box.offsetHeight()) - box.marginBottom();
    case CSSPropertyLeft:
        return box.offsetLeft() - box.marginLeft();
    case CSSPropertyRight:
        return container.clientWidth() - (box.offsetLeft() + box.offsetWidth()) - box.marginRight();
    default:
        ASSERT_NOT_REACHED();
    }

    return 0;
}

static RefPtr<CSSValue> positionOffsetValue(const RenderStyle& style, CSSPropertyID propertyID, RenderObject* renderer)
{
    auto offset = getOffsetComputedLength(style, propertyID);

    // If the element is not displayed; return the "computed value".
    if (!renderer || !renderer->isBox())
        return zoomAdjustedPixelValueForLength(offset, style);

    auto& box = downcast<RenderBox>(*renderer);
    auto* containingBlock = box.containingBlock();

    // Resolve a "computed value" percentage if the element is positioned.
    if (containingBlock && offset.isPercentOrCalculated() && box.isPositioned()) {
        bool isVerticalProperty;
        if (propertyID == CSSPropertyTop || propertyID == CSSPropertyBottom)
            isVerticalProperty = true;
        else {
            ASSERT(propertyID == CSSPropertyLeft || propertyID == CSSPropertyRight);
            isVerticalProperty = false;
        }
        LayoutUnit containingBlockSize;
        if (box.isStickilyPositioned()) {
            auto& enclosingClippingBox = box.enclosingClippingBoxForStickyPosition().first;
            if (isVerticalProperty == enclosingClippingBox.isHorizontalWritingMode())
                containingBlockSize = enclosingClippingBox.contentLogicalHeight();
            else
                containingBlockSize = enclosingClippingBox.contentLogicalWidth();
        } else {
            if (isVerticalProperty == containingBlock->isHorizontalWritingMode()) {
                containingBlockSize = box.isOutOfFlowPositioned()
                    ? box.containingBlockLogicalHeightForPositioned(*containingBlock, false)
                    : box.containingBlockLogicalHeightForContent(ExcludeMarginBorderPadding);
            } else {
                containingBlockSize = box.isOutOfFlowPositioned()
                    ? box.containingBlockLogicalWidthForPositioned(*containingBlock, nullptr, false)
                    : box.containingBlockLogicalWidthForContent();
            }
        }
        return zoomAdjustedPixelValue(floatValueForLength(offset, containingBlockSize), style);
    }

    // Return a "computed value" length.
    if (!offset.isAuto())
        return zoomAdjustedPixelValueForLength(offset, style);

    // The property won't be overconstrained if its computed value is "auto", so the "used value" can be returned.
    if (box.isRelativelyPositioned())
        return zoomAdjustedPixelValue(getOffsetUsedStyleRelative(box, propertyID), style);

    if (containingBlock && box.isOutOfFlowPositioned())
        return zoomAdjustedPixelValue(getOffsetUsedStyleOutOfFlowPositioned(*containingBlock, box, propertyID), style);

    return CSSValuePool::singleton().createIdentifierValue(CSSValueAuto);
}

Ref<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());
    return CSSValuePool::singleton().createColorValue(color);
}

static Ref<CSSPrimitiveValue> percentageOrZoomAdjustedValue(Length length, const RenderStyle& style)
{
    if (length.isPercent())
        return CSSValuePool::singleton().createValue(length.percent(), CSSUnitType::CSS_PERCENTAGE);
    
    return zoomAdjustedPixelValueForLength(length, style);
}

static Ref<CSSPrimitiveValue> autoOrZoomAdjustedValue(Length length, const RenderStyle& style)
{
    if (length.isAuto())
        return CSSValuePool::singleton().createIdentifierValue(CSSValueAuto);

    return zoomAdjustedPixelValueForLength(length, style);
}

static Ref<CSSValueList> borderRadiusCornerValues(const LengthSize& radius, const RenderStyle& style)
{
    auto list = CSSValueList::createSpaceSeparated();
    list->append(percentageOrZoomAdjustedValue(radius.width, style));
    list->append(percentageOrZoomAdjustedValue(radius.height, style));
    return list;
}

static Ref<CSSValue> valueForQuotes(const QuotesData* quotes)
{
    if (!quotes)
        return CSSValuePool::singleton().createIdentifierValue(CSSValueAuto);
    unsigned size = quotes->size();
    if (!size)
        return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
    auto list = CSSValueList::createSpaceSeparated();
    for (unsigned i = 0; i < size; ++i) {
        list->append(CSSValuePool::singleton().createValue(quotes->openQuote(i), CSSUnitType::CSS_STRING));
        list->append(CSSValuePool::singleton().createValue(quotes->closeQuote(i), CSSUnitType::CSS_STRING));
    }
    return list;
}

static Ref<CSSValue> borderRadiusCornerValue(const LengthSize& radius, const RenderStyle& style)
{
    if (radius.width == radius.height)
        return percentageOrZoomAdjustedValue(radius.width, style);
    return borderRadiusCornerValues(radius, 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 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);

    auto topLeftRadius = borderRadiusCornerValues(style.borderTopLeftRadius(), style);
    auto topRightRadius = borderRadiusCornerValues(style.borderTopRightRadius(), style);
    auto bottomRightRadius = borderRadiusCornerValues(style.borderBottomRightRadius(), style);
    auto bottomLeftRadius = borderRadiusCornerValues(style.borderBottomLeftRadius(), style);

    auto horizontalRadii = CSSValueList::createSpaceSeparated();
    horizontalRadii->append(*topLeftRadius->item(0));
    if (showHorizontalTopRight)
        horizontalRadii->append(*topRightRadius->item(0));
    if (showHorizontalBottomRight)
        horizontalRadii->append(*bottomRightRadius->item(0));
    if (showHorizontalBottomLeft)
        horizontalRadii->append(*bottomLeftRadius->item(0));

    list->append(WTFMove(horizontalRadii));

    auto verticalRadiiList = CSSValueList::createSpaceSeparated();
    verticalRadiiList->append(*topLeftRadius->item(1));
    if (showVerticalTopRight)
        verticalRadiiList->append(*topRightRadius->item(1));
    if (showVerticalBottomRight)
        verticalRadiiList->append(*bottomRightRadius->item(1));
    if (showVerticalBottomLeft)
        verticalRadiiList->append(*bottomLeftRadius->item(1));

    if (!verticalRadiiList->equals(downcast<CSSValueList>(*list->item(0))))
        list->append(WTFMove(verticalRadiiList));

    return list;
}

static LayoutRect sizingBox(RenderObject& renderer)
{
    if (!is<RenderBox>(renderer))
        return LayoutRect();

    auto& box = downcast<RenderBox>(renderer);
    return box.style().boxSizing() == BoxSizing::BorderBox ? box.borderBoxRect() : box.computedCSSContentBoxRect();
}

static FloatRect transformReferenceBox(const RenderStyle& style, const RenderElement& renderer)
{
    if (is<RenderBox>(renderer))
        return downcast<RenderBox>(renderer).referenceBox(transformBoxToCSSBoxType(style.transformBox()));

    if (is<SVGElement>(renderer.element()))
        return SVGRenderSupport::transformReferenceBox(renderer, downcast<SVGElement>(*renderer.element()), style);

    return { };
}

static Ref<CSSFunctionValue> matrixTransformValue(const TransformationMatrix& transform, const RenderStyle& style)
{
    RefPtr<CSSFunctionValue> transformValue;
    auto& cssValuePool = CSSValuePool::singleton();
    if (transform.isAffine()) {
        transformValue = CSSFunctionValue::create(CSSValueMatrix);

        transformValue->append(cssValuePool.createValue(transform.a(), CSSUnitType::CSS_NUMBER));
        transformValue->append(cssValuePool.createValue(transform.b(), CSSUnitType::CSS_NUMBER));
        transformValue->append(cssValuePool.createValue(transform.c(), CSSUnitType::CSS_NUMBER));
        transformValue->append(cssValuePool.createValue(transform.d(), CSSUnitType::CSS_NUMBER));
        transformValue->append(zoomAdjustedNumberValue(transform.e(), style));
        transformValue->append(zoomAdjustedNumberValue(transform.f(), style));
    } else {
        transformValue = CSSFunctionValue::create(CSSValueMatrix3d);

        transformValue->append(cssValuePool.createValue(transform.m11(), CSSUnitType::CSS_NUMBER));
        transformValue->append(cssValuePool.createValue(transform.m12(), CSSUnitType::CSS_NUMBER));
        transformValue->append(cssValuePool.createValue(transform.m13(), CSSUnitType::CSS_NUMBER));
        transformValue->append(cssValuePool.createValue(transform.m14(), CSSUnitType::CSS_NUMBER));

        transformValue->append(cssValuePool.createValue(transform.m21(), CSSUnitType::CSS_NUMBER));
        transformValue->append(cssValuePool.createValue(transform.m22(), CSSUnitType::CSS_NUMBER));
        transformValue->append(cssValuePool.createValue(transform.m23(), CSSUnitType::CSS_NUMBER));
        transformValue->append(cssValuePool.createValue(transform.m24(), CSSUnitType::CSS_NUMBER));

        transformValue->append(cssValuePool.createValue(transform.m31(), CSSUnitType::CSS_NUMBER));
        transformValue->append(cssValuePool.createValue(transform.m32(), CSSUnitType::CSS_NUMBER));
        transformValue->append(cssValuePool.createValue(transform.m33(), CSSUnitType::CSS_NUMBER));
        transformValue->append(cssValuePool.createValue(transform.m34(), CSSUnitType::CSS_NUMBER));

        transformValue->append(zoomAdjustedNumberValue(transform.m41(), style));
        transformValue->append(zoomAdjustedNumberValue(transform.m42(), style));
        transformValue->append(zoomAdjustedNumberValue(transform.m43(), style));
        transformValue->append(cssValuePool.createValue(transform.m44(), CSSUnitType::CSS_NUMBER));
    }

    return transformValue.releaseNonNull();
}

static bool rendererCanBeTransformed(RenderObject* renderer)
{
    // Inline renderers do not support transforms.
    return renderer && !is<RenderInline>(*renderer);
}

static Ref<CSSValue> computedTransform(RenderObject* renderer, const RenderStyle& style)
{
    if (!rendererCanBeTransformed(renderer) || !style.hasTransform())
        return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);

    FloatRect pixelSnappedRect;
    if (is<RenderBox>(*renderer))
        pixelSnappedRect = snapRectToDevicePixels(downcast<RenderBox>(*renderer).borderBoxRect(), renderer->document().deviceScaleFactor());

    TransformationMatrix transform;
    style.applyTransform(transform, pixelSnappedRect, { });
    // Note that this does not flatten to an affine transform if ENABLE(3D_TRANSFORMS) is off, by design.

    // FIXME: Need to print out individual functions (https://bugs.webkit.org/show_bug.cgi?id=23924)
    auto list = CSSValueList::createSpaceSeparated();
    list->append(matrixTransformValue(transform, style));
    return list;
}

// https://drafts.csswg.org/css-transforms-2/#propdef-translate
// Computed value: the keyword none or a pair of computed <length-percentage> values and an absolute length
static Ref<CSSValue> computedTranslate(RenderObject* renderer, const RenderStyle& style)
{
    auto* translate = style.translate();
    if (!translate || !rendererCanBeTransformed(renderer) || translate->isIdentity())
        return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);

    auto list = CSSValueList::createSpaceSeparated();
    list->append(zoomAdjustedPixelValueForLength(translate->x(), style));

    if (!translate->y().isZero() || !translate->z().isZero())
        list->append(zoomAdjustedPixelValueForLength(translate->y(), style));

    if (!translate->z().isZero())
        list->append(zoomAdjustedPixelValueForLength(translate->z(), style));

    return list;
}

static Ref<CSSValue> computedScale(RenderObject* renderer, const RenderStyle& style)
{
    auto* scale = style.scale();
    auto& cssValuePool = CSSValuePool::singleton();
    if (!scale || !rendererCanBeTransformed(renderer) || scale->isIdentity())
        return cssValuePool.createIdentifierValue(CSSValueNone);

    auto list = CSSValueList::createSpaceSeparated();
    list->append(cssValuePool.createValue(scale->x(), CSSUnitType::CSS_NUMBER));
    if (scale->z() != 1) {
        list->append(cssValuePool.createValue(scale->y(), CSSUnitType::CSS_NUMBER));
        list->append(cssValuePool.createValue(scale->z(), CSSUnitType::CSS_NUMBER));
    } else if (scale->x() != scale->y())
        list->append(cssValuePool.createValue(scale->y(), CSSUnitType::CSS_NUMBER));
    return list;
}

static Ref<CSSValue> computedRotate(RenderObject* renderer, const RenderStyle& style)
{
    auto* rotate = style.rotate();
    auto& cssValuePool = CSSValuePool::singleton();
    if (!rotate || !rendererCanBeTransformed(renderer) || rotate->isIdentity())
        return cssValuePool.createIdentifierValue(CSSValueNone);

    if (!rotate->is3DOperation() || (!rotate->x() && !rotate->y() && rotate->z()))
        return cssValuePool.createValue(rotate->angle(), CSSUnitType::CSS_DEG);

    auto list = CSSValueList::createSpaceSeparated();

    if (rotate->x() && !rotate->y() && !rotate->z())
        list->append(cssValuePool.createIdentifierValue(CSSValueX));
    else if (!rotate->x() && rotate->y() && !rotate->z())
        list->append(cssValuePool.createIdentifierValue(CSSValueY));
    else {
        list->append(cssValuePool.createValue(rotate->x(), CSSUnitType::CSS_NUMBER));
        list->append(cssValuePool.createValue(rotate->y(), CSSUnitType::CSS_NUMBER));
        list->append(cssValuePool.createValue(rotate->z(), CSSUnitType::CSS_NUMBER));
    }

    list->append(cssValuePool.createValue(rotate->angle(), CSSUnitType::CSS_DEG));

    return list;
}

static inline Ref<CSSPrimitiveValue> adjustLengthForZoom(double length, const RenderStyle& style, AdjustPixelValuesForComputedStyle adjust)
{
    return adjust == AdjustPixelValues ? zoomAdjustedPixelValue(length, style) : CSSValuePool::singleton().createValue(length, CSSUnitType::CSS_PX);
}

static inline Ref<CSSPrimitiveValue> adjustLengthForZoom(const Length& length, const RenderStyle& style, AdjustPixelValuesForComputedStyle adjust)
{
    return adjust == AdjustPixelValues ? zoomAdjustedPixelValue(length.value(), style) : CSSValuePool::singleton().createValue(length);
}

Ref<CSSValue> ComputedStyleExtractor::valueForShadow(const ShadowData* shadow, CSSPropertyID propertyID, const RenderStyle& style, AdjustPixelValuesForComputedStyle adjust)
{
    auto& cssValuePool = CSSValuePool::singleton();
    if (!shadow)
        return cssValuePool.createIdentifierValue(CSSValueNone);

    auto list = CSSValueList::createCommaSeparated();
    for (const ShadowData* currShadowData = shadow; currShadowData; currShadowData = currShadowData->next()) {
        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() == ShadowStyle::Normal ? RefPtr<CSSPrimitiveValue>() : cssValuePool.createIdentifierValue(CSSValueInset);
        auto color = cssValuePool.createColorValue(currShadowData->color());
        list->prepend(CSSShadowValue::create(WTFMove(x), WTFMove(y), WTFMove(blur), WTFMove(spread), WTFMove(style), WTFMove(color)));
    }
    return list;
}

Ref<CSSValue> ComputedStyleExtractor::valueForFilter(const RenderStyle& style, const FilterOperations& filterOperations, AdjustPixelValuesForComputedStyle adjust)
{
    auto& cssValuePool = CSSValuePool::singleton();
    if (filterOperations.operations().isEmpty())
        return cssValuePool.createIdentifierValue(CSSValueNone);

    auto list = CSSValueList::createSpaceSeparated();

    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;

        if (filterOperation.type() == FilterOperation::REFERENCE) {
            ReferenceFilterOperation& referenceOperation = downcast<ReferenceFilterOperation>(filterOperation);
            list->append(cssValuePool.createValue(referenceOperation.url(), CSSUnitType::CSS_URI));
        } else {
            RefPtr<CSSFunctionValue> filterValue;
            switch (filterOperation.type()) {
            case FilterOperation::GRAYSCALE: {
                filterValue = CSSFunctionValue::create(CSSValueGrayscale);
                filterValue->append(cssValuePool.createValue(downcast<BasicColorMatrixFilterOperation>(filterOperation).amount(), CSSUnitType::CSS_NUMBER));
                break;
            }
            case FilterOperation::SEPIA: {
                filterValue = CSSFunctionValue::create(CSSValueSepia);
                filterValue->append(cssValuePool.createValue(downcast<BasicColorMatrixFilterOperation>(filterOperation).amount(), CSSUnitType::CSS_NUMBER));
                break;
            }
            case FilterOperation::SATURATE: {
                filterValue = CSSFunctionValue::create(CSSValueSaturate);
                filterValue->append(cssValuePool.createValue(downcast<BasicColorMatrixFilterOperation>(filterOperation).amount(), CSSUnitType::CSS_NUMBER));
                break;
            }
            case FilterOperation::HUE_ROTATE: {
                filterValue = CSSFunctionValue::create(CSSValueHueRotate);
                filterValue->append(cssValuePool.createValue(downcast<BasicColorMatrixFilterOperation>(filterOperation).amount(), CSSUnitType::CSS_DEG));
                break;
            }
            case FilterOperation::INVERT: {
                filterValue = CSSFunctionValue::create(CSSValueInvert);
                filterValue->append(cssValuePool.createValue(downcast<BasicComponentTransferFilterOperation>(filterOperation).amount(), CSSUnitType::CSS_NUMBER));
                break;
            }
            case FilterOperation::APPLE_INVERT_LIGHTNESS: {
                filterValue = CSSFunctionValue::create(CSSValueAppleInvertLightness);
                break;
            }
            case FilterOperation::OPACITY: {
                filterValue = CSSFunctionValue::create(CSSValueOpacity);
                filterValue->append(cssValuePool.createValue(downcast<BasicComponentTransferFilterOperation>(filterOperation).amount(), CSSUnitType::CSS_NUMBER));
                break;
            }
            case FilterOperation::BRIGHTNESS: {
                filterValue = CSSFunctionValue::create(CSSValueBrightness);
                filterValue->append(cssValuePool.createValue(downcast<BasicComponentTransferFilterOperation>(filterOperation).amount(), CSSUnitType::CSS_NUMBER));
                break;
            }
            case FilterOperation::CONTRAST: {
                filterValue = CSSFunctionValue::create(CSSValueContrast);
                filterValue->append(cssValuePool.createValue(downcast<BasicComponentTransferFilterOperation>(filterOperation).amount(), CSSUnitType::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, ShadowStyle::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());
        }
    }
    return list;
}

static Ref<CSSValue> specifiedValueForGridTrackBreadth(const GridLength& trackBreadth, const RenderStyle& style)
{
    if (!trackBreadth.isLength())
        return CSSValuePool::singleton().createValue(trackBreadth.flex(), CSSUnitType::CSS_FR);

    const Length& trackBreadthLength = trackBreadth.length();
    if (trackBreadthLength.isAuto())
        return CSSValuePool::singleton().createIdentifierValue(CSSValueAuto);
    return zoomAdjustedPixelValueForLength(trackBreadthLength, style);
}

static Ref<CSSValue> specifiedValueForGridTrackSize(const GridTrackSize& trackSize, const RenderStyle& style)
{
    switch (trackSize.type()) {
    case LengthTrackSizing:
        return specifiedValueForGridTrackBreadth(trackSize.minTrackBreadth(), style);
    case FitContentTrackSizing: {
        auto fitContentTrackSize = CSSFunctionValue::create(CSSValueFitContent);
        fitContentTrackSize->append(zoomAdjustedPixelValueForLength(trackSize.fitContentTrackBreadth().length(), style));
        return fitContentTrackSize;
    }
    default:
        ASSERT(trackSize.type() == MinMaxTrackSizing);
        if (trackSize.minTrackBreadth().isAuto() && trackSize.maxTrackBreadth().isFlex())
            return CSSValuePool::singleton().createValue(trackSize.maxTrackBreadth().flex(), CSSUnitType::CSS_FR);

        auto minMaxTrackBreadths = CSSFunctionValue::create(CSSValueMinmax);
        minMaxTrackBreadths->append(specifiedValueForGridTrackBreadth(trackSize.minTrackBreadth(), style));
        minMaxTrackBreadths->append(specifiedValueForGridTrackBreadth(trackSize.maxTrackBreadth(), style));
        return minMaxTrackBreadths;
    }
}

class OrderedNamedLinesCollector {
    WTF_MAKE_NONCOPYABLE(OrderedNamedLinesCollector);
public:
    OrderedNamedLinesCollector(const RenderStyle& style, bool isRowAxis)
        : m_orderedNamedGridLines(isRowAxis ? style.orderedNamedGridColumnLines() : style.orderedNamedGridRowLines())
        , m_orderedNamedAutoRepeatGridLines(isRowAxis ? style.autoRepeatOrderedNamedGridColumnLines() : style.autoRepeatOrderedNamedGridRowLines())
    {
    }
    virtual ~OrderedNamedLinesCollector() = default;

    bool isEmpty() const { return m_orderedNamedGridLines.isEmpty() && m_orderedNamedAutoRepeatGridLines.isEmpty(); }
    virtual void collectLineNamesForIndex(CSSGridLineNamesValue&, unsigned index) const;

protected:

    enum NamedLinesType { NamedLines, AutoRepeatNamedLines };
    void appendLines(CSSGridLineNamesValue&, unsigned index, NamedLinesType) const;

    const OrderedNamedGridLinesMap& m_orderedNamedGridLines;
    const OrderedNamedGridLinesMap& m_orderedNamedAutoRepeatGridLines;
};

class OrderedNamedLinesCollectorInsideRepeat : public OrderedNamedLinesCollector {
public:
    OrderedNamedLinesCollectorInsideRepeat(const RenderStyle& style, bool isRowAxis)
        : OrderedNamedLinesCollector(style, isRowAxis)
    {
    }

    void collectLineNamesForIndex(CSSGridLineNamesValue&, unsigned index) const override;
};

class OrderedNamedLinesCollectorInGridLayout : public OrderedNamedLinesCollector {
public:
    OrderedNamedLinesCollectorInGridLayout(const RenderStyle& style, bool isRowAxis, unsigned autoRepeatTracksCount, unsigned autoRepeatTrackListLength)
        : OrderedNamedLinesCollector(style, isRowAxis)
        , m_insertionPoint(isRowAxis ? style.gridAutoRepeatColumnsInsertionPoint() : style.gridAutoRepeatRowsInsertionPoint())
        , m_autoRepeatTotalTracks(autoRepeatTracksCount)
        , m_autoRepeatTrackListLength(autoRepeatTrackListLength)
    {
    }

    void collectLineNamesForIndex(CSSGridLineNamesValue&, unsigned index) const override;

private:
    unsigned m_insertionPoint;
    unsigned m_autoRepeatTotalTracks;
    unsigned m_autoRepeatTrackListLength;
};

void OrderedNamedLinesCollector::appendLines(CSSGridLineNamesValue& lineNamesValue, unsigned index, NamedLinesType type) const
{
    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();
    for (const auto& lineName : iter->value)
        lineNamesValue.append(cssValuePool.createCustomIdent(lineName));
}

void OrderedNamedLinesCollector::collectLineNamesForIndex(CSSGridLineNamesValue& lineNamesValue, unsigned i) const
{
    ASSERT(!isEmpty());
    appendLines(lineNamesValue, i, NamedLines);
}

void OrderedNamedLinesCollectorInsideRepeat::collectLineNamesForIndex(CSSGridLineNamesValue& lineNamesValue, unsigned i) const
{
    ASSERT(!isEmpty());
    appendLines(lineNamesValue, i, AutoRepeatNamedLines);
}

void OrderedNamedLinesCollectorInGridLayout::collectLineNamesForIndex(CSSGridLineNamesValue& lineNamesValue, unsigned i) const
{
    ASSERT(!isEmpty());
    if (!m_autoRepeatTrackListLength || 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;
}

template <typename T, typename F>
void populateGridTrackList(CSSValueList& list, OrderedNamedLinesCollector& collector, const Vector<T>& tracks, F getTrackSize, int start, int end, int offset = 0)
{
    ASSERT(0 <= start);
    ASSERT(start <= end);
    ASSERT(static_cast<unsigned>(end) <= tracks.size());
    for (int i = start; i < end; ++i) {
        if (i + offset >= 0)
            addValuesForNamedGridLinesAtIndex(collector, i + offset, list);
        list.append(getTrackSize(tracks[i]));
    }
    if (end + offset >= 0)
        addValuesForNamedGridLinesAtIndex(collector, end + offset, list);
}

template <typename T, typename F>
void populateGridTrackList(CSSValueList& list, OrderedNamedLinesCollector& collector, const Vector<T>& tracks, F getTrackSize, int offset = 0)
{
    populateGridTrackList<T>(list, collector, tracks, getTrackSize, 0, tracks.size(), offset);
}

static Ref<CSSValue> valueForGridTrackList(GridTrackSizingDirection direction, RenderObject* renderer, const RenderStyle& style)
{
    bool isRowAxis = direction == ForColumns;
    bool isRenderGrid = is<RenderGrid>(renderer);
    auto& trackSizes = isRowAxis ? style.gridColumns() : style.gridRows();
    auto& autoRepeatTrackSizes = isRowAxis ? style.gridAutoRepeatColumns() : style.gridAutoRepeatRows();

    // Handle the 'none' case.
    bool trackListIsEmpty = trackSizes.isEmpty() && autoRepeatTrackSizes.isEmpty();
    if (isRenderGrid && trackListIsEmpty) {
        // For grids we should consider every listed track, whether implicitly or explicitly
        // created. Empty grids have a sole grid line per axis.
        auto& grid = downcast<RenderGrid>(*renderer);
        auto& positions = isRowAxis ? grid.columnPositions() : grid.rowPositions();
        trackListIsEmpty = positions.size() == 1;
    }

    if (trackListIsEmpty)
        return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);

    auto list = CSSValueList::createSpaceSeparated();

    // If the element is a grid container, the resolved value is the used value,
    // specifying track sizes in pixels and expanding the repeat() notation.
    if (isRenderGrid) {
        auto* grid = downcast<RenderGrid>(renderer);
        OrderedNamedLinesCollectorInGridLayout collector(style, isRowAxis, grid->autoRepeatCountForDirection(direction), autoRepeatTrackSizes.size());
        // Named grid line indices are relative to the explicit grid, but we are including all tracks.
        // So we need to subtract the number of leading implicit tracks in order to get the proper line index.
        int offset = -grid->explicitGridStartForDirection(direction);
        populateGridTrackList(list.get(), collector, grid->trackSizesForComputedStyle(direction), [&](const LayoutUnit& v) {
            return zoomAdjustedPixelValue(v, style);
        }, offset);
        return list;
    }

    // Otherwise, the resolved value is the computed value, preserving repeat().
    OrderedNamedLinesCollector collector(style, isRowAxis);
    auto getTrackSize = [&](const GridTrackSize& v) {
        return specifiedValueForGridTrackSize(v, style);
    };

    if (autoRepeatTrackSizes.isEmpty()) {
        // If there's no auto repeat(), just add all the line names and track sizes.
        populateGridTrackList(list.get(), collector, trackSizes, getTrackSize);
        return list;
    }

    // Add the line names and track sizes that precede the auto repeat().
    int autoRepeatInsertionPoint = std::clamp<int>(isRowAxis ? style.gridAutoRepeatColumnsInsertionPoint() : style.gridAutoRepeatRowsInsertionPoint(), 0, trackSizes.size());
    populateGridTrackList(list.get(), collector, trackSizes, getTrackSize, 0, autoRepeatInsertionPoint);

    // Add a CSSGridAutoRepeatValue with the contents of the auto repeat().
    AutoRepeatType autoRepeatType = isRowAxis ? style.gridAutoRepeatColumnsType() : style.gridAutoRepeatRowsType();
    auto repeatedValues = CSSGridAutoRepeatValue::create(autoRepeatType == AutoRepeatType::Fill ? CSSValueAutoFill : CSSValueAutoFit);
    OrderedNamedLinesCollectorInsideRepeat repeatCollector(style, isRowAxis);
    populateGridTrackList(repeatedValues.get(), repeatCollector, autoRepeatTrackSizes, getTrackSize);
    list->append(repeatedValues.get());

    // Add the line names and track sizes that follow the auto repeat().
    populateGridTrackList(list.get(), collector, trackSizes, getTrackSize, autoRepeatInsertionPoint, trackSizes.size(), 1);
    return list;
}

static Ref<CSSValue> valueForGridPosition(const GridPosition& position)
{
    auto& cssValuePool = CSSValuePool::singleton();
    if (position.isAuto())
        return cssValuePool.createIdentifierValue(CSSValueAuto);

    if (position.isNamedGridArea())
        return cssValuePool.createCustomIdent(position.namedGridLine());

    auto list = CSSValueList::createSpaceSeparated();
    if (position.isSpan()) {
        list->append(cssValuePool.createIdentifierValue(CSSValueSpan));
        list->append(cssValuePool.createValue(position.spanPosition(), CSSUnitType::CSS_NUMBER));
    } else
        list->append(cssValuePool.createValue(position.integerPosition(), CSSUnitType::CSS_NUMBER));

    if (!position.namedGridLine().isNull())
        list->append(cssValuePool.createCustomIdent(position.namedGridLine()));
    return list;
}

static Ref<CSSValue> createTransitionPropertyValue(const Animation& animation)
{
    switch (animation.property().mode) {
    case Animation::TransitionMode::None:
        return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
    case Animation::TransitionMode::All:
        return CSSValuePool::singleton().createIdentifierValue(CSSValueAll);
    case Animation::TransitionMode::SingleProperty:
        return CSSValuePool::singleton().createCustomIdent(getPropertyNameString(animation.property().id));
    case Animation::TransitionMode::UnknownProperty:
        return CSSValuePool::singleton().createCustomIdent(animation.unknownProperty());
    }
    ASSERT_NOT_REACHED();
    return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
}

static Ref<CSSValueList> transitionPropertyValue(const AnimationList* animationList)
{
    auto list = CSSValueList::createCommaSeparated();
    if (animationList) {
        for (size_t i = 0; i < animationList->size(); ++i)
            list->append(createTransitionPropertyValue(animationList->animation(i)));
    } else
        list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueAll));
    return list;
}

static Ref<CSSValueList> valueForScrollSnapType(const ScrollSnapType& type)
{
    auto value = CSSValueList::createSpaceSeparated();
    if (type.strictness == ScrollSnapStrictness::None)
        value->append(CSSValuePool::singleton().createValue(CSSValueNone));
    else {
        value->append(CSSPrimitiveValue::create(type.axis));
        if (type.strictness != ScrollSnapStrictness::Proximity)
            value->append(CSSPrimitiveValue::create(type.strictness));
    }
    return value;
}

static Ref<CSSValueList> valueForScrollSnapAlignment(const ScrollSnapAlign& alignment)
{
    auto value = CSSValueList::createSpaceSeparated();
    value->append(CSSPrimitiveValue::create(alignment.blockAlign));
    if (alignment.inlineAlign != alignment.blockAlign)
        value->append(CSSPrimitiveValue::create(alignment.inlineAlign));
    return value;
}

static Ref<CSSValue> willChangePropertyValue(const WillChangeData* willChangeData)
{
    auto& cssValuePool = CSSValuePool::singleton();
    if (!willChangeData || !willChangeData->numFeatures())
        return cssValuePool.createIdentifierValue(CSSValueAuto);

    auto list = CSSValueList::createCommaSeparated();
    for (size_t i = 0; i < willChangeData->numFeatures(); ++i) {
        WillChangeData::FeaturePropertyPair feature = willChangeData->featureAt(i);
        switch (feature.first) {
        case WillChangeData::ScrollPosition:
            list->append(cssValuePool.createIdentifierValue(CSSValueScrollPosition));
            break;
        case WillChangeData::Contents:
            list->append(cssValuePool.createIdentifierValue(CSSValueContents));
            break;
        case WillChangeData::Property:
            list->append(cssValuePool.createIdentifierValue(feature.second));
            break;
        case WillChangeData::Invalid:
            ASSERT_NOT_REACHED();
            break;
        }
    }

    return list;
}

static inline void appendLigaturesValue(CSSValueList& list, FontVariantLigatures value, CSSValueID yesValue, CSSValueID noValue)
{
    switch (value) {
    case FontVariantLigatures::Normal:
        return;
    case FontVariantLigatures::No:
        list.append(CSSValuePool::singleton().createIdentifierValue(noValue));
        return;
    case FontVariantLigatures::Yes:
        list.append(CSSValuePool::singleton().createIdentifierValue(yesValue));
        return;
    }
    ASSERT_NOT_REACHED();
}

static Ref<CSSValue> fontVariantLigaturesPropertyValue(FontVariantLigatures common, FontVariantLigatures discretionary, FontVariantLigatures historical, FontVariantLigatures contextualAlternates)
{
    auto& cssValuePool = CSSValuePool::singleton();
    if (common == FontVariantLigatures::No && discretionary == FontVariantLigatures::No && historical == FontVariantLigatures::No && contextualAlternates == FontVariantLigatures::No)
        return cssValuePool.createIdentifierValue(CSSValueNone);
    if (common == FontVariantLigatures::Normal && discretionary == FontVariantLigatures::Normal && historical == FontVariantLigatures::Normal && contextualAlternates == FontVariantLigatures::Normal)
        return cssValuePool.createIdentifierValue(CSSValueNormal);

    auto valueList = CSSValueList::createSpaceSeparated();
    appendLigaturesValue(valueList, common, CSSValueCommonLigatures, CSSValueNoCommonLigatures);
    appendLigaturesValue(valueList, discretionary, CSSValueDiscretionaryLigatures, CSSValueNoDiscretionaryLigatures);
    appendLigaturesValue(valueList, historical, CSSValueHistoricalLigatures, CSSValueNoHistoricalLigatures);
    appendLigaturesValue(valueList, contextualAlternates, CSSValueContextual, CSSValueNoContextual);
    return valueList;
}

static Ref<CSSValue> fontVariantPositionPropertyValue(FontVariantPosition position)
{
    auto& cssValuePool = CSSValuePool::singleton();
    CSSValueID valueID = CSSValueNormal;
    switch (position) {
    case FontVariantPosition::Normal:
        break;
    case FontVariantPosition::Subscript:
        valueID = CSSValueSub;
        break;
    case FontVariantPosition::Superscript:
        valueID = CSSValueSuper;
        break;
    }
    return cssValuePool.createIdentifierValue(valueID);
}

static Ref<CSSValue> fontVariantCapsPropertyValue(FontVariantCaps caps)
{
    auto& cssValuePool = CSSValuePool::singleton();
    CSSValueID valueID = CSSValueNormal;
    switch (caps) {
    case FontVariantCaps::Normal:
        break;
    case FontVariantCaps::Small:
        valueID = CSSValueSmallCaps;
        break;
    case FontVariantCaps::AllSmall:
        valueID = CSSValueAllSmallCaps;
        break;
    case FontVariantCaps::Petite:
        valueID = CSSValuePetiteCaps;
        break;
    case FontVariantCaps::AllPetite:
        valueID = CSSValueAllPetiteCaps;
        break;
    case FontVariantCaps::Unicase:
        valueID = CSSValueUnicase;
        break;
    case FontVariantCaps::Titling:
        valueID = CSSValueTitlingCaps;
        break;
    }
    return cssValuePool.createIdentifierValue(valueID);
}

static Ref<CSSValue> fontVariantNumericPropertyValue(FontVariantNumericFigure figure, FontVariantNumericSpacing spacing, FontVariantNumericFraction fraction, FontVariantNumericOrdinal ordinal, FontVariantNumericSlashedZero slashedZero)
{
    auto& cssValuePool = CSSValuePool::singleton();
    if (figure == FontVariantNumericFigure::Normal && spacing == FontVariantNumericSpacing::Normal && fraction == FontVariantNumericFraction::Normal && ordinal == FontVariantNumericOrdinal::Normal && slashedZero == FontVariantNumericSlashedZero::Normal)
        return cssValuePool.createIdentifierValue(CSSValueNormal);

    auto valueList = CSSValueList::createSpaceSeparated();
    switch (figure) {
    case FontVariantNumericFigure::Normal:
        break;
    case FontVariantNumericFigure::LiningNumbers:
        valueList->append(cssValuePool.createIdentifierValue(CSSValueLiningNums));
        break;
    case FontVariantNumericFigure::OldStyleNumbers:
        valueList->append(cssValuePool.createIdentifierValue(CSSValueOldstyleNums));
        break;
    }

    switch (spacing) {
    case FontVariantNumericSpacing::Normal:
        break;
    case FontVariantNumericSpacing::ProportionalNumbers:
        valueList->append(cssValuePool.createIdentifierValue(CSSValueProportionalNums));
        break;
    case FontVariantNumericSpacing::TabularNumbers:
        valueList->append(cssValuePool.createIdentifierValue(CSSValueTabularNums));
        break;
    }

    switch (fraction) {
    case FontVariantNumericFraction::Normal:
        break;
    case FontVariantNumericFraction::DiagonalFractions:
        valueList->append(cssValuePool.createIdentifierValue(CSSValueDiagonalFractions));
        break;
    case FontVariantNumericFraction::StackedFractions:
        valueList->append(cssValuePool.createIdentifierValue(CSSValueStackedFractions));
        break;
    }

    if (ordinal == FontVariantNumericOrdinal::Yes)
        valueList->append(cssValuePool.createIdentifierValue(CSSValueOrdinal));
    if (slashedZero == FontVariantNumericSlashedZero::Yes)
        valueList->append(cssValuePool.createIdentifierValue(CSSValueSlashedZero));

    return valueList;
}

static Ref<CSSValue> fontVariantAlternatesPropertyValue(FontVariantAlternates alternates)
{
    auto& cssValuePool = CSSValuePool::singleton();
    CSSValueID valueID = CSSValueNormal;
    switch (alternates) {
    case FontVariantAlternates::Normal:
        break;
    case FontVariantAlternates::HistoricalForms:
        valueID = CSSValueHistoricalForms;
        break;
    }
    return cssValuePool.createIdentifierValue(valueID);
}

static Ref<CSSValue> fontVariantEastAsianPropertyValue(FontVariantEastAsianVariant variant, FontVariantEastAsianWidth width, FontVariantEastAsianRuby ruby)
{
    auto& cssValuePool = CSSValuePool::singleton();
    if (variant == FontVariantEastAsianVariant::Normal && width == FontVariantEastAsianWidth::Normal && ruby == FontVariantEastAsianRuby::Normal)
        return cssValuePool.createIdentifierValue(CSSValueNormal);

    auto valueList = CSSValueList::createSpaceSeparated();
    switch (variant) {
    case FontVariantEastAsianVariant::Normal:
        break;
    case FontVariantEastAsianVariant::Jis78:
        valueList->append(cssValuePool.createIdentifierValue(CSSValueJis78));
        break;
    case FontVariantEastAsianVariant::Jis83:
        valueList->append(cssValuePool.createIdentifierValue(CSSValueJis83));
        break;
    case FontVariantEastAsianVariant::Jis90:
        valueList->append(cssValuePool.createIdentifierValue(CSSValueJis90));
        break;
    case FontVariantEastAsianVariant::Jis04:
        valueList->append(cssValuePool.createIdentifierValue(CSSValueJis04));
        break;
    case FontVariantEastAsianVariant::Simplified:
        valueList->append(cssValuePool.createIdentifierValue(CSSValueSimplified));
        break;
    case FontVariantEastAsianVariant::Traditional:
        valueList->append(cssValuePool.createIdentifierValue(CSSValueTraditional));
        break;
    }

    switch (width) {
    case FontVariantEastAsianWidth::Normal:
        break;
    case FontVariantEastAsianWidth::Full:
        valueList->append(cssValuePool.createIdentifierValue(CSSValueFullWidth));
        break;
    case FontVariantEastAsianWidth::Proportional:
        valueList->append(cssValuePool.createIdentifierValue(CSSValueProportionalWidth));
        break;
    }

    if (ruby == FontVariantEastAsianRuby::Yes)
        valueList->append(cssValuePool.createIdentifierValue(CSSValueRuby));

    return valueList;
}

static Ref<CSSValueList> delayValue(const AnimationList* animationList)
{
    auto& cssValuePool = CSSValuePool::singleton();
    auto list = CSSValueList::createCommaSeparated();
    if (animationList) {
        for (size_t i = 0; i < animationList->size(); ++i)
            list->append(cssValuePool.createValue(animationList->animation(i).delay(), CSSUnitType::CSS_S));
    } else {
        // Note that initialAnimationDelay() is used for both transitions and animations
        list->append(cssValuePool.createValue(Animation::initialDelay(), CSSUnitType::CSS_S));
    }
    return list;
}

static Ref<CSSValueList> durationValue(const AnimationList* animationList)
{
    auto& cssValuePool = CSSValuePool::singleton();
    auto list = CSSValueList::createCommaSeparated();
    if (animationList) {
        for (size_t i = 0; i < animationList->size(); ++i)
            list->append(cssValuePool.createValue(animationList->animation(i).duration(), CSSUnitType::CSS_S));
    } else {
        // Note that initialAnimationDuration() is used for both transitions and animations
        list->append(cssValuePool.createValue(Animation::initialDuration(), CSSUnitType::CSS_S));
    }
    return list;
}

static Ref<CSSValue> createTimingFunctionValue(const TimingFunction& timingFunction)
{
    switch (timingFunction.type()) {
    case TimingFunction::CubicBezierFunction: {
        auto& function = downcast<CubicBezierTimingFunction>(timingFunction);
        if (function.timingFunctionPreset() != CubicBezierTimingFunction::Custom) {
            CSSValueID valueId = CSSValueInvalid;
            switch (function.timingFunctionPreset()) {
            case CubicBezierTimingFunction::Ease:
                valueId = CSSValueEase;
                break;
            case CubicBezierTimingFunction::EaseIn:
                valueId = CSSValueEaseIn;
                break;
            case CubicBezierTimingFunction::EaseOut:
                valueId = CSSValueEaseOut;
                break;
            default:
                ASSERT(function.timingFunctionPreset() == CubicBezierTimingFunction::EaseInOut);
                valueId = CSSValueEaseInOut;
                break;
            }
            return CSSValuePool::singleton().createIdentifierValue(valueId);
        }
        return CSSCubicBezierTimingFunctionValue::create(function.x1(), function.y1(), function.x2(), function.y2());
    }
    case TimingFunction::StepsFunction: {
        auto& function = downcast<StepsTimingFunction>(timingFunction);
        return CSSStepsTimingFunctionValue::create(function.numberOfSteps(), function.stepPosition());
    }
    case TimingFunction::SpringFunction: {
        auto& function = downcast<SpringTimingFunction>(timingFunction);
        return CSSSpringTimingFunctionValue::create(function.mass(), function.stiffness(), function.damping(), function.initialVelocity());
    }
    default:
        ASSERT(timingFunction.type() == TimingFunction::LinearFunction);
        return CSSValuePool::singleton().createIdentifierValue(CSSValueLinear);
    }
}

static Ref<CSSValueList> timingFunctionValue(const AnimationList* animationList)
{
    auto list = CSSValueList::createCommaSeparated();
    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->append(createTimingFunctionValue(Animation::initialTimingFunction()));
    return list;
}

static Ref<CSSValue> createLineBoxContainValue(OptionSet<LineBoxContain> lineBoxContain)
{
    if (!lineBoxContain)
        return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
    return CSSLineBoxContainValue::create(lineBoxContain);
}

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(Element& element, bool allowVisitedStyle, StringView pseudoElementName)
    : m_element(element)
    , m_allowVisitedStyle(allowVisitedStyle)
{
    StringView name = pseudoElementName;
    if (name.startsWith(':'))
        name = name.substring(1);
    if (name.startsWith(':'))
        name = name.substring(1);
    m_pseudoElementSpecifier = CSSSelector::pseudoId(CSSSelector::parsePseudoElementType(name));
}

CSSComputedStyleDeclaration::~CSSComputedStyleDeclaration() = default;

Ref<CSSComputedStyleDeclaration> CSSComputedStyleDeclaration::create(Element& element, bool allowVisitedStyle, StringView pseudoElementName)
{
    return adoptRef(*new CSSComputedStyleDeclaration(element, allowVisitedStyle, pseudoElementName));
}

void CSSComputedStyleDeclaration::ref()
{
    ++m_refCount;
}

void CSSComputedStyleDeclaration::deref()
{
    ASSERT(m_refCount);
    if (!--m_refCount)
        delete this;
}

String CSSComputedStyleDeclaration::cssText() const
{
    StringBuilder result;
    for (unsigned i = 0; i < numComputedPropertyIDs; i++) {
        if (i)
            result.append(' ');
        result.append(getPropertyName(computedPropertyIDs[i]), ": ", getPropertyValue(computedPropertyIDs[i]), ';');
    }
    return result.toString();
}

ExceptionOr<void> CSSComputedStyleDeclaration::setCssText(const String&)
{
    return Exception { NoModificationAllowedError };
}

RefPtr<CSSPrimitiveValue> ComputedStyleExtractor::getFontSizeCSSValuePreferringKeyword()
{
    if (!m_element)
        return nullptr;

    m_element->document().updateLayoutIgnorePendingStylesheets();

    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().computedSize(), *style);
}

bool ComputedStyleExtractor::useFixedFontDefaultSize()
{
    if (!m_element)
        return false;
    auto* style = m_element->computedStyle(m_pseudoElementSpecifier);
    if (!style)
        return false;

    return style->fontDescription().useFixedDefaultSize();
}

static CSSValueID identifierForFamily(const AtomString& family)
{
    if (family == cursiveFamily)
        return CSSValueCursive;
    if (family == fantasyFamily)
        return CSSValueFantasy;
    if (family == monospaceFamily)
        return CSSValueMonospace;
    if (family == pictographFamily)
        return CSSValueWebkitPictograph;
    if (family == sansSerifFamily)
        return CSSValueSansSerif;
    if (family == serifFamily)
        return CSSValueSerif;
    if (family == systemUiFamily)
        return CSSValueSystemUi;
    return CSSValueInvalid;
}

static Ref<CSSPrimitiveValue> valueForFamily(const AtomString& family)
{
    if (CSSValueID familyIdentifier = identifierForFamily(family))
        return CSSValuePool::singleton().createIdentifierValue(familyIdentifier);
    return CSSValuePool::singleton().createFontFamilyValue(family);
}

static Ref<CSSValue> touchActionFlagsToCSSValue(OptionSet<TouchAction> touchActions)
{
    auto& cssValuePool = CSSValuePool::singleton();

    if (touchActions & TouchAction::Auto)
        return cssValuePool.createIdentifierValue(CSSValueAuto);
    if (touchActions & TouchAction::None)
        return cssValuePool.createIdentifierValue(CSSValueNone);
    if (touchActions & TouchAction::Manipulation)
        return cssValuePool.createIdentifierValue(CSSValueManipulation);

    auto list = CSSValueList::createSpaceSeparated();
    if (touchActions & TouchAction::PanX)
        list->append(cssValuePool.createIdentifierValue(CSSValuePanX));
    if (touchActions & TouchAction::PanY)
        list->append(cssValuePool.createIdentifierValue(CSSValuePanY));
    if (touchActions & TouchAction::PinchZoom)
        list->append(cssValuePool.createIdentifierValue(CSSValuePinchZoom));

    if (!list->length())
        return cssValuePool.createIdentifierValue(CSSValueAuto);
    return list;
}

static Ref<CSSValue> renderTextDecorationFlagsToCSSValue(OptionSet<TextDecoration> textDecoration)
{
    auto& cssValuePool = CSSValuePool::singleton();
    // Blink value is ignored.
    auto list = CSSValueList::createSpaceSeparated();
    if (textDecoration & TextDecoration::Underline)
        list->append(cssValuePool.createIdentifierValue(CSSValueUnderline));
    if (textDecoration & TextDecoration::Overline)
        list->append(cssValuePool.createIdentifierValue(CSSValueOverline));
    if (textDecoration & TextDecoration::LineThrough)
        list->append(cssValuePool.createIdentifierValue(CSSValueLineThrough));

    if (!list->length())
        return cssValuePool.createIdentifierValue(CSSValueNone);
    return list;
}

static Ref<CSSValue> renderTextDecorationStyleFlagsToCSSValue(TextDecorationStyle textDecorationStyle)
{
    switch (textDecorationStyle) {
    case TextDecorationStyle::Solid:
        return CSSValuePool::singleton().createIdentifierValue(CSSValueSolid);
    case TextDecorationStyle::Double:
        return CSSValuePool::singleton().createIdentifierValue(CSSValueDouble);
    case TextDecorationStyle::Dotted:
        return CSSValuePool::singleton().createIdentifierValue(CSSValueDotted);
    case TextDecorationStyle::Dashed:
        return CSSValuePool::singleton().createIdentifierValue(CSSValueDashed);
    case TextDecorationStyle::Wavy:
        return CSSValuePool::singleton().createIdentifierValue(CSSValueWavy);
    }

    ASSERT_NOT_REACHED();
    return CSSValuePool::singleton().createExplicitInitialValue();
}

static RefPtr<CSSValue> renderTextDecorationSkipToCSSValue(TextDecorationSkipInk textDecorationSkipInk)
{
    switch (textDecorationSkipInk) {
    case TextDecorationSkipInk::None:
        return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
    case TextDecorationSkipInk::Auto:
        return CSSValuePool::singleton().createIdentifierValue(CSSValueAuto);
    case TextDecorationSkipInk::All:
        return nullptr;
    }

    ASSERT_NOT_REACHED();
    return CSSValuePool::singleton().createExplicitInitialValue();
}

static Ref<CSSValue> textUnderlineOffsetToCSSValue(const TextUnderlineOffset& textUnderlineOffset)
{
    if (textUnderlineOffset.isAuto())
        return CSSValuePool::singleton().createIdentifierValue(CSSValueAuto);
    ASSERT(textUnderlineOffset.isLength());
    return CSSValuePool::singleton().createValue(textUnderlineOffset.lengthValue(), CSSUnitType::CSS_PX);
}

static Ref<CSSValue> textDecorationThicknessToCSSValue(const TextDecorationThickness& textDecorationThickness)
{
    if (textDecorationThickness.isAuto())
        return CSSValuePool::singleton().createIdentifierValue(CSSValueAuto);
    if (textDecorationThickness.isFromFont())
        return CSSValuePool::singleton().createIdentifierValue(CSSValueFromFont);
    ASSERT(textDecorationThickness.isLength());
    return CSSValuePool::singleton().createValue(textDecorationThickness.lengthValue(), CSSUnitType::CSS_PX);
}

static Ref<CSSValue> renderEmphasisPositionFlagsToCSSValue(OptionSet<TextEmphasisPosition> textEmphasisPosition)
{
    ASSERT(!((textEmphasisPosition & TextEmphasisPosition::Over) && (textEmphasisPosition & TextEmphasisPosition::Under)));
    ASSERT(!((textEmphasisPosition & TextEmphasisPosition::Left) && (textEmphasisPosition & TextEmphasisPosition::Right)));
    auto& cssValuePool = CSSValuePool::singleton();
    auto list = CSSValueList::createSpaceSeparated();
    if (textEmphasisPosition & TextEmphasisPosition::Over)
        list->append(cssValuePool.createIdentifierValue(CSSValueOver));
    if (textEmphasisPosition & TextEmphasisPosition::Under)
        list->append(cssValuePool.createIdentifierValue(CSSValueUnder));
    if (textEmphasisPosition & TextEmphasisPosition::Left)
        list->append(cssValuePool.createIdentifierValue(CSSValueLeft));
    if (textEmphasisPosition & TextEmphasisPosition::Right)
        list->append(cssValuePool.createIdentifierValue(CSSValueRight));
    if (!list->length())
        return cssValuePool.createIdentifierValue(CSSValueNone);
    return list;
}

static Ref<CSSValue> speakAsToCSSValue(OptionSet<SpeakAs> speakAs)
{
    auto& cssValuePool = CSSValuePool::singleton();
    auto list = CSSValueList::createSpaceSeparated();
    if (speakAs & SpeakAs::SpellOut)
        list->append(cssValuePool.createIdentifierValue(CSSValueSpellOut));
    if (speakAs & SpeakAs::Digits)
        list->append(cssValuePool.createIdentifierValue(CSSValueDigits));
    if (speakAs & SpeakAs::LiteralPunctuation)
        list->append(cssValuePool.createIdentifierValue(CSSValueLiteralPunctuation));
    if (speakAs & SpeakAs::NoPunctuation)
        list->append(cssValuePool.createIdentifierValue(CSSValueNoPunctuation));
    if (!list->length())
        return cssValuePool.createIdentifierValue(CSSValueNormal);
    return list;
}
    
static Ref<CSSValue> hangingPunctuationToCSSValue(OptionSet<HangingPunctuation> hangingPunctuation)
{
    auto& cssValuePool = CSSValuePool::singleton();
    auto list = CSSValueList::createSpaceSeparated();
    if (hangingPunctuation & HangingPunctuation::First)
        list->append(cssValuePool.createIdentifierValue(CSSValueFirst));
    if (hangingPunctuation & HangingPunctuation::AllowEnd)
        list->append(cssValuePool.createIdentifierValue(CSSValueAllowEnd));
    if (hangingPunctuation & HangingPunctuation::ForceEnd)
        list->append(cssValuePool.createIdentifierValue(CSSValueForceEnd));
    if (hangingPunctuation & HangingPunctuation::Last)
        list->append(cssValuePool.createIdentifierValue(CSSValueLast));
    if (!list->length())
        return cssValuePool.createIdentifierValue(CSSValueNone);
    return list;
}
    
static Ref<CSSValue> fillRepeatToCSSValue(FillRepeat xRepeat, FillRepeat yRepeat)
{
    // For backwards compatibility, if both values are equal, just return one of them. And
    // if the two values are equivalent to repeat-x or repeat-y, just return the shorthand.
    auto& cssValuePool = CSSValuePool::singleton();
    if (xRepeat == yRepeat)
        return cssValuePool.createValue(xRepeat);
    if (xRepeat == FillRepeat::Repeat && yRepeat == FillRepeat::NoRepeat)
        return cssValuePool.createIdentifierValue(CSSValueRepeatX);
    if (xRepeat == FillRepeat::NoRepeat && yRepeat == FillRepeat::Repeat)
        return cssValuePool.createIdentifierValue(CSSValueRepeatY);

    auto list = CSSValueList::createSpaceSeparated();
    list->append(cssValuePool.createValue(xRepeat));
    list->append(cssValuePool.createValue(yRepeat));
    return list;
}

static Ref<CSSValue> maskSourceTypeToCSSValue(MaskMode type)
{
    switch (type) {
    case MaskMode::Alpha:
        return CSSValuePool::singleton().createValue(CSSValueAlpha);
    case MaskMode::Luminance:
        ASSERT(type == MaskMode::Luminance);
        return CSSValuePool::singleton().createValue(CSSValueLuminance);
    case MaskMode::MatchSource:
        // MatchSource is only available in the mask-mode property.
        return CSSValuePool::singleton().createValue(CSSValueAlpha);
    }
    ASSERT_NOT_REACHED();
    return CSSValuePool::singleton().createValue(CSSValueAlpha);
}

static Ref<CSSValue> maskModeToCSSValue(MaskMode type)
{
    switch (type) {
    case MaskMode::Alpha:
        return CSSValuePool::singleton().createValue(CSSValueAlpha);
    case MaskMode::Luminance:
        return CSSValuePool::singleton().createValue(CSSValueLuminance);
    case MaskMode::MatchSource:
        return CSSValuePool::singleton().createValue(CSSValueMatchSource);
    }
    ASSERT_NOT_REACHED();
    return CSSValuePool::singleton().createValue(CSSValueMatchSource);
}

static Ref<CSSValue> fillSizeToCSSValue(const FillSize& fillSize, const RenderStyle& style)
{
    if (fillSize.type == FillSizeType::Contain)
        return CSSValuePool::singleton().createIdentifierValue(CSSValueContain);

    if (fillSize.type == FillSizeType::Cover)
        return CSSValuePool::singleton().createIdentifierValue(CSSValueCover);

    if (fillSize.size.height.isAuto())
        return zoomAdjustedPixelValueForLength(fillSize.size.width, style);

    auto list = CSSValueList::createSpaceSeparated();
    list->append(zoomAdjustedPixelValueForLength(fillSize.size.width, style));
    list->append(zoomAdjustedPixelValueForLength(fillSize.size.height, style));
    return list;
}

static Ref<CSSValue> altTextToCSSValue(const RenderStyle& style)
{
    return CSSValuePool::singleton().createValue(style.contentAltText(), CSSUnitType::CSS_STRING);
}
    
static Ref<CSSValueList> contentToCSSValue(const RenderStyle& style)
{
    auto& cssValuePool = CSSValuePool::singleton();
    auto list = CSSValueList::createSpaceSeparated();
    for (auto* contentData = style.contentData(); contentData; contentData = contentData->next()) {
        if (is<CounterContentData>(*contentData))
            list->append(cssValuePool.createValue(downcast<CounterContentData>(*contentData).counter().identifier(), CSSUnitType::CSS_COUNTER_NAME));
        else if (is<ImageContentData>(*contentData))
            list->append(downcast<ImageContentData>(*contentData).image().cssValue());
        else if (is<TextContentData>(*contentData))
            list->append(cssValuePool.createValue(downcast<TextContentData>(*contentData).text(), CSSUnitType::CSS_STRING));
    }
    return list;
}

static Ref<CSSValue> counterToCSSValue(const RenderStyle& style, CSSPropertyID propertyID)
{
    auto* map = style.counterDirectives();
    if (!map)
        return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);

    auto& cssValuePool = CSSValuePool::singleton();
    auto list = CSSValueList::createSpaceSeparated();
    for (auto& keyValue : *map) {
        list->append(cssValuePool.createCustomIdent(keyValue.key));
        double number = (propertyID == CSSPropertyCounterIncrement ? keyValue.value.incrementValue : keyValue.value.resetValue).value_or(0);
        list->append(cssValuePool.createValue(number, CSSUnitType::CSS_NUMBER));
    }
    return list;
}

static Ref<CSSValueList> fontFamilyListFromStyle(const RenderStyle& style)
{
    auto list = CSSValueList::createCommaSeparated();
    for (unsigned i = 0; i < style.fontCascade().familyCount(); ++i)
        list->append(valueForFamily(style.fontCascade().familyAt(i)));
    return list;
}

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())
        return CSSValuePool::singleton().createIdentifierValue(CSSValueNormal);
    if (length.isPercent()) {
        // This is imperfect, because it doesn't include the zoom factor and the real computation
        // for how high to be in pixels does include things like minimum font size and the zoom factor.
        // On the other hand, since font-size doesn't include the zoom factor, we really can't do
        // that here either.
        return zoomAdjustedPixelValue(static_cast<double>(length.percent() * style.fontDescription().computedSize()) / 100, style);
    }
    return zoomAdjustedPixelValue(floatValueForLength(length, 0), style);
}

static Ref<CSSPrimitiveValue> fontSizeFromStyle(const RenderStyle& style)
{
    return zoomAdjustedPixelValue(style.fontDescription().computedSize(), style);
}

static Ref<CSSPrimitiveValue> fontPaletteFromStyle(const RenderStyle& style)
{
    auto fontPalette = style.fontDescription().fontPalette();
    switch (fontPalette.type) {
    case FontPalette::Type::Normal:
        return CSSValuePool::singleton().createIdentifierValue(CSSValueNormal);
    case FontPalette::Type::Light:
        return CSSValuePool::singleton().createIdentifierValue(CSSValueLight);
    case FontPalette::Type::Dark:
        return CSSValuePool::singleton().createIdentifierValue(CSSValueDark);
    case FontPalette::Type::Custom:
        return CSSValuePool::singleton().createCustomIdent(fontPalette.identifier);
    }
    RELEASE_ASSERT_NOT_REACHED();
}

Ref<CSSPrimitiveValue> ComputedStyleExtractor::fontNonKeywordWeightFromStyleValue(FontSelectionValue weight)
{
    return CSSValuePool::singleton().createValue(static_cast<float>(weight), CSSUnitType::CSS_NUMBER);
}

static Ref<CSSPrimitiveValue> fontNonKeywordWeightFromStyle(const RenderStyle& style)
{
    return ComputedStyleExtractor::fontNonKeywordWeightFromStyleValue(style.fontDescription().weight());
}

Ref<CSSPrimitiveValue> ComputedStyleExtractor::fontWeightFromStyleValue(FontSelectionValue weight)
{
    if (auto value = fontWeightKeyword(weight))
        return CSSValuePool::singleton().createIdentifierValue(value.value());
    return fontNonKeywordWeightFromStyleValue(weight);
}

Ref<CSSPrimitiveValue> ComputedStyleExtractor::fontNonKeywordStretchFromStyleValue(FontSelectionValue stretch)
{
    return CSSValuePool::singleton().createValue(static_cast<float>(stretch), CSSUnitType::CSS_PERCENTAGE);
}

Ref<CSSPrimitiveValue> ComputedStyleExtractor::fontStretchFromStyleValue(FontSelectionValue stretch)
{
    if (auto keyword = fontStretchKeyword(stretch))
        return CSSValuePool::singleton().createIdentifierValue(keyword.value());
    return fontNonKeywordStretchFromStyleValue(stretch);
}

static Ref<CSSPrimitiveValue> fontStretchFromStyle(const RenderStyle& style)
{
    return ComputedStyleExtractor::fontStretchFromStyleValue(style.fontDescription().stretch());
}

Ref<CSSFontStyleValue> ComputedStyleExtractor::fontNonKeywordStyleFromStyleValue(FontSelectionValue italic)
{
    return CSSFontStyleValue::create(CSSValuePool::singleton().createIdentifierValue(CSSValueOblique), CSSValuePool::singleton().createValue(static_cast<float>(italic), CSSUnitType::CSS_DEG));
}

Ref<CSSFontStyleValue> ComputedStyleExtractor::fontStyleFromStyleValue(std::optional<FontSelectionValue> italic, FontStyleAxis fontStyleAxis)
{
    if (auto keyword = fontStyleKeyword(italic, fontStyleAxis))
        return CSSFontStyleValue::create(CSSValuePool::singleton().createIdentifierValue(keyword.value()));
    return fontNonKeywordStyleFromStyleValue(italic.value());
}

static Ref<CSSFontStyleValue> fontStyleFromStyle(const RenderStyle& style)
{
    return ComputedStyleExtractor::fontStyleFromStyleValue(style.fontDescription().italic(), style.fontDescription().fontStyleAxis());
}

static Ref<CSSValue> fontVariantFromStyle(const RenderStyle& style)
{
    if (style.fontDescription().variantSettings().isAllNormal())
        return CSSValuePool::singleton().createIdentifierValue(CSSValueNormal);

    auto list = CSSValueList::createSpaceSeparated();

    switch (style.fontDescription().variantCommonLigatures()) {
    case FontVariantLigatures::Normal:
        break;
    case FontVariantLigatures::Yes:
        list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueCommonLigatures));
        break;
    case FontVariantLigatures::No:
        list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueNoCommonLigatures));
        break;
    }

    switch (style.fontDescription().variantDiscretionaryLigatures()) {
    case FontVariantLigatures::Normal:
        break;
    case FontVariantLigatures::Yes:
        list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueDiscretionaryLigatures));
        break;
    case FontVariantLigatures::No:
        list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueNoDiscretionaryLigatures));
        break;
    }

    switch (style.fontDescription().variantHistoricalLigatures()) {
    case FontVariantLigatures::Normal:
        break;
    case FontVariantLigatures::Yes:
        list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueHistoricalLigatures));
        break;
    case FontVariantLigatures::No:
        list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueNoHistoricalLigatures));
        break;
    }

    switch (style.fontDescription().variantContextualAlternates()) {
    case FontVariantLigatures::Normal:
        break;
    case FontVariantLigatures::Yes:
        list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueContextual));
        break;
    case FontVariantLigatures::No:
        list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueNoContextual));
        break;
    }

    switch (style.fontDescription().variantPosition()) {
    case FontVariantPosition::Normal:
        break;
    case FontVariantPosition::Subscript:
        list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueSub));
        break;
    case FontVariantPosition::Superscript:
        list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueSuper));
        break;
    }

    switch (style.fontDescription().variantCaps()) {
    case FontVariantCaps::Normal:
        break;
    case FontVariantCaps::Small:
        list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueSmallCaps));
        break;
    case FontVariantCaps::AllSmall:
        list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueAllSmallCaps));
        break;
    case FontVariantCaps::Petite:
        list->append(CSSValuePool::singleton().createIdentifierValue(CSSValuePetiteCaps));
        break;
    case FontVariantCaps::AllPetite:
        list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueAllPetiteCaps));
        break;
    case FontVariantCaps::Unicase:
        list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueUnicase));
        break;
    case FontVariantCaps::Titling:
        list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueTitlingCaps));
        break;
    }

    switch (style.fontDescription().variantNumericFigure()) {
    case FontVariantNumericFigure::Normal:
        break;
    case FontVariantNumericFigure::LiningNumbers:
        list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueLiningNums));
        break;
    case FontVariantNumericFigure::OldStyleNumbers:
        list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueOldstyleNums));
        break;
    }

    switch (style.fontDescription().variantNumericSpacing()) {
    case FontVariantNumericSpacing::Normal:
        break;
    case FontVariantNumericSpacing::ProportionalNumbers:
        list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueProportionalNums));
        break;
    case FontVariantNumericSpacing::TabularNumbers:
        list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueTabularNums));
        break;
    }

    switch (style.fontDescription().variantNumericFraction()) {
    case FontVariantNumericFraction::Normal:
        break;
    case FontVariantNumericFraction::DiagonalFractions:
        list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueDiagonalFractions));
        break;
    case FontVariantNumericFraction::StackedFractions:
        list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueStackedFractions));
        break;
    }

    switch (style.fontDescription().variantNumericOrdinal()) {
    case FontVariantNumericOrdinal::Normal:
        break;
    case FontVariantNumericOrdinal::Yes:
        list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueOrdinal));
        break;
    }

    switch (style.fontDescription().variantNumericSlashedZero()) {
    case FontVariantNumericSlashedZero::Normal:
        break;
    case FontVariantNumericSlashedZero::Yes:
        list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueSlashedZero));
        break;
    }

    switch (style.fontDescription().variantAlternates()) {
    case FontVariantAlternates::Normal:
        break;
    case FontVariantAlternates::HistoricalForms:
        list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueHistoricalForms));
        break;
    }

    switch (style.fontDescription().variantEastAsianVariant()) {
    case FontVariantEastAsianVariant::Normal:
        break;
    case FontVariantEastAsianVariant::Jis78:
        list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueJis78));
        break;
    case FontVariantEastAsianVariant::Jis83:
        list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueJis83));
        break;
    case FontVariantEastAsianVariant::Jis90:
        list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueJis90));
        break;
    case FontVariantEastAsianVariant::Jis04:
        list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueJis04));
        break;
    case FontVariantEastAsianVariant::Simplified:
        list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueSimplified));
        break;
    case FontVariantEastAsianVariant::Traditional:
        list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueTraditional));
        break;
    }

    switch (style.fontDescription().variantEastAsianWidth()) {
    case FontVariantEastAsianWidth::Normal:
        break;
    case FontVariantEastAsianWidth::Full:
        list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueFullWidth));
        break;
    case FontVariantEastAsianWidth::Proportional:
        list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueProportionalWidth));
        break;
    }

    switch (style.fontDescription().variantEastAsianRuby()) {
    case FontVariantEastAsianRuby::Normal:
        break;
    case FontVariantEastAsianRuby::Yes:
        list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueRuby));
        break;
    }

    return list;
}

static Ref<CSSValue> fontSynthesisFromStyle(const RenderStyle& style)
{
    if (style.fontDescription().fontSynthesis() == FontSynthesisNone)
        return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);

    auto list = CSSValueList::createSpaceSeparated();
    if (style.fontDescription().fontSynthesis() & FontSynthesisStyle)
        list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueStyle));
    if (style.fontDescription().fontSynthesis() & FontSynthesisWeight)
        list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueWeight));
    if (style.fontDescription().fontSynthesis() & FontSynthesisSmallCaps)
        list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueSmallCaps));
    return list;
}

typedef const Length& (RenderStyle::*RenderStyleLengthGetter)() const;
typedef LayoutUnit (RenderBoxModelObject::*RenderBoxComputedCSSValueGetter)() const;

template<RenderStyleLengthGetter lengthGetter, RenderBoxComputedCSSValueGetter computedCSSValueGetter>
static RefPtr<CSSValue> zoomAdjustedPaddingOrMarginPixelValue(const RenderStyle& style, RenderObject* renderer)
{
    Length unzoomzedLength = (style.*lengthGetter)();
    if (!is<RenderBox>(renderer) || unzoomzedLength.isFixed())
        return zoomAdjustedPixelValueForLength(unzoomzedLength, style);
    return zoomAdjustedPixelValue((downcast<RenderBox>(*renderer).*computedCSSValueGetter)(), style);
}

template<RenderStyleLengthGetter lengthGetter>
static bool paddingOrMarginIsRendererDependent(const RenderStyle* style, RenderObject* renderer)
{
    return renderer && style && renderer->isBox() && !(style->*lengthGetter)().isFixed();
}

static bool positionOffsetValueIsRendererDependent(const RenderStyle* style, RenderObject* renderer)
{
    return renderer && style && renderer->isBox();
}

static CSSValueID convertToPageBreak(BreakBetween value)
{
    if (value == BreakBetween::Page || value == BreakBetween::LeftPage || value == BreakBetween::RightPage
        || value == BreakBetween::RectoPage || value == BreakBetween::VersoPage)
        return CSSValueAlways; // CSS 2.1 allows us to map these to always.
    if (value == BreakBetween::Avoid || value == BreakBetween::AvoidPage)
        return CSSValueAvoid;
    return CSSValueAuto;
}

static CSSValueID convertToColumnBreak(BreakBetween value)
{
    if (value == BreakBetween::Column)
        return CSSValueAlways;
    if (value == BreakBetween::Avoid || value == BreakBetween::AvoidColumn)
        return CSSValueAvoid;
    return CSSValueAuto;
}

static CSSValueID convertToPageBreak(BreakInside value)
{
    if (value == BreakInside::Avoid || value == BreakInside::AvoidPage)
        return CSSValueAvoid;
    return CSSValueAuto;
}

static CSSValueID convertToColumnBreak(BreakInside value)
{
    if (value == BreakInside::Avoid || value == BreakInside::AvoidColumn)
        return CSSValueAvoid;
    return CSSValueAuto;
}

static inline bool isNonReplacedInline(RenderObject& renderer)
{
    return renderer.isInline() && !renderer.isReplaced();
}

static bool isLayoutDependent(CSSPropertyID propertyID, const RenderStyle* style, RenderObject* renderer)
{
    switch (propertyID) {
    case CSSPropertyTop:
    case CSSPropertyBottom:
    case CSSPropertyLeft:
    case CSSPropertyRight:
    case CSSPropertyInsetBlockStart:
    case CSSPropertyInsetBlockEnd:
    case CSSPropertyInsetInlineStart:
    case CSSPropertyInsetInlineEnd:
        return positionOffsetValueIsRendererDependent(style, renderer);
    case CSSPropertyWidth:
    case CSSPropertyHeight:
    case CSSPropertyInlineSize:
    case CSSPropertyBlockSize:
        return renderer && !renderer->isRenderSVGModelObject() && !isNonReplacedInline(*renderer);
    case CSSPropertyPerspectiveOrigin:
    case CSSPropertyTransformOrigin:
    case CSSPropertyTransform:
    case CSSPropertyFilter: // Why are filters layout-dependent?
#if ENABLE(FILTERS_LEVEL_2)
    case CSSPropertyWebkitBackdropFilter: // Ditto for backdrop-filter.
#endif
        return true;
    case CSSPropertyMargin: {
        if (!renderer || !renderer->isBox())
            return false;
        return !(style && style->marginTop().isFixed() && style->marginRight().isFixed()
            && style->marginBottom().isFixed() && style->marginLeft().isFixed());
    }
    case CSSPropertyMarginTop:
        return paddingOrMarginIsRendererDependent<&RenderStyle::marginTop>(style, renderer);
    case CSSPropertyMarginRight:
        return paddingOrMarginIsRendererDependent<&RenderStyle::marginRight>(style, renderer);
    case CSSPropertyMarginBottom:
        return paddingOrMarginIsRendererDependent<&RenderStyle::marginBottom>(style, renderer);
    case CSSPropertyMarginLeft:
        return paddingOrMarginIsRendererDependent<&RenderStyle::marginLeft>(style, renderer);
    case CSSPropertyPadding: {
        if (!renderer || !renderer->isBox())
            return false;
        return !(style && style->paddingTop().isFixed() && style->paddingRight().isFixed()
            && style->paddingBottom().isFixed() && style->paddingLeft().isFixed());
    }
    case CSSPropertyPaddingTop:
        return paddingOrMarginIsRendererDependent<&RenderStyle::paddingTop>(style, renderer);
    case CSSPropertyPaddingRight:
        return paddingOrMarginIsRendererDependent<&RenderStyle::paddingRight>(style, renderer);
    case CSSPropertyPaddingBottom:
        return paddingOrMarginIsRendererDependent<&RenderStyle::paddingBottom>(style, renderer);
    case CSSPropertyPaddingLeft:
        return paddingOrMarginIsRendererDependent<&RenderStyle::paddingLeft>(style, renderer); 
    case CSSPropertyGridTemplateColumns:
    case CSSPropertyGridTemplateRows:
    case CSSPropertyGridTemplate:
    case CSSPropertyGrid:
        return renderer && renderer->isRenderGrid();
    default:
        return false;
    }
}

Element* ComputedStyleExtractor::styledElement() const
{
    if (!m_element)
        return nullptr;
    PseudoElement* pseudoElement;
    if (m_pseudoElementSpecifier == PseudoId::Before && (pseudoElement = m_element->beforePseudoElement()))
        return pseudoElement;
    if (m_pseudoElementSpecifier == PseudoId::After && (pseudoElement = m_element->afterPseudoElement()))
        return pseudoElement;
    return m_element.get();
}

RenderElement* ComputedStyleExtractor::styledRenderer() const
{
    auto* element = styledElement();
    if (!element)
        return nullptr;
    if (m_pseudoElementSpecifier != PseudoId::None && element == m_element.get())
        return nullptr;
    if (element->hasDisplayContents())
        return nullptr;
    return element->renderer();
}

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;
    }
}

static bool nonInheritedColorPropertyHasValueCurrentColor(CSSPropertyID propertyID, const RenderStyle* style)
{
    if (CSSProperty::isInheritedProperty(propertyID) || !CSSProperty::isColorProperty(propertyID))
        return false;

    if (!style)
        return true;

    return RenderStyle::isCurrentColor(style->unresolvedColorForProperty(propertyID));
}

// In CSS 2.1 the returned object should actually contain the "used values"
// rather then the "computed values" (despite the name saying otherwise).
//
// See;
// http://www.w3.org/TR/CSS21/cascade.html#used-value
// http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSStyleDeclaration
// https://developer.mozilla.org/en-US/docs/Web/API/Window/getComputedStyle#Notes
RefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropertyID propertyID, EUpdateLayout updateLayout) const
{
    return ComputedStyleExtractor(m_element.ptr(), m_allowVisitedStyle, m_pseudoElementSpecifier).propertyValue(propertyID, updateLayout);
}

Ref<MutableStyleProperties> CSSComputedStyleDeclaration::copyProperties() const
{
    return ComputedStyleExtractor(m_element.ptr(), m_allowVisitedStyle, m_pseudoElementSpecifier).copyProperties();
}

const Settings* CSSComputedStyleDeclaration::settings() const
{
    return &m_element->document().settings();
}

static inline bool hasValidStyleForProperty(Element& element, CSSPropertyID propertyID)
{
    if (element.styleValidity() != Style::Validity::Valid)
        return false;
    if (element.document().hasPendingFullStyleRebuild())
        return false;
    if (!element.document().childNeedsStyleRecalc())
        return true;

    bool isInherited = CSSProperty::isInheritedProperty(propertyID) || isImplicitlyInheritedGridOrFlexProperty(propertyID);
    bool maybeExplicitlyInherited = !isInherited;

    const auto* currentElement = &element;
    for (auto& ancestor : composedTreeAncestors(element)) {
        if (ancestor.styleValidity() >= Style::Validity::SubtreeInvalid)
            return false;

        if (maybeExplicitlyInherited) {
            auto* style = currentElement->renderStyle();
            // While most color properties are not inherited, the value 'currentcolor' resolves to the value of the inherited 'color' property.
            if (nonInheritedColorPropertyHasValueCurrentColor(propertyID, style))
                isInherited = true;

            maybeExplicitlyInherited = !style || style->hasExplicitlyInheritedProperties();
        }

        if ((isInherited || maybeExplicitlyInherited) && ancestor.styleValidity() == Style::Validity::ElementInvalid)
            return false;

        if (ancestor.directChildNeedsStyleRecalc() && currentElement->styleIsAffectedByPreviousSibling())
            return false;

        currentElement = &ancestor;
    }

    return true;
}

static bool updateStyleIfNeededForProperty(Element& element, CSSPropertyID propertyID)
{
    auto& document = element.document();

    document.styleScope().flushPendingUpdate();

    auto hasValidStyle = [&] {
        auto shorthand = shorthandForProperty(propertyID);
        if (shorthand.length()) {
            for (auto longhand : shorthand) {
                if (!hasValidStyleForProperty(element, longhand))
                    return false;
            }
            return true;
        }
        return hasValidStyleForProperty(element, propertyID);
    }();

    if (hasValidStyle)
        return false;

    document.updateStyleIfNeeded();
    return true;
}

static inline const RenderStyle* computeRenderStyleForProperty(Element& element, PseudoId pseudoElementSpecifier, CSSPropertyID propertyID, std::unique_ptr<RenderStyle>& ownedStyle)
{
    auto* renderer = element.renderer();

    if (renderer && renderer->isComposited() && CSSPropertyAnimation::animationOfPropertyIsAccelerated(propertyID)) {
        ownedStyle = renderer->animatedStyle();
        if (pseudoElementSpecifier != PseudoId::None && !element.isPseudoElement()) {
            // FIXME: This cached pseudo style will only exist if the animation has been run at least once.
            return ownedStyle->getCachedPseudoStyle(pseudoElementSpecifier);
        }
        return ownedStyle.get();
    }

    return element.computedStyle(element.isPseudoElement() ? PseudoId::None : pseudoElementSpecifier);
}

static Ref<CSSValue> shapePropertyValue(const RenderStyle& style, const ShapeValue* shapeValue)
{
    if (!shapeValue)
        return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);

    if (shapeValue->type() == ShapeValue::Type::Box)
        return CSSValuePool::singleton().createValue(shapeValue->cssBox());

    if (shapeValue->type() == ShapeValue::Type::Image) {
        if (shapeValue->image())
            return shapeValue->image()->cssValue();
        return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
    }

    ASSERT(shapeValue->type() == ShapeValue::Type::Shape);

    auto list = CSSValueList::createSpaceSeparated();
    list->append(valueForBasicShape(style, *shapeValue->shape()));
    if (shapeValue->cssBox() != CSSBoxType::BoxMissing)
        list->append(CSSValuePool::singleton().createValue(shapeValue->cssBox()));
    return list;
}

static Ref<CSSValueList> valueForItemPositionWithOverflowAlignment(const StyleSelfAlignmentData& data)
{
    auto& cssValuePool = CSSValuePool::singleton();
    auto result = CSSValueList::createSpaceSeparated();
    if (data.positionType() == ItemPositionType::Legacy)
        result->append(cssValuePool.createIdentifierValue(CSSValueLegacy));
    if (data.position() == ItemPosition::Baseline)
        result->append(cssValuePool.createIdentifierValue(CSSValueBaseline));
    else if (data.position() == ItemPosition::LastBaseline) {
        result->append(cssValuePool.createIdentifierValue(CSSValueLast));
        result->append(cssValuePool.createIdentifierValue(CSSValueBaseline));
    } else {
        if (data.position() >= ItemPosition::Center && data.overflow() != OverflowAlignment::Default)
            result->append(cssValuePool.createValue(data.overflow()));
        if (data.position() == ItemPosition::Legacy)
            result->append(cssValuePool.createIdentifierValue(CSSValueNormal));
        else
            result->append(cssValuePool.createValue(data.position()));
    }
    ASSERT(result->length() <= 2);
    return result;
}

static Ref<CSSValueList> valueForContentPositionAndDistributionWithOverflowAlignment(const StyleContentAlignmentData& data)
{
    auto& cssValuePool = CSSValuePool::singleton();
    auto result = CSSValueList::createSpaceSeparated();
    // Handle content-distribution values
    if (data.distribution() != ContentDistribution::Default)
        result->append(cssValuePool.createValue(data.distribution()));

    // Handle content-position values (either as fallback or actual value)
    switch (data.position()) {
    case ContentPosition::Normal:
        // Handle 'normal' value, not valid as content-distribution fallback.
        if (data.distribution() == ContentDistribution::Default)
            result->append(cssValuePool.createIdentifierValue(CSSValueNormal));
        break;
    case ContentPosition::LastBaseline:
        result->append(cssValuePool.createIdentifierValue(CSSValueLast));
        result->append(cssValuePool.createIdentifierValue(CSSValueBaseline));
        break;
    default:
        // Handle overflow-alignment (only allowed for content-position values)
        if ((data.position() >= ContentPosition::Center || data.distribution() != ContentDistribution::Default) && data.overflow() != OverflowAlignment::Default)
            result->append(cssValuePool.createValue(data.overflow()));
        result->append(cssValuePool.createValue(data.position()));
    }

    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 paintOrderList;
}

inline static bool isFlexOrGridItem(RenderObject* renderer)
{
    if (!renderer || !renderer->isBox())
        return false;
    auto& box = downcast<RenderBox>(*renderer);
    return box.isFlexItem() || box.isGridItem();
}

RefPtr<CSSValue> ComputedStyleExtractor::customPropertyValue(const String& propertyName)
{
    Element* styledElement = this->styledElement();
    if (!styledElement)
        return nullptr;
    
    if (updateStyleIfNeededForProperty(*styledElement, CSSPropertyCustom)) {
        // Style update may change styledElement() to PseudoElement or back.
        styledElement = this->styledElement();
    }

    std::unique_ptr<RenderStyle> ownedStyle;
    auto* style = computeRenderStyleForProperty(*styledElement, m_pseudoElementSpecifier, CSSPropertyCustom, ownedStyle);
    if (!style)
        return nullptr;

    auto* value = style->getCustomProperty(propertyName);
    if (!value) {
        auto registered = styledElement->document().getCSSRegisteredCustomPropertySet().get(propertyName);
        return registered ? registered->initialValueCopy() : nullptr;
    }

    return WTF::switchOn(value->value(), [&](const Length& value) -> Ref<CSSValue> {
        return zoomAdjustedPixelValueForLength(value, *style);
    }, [&](auto&) -> Ref<CSSValue> {
        return CSSCustomPropertyValue::create(*value);
    });
}

String ComputedStyleExtractor::customPropertyText(const String& propertyName)
{
    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), CSSUnitType::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(), fontDescription.fontStyleAxis()))
        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;

    std::unique_ptr<RenderStyle> ownedStyle;
    const RenderStyle* style = nullptr;
    RenderElement* renderer = nullptr;
    bool forceFullLayout = false;
    if (updateLayout) {
        Document& document = m_element->document();

        if (updateStyleIfNeededForProperty(*styledElement, propertyID)) {
            // Style update may change styledElement() to PseudoElement or back.
            styledElement = this->styledElement();
        }
        renderer = styledRenderer();

        if (propertyID == CSSPropertyDisplay && !renderer && is<SVGElement>(*styledElement) && !downcast<SVGElement>(*styledElement).isValid())
            return nullptr;

        style = computeRenderStyleForProperty(*styledElement, m_pseudoElementSpecifier, propertyID, ownedStyle);

        // FIXME: Some of these cases could be narrowed down or optimized better.
        forceFullLayout = isLayoutDependent(propertyID, style, renderer)
            || styledElement->isInShadowTree()
            || (document.styleScope().resolverIfExists() && document.styleScope().resolverIfExists()->hasViewportDependentMediaQueries() && document.ownerElement());

        if (forceFullLayout) {
            document.updateLayoutIgnorePendingStylesheets();
            styledElement = this->styledElement();
        }
    }

    if (!updateLayout || forceFullLayout) {
        style = computeRenderStyleForProperty(*styledElement, m_pseudoElementSpecifier, propertyID, ownedStyle);
        renderer = styledRenderer();
    }

    if (!style)
        return nullptr;

    return valueForPropertyInStyle(*style, propertyID, renderer);
}

RefPtr<CSSValue> ComputedStyleExtractor::valueForPropertyInStyle(const RenderStyle& style, CSSPropertyID propertyID, RenderElement* renderer)
{
    auto& cssValuePool = CSSValuePool::singleton();
    propertyID = CSSProperty::resolveDirectionAwareProperty(propertyID, style.direction(), style.writingMode());

    switch (propertyID) {
        case CSSPropertyInvalid:
#if ENABLE(TEXT_AUTOSIZING)
        case CSSPropertyInternalTextAutosizingStatus:
#endif
            break;
        case CSSPropertyAccentColor: {
            if (!m_element->document().settings().accentColorEnabled())
                return nullptr;
            if (style.hasAutoAccentColor())
                return cssValuePool.createIdentifierValue(CSSValueAuto);
            return currentColorOrValidColor(&style, style.accentColor());
        }
        case CSSPropertyBackgroundColor:
            return m_allowVisitedStyle ? cssValuePool.createColorValue(style.visitedDependentColor(CSSPropertyBackgroundColor)) : currentColorOrValidColor(&style, style.backgroundColor());
        case CSSPropertyBackgroundImage:
        case CSSPropertyWebkitMaskImage: {
            auto& layers = propertyID == CSSPropertyWebkitMaskImage ? style.maskLayers() : style.backgroundLayers();
            if (!layers.next()) {
                if (layers.image())
                    return layers.image()->cssValue();
                return cssValuePool.createIdentifierValue(CSSValueNone);
            }
            auto list = CSSValueList::createCommaSeparated();
            for (auto* currLayer = &layers; currLayer; currLayer = currLayer->next()) {
                if (currLayer->image())
                    list->append(currLayer->image()->cssValue());
                else
                    list->append(cssValuePool.createIdentifierValue(CSSValueNone));
            }
            return list;
        }
        case CSSPropertyBackgroundSize:
        case CSSPropertyWebkitBackgroundSize:
        case CSSPropertyWebkitMaskSize: {
            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;
        }
        case CSSPropertyBackgroundRepeat:
        case CSSPropertyWebkitMaskRepeat: {
            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;
        }
        case CSSPropertyWebkitMaskSourceType: {
            auto& layers = style.maskLayers();
            if (!layers.next())
                return maskSourceTypeToCSSValue(layers.maskMode());
            auto list = CSSValueList::createCommaSeparated();
            for (auto* currLayer = &layers; currLayer; currLayer = currLayer->next())
                list->append(maskSourceTypeToCSSValue(currLayer->maskMode()));
            return list;
        }
        case CSSPropertyWebkitMaskMode: {
            auto& layers = style.maskLayers();
            if (!layers.next())
                return maskModeToCSSValue(layers.maskMode());
            auto list = CSSValueList::createCommaSeparated();
            for (auto* currLayer = &layers; currLayer; currLayer = currLayer->next())
                list->append(maskModeToCSSValue(currLayer->maskMode()));
            return list;
        }
        case CSSPropertyWebkitBackgroundComposite:
        case CSSPropertyWebkitMaskComposite: {
            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;
        }
        case CSSPropertyBackgroundAttachment: {
            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;
        }
        case CSSPropertyBackgroundClip:
        case CSSPropertyBackgroundOrigin:
        case CSSPropertyWebkitBackgroundClip:
        case CSSPropertyWebkitBackgroundOrigin:
        case CSSPropertyWebkitMaskClip:
        case CSSPropertyWebkitMaskOrigin: {
            auto& layers = (propertyID == CSSPropertyWebkitMaskClip || propertyID == CSSPropertyWebkitMaskOrigin) ? style.maskLayers() : style.backgroundLayers();
            bool isClip = propertyID == CSSPropertyBackgroundClip || propertyID == CSSPropertyWebkitBackgroundClip || propertyID == CSSPropertyWebkitMaskClip;
            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 list;
        }
        case CSSPropertyBackgroundPosition:
        case CSSPropertyWebkitMaskPosition: {
            auto& layers = propertyID == CSSPropertyWebkitMaskPosition ? style.maskLayers() : style.backgroundLayers();
            if (!layers.next())
                return createPositionListForLayer(propertyID, layers, style);

            auto list = CSSValueList::createCommaSeparated();
            for (auto* currLayer = &layers; currLayer; currLayer = currLayer->next())
                list->append(createPositionListForLayer(propertyID, *currLayer, style));
            return list;
        }
        case CSSPropertyBackgroundPositionX:
        case CSSPropertyWebkitMaskPositionX: {
            auto& layers = propertyID == CSSPropertyWebkitMaskPositionX ? style.maskLayers() : style.backgroundLayers();
            if (!layers.next())
                return createSingleAxisPositionValueForLayer(propertyID, layers, style);

            auto list = CSSValueList::createCommaSeparated();
            for (auto* currLayer = &layers; currLayer; currLayer = currLayer->next())
                list->append(createSingleAxisPositionValueForLayer(propertyID, *currLayer, style));

            return list;
        }
        case CSSPropertyBackgroundPositionY:
        case CSSPropertyWebkitMaskPositionY: {
            auto& layers = propertyID == CSSPropertyWebkitMaskPositionY ? style.maskLayers() : style.backgroundLayers();
            if (!layers.next())
                return createSingleAxisPositionValueForLayer(propertyID, layers, style);

            auto list = CSSValueList::createCommaSeparated();
            for (auto* currLayer = &layers; currLayer; currLayer = currLayer->next())
                list->append(createSingleAxisPositionValueForLayer(propertyID, *currLayer, style));

            return list;
        }
        case CSSPropertyBorderCollapse:
            if (style.borderCollapse() == BorderCollapse::Collapse)
                return cssValuePool.createIdentifierValue(CSSValueCollapse);
            return cssValuePool.createIdentifierValue(CSSValueSeparate);
        case CSSPropertyBorderSpacing: {
            auto list = CSSValueList::createSpaceSeparated();
            list->append(zoomAdjustedPixelValue(style.horizontalBorderSpacing(), style));
            list->append(zoomAdjustedPixelValue(style.verticalBorderSpacing(), style));
            return list;
        }
        case CSSPropertyWebkitBorderHorizontalSpacing:
            return zoomAdjustedPixelValue(style.horizontalBorderSpacing(), style);
        case CSSPropertyWebkitBorderVerticalSpacing:
            return zoomAdjustedPixelValue(style.verticalBorderSpacing(), style);
        case CSSPropertyBorderImageSource:
            if (style.borderImageSource())
                return style.borderImageSource()->cssValue();
            return cssValuePool.createIdentifierValue(CSSValueNone);
        case CSSPropertyBorderTopColor:
            return m_allowVisitedStyle ? cssValuePool.createColorValue(style.visitedDependentColor(CSSPropertyBorderTopColor)) : currentColorOrValidColor(&style, style.borderTopColor());
        case CSSPropertyBorderRightColor:
            return m_allowVisitedStyle ? cssValuePool.createColorValue(style.visitedDependentColor(CSSPropertyBorderRightColor)) : currentColorOrValidColor(&style, style.borderRightColor());
        case CSSPropertyBorderBottomColor:
            return m_allowVisitedStyle ? cssValuePool.createColorValue(style.visitedDependentColor(CSSPropertyBorderBottomColor)) : currentColorOrValidColor(&style, style.borderBottomColor());
        case CSSPropertyBorderLeftColor:
            return m_allowVisitedStyle ? cssValuePool.createColorValue(style.visitedDependentColor(CSSPropertyBorderLeftColor)) : currentColorOrValidColor(&style, style.borderLeftColor());
        case CSSPropertyBorderTopStyle:
            return cssValuePool.createValue(style.borderTopStyle());
        case CSSPropertyBorderRightStyle:
            return cssValuePool.createValue(style.borderRightStyle());
        case CSSPropertyBorderBottomStyle:
            return cssValuePool.createValue(style.borderBottomStyle());
        case CSSPropertyBorderLeftStyle:
            return cssValuePool.createValue(style.borderLeftStyle());
        case CSSPropertyBorderTopWidth:
            return zoomAdjustedPixelValue(style.borderTopWidth(), style);
        case CSSPropertyBorderRightWidth:
            return zoomAdjustedPixelValue(style.borderRightWidth(), style);
        case CSSPropertyBorderBottomWidth:
            return zoomAdjustedPixelValue(style.borderBottomWidth(), style);
        case CSSPropertyBorderLeftWidth:
            return zoomAdjustedPixelValue(style.borderLeftWidth(), style);
        case CSSPropertyBottom:
            return positionOffsetValue(style, CSSPropertyBottom, renderer);
        case CSSPropertyWebkitBoxAlign:
            return cssValuePool.createValue(style.boxAlign());
#if ENABLE(CSS_BOX_DECORATION_BREAK)
        case CSSPropertyWebkitBoxDecorationBreak:
            if (style.boxDecorationBreak() == BoxDecorationBreak::Slice)
                return cssValuePool.createIdentifierValue(CSSValueSlice);
        return cssValuePool.createIdentifierValue(CSSValueClone);
#endif
        case CSSPropertyWebkitBoxDirection:
            return cssValuePool.createValue(style.boxDirection());
        case CSSPropertyWebkitBoxFlex:
            return cssValuePool.createValue(style.boxFlex(), CSSUnitType::CSS_NUMBER);
        case CSSPropertyWebkitBoxFlexGroup:
            return cssValuePool.createValue(style.boxFlexGroup(), CSSUnitType::CSS_NUMBER);
        case CSSPropertyWebkitBoxLines:
            return cssValuePool.createValue(style.boxLines());
        case CSSPropertyWebkitBoxOrdinalGroup:
            return cssValuePool.createValue(style.boxOrdinalGroup(), CSSUnitType::CSS_NUMBER);
        case CSSPropertyWebkitBoxOrient:
            return cssValuePool.createValue(style.boxOrient());
        case CSSPropertyWebkitBoxPack:
            return cssValuePool.createValue(style.boxPack());
        case CSSPropertyWebkitBoxReflect:
            return valueForReflection(style.boxReflect(), style);
        case CSSPropertyBoxShadow:
        case CSSPropertyWebkitBoxShadow:
            return valueForShadow(style.boxShadow(), propertyID, style);
        case CSSPropertyCaptionSide:
            return cssValuePool.createValue(style.captionSide());
        case CSSPropertyCaretColor:
            return m_allowVisitedStyle ? cssValuePool.createColorValue(style.visitedDependentColor(CSSPropertyCaretColor)) : currentColorOrValidColor(&style, style.caretColor());
        case CSSPropertyClear:
            return cssValuePool.createValue(style.clear());
        case CSSPropertyColor:
            return cssValuePool.createColorValue(m_allowVisitedStyle ? style.visitedDependentColor(CSSPropertyColor) : style.color());
        case CSSPropertyWebkitPrintColorAdjust:
            return cssValuePool.createValue(style.printColorAdjust());
        case CSSPropertyWebkitColumnAxis:
            return cssValuePool.createValue(style.columnAxis());
        case CSSPropertyColumnCount:
            if (style.hasAutoColumnCount())
                return cssValuePool.createIdentifierValue(CSSValueAuto);
            return cssValuePool.createValue(style.columnCount(), CSSUnitType::CSS_NUMBER);
        case CSSPropertyColumnFill:
            return cssValuePool.createValue(style.columnFill());
        case CSSPropertyColumnGap:
            if (style.columnGap().isNormal())
                return cssValuePool.createIdentifierValue(CSSValueNormal);
            return zoomAdjustedPixelValueForLength(style.columnGap().length(), style);
        case CSSPropertyRowGap:
            if (style.rowGap().isNormal())
                return cssValuePool.createIdentifierValue(CSSValueNormal);
            return zoomAdjustedPixelValueForLength(style.rowGap().length(), style);
        case CSSPropertyWebkitColumnProgression:
            return cssValuePool.createValue(style.columnProgression());
        case CSSPropertyColumnRuleColor:
            return m_allowVisitedStyle ? cssValuePool.createColorValue(style.visitedDependentColor(CSSPropertyOutlineColor)) : currentColorOrValidColor(&style, style.columnRuleColor());
        case CSSPropertyColumnRuleStyle:
            return cssValuePool.createValue(style.columnRuleStyle());
        case CSSPropertyColumnRuleWidth:
            return zoomAdjustedPixelValue(style.columnRuleWidth(), style);
        case CSSPropertyColumnSpan:
            return cssValuePool.createIdentifierValue(style.columnSpan() == ColumnSpan::All ? CSSValueAll : CSSValueNone);
        case CSSPropertyWebkitColumnBreakAfter:
            return cssValuePool.createValue(convertToColumnBreak(style.breakAfter()));
        case CSSPropertyWebkitColumnBreakBefore:
            return cssValuePool.createValue(convertToColumnBreak(style.breakBefore()));
        case CSSPropertyWebkitColumnBreakInside:
            return cssValuePool.createValue(convertToColumnBreak(style.breakInside()));
        case CSSPropertyColumnWidth:
            if (style.hasAutoColumnWidth())
                return cssValuePool.createIdentifierValue(CSSValueAuto);
            return zoomAdjustedPixelValue(style.columnWidth(), style);
        case CSSPropertyTabSize:
            return cssValuePool.createValue(style.tabSize().widthInPixels(1.0), style.tabSize().isSpaces() ? CSSUnitType::CSS_NUMBER : CSSUnitType::CSS_PX);
        case CSSPropertyCursor: {
            RefPtr<CSSValueList> list;
            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());
            }
            auto value = cssValuePool.createValue(style.cursor());
            if (list) {
                list->append(WTFMove(value));
                return list;
            }
            return value;
        }
#if ENABLE(CURSOR_VISIBILITY)
        case CSSPropertyWebkitCursorVisibility:
            return cssValuePool.createValue(style.cursorVisibility());
#endif
        case CSSPropertyDirection:
            return cssValuePool.createValue(style.direction());
        case CSSPropertyDisplay:
            return cssValuePool.createValue(style.display());
        case CSSPropertyEmptyCells:
            return cssValuePool.createValue(style.emptyCells());
        case CSSPropertyAlignContent:
            return valueForContentPositionAndDistributionWithOverflowAlignment(style.alignContent());
        case CSSPropertyAlignItems:
            return valueForItemPositionWithOverflowAlignment(style.alignItems());
        case CSSPropertyAlignSelf:
            return valueForItemPositionWithOverflowAlignment(style.alignSelf());
        case CSSPropertyFlex:
            return getCSSPropertyValuesForShorthandProperties(flexShorthand());
        case CSSPropertyFlexBasis:
            return cssValuePool.createValue(style.flexBasis(), style);
        case CSSPropertyFlexDirection:
            return cssValuePool.createValue(style.flexDirection());
        case CSSPropertyFlexFlow:
            return getCSSPropertyValuesForShorthandProperties(flexFlowShorthand());
        case CSSPropertyFlexGrow:
            return cssValuePool.createValue(style.flexGrow());
        case CSSPropertyFlexShrink:
            return cssValuePool.createValue(style.flexShrink());
        case CSSPropertyFlexWrap:
            return cssValuePool.createValue(style.flexWrap());
        case CSSPropertyJustifyContent:
            return valueForContentPositionAndDistributionWithOverflowAlignment(style.justifyContent());
        case CSSPropertyJustifyItems:
            return valueForItemPositionWithOverflowAlignment(style.justifyItems());
        case CSSPropertyJustifySelf:
            return valueForItemPositionWithOverflowAlignment(style.justifySelf());
        case CSSPropertyPlaceContent:
            return getCSSPropertyValuesForShorthandProperties(placeContentShorthand());
        case CSSPropertyPlaceItems:
            return getCSSPropertyValuesForShorthandProperties(placeItemsShorthand());
        case CSSPropertyPlaceSelf:
            return getCSSPropertyValuesForShorthandProperties(placeSelfShorthand());
        case CSSPropertyOrder:
            return cssValuePool.createValue(style.order(), CSSUnitType::CSS_NUMBER);
        case CSSPropertyFloat:
            if (style.display() != DisplayType::None && style.hasOutOfFlowPosition())
                return cssValuePool.createIdentifierValue(CSSValueNone);
            return cssValuePool.createValue(style.floating());
        case CSSPropertyFont: {
            auto computedFont = fontShorthandValueForSelectionProperties(style.fontDescription());
            computedFont->size = fontSizeFromStyle(style);
            computedFont->lineHeight = lineHeightFromStyle(style);
            computedFont->family = fontFamilyListFromStyle(style);
            return computedFont;
        }
        case CSSPropertyFontFamily:
            return fontFamilyFromStyle(style);
        case CSSPropertyFontSize:
            return fontSizeFromStyle(style);
        case CSSPropertyFontStyle:
            return fontStyleFromStyle(style);
        case CSSPropertyFontStretch:
            return fontStretchFromStyle(style);
        case CSSPropertyFontVariant:
            return fontVariantFromStyle(style);
        case CSSPropertyFontWeight:
            return fontNonKeywordWeightFromStyle(style);
        case CSSPropertyFontPalette:
            return fontPaletteFromStyle(style);
        case CSSPropertyFontSynthesis:
            return fontSynthesisFromStyle(style);
        case CSSPropertyFontFeatureSettings: {
            const FontFeatureSettings& featureSettings = style.fontDescription().featureSettings();
            if (!featureSettings.size())
                return cssValuePool.createIdentifierValue(CSSValueNormal);
            auto list = CSSValueList::createCommaSeparated();
            for (auto& feature : featureSettings)
                list->append(CSSFontFeatureValue::create(FontTag(feature.tag()), feature.value()));
            return list;
        }
#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 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));
            else
                list->append(cssValuePool.createIdentifierValue(CSSValueColumn));

            if (style.isGridAutoFlowAlgorithmDense())
                list->append(cssValuePool.createIdentifierValue(CSSValueDense));

            return list;
        }

        // Specs mention that getComputedStyle() should return the used value of the property instead of the computed
        // one for grid-template-{rows|columns} but not for the grid-auto-{rows|columns} as things like
        // grid-auto-columns: 2fr; cannot be resolved to a value in pixels as the '2fr' means very different things
        // depending on the size of the explicit grid or the number of implicit tracks added to the grid. See
        // http://lists.w3.org/Archives/Public/www-style/2013Nov/0014.html
        case CSSPropertyGridAutoColumns:
            return valueForGridTrackSizeList(ForColumns, style);
        case CSSPropertyGridAutoRows:
            return valueForGridTrackSizeList(ForRows, style);

        case CSSPropertyGridTemplateColumns:
            return valueForGridTrackList(ForColumns, renderer, style);
        case CSSPropertyGridTemplateRows:
            return valueForGridTrackList(ForRows, renderer, style);

        case CSSPropertyGridColumnStart:
            return valueForGridPosition(style.gridItemColumnStart());
        case CSSPropertyGridColumnEnd:
            return valueForGridPosition(style.gridItemColumnEnd());
        case CSSPropertyGridRowStart:
            return valueForGridPosition(style.gridItemRowStart());
        case CSSPropertyGridRowEnd:
            return valueForGridPosition(style.gridItemRowEnd());
        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());
        case CSSPropertyGap:
            return getCSSPropertyValuesForShorthandProperties(gapShorthand());
        case CSSPropertyHeight:
            if (renderer && !renderer->isRenderSVGModelObject()) {
                // According to http://www.w3.org/TR/CSS2/visudet.html#the-height-property,
                // the "height" property does not apply for non-replaced inline elements.
                if (!isNonReplacedInline(*renderer))
                    return zoomAdjustedPixelValue(sizingBox(*renderer).height(), style);
            }
            return zoomAdjustedPixelValueForLength(style.height(), style);
        case CSSPropertyWebkitHyphens:
            return cssValuePool.createValue(style.hyphens());
        case CSSPropertyWebkitHyphenateCharacter:
            if (style.hyphenationString().isNull())
                return cssValuePool.createIdentifierValue(CSSValueAuto);
            return cssValuePool.createValue(style.hyphenationString(), CSSUnitType::CSS_STRING);
        case CSSPropertyWebkitHyphenateLimitAfter:
            if (style.hyphenationLimitAfter() < 0)
                return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
            return CSSPrimitiveValue::create(style.hyphenationLimitAfter(), CSSUnitType::CSS_NUMBER);
        case CSSPropertyWebkitHyphenateLimitBefore:
            if (style.hyphenationLimitBefore() < 0)
                return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
            return CSSPrimitiveValue::create(style.hyphenationLimitBefore(), CSSUnitType::CSS_NUMBER);
        case CSSPropertyWebkitHyphenateLimitLines:
            if (style.hyphenationLimitLines() < 0)
                return CSSPrimitiveValue::createIdentifier(CSSValueNoLimit);
            return CSSPrimitiveValue::create(style.hyphenationLimitLines(), CSSUnitType::CSS_NUMBER);
        case CSSPropertyWebkitBorderFit:
            if (style.borderFit() == BorderFit::Border)
                return cssValuePool.createIdentifierValue(CSSValueBorder);
            return cssValuePool.createIdentifierValue(CSSValueLines);
        case CSSPropertyImageOrientation:
            if (style.imageOrientation() == ImageOrientation::FromImage)
                return cssValuePool.createIdentifierValue(CSSValueFromImage);
            return cssValuePool.createIdentifierValue(CSSValueNone);
        case CSSPropertyImageRendering:
            return CSSPrimitiveValue::create(style.imageRendering());
#if ENABLE(CSS_IMAGE_RESOLUTION)
        case CSSPropertyImageResolution:
            return cssValuePool.createValue(style.imageResolution(), CSSUnitType::CSS_DPPX);
#endif
        case CSSPropertyInputSecurity:
            return cssValuePool.createValue(style.inputSecurity());
        case CSSPropertyLeft:
            return positionOffsetValue(style, CSSPropertyLeft, renderer);
        case CSSPropertyLetterSpacing:
            if (!style.letterSpacing())
                return cssValuePool.createIdentifierValue(CSSValueNormal);
            return zoomAdjustedPixelValue(style.letterSpacing(), style);
        case CSSPropertyWebkitLineClamp:
            if (style.lineClamp().isNone())
                return cssValuePool.createIdentifierValue(CSSValueNone);
            return cssValuePool.createValue(style.lineClamp().value(), style.lineClamp().isPercentage() ? CSSUnitType::CSS_PERCENTAGE : CSSUnitType::CSS_NUMBER);
        case CSSPropertyLineHeight:
            return lineHeightFromStyle(style);
        case CSSPropertyListStyleImage:
            if (style.listStyleImage())
                return style.listStyleImage()->cssValue();
            return cssValuePool.createIdentifierValue(CSSValueNone);
        case CSSPropertyListStylePosition:
            return cssValuePool.createValue(style.listStylePosition());
        case CSSPropertyListStyleType:
            if (style.listStyleType() == ListStyleType::String)
                return cssValuePool.createValue(style.listStyleStringValue(), CSSUnitType::CSS_STRING);
            return cssValuePool.createValue(style.listStyleType());
        case CSSPropertyWebkitLocale:
            if (style.specifiedLocale().isNull())
                return cssValuePool.createIdentifierValue(CSSValueAuto);
            return cssValuePool.createCustomIdent(style.specifiedLocale());
        case CSSPropertyMarginTop:
            return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::marginTop, &RenderBoxModelObject::marginTop>(style, renderer);
        case CSSPropertyMarginRight: {
            Length marginRight = style.marginRight();
            if (marginRight.isFixed() || !is<RenderBox>(renderer))
                return zoomAdjustedPixelValueForLength(marginRight, style);
            float value;
            if (marginRight.isPercentOrCalculated()) {
                // RenderBox gives a marginRight() that is the distance between the right-edge of the child box
                // and the right-edge of the containing box, when display == DisplayType::Block. Let's calculate the absolute
                // value of the specified margin-right % instead of relying on RenderBox's marginRight() value.
                value = minimumValueForLength(marginRight, downcast<RenderBox>(*renderer).containingBlockLogicalWidthForContent());
            } else
                value = downcast<RenderBox>(*renderer).marginRight();
            return zoomAdjustedPixelValue(value, style);
        }
        case CSSPropertyMarginBottom:
            return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::marginBottom, &RenderBoxModelObject::marginBottom>(style, renderer);
        case CSSPropertyMarginLeft:
            return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::marginLeft, &RenderBoxModelObject::marginLeft>(style, renderer);
        case CSSPropertyWebkitUserModify:
            return cssValuePool.createValue(style.userModify());
        case CSSPropertyMaxHeight: {
            const Length& maxHeight = style.maxHeight();
            if (maxHeight.isUndefined())
                return cssValuePool.createIdentifierValue(CSSValueNone);
            return zoomAdjustedPixelValueForLength(maxHeight, style);
        }
        case CSSPropertyMaxWidth: {
            const Length& maxWidth = style.maxWidth();
            if (maxWidth.isUndefined())
                return cssValuePool.createIdentifierValue(CSSValueNone);
            return zoomAdjustedPixelValueForLength(maxWidth, style);
        }
        case CSSPropertyMinHeight:
            if (style.minHeight().isAuto()) {
                if (isFlexOrGridItem(renderer))
                    return cssValuePool.createIdentifierValue(CSSValueAuto);
                return zoomAdjustedPixelValue(0, style);
            }
            return zoomAdjustedPixelValueForLength(style.minHeight(), style);
        case CSSPropertyMinWidth:
            if (style.minWidth().isAuto()) {
                if (isFlexOrGridItem(renderer))
                    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 list;
        }
        case CSSPropertyOpacity:
            return cssValuePool.createValue(style.opacity(), CSSUnitType::CSS_NUMBER);
        case CSSPropertyOrphans:
            if (style.hasAutoOrphans())
                return cssValuePool.createIdentifierValue(CSSValueAuto);
            return cssValuePool.createValue(style.orphans(), CSSUnitType::CSS_NUMBER);
        case CSSPropertyOutlineColor:
            return m_allowVisitedStyle ? cssValuePool.createColorValue(style.visitedDependentColor(CSSPropertyOutlineColor)) : currentColorOrValidColor(&style, style.outlineColor());
        case CSSPropertyOutlineOffset:
            return zoomAdjustedPixelValue(style.outlineOffset(), style);
        case CSSPropertyOutlineStyle:
            if (style.outlineStyleIsAuto() == OutlineIsAuto::On)
                return cssValuePool.createIdentifierValue(CSSValueAuto);
            return cssValuePool.createValue(style.outlineStyle());
        case CSSPropertyOutlineWidth:
            return zoomAdjustedPixelValue(style.outlineWidth(), style);
        case CSSPropertyOverflow:
            return getCSSPropertyValuesFor2SidesShorthand(overflowShorthand());
        case CSSPropertyOverflowWrap:
            return cssValuePool.createValue(style.overflowWrap());
        case CSSPropertyOverflowX:
            return cssValuePool.createValue(style.overflowX());
        case CSSPropertyOverflowY:
            return cssValuePool.createValue(style.overflowY());
        case CSSPropertyOverscrollBehavior:
            if (!m_element->document().settings().overscrollBehaviorEnabled())
                return nullptr;
            return cssValuePool.createValue(std::max(style.overscrollBehaviorX(), style.overscrollBehaviorY()));
        case CSSPropertyOverscrollBehaviorX:
            if (!m_element->document().settings().overscrollBehaviorEnabled())
                return nullptr;
            return cssValuePool.createValue(style.overscrollBehaviorX());
        case CSSPropertyOverscrollBehaviorY:
            if (!m_element->document().settings().overscrollBehaviorEnabled())
                return nullptr;
            return cssValuePool.createValue(style.overscrollBehaviorY());
        case CSSPropertyPaddingTop:
            return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::paddingTop, &RenderBoxModelObject::computedCSSPaddingTop>(style, renderer);
        case CSSPropertyPaddingRight:
            return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::paddingRight, &RenderBoxModelObject::computedCSSPaddingRight>(style, renderer);
        case CSSPropertyPaddingBottom:
            return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::paddingBottom, &RenderBoxModelObject::computedCSSPaddingBottom>(style, renderer);
        case CSSPropertyPaddingLeft:
            return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::paddingLeft, &RenderBoxModelObject::computedCSSPaddingLeft>(style, renderer);
        case CSSPropertyPageBreakAfter:
            return cssValuePool.createValue(convertToPageBreak(style.breakAfter()));
        case CSSPropertyPageBreakBefore:
            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:
            return positionOffsetValue(style, CSSPropertyRight, renderer);
        case CSSPropertyWebkitRubyPosition:
            return cssValuePool.createValue(style.rubyPosition());
        case CSSPropertyTableLayout:
            return cssValuePool.createValue(style.tableLayout());
        case CSSPropertyTextAlign:
            return cssValuePool.createValue(style.textAlign());
        case CSSPropertyTextDecoration:
            return renderTextDecorationFlagsToCSSValue(style.textDecoration());
#if ENABLE(CSS3_TEXT)
        case CSSPropertyWebkitTextAlignLast:
            return cssValuePool.createValue(style.textAlignLast());
        case CSSPropertyWebkitTextJustify:
            return cssValuePool.createValue(style.textJustify());
#endif // CSS3_TEXT
        case CSSPropertyWebkitTextDecoration:
            return getCSSPropertyValuesForShorthandProperties(webkitTextDecorationShorthand());
        case CSSPropertyTextDecorationLine:
            return renderTextDecorationFlagsToCSSValue(style.textDecoration());
        case CSSPropertyTextDecorationStyle:
            return renderTextDecorationStyleFlagsToCSSValue(style.textDecorationStyle());
        case CSSPropertyTextDecorationColor:
            return currentColorOrValidColor(&style, style.textDecorationColor());
        case CSSPropertyTextDecorationSkip:
            return renderTextDecorationSkipToCSSValue(style.textDecorationSkipInk());
        case CSSPropertyTextDecorationSkipInk:
            return cssValuePool.createValue(style.textDecorationSkipInk());
        case CSSPropertyTextUnderlinePosition:
            return cssValuePool.createValue(style.textUnderlinePosition());
        case CSSPropertyTextUnderlineOffset:
            return textUnderlineOffsetToCSSValue(style.textUnderlineOffset());
        case CSSPropertyTextDecorationThickness:
            return textDecorationThicknessToCSSValue(style.textDecorationThickness());
        case CSSPropertyWebkitTextDecorationsInEffect:
            return renderTextDecorationFlagsToCSSValue(style.textDecorationsInEffect());
        case CSSPropertyWebkitTextFillColor:
            return currentColorOrValidColor(&style, style.textFillColor());
        case CSSPropertyWebkitTextEmphasisColor:
            return currentColorOrValidColor(&style, style.textEmphasisColor());
        case CSSPropertyWebkitTextEmphasisPosition:
            return renderEmphasisPositionFlagsToCSSValue(style.textEmphasisPosition());
        case CSSPropertyWebkitTextEmphasisStyle:
            switch (style.textEmphasisMark()) {
            case TextEmphasisMark::None:
                return cssValuePool.createIdentifierValue(CSSValueNone);
            case TextEmphasisMark::Custom:
                return cssValuePool.createValue(style.textEmphasisCustomMark(), CSSUnitType::CSS_STRING);
            case TextEmphasisMark::Auto:
                ASSERT_NOT_REACHED();
#if !ASSERT_ENABLED
                FALLTHROUGH;
#endif
            case TextEmphasisMark::Dot:
            case TextEmphasisMark::Circle:
            case TextEmphasisMark::DoubleCircle:
            case TextEmphasisMark::Triangle:
            case TextEmphasisMark::Sesame:
                auto list = CSSValueList::createSpaceSeparated();
                list->append(cssValuePool.createValue(style.textEmphasisFill()));
                list->append(cssValuePool.createValue(style.textEmphasisMark()));
                return list;
            }
            RELEASE_ASSERT_NOT_REACHED();
        case CSSPropertyTextIndent: {
            auto textIndent = zoomAdjustedPixelValueForLength(style.textIndent(), style);
            if (style.textIndentLine() == TextIndentLine::EachLine || style.textIndentType() == TextIndentType::Hanging) {
                auto list = CSSValueList::createSpaceSeparated();
                list->append(WTFMove(textIndent));
                if (style.textIndentType() == TextIndentType::Hanging)
                    list->append(cssValuePool.createIdentifierValue(CSSValueHanging));
                if (style.textIndentLine() == TextIndentLine::EachLine)
                    list->append(cssValuePool.createIdentifierValue(CSSValueEachLine));
                return list;
            }
            return textIndent;
        }
        case CSSPropertyTextShadow:
            return valueForShadow(style.textShadow(), propertyID, style);
        case CSSPropertyTextRendering:
            return cssValuePool.createValue(style.fontDescription().textRenderingMode());
        case CSSPropertyTextOverflow:
            if (style.textOverflow() == TextOverflow::Ellipsis)
                return cssValuePool.createIdentifierValue(CSSValueEllipsis);
            return cssValuePool.createIdentifierValue(CSSValueClip);
        case CSSPropertyWebkitTextSecurity:
            return cssValuePool.createValue(style.textSecurity());
#if ENABLE(TEXT_AUTOSIZING)
        case CSSPropertyWebkitTextSizeAdjust:
            if (style.textSizeAdjust().isAuto())
                return cssValuePool.createIdentifierValue(CSSValueAuto);
            if (style.textSizeAdjust().isNone())
                return cssValuePool.createIdentifierValue(CSSValueNone);
            return CSSPrimitiveValue::create(style.textSizeAdjust().percentage(), CSSUnitType::CSS_PERCENTAGE);
#endif
        case CSSPropertyWebkitTextStrokeColor:
            return currentColorOrValidColor(&style, style.textStrokeColor());
        case CSSPropertyWebkitTextStrokeWidth:
            return zoomAdjustedPixelValue(style.textStrokeWidth(), style);
        case CSSPropertyTextTransform:
            return cssValuePool.createValue(style.textTransform());
        case CSSPropertyTop:
            return positionOffsetValue(style, CSSPropertyTop, renderer);
        case CSSPropertyUnicodeBidi:
            return cssValuePool.createValue(style.unicodeBidi());
        case CSSPropertyVerticalAlign:
            switch (style.verticalAlign()) {
            case VerticalAlign::Baseline:
                return cssValuePool.createIdentifierValue(CSSValueBaseline);
            case VerticalAlign::Middle:
                return cssValuePool.createIdentifierValue(CSSValueMiddle);
            case VerticalAlign::Sub:
                return cssValuePool.createIdentifierValue(CSSValueSub);
            case VerticalAlign::Super:
                return cssValuePool.createIdentifierValue(CSSValueSuper);
            case VerticalAlign::TextTop:
                return cssValuePool.createIdentifierValue(CSSValueTextTop);
            case VerticalAlign::TextBottom:
                return cssValuePool.createIdentifierValue(CSSValueTextBottom);
            case VerticalAlign::Top:
                return cssValuePool.createIdentifierValue(CSSValueTop);
            case VerticalAlign::Bottom:
                return cssValuePool.createIdentifierValue(CSSValueBottom);
            case VerticalAlign::BaselineMiddle:
                return cssValuePool.createIdentifierValue(CSSValueWebkitBaselineMiddle);
            case VerticalAlign::Length:
                return cssValuePool.createValue(style.verticalAlignLength(), style);
            }
            ASSERT_NOT_REACHED();
            return nullptr;
        case CSSPropertyVisibility:
            return cssValuePool.createValue(style.visibility());
        case CSSPropertyWhiteSpace:
            return cssValuePool.createValue(style.whiteSpace());
        case CSSPropertyWidows:
            if (style.hasAutoWidows())
                return cssValuePool.createIdentifierValue(CSSValueAuto);
            return cssValuePool.createValue(style.widows(), CSSUnitType::CSS_NUMBER);
        case CSSPropertyWidth:
            if (renderer && !renderer->isRenderSVGModelObject()) {
                // According to http://www.w3.org/TR/CSS2/visudet.html#the-width-property,
                // the "width" property does not apply for non-replaced inline elements.
                if (!isNonReplacedInline(*renderer))
                    return zoomAdjustedPixelValue(sizingBox(*renderer).width(), style);
            }
            return zoomAdjustedPixelValueForLength(style.width(), style);
        case CSSPropertyWillChange:
            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 CSSPropertyLineBreak:
            return cssValuePool.createValue(style.lineBreak());
        case CSSPropertyWebkitNbspMode:
            return cssValuePool.createValue(style.nbspMode());
        case CSSPropertyResize:
            return cssValuePool.createValue(style.resize());
        case CSSPropertyWebkitFontKerning:
            return cssValuePool.createValue(style.fontDescription().kerning());
        case CSSPropertyWebkitFontSmoothing:
            return cssValuePool.createValue(style.fontDescription().fontSmoothing());
        case CSSPropertyFontVariantLigatures:
            return fontVariantLigaturesPropertyValue(style.fontDescription().variantCommonLigatures(), style.fontDescription().variantDiscretionaryLigatures(), style.fontDescription().variantHistoricalLigatures(), style.fontDescription().variantContextualAlternates());
        case CSSPropertyFontVariantPosition:
            return fontVariantPositionPropertyValue(style.fontDescription().variantPosition());
        case CSSPropertyFontVariantCaps:
            return fontVariantCapsPropertyValue(style.fontDescription().variantCaps());
        case CSSPropertyFontVariantNumeric:
            return fontVariantNumericPropertyValue(style.fontDescription().variantNumericFigure(), style.fontDescription().variantNumericSpacing(), style.fontDescription().variantNumericFraction(), style.fontDescription().variantNumericOrdinal(), style.fontDescription().variantNumericSlashedZero());
        case CSSPropertyFontVariantAlternates:
            return fontVariantAlternatesPropertyValue(style.fontDescription().variantAlternates());
        case CSSPropertyFontVariantEastAsian:
            return fontVariantEastAsianPropertyValue(style.fontDescription().variantEastAsianVariant(), style.fontDescription().variantEastAsianWidth(), style.fontDescription().variantEastAsianRuby());
        case CSSPropertyZIndex:
            if (style.hasAutoSpecifiedZIndex())
                return cssValuePool.createIdentifierValue(CSSValueAuto);
            return cssValuePool.createValue(style.specifiedZIndex(), CSSUnitType::CSS_NUMBER);
        case CSSPropertyZoom:
            return cssValuePool.createValue(style.zoom(), CSSUnitType::CSS_NUMBER);
        case CSSPropertyBoxSizing:
            if (style.boxSizing() == BoxSizing::ContentBox)
                return cssValuePool.createIdentifierValue(CSSValueContentBox);
            return cssValuePool.createIdentifierValue(CSSValueBorderBox);
        case CSSPropertyAnimationDelay:
            return delayValue(style.animations());
        case CSSPropertyAnimationDirection: {
            auto list = CSSValueList::createCommaSeparated();
            const AnimationList* t = style.animations();
            if (t) {
                for (size_t i = 0; i < t->size(); ++i) {
                    switch (t->animation(i).direction()) {
                    case Animation::AnimationDirectionNormal:
                        list->append(cssValuePool.createIdentifierValue(CSSValueNormal));
                        break;
                    case Animation::AnimationDirectionAlternate:
                        list->append(cssValuePool.createIdentifierValue(CSSValueAlternate));
                        break;
                    case Animation::AnimationDirectionReverse:
                        list->append(cssValuePool.createIdentifierValue(CSSValueReverse));
                        break;
                    case Animation::AnimationDirectionAlternateReverse:
                        list->append(cssValuePool.createIdentifierValue(CSSValueAlternateReverse));
                        break;
                    }
                }
            } else
                list->append(cssValuePool.createIdentifierValue(CSSValueNormal));
            return list;
        }
        case CSSPropertyAnimationDuration:
            return durationValue(style.animations());
        case CSSPropertyAnimationFillMode: {
            auto list = CSSValueList::createCommaSeparated();
            const AnimationList* t = style.animations();
            if (t) {
                for (size_t i = 0; i < t->size(); ++i) {
                    switch (t->animation(i).fillMode()) {
                    case AnimationFillMode::None:
                        list->append(cssValuePool.createIdentifierValue(CSSValueNone));
                        break;
                    case AnimationFillMode::Forwards:
                        list->append(cssValuePool.createIdentifierValue(CSSValueForwards));
                        break;
                    case AnimationFillMode::Backwards:
                        list->append(cssValuePool.createIdentifierValue(CSSValueBackwards));
                        break;
                    case AnimationFillMode::Both:
                        list->append(cssValuePool.createIdentifierValue(CSSValueBoth));
                        break;
                    }
                }
            } else
                list->append(cssValuePool.createIdentifierValue(CSSValueNone));
            return list;
        }
        case CSSPropertyAnimationIterationCount: {
            auto list = CSSValueList::createCommaSeparated();
            const AnimationList* t = style.animations();
            if (t) {
                for (size_t i = 0; i < t->size(); ++i) {
                    double iterationCount = t->animation(i).iterationCount();
                    if (iterationCount == Animation::IterationCountInfinite)
                        list->append(cssValuePool.createIdentifierValue(CSSValueInfinite));
                    else
                        list->append(cssValuePool.createValue(iterationCount, CSSUnitType::CSS_NUMBER));
                }
            } else
                list->append(cssValuePool.createValue(Animation::initialIterationCount(), CSSUnitType::CSS_NUMBER));
            return list;
        }
        case CSSPropertyAnimationName: {
            auto list = CSSValueList::createCommaSeparated();
            const AnimationList* t = style.animations();
            if (t) {
                for (size_t i = 0; i < t->size(); ++i) {
                    auto& name = t->animation(i).name();
                    if (name.isIdentifier)
                        list->append(cssValuePool.createCustomIdent(name.string));
                    else
                        list->append(cssValuePool.createValue(name.string, CSSUnitType::CSS_STRING));
                }
            } else
                list->append(cssValuePool.createIdentifierValue(CSSValueNone));
            return list;
        }
        case CSSPropertyAnimationPlayState: {
            auto list = CSSValueList::createCommaSeparated();
            const AnimationList* t = style.animations();
            if (t) {
                for (size_t i = 0; i < t->size(); ++i) {
                    switch (t->animation(i).playState()) {
                    case AnimationPlayState::Playing:
                        list->append(cssValuePool.createIdentifierValue(CSSValueRunning));
                        break;
                    case AnimationPlayState::Paused:
                        list->append(cssValuePool.createIdentifierValue(CSSValuePaused));
                        break;
                    }
                }
            } else
                list->append(cssValuePool.createIdentifierValue(CSSValueRunning));
            return list;
        }
        case CSSPropertyAnimationTimingFunction:
            return timingFunctionValue(style.animations());
        case CSSPropertyAppearance:
            return cssValuePool.createValue(style.appearance());
        case CSSPropertyAspectRatio:
            if (!m_element->document().settings().aspectRatioEnabled())
                return nullptr;
            switch (style.aspectRatioType()) {
            case AspectRatioType::Auto:
                return cssValuePool.createIdentifierValue(CSSValueAuto);
            case AspectRatioType::AutoZero:
            case AspectRatioType::AutoAndRatio:
            case AspectRatioType::Ratio: {
                auto ratioList = CSSValueList::createSlashSeparated();
                ratioList->append(cssValuePool.createValue(style.aspectRatioWidth(), CSSUnitType::CSS_NUMBER));
                ratioList->append(cssValuePool.createValue(style.aspectRatioHeight(), CSSUnitType::CSS_NUMBER));
                if (style.aspectRatioType() != AspectRatioType::AutoAndRatio)
                    return ratioList;
                auto list = CSSValueList::createSpaceSeparated();
                list->append(cssValuePool.createIdentifierValue(CSSValueAuto));
                list->append(ratioList);
                return list;
            }
            }
            ASSERT_NOT_REACHED();
            return nullptr;
        case CSSPropertyContain: {
            if (!m_element->document().settings().cssContainmentEnabled())
                return nullptr;
            auto containment = style.contain();
            if (!containment)
                return cssValuePool.createIdentifierValue(CSSValueNone);
            if (containment == RenderStyle::strictContainment())
                return cssValuePool.createIdentifierValue(CSSValueStrict);
            if (containment == RenderStyle::contentContainment())
                return cssValuePool.createIdentifierValue(CSSValueContent);
            auto list = CSSValueList::createSpaceSeparated();
            if (containment & Containment::Size)
                list->append(cssValuePool.createIdentifierValue(CSSValueSize));
            if (containment & Containment::Layout)
                list->append(cssValuePool.createIdentifierValue(CSSValueLayout));
            if (containment & Containment::Paint)
                list->append(cssValuePool.createIdentifierValue(CSSValuePaint));
            return list;
        }
        case CSSPropertyBackfaceVisibility:
            return cssValuePool.createIdentifierValue((style.backfaceVisibility() == BackfaceVisibility::Hidden) ? CSSValueHidden : CSSValueVisible);
        case CSSPropertyWebkitBorderImage:
            return valueForNinePieceImage(style.borderImage(), style);
        case CSSPropertyBorderImageOutset:
            return valueForNinePieceImageQuad(style.borderImage().outset(), style);
        case CSSPropertyBorderImageRepeat:
            return valueForNinePieceImageRepeat(style.borderImage());
        case CSSPropertyBorderImageSlice:
            return valueForNinePieceImageSlice(style.borderImage());
        case CSSPropertyBorderImageWidth:
            return valueForNinePieceImageQuad(style.borderImage().borderSlices(), style);
        case CSSPropertyWebkitMaskBoxImage:
            return valueForNinePieceImage(style.maskBoxImage(), style);
        case CSSPropertyWebkitMaskBoxImageOutset:
            return valueForNinePieceImageQuad(style.maskBoxImage().outset(), style);
        case CSSPropertyWebkitMaskBoxImageRepeat:
            return valueForNinePieceImageRepeat(style.maskBoxImage());
        case CSSPropertyWebkitMaskBoxImageSlice:
            return valueForNinePieceImageSlice(style.maskBoxImage());
        case CSSPropertyWebkitMaskBoxImageWidth:
            return valueForNinePieceImageQuad(style.maskBoxImage().borderSlices(), style);
        case CSSPropertyWebkitMaskBoxImageSource:
            if (style.maskBoxImageSource())
                return style.maskBoxImageSource()->cssValue();
            return cssValuePool.createIdentifierValue(CSSValueNone);
        case CSSPropertyWebkitFontSizeDelta:
            // Not a real style property -- used by the editing engine -- so has no computed value.
            break;
        case CSSPropertyWebkitInitialLetter: {
            auto drop = !style.initialLetterDrop() ? cssValuePool.createIdentifierValue(CSSValueNormal) : cssValuePool.createValue(style.initialLetterDrop(), CSSUnitType::CSS_NUMBER);
            auto size = !style.initialLetterHeight() ? cssValuePool.createIdentifierValue(CSSValueNormal) : cssValuePool.createValue(style.initialLetterHeight(), CSSUnitType::CSS_NUMBER);
            return cssValuePool.createValue(Pair::create(WTFMove(drop), WTFMove(size)));
        }
        case CSSPropertyWebkitMarginBottomCollapse:
        case CSSPropertyWebkitMarginAfterCollapse:
            return cssValuePool.createValue(style.marginAfterCollapse());
        case CSSPropertyWebkitMarginTopCollapse:
        case CSSPropertyWebkitMarginBeforeCollapse:
            return cssValuePool.createValue(style.marginBeforeCollapse());
#if ENABLE(OVERFLOW_SCROLLING_TOUCH)
        case CSSPropertyWebkitOverflowScrolling:
            if (!style.useTouchOverflowScrolling())
                return cssValuePool.createIdentifierValue(CSSValueAuto);
            return cssValuePool.createIdentifierValue(CSSValueTouch);
#endif
        case CSSPropertyScrollBehavior:
            if (!style.useSmoothScrolling())
                return cssValuePool.createIdentifierValue(CSSValueAuto);
            return cssValuePool.createIdentifierValue(CSSValueSmooth);
        case CSSPropertyPerspective:
            if (!style.hasPerspective())
                return cssValuePool.createIdentifierValue(CSSValueNone);
            return zoomAdjustedPixelValue(style.perspective(), style);
        case CSSPropertyPerspectiveOrigin: {
            auto list = CSSValueList::createSpaceSeparated();
            if (renderer) {
                auto box = transformReferenceBox(style, *renderer);
                list->append(zoomAdjustedPixelValue(minimumValueForLength(style.perspectiveOriginX(), box.width()), style));
                list->append(zoomAdjustedPixelValue(minimumValueForLength(style.perspectiveOriginY(), box.height()), style));
            } else {
                list->append(zoomAdjustedPixelValueForLength(style.perspectiveOriginX(), style));
                list->append(zoomAdjustedPixelValueForLength(style.perspectiveOriginY(), style));
            }
            return list;
        }
        case CSSPropertyWebkitRtlOrdering:
            return cssValuePool.createIdentifierValue(style.rtlOrdering() == Order::Visual ? CSSValueVisual : CSSValueLogical);
#if ENABLE(TOUCH_EVENTS)
        case CSSPropertyWebkitTapHighlightColor:
            return currentColorOrValidColor(&style, style.tapHighlightColor());
#endif
        case CSSPropertyTouchAction:
            return touchActionFlagsToCSSValue(style.touchActions());
#if PLATFORM(IOS_FAMILY)
        case CSSPropertyWebkitTouchCallout:
            return cssValuePool.createIdentifierValue(style.touchCalloutEnabled() ? CSSValueDefault : CSSValueNone);
#endif
        case CSSPropertyWebkitUserDrag:
            return cssValuePool.createValue(style.userDrag());
        case CSSPropertyWebkitUserSelect:
            return cssValuePool.createValue(style.userSelect());
        case CSSPropertyBorderBottomLeftRadius:
            return borderRadiusCornerValue(style.borderBottomLeftRadius(), style);
        case CSSPropertyBorderBottomRightRadius:
            return borderRadiusCornerValue(style.borderBottomRightRadius(), style);
        case CSSPropertyBorderTopLeftRadius:
            return borderRadiusCornerValue(style.borderTopLeftRadius(), style);
        case CSSPropertyBorderTopRightRadius:
            return borderRadiusCornerValue(style.borderTopRightRadius(), style);
        case CSSPropertyClip: {
            if (!style.hasClip())
                return cssValuePool.createIdentifierValue(CSSValueAuto);
            if (style.clip().top().isAuto() && style.clip().right().isAuto()
                && style.clip().top().isAuto() && style.clip().right().isAuto())
                return cssValuePool.createIdentifierValue(CSSValueAuto);

            auto rect = Rect::create();
            rect->setTop(autoOrZoomAdjustedValue(style.clip().top(), style));
            rect->setRight(autoOrZoomAdjustedValue(style.clip().right(), style));
            rect->setBottom(autoOrZoomAdjustedValue(style.clip().bottom(), style));
            rect->setLeft(autoOrZoomAdjustedValue(style.clip().left(), style));
            return cssValuePool.createValue(WTFMove(rect));
        }
        case CSSPropertySpeakAs:
            return speakAsToCSSValue(style.speakAs());
        case CSSPropertyTransform:
            return computedTransform(renderer, style);
        case CSSPropertyTransformBox:
            return CSSPrimitiveValue::create(style.transformBox());
        case CSSPropertyTransformOrigin: {
            auto list = CSSValueList::createSpaceSeparated();
            if (renderer) {
                auto box = transformReferenceBox(style, *renderer);
                list->append(zoomAdjustedPixelValue(minimumValueForLength(style.transformOriginX(), box.width()), style));
                list->append(zoomAdjustedPixelValue(minimumValueForLength(style.transformOriginY(), box.height()), style));
                if (style.transformOriginZ())
                    list->append(zoomAdjustedPixelValue(style.transformOriginZ(), style));
            } else {
                list->append(zoomAdjustedPixelValueForLength(style.transformOriginX(), style));
                list->append(zoomAdjustedPixelValueForLength(style.transformOriginY(), style));
                if (style.transformOriginZ())
                    list->append(zoomAdjustedPixelValue(style.transformOriginZ(), style));
            }
            return list;
        }
        case CSSPropertyTransformStyle:
        case CSSPropertyWebkitTransformStyle:
            switch (style.transformStyle3D()) {
            case TransformStyle3D::Flat:
                return cssValuePool.createIdentifierValue(CSSValueFlat);
            case TransformStyle3D::Preserve3D:
                return cssValuePool.createIdentifierValue(CSSValuePreserve3d);
#if ENABLE(CSS_TRANSFORM_STYLE_OPTIMIZED_3D)
            case TransformStyle3D::Optimized3D:
                return cssValuePool.createIdentifierValue(CSSValueOptimized3d);
#endif
            }
            ASSERT_NOT_REACHED();
            return nullptr;
        case CSSPropertyTranslate:
            if (!m_element->document().settings().cssIndividualTransformPropertiesEnabled())
                return nullptr;
            return computedTranslate(renderer, style);
        case CSSPropertyScale:
            if (!m_element->document().settings().cssIndividualTransformPropertiesEnabled())
                return nullptr;
            return computedScale(renderer, style);
        case CSSPropertyRotate:
            if (!m_element->document().settings().cssIndividualTransformPropertiesEnabled())
                return nullptr;
            return computedRotate(renderer, style);
        case CSSPropertyTransitionDelay:
            return delayValue(style.transitions());
        case CSSPropertyTransitionDuration:
            return durationValue(style.transitions());
        case CSSPropertyTransitionProperty:
            return transitionPropertyValue(style.transitions());
        case CSSPropertyTransitionTimingFunction:
            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(), CSSUnitType::CSS_S));
                    list->append(createTimingFunctionValue(*animation.timingFunction()));
                    list->append(cssValuePool.createValue(animation.delay(), CSSUnitType::CSS_S));
                    transitionsList->append(WTFMove(list));
                }
                return transitionsList;
            }

            auto list = CSSValueList::createSpaceSeparated();
            // transition-property default value.
            list->append(cssValuePool.createIdentifierValue(CSSValueAll));
            list->append(cssValuePool.createValue(Animation::initialDuration(), CSSUnitType::CSS_S));
            list->append(createTimingFunctionValue(Animation::initialTimingFunction()));
            list->append(cssValuePool.createValue(Animation::initialDelay(), CSSUnitType::CSS_S));
            return list;
        }
        case CSSPropertyPointerEvents:
            return cssValuePool.createValue(style.pointerEvents());
        case CSSPropertyWebkitLineGrid:
            if (style.lineGrid().isNull())
                return cssValuePool.createIdentifierValue(CSSValueNone);
            return cssValuePool.createCustomIdent(style.lineGrid());
        case CSSPropertyWebkitLineSnap:
            return CSSPrimitiveValue::create(style.lineSnap());
        case CSSPropertyWebkitLineAlign:
            return CSSPrimitiveValue::create(style.lineAlign());
        case CSSPropertyWritingMode:
            return cssValuePool.createValue(style.writingMode());
        case CSSPropertyWebkitTextCombine:
            return cssValuePool.createValue(style.textCombine());
        case CSSPropertyWebkitTextOrientation:
            return CSSPrimitiveValue::create(style.textOrientation());
        case CSSPropertyTextOrientation:
            return CSSPrimitiveValue::create(style.textOrientation());
        case CSSPropertyWebkitLineBoxContain:
            return createLineBoxContainValue(style.lineBoxContain());
        case CSSPropertyAlt:
            return altTextToCSSValue(style);
        case CSSPropertyContent:
            return contentToCSSValue(style);
        case CSSPropertyCounterIncrement:
            return counterToCSSValue(style, propertyID);
        case CSSPropertyCounterReset:
            return counterToCSSValue(style, propertyID);
        case CSSPropertyClipPath: {
            auto* operation = style.clipPath();
            if (!operation)
                return cssValuePool.createIdentifierValue(CSSValueNone);
            if (is<ReferenceClipPathOperation>(*operation))
                return CSSPrimitiveValue::create(downcast<ReferenceClipPathOperation>(*operation).url(), CSSUnitType::CSS_URI);
            auto list = CSSValueList::createSpaceSeparated();
            if (is<ShapeClipPathOperation>(*operation)) {
                auto& shapeOperation = downcast<ShapeClipPathOperation>(*operation);
                list->append(valueForBasicShape(style, shapeOperation.basicShape()));
                if (shapeOperation.referenceBox() != CSSBoxType::BoxMissing)
                    list->append(cssValuePool.createValue(shapeOperation.referenceBox()));
            }
            if (is<BoxClipPathOperation>(*operation))
                list->append(cssValuePool.createValue(downcast<BoxClipPathOperation>(*operation).referenceBox()));
            return list;
        }
        case CSSPropertyShapeMargin:
            return cssValuePool.createValue(style.shapeMargin(), style);
        case CSSPropertyShapeImageThreshold:
            return cssValuePool.createValue(style.shapeImageThreshold(), CSSUnitType::CSS_NUMBER);
        case CSSPropertyShapeOutside:
            return shapePropertyValue(style, style.shapeOutside());
        case CSSPropertyFilter:
            return valueForFilter(style, style.filter());
        case CSSPropertyAppleColorFilter:
            return valueForFilter(style, style.appleColorFilter());
#if ENABLE(FILTERS_LEVEL_2)
        case CSSPropertyWebkitBackdropFilter:
            return valueForFilter(style, style.backdropFilter());
#endif
        case CSSPropertyMathStyle:
            return cssValuePool.createValue(style.mathStyle());
#if ENABLE(CSS_COMPOSITING)
        case CSSPropertyMixBlendMode:
            return cssValuePool.createValue(style.blendMode());
        case CSSPropertyIsolation:
            return cssValuePool.createValue(style.isolation());
#endif
        case CSSPropertyBackgroundBlendMode: {
            auto& layers = style.backgroundLayers();
            if (!layers.next())
                return cssValuePool.createValue(layers.blendMode());
            auto list = CSSValueList::createCommaSeparated();
            for (auto* currLayer = &layers; currLayer; currLayer = currLayer->next())
                list->append(cssValuePool.createValue(currLayer->blendMode()));
            return list;
        }
        case CSSPropertyBackground:
            return getBackgroundShorthandValue();
        case CSSPropertyBorder: {
            auto value = propertyValue(CSSPropertyBorderTop, DoNotUpdateLayout);
            const CSSPropertyID properties[3] = { CSSPropertyBorderRight, CSSPropertyBorderBottom, CSSPropertyBorderLeft };
            for (auto& property : properties) {
                if (!compareCSSValuePtr<CSSValue>(value, propertyValue(property, DoNotUpdateLayout)))
                    return nullptr;
            }
            return value;
        }
        case CSSPropertyBorderBlock: {
            auto value = propertyValue(CSSPropertyBorderBlockStart, DoNotUpdateLayout);
            if (!compareCSSValuePtr<CSSValue>(value, propertyValue(CSSPropertyBorderBlockEnd, DoNotUpdateLayout)))
                return nullptr;
            return value;
        }
        case CSSPropertyBorderBlockColor:
            return getCSSPropertyValuesFor2SidesShorthand(borderBlockColorShorthand());
        case CSSPropertyBorderBlockStyle:
            return getCSSPropertyValuesFor2SidesShorthand(borderBlockStyleShorthand());
        case CSSPropertyBorderBlockWidth:
            return getCSSPropertyValuesFor2SidesShorthand(borderBlockWidthShorthand());
        case CSSPropertyBorderBottom:
            return getCSSPropertyValuesForShorthandProperties(borderBottomShorthand());
        case CSSPropertyBorderColor:
            return getCSSPropertyValuesFor4SidesShorthand(borderColorShorthand());
        case CSSPropertyBorderLeft:
            return getCSSPropertyValuesForShorthandProperties(borderLeftShorthand());
        case CSSPropertyBorderImage:
            return valueForNinePieceImage(style.borderImage(), style);
        case CSSPropertyBorderInline: {
            auto value = propertyValue(CSSPropertyBorderInlineStart, DoNotUpdateLayout);
            if (!compareCSSValuePtr<CSSValue>(value, propertyValue(CSSPropertyBorderInlineEnd, DoNotUpdateLayout)))
                return nullptr;
            return value;
        }
        case CSSPropertyBorderInlineColor:
            return getCSSPropertyValuesFor2SidesShorthand(borderInlineColorShorthand());
        case CSSPropertyBorderInlineStyle:
            return getCSSPropertyValuesFor2SidesShorthand(borderInlineStyleShorthand());
        case CSSPropertyBorderInlineWidth:
            return getCSSPropertyValuesFor2SidesShorthand(borderInlineWidthShorthand());
        case CSSPropertyBorderRadius:
            return borderRadiusShorthandValue(style);
        case CSSPropertyBorderRight:
            return getCSSPropertyValuesForShorthandProperties(borderRightShorthand());
        case CSSPropertyBorderStyle:
            return getCSSPropertyValuesFor4SidesShorthand(borderStyleShorthand());
        case CSSPropertyBorderTop:
            return getCSSPropertyValuesForShorthandProperties(borderTopShorthand());
        case CSSPropertyBorderWidth:
            return getCSSPropertyValuesFor4SidesShorthand(borderWidthShorthand());
        case CSSPropertyColumnRule:
            return getCSSPropertyValuesForShorthandProperties(columnRuleShorthand());
        case CSSPropertyColumns:
            return getCSSPropertyValuesForShorthandProperties(columnsShorthand());
        case CSSPropertyInset:
            return getCSSPropertyValuesFor4SidesShorthand(insetShorthand());
        case CSSPropertyInsetBlock:
            return getCSSPropertyValuesFor2SidesShorthand(insetBlockShorthand());
        case CSSPropertyInsetInline:
            return getCSSPropertyValuesFor2SidesShorthand(insetInlineShorthand());
        case CSSPropertyListStyle:
            return getCSSPropertyValuesForShorthandProperties(listStyleShorthand());
        case CSSPropertyMargin:
            return getCSSPropertyValuesFor4SidesShorthand(marginShorthand());
        case CSSPropertyMarginBlock:
            return getCSSPropertyValuesFor2SidesShorthand(marginBlockShorthand());
        case CSSPropertyMarginInline:
            return getCSSPropertyValuesFor2SidesShorthand(marginInlineShorthand());
        case CSSPropertyOutline:
            return getCSSPropertyValuesForShorthandProperties(outlineShorthand());
        case CSSPropertyPadding:
            return getCSSPropertyValuesFor4SidesShorthand(paddingShorthand());
        case CSSPropertyPaddingBlock:
            return getCSSPropertyValuesFor2SidesShorthand(paddingBlockShorthand());
        case CSSPropertyPaddingInline:
            return getCSSPropertyValuesFor2SidesShorthand(paddingInlineShorthand());
        case CSSPropertyScrollMargin:
            return getCSSPropertyValuesFor4SidesShorthand(scrollMarginShorthand());
        case CSSPropertyScrollMarginBottom:
            return zoomAdjustedPixelValueForLength(style.scrollMarginBottom(), style);
        case CSSPropertyScrollMarginTop:
            return zoomAdjustedPixelValueForLength(style.scrollMarginTop(), style);
        case CSSPropertyScrollMarginRight:
            return zoomAdjustedPixelValueForLength(style.scrollMarginRight(), style);
        case CSSPropertyScrollMarginLeft:
            return zoomAdjustedPixelValueForLength(style.scrollMarginLeft(), style);
        case CSSPropertyScrollMarginBlock:
            return getCSSPropertyValuesFor2SidesShorthand(scrollMarginBlockShorthand());
        case CSSPropertyScrollMarginInline:
            return getCSSPropertyValuesFor2SidesShorthand(scrollMarginInlineShorthand());
        case CSSPropertyScrollPadding:
            return getCSSPropertyValuesFor4SidesShorthand(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 CSSPropertyScrollPaddingBlock:
            return getCSSPropertyValuesFor2SidesShorthand(scrollPaddingBlockShorthand());
        case CSSPropertyScrollPaddingInline:
            return getCSSPropertyValuesFor2SidesShorthand(scrollPaddingInlineShorthand());
        case CSSPropertyScrollSnapAlign:
            return valueForScrollSnapAlignment(style.scrollSnapAlign());
        case CSSPropertyScrollSnapStop:
            return CSSPrimitiveValue::create(style.scrollSnapStop());
        case CSSPropertyScrollSnapType:
            return valueForScrollSnapType(style.scrollSnapType());

#if ENABLE(CSS_TRAILING_WORD)
        case CSSPropertyAppleTrailingWord:
            return cssValuePool.createValue(style.trailingWord());
#endif

#if ENABLE(APPLE_PAY)
        case CSSPropertyApplePayButtonStyle:
            return cssValuePool.createValue(style.applePayButtonStyle());
        case CSSPropertyApplePayButtonType:
            return cssValuePool.createValue(style.applePayButtonType());
#endif

#if ENABLE(DARK_MODE_CSS)
        case CSSPropertyColorScheme: {
            auto colorScheme = style.colorScheme();
            if (colorScheme.isAuto())
                return cssValuePool.createIdentifierValue(CSSValueAuto);

            auto list = CSSValueList::createSpaceSeparated();
            if (colorScheme.contains(ColorScheme::Light))
                list->append(cssValuePool.createIdentifierValue(CSSValueLight));
            if (colorScheme.contains(ColorScheme::Dark))
                list->append(cssValuePool.createIdentifierValue(CSSValueDark));
            if (!colorScheme.allowsTransformations())
                list->append(cssValuePool.createIdentifierValue(CSSValueOnly));
            ASSERT(list->length());
            return list;
        }
#endif

        /* Individual properties not part of the spec */
        case CSSPropertyBackgroundRepeatX:
        case CSSPropertyBackgroundRepeatY:
            break;

        // Length properties for SVG.
        case CSSPropertyCx:
            return zoomAdjustedPixelValueForLength(style.svgStyle().cx(), style);
        case CSSPropertyCy:
            return zoomAdjustedPixelValueForLength(style.svgStyle().cy(), style);
        case CSSPropertyR:
            return zoomAdjustedPixelValueForLength(style.svgStyle().r(), style);
        case CSSPropertyRx:
            return zoomAdjustedPixelValueForLength(style.svgStyle().rx(), style);
        case CSSPropertyRy:
            return zoomAdjustedPixelValueForLength(style.svgStyle().ry(), style);
        case CSSPropertyStrokeDashoffset:
            return zoomAdjustedPixelValueForLength(style.svgStyle().strokeDashOffset(), style);
        case CSSPropertyX:
            return zoomAdjustedPixelValueForLength(style.svgStyle().x(), style);
        case CSSPropertyY:
            return zoomAdjustedPixelValueForLength(style.svgStyle().y(), style);
        case CSSPropertyWebkitTextZoom:
            return cssValuePool.createValue(style.textZoom());

        case CSSPropertyPaintOrder:
            return paintOrder(style.paintOrder());
        case CSSPropertyStrokeLinecap:
            return CSSPrimitiveValue::create(style.capStyle());
        case CSSPropertyStrokeLinejoin:
            return CSSPrimitiveValue::create(style.joinStyle());
        case CSSPropertyStrokeWidth:
            return zoomAdjustedPixelValueForLength(style.strokeWidth(), style);
        case CSSPropertyStrokeColor:
            return currentColorOrValidColor(&style, style.strokeColor());
        case CSSPropertyStrokeMiterlimit:
            return CSSPrimitiveValue::create(style.strokeMiterLimit(), CSSUnitType::CSS_NUMBER);

        case CSSPropertyQuotes:
            return valueForQuotes(style.quotes());

        /* Unimplemented CSS 3 properties (including CSS3 shorthand properties) */
        case CSSPropertyAll:
        case CSSPropertyAnimation:
        case CSSPropertyWebkitTextEmphasis:
            break;

        /* Directional properties are resolved by resolveDirectionAwareProperty() before the switch. */
        case CSSPropertyBorderBlockEnd:
        case CSSPropertyBorderBlockEndColor:
        case CSSPropertyBorderBlockEndStyle:
        case CSSPropertyBorderBlockEndWidth:
        case CSSPropertyBorderBlockStart:
        case CSSPropertyBorderBlockStartColor:
        case CSSPropertyBorderBlockStartStyle:
        case CSSPropertyBorderBlockStartWidth:
        case CSSPropertyBorderEndEndRadius:        
        case CSSPropertyBorderEndStartRadius:        
        case CSSPropertyBorderInlineEnd:
        case CSSPropertyBorderInlineEndColor:
        case CSSPropertyBorderInlineEndStyle:
        case CSSPropertyBorderInlineEndWidth:
        case CSSPropertyBorderInlineStart:
        case CSSPropertyBorderInlineStartColor:
        case CSSPropertyBorderInlineStartStyle:
        case CSSPropertyBorderInlineStartWidth:
        case CSSPropertyBorderStartEndRadius:        
        case CSSPropertyBorderStartStartRadius:        
        case CSSPropertyInsetBlockEnd:
        case CSSPropertyInsetBlockStart:
        case CSSPropertyInsetInlineEnd:
        case CSSPropertyInsetInlineStart:
        case CSSPropertyMarginBlockEnd:
        case CSSPropertyMarginBlockStart:
        case CSSPropertyMarginInlineEnd:
        case CSSPropertyMarginInlineStart:
        case CSSPropertyPaddingBlockEnd:
        case CSSPropertyPaddingBlockStart:
        case CSSPropertyPaddingInlineEnd:
        case CSSPropertyPaddingInlineStart:
        case CSSPropertyBlockSize:
        case CSSPropertyInlineSize:
        case CSSPropertyMaxBlockSize:
        case CSSPropertyMaxInlineSize:
        case CSSPropertyMinBlockSize:
        case CSSPropertyMinInlineSize:
        case CSSPropertyScrollMarginBlockEnd:
        case CSSPropertyScrollMarginBlockStart:
        case CSSPropertyScrollMarginInlineEnd:
        case CSSPropertyScrollMarginInlineStart:
        case CSSPropertyScrollPaddingBlockEnd:
        case CSSPropertyScrollPaddingBlockStart:
        case CSSPropertyScrollPaddingInlineEnd:
        case CSSPropertyScrollPaddingInlineStart:
            ASSERT_NOT_REACHED();
            break;

        // These are intentionally unimplemented because they are actually descriptors for @counter-style.
        case CSSPropertySystem:
        case CSSPropertyNegative:
        case CSSPropertyPrefix:
        case CSSPropertySuffix:
        case CSSPropertyRange:
        case CSSPropertyPad:
        case CSSPropertyFallback:
        case CSSPropertySymbols:
        case CSSPropertyAdditiveSymbols:
            break;

        /* Unimplemented @font-face properties */
        case CSSPropertySrc:
        case CSSPropertyUnicodeRange:
        case CSSPropertyFontDisplay:
            break;

        // Unimplemented @font-palette-values properties
        case CSSPropertyBasePalette:
        case CSSPropertyOverrideColors:
            break;

        /* Other unimplemented properties */
        case CSSPropertyPage: // for @page
        case CSSPropertySize: // for @page
            break;

        /* Unimplemented -webkit- properties */
        case CSSPropertyWebkitBorderRadius:
        case CSSPropertyWebkitMarginCollapse:
        case CSSPropertyWebkitMarqueeDirection:
        case CSSPropertyWebkitMarqueeIncrement:
        case CSSPropertyWebkitMarqueeRepetition:
        case CSSPropertyWebkitMarqueeStyle:
        case CSSPropertyWebkitMarqueeSpeed:
        case CSSPropertyWebkitMask:
        case CSSPropertyWebkitMaskRepeatX:
        case CSSPropertyWebkitMaskRepeatY:
        case CSSPropertyPerspectiveOriginX:
        case CSSPropertyPerspectiveOriginY:
        case CSSPropertyWebkitTextStroke:
        case CSSPropertyTransformOriginX:
        case CSSPropertyTransformOriginY:
        case CSSPropertyTransformOriginZ:
            break;

        case CSSPropertyBufferedRendering:
        case CSSPropertyClipRule:
        case CSSPropertyMask:
        case CSSPropertyEnableBackground:
        case CSSPropertyFloodColor:
        case CSSPropertyFloodOpacity:
        case CSSPropertyLightingColor:
        case CSSPropertyStopColor:
        case CSSPropertyStopOpacity:
        case CSSPropertyColorInterpolation:
        case CSSPropertyColorInterpolationFilters:
        case CSSPropertyColorProfile:
        case CSSPropertyColorRendering:
        case CSSPropertyFill:
        case CSSPropertyFillOpacity:
        case CSSPropertyFillRule:
        case CSSPropertyMarker:
        case CSSPropertyMarkerEnd:
        case CSSPropertyMarkerMid:
        case CSSPropertyMarkerStart:
        case CSSPropertyMaskType:
        case CSSPropertyShapeRendering:
        case CSSPropertyStroke:
        case CSSPropertyStrokeDasharray:
        case CSSPropertyStrokeOpacity:
        case CSSPropertyAlignmentBaseline:
        case CSSPropertyBaselineShift:
        case CSSPropertyDominantBaseline:
        case CSSPropertyGlyphOrientationHorizontal:
        case CSSPropertyGlyphOrientationVertical:
        case CSSPropertyKerning:
        case CSSPropertyTextAnchor:
        case CSSPropertyVectorEffect:
            return svgPropertyValue(propertyID);
        case CSSPropertyCustom:
            ASSERT_NOT_REACHED();
            return nullptr;
    }

    return nullptr;
}

String CSSComputedStyleDeclaration::getPropertyValue(CSSPropertyID propertyID) const
{
    auto value = getPropertyCSSValue(propertyID);
    if (!value)
        return emptyString(); // FIXME: Should this be null instead, as it is in StyleProperties::getPropertyValue?
    return value->cssText();
}

unsigned CSSComputedStyleDeclaration::length() const
{
    updateStyleIfNeededForProperty(m_element.get(), CSSPropertyCustom);

    auto* style = m_element->computedStyle(m_pseudoElementSpecifier);
    if (!style)
        return 0;

    return numComputedPropertyIDs + style->inheritedCustomProperties().size() + style->nonInheritedCustomProperties().size();
}

String CSSComputedStyleDeclaration::item(unsigned i) const
{
    if (i >= length())
        return String();

    if (i < numComputedPropertyIDs)
        return getPropertyNameString(computedPropertyIDs[i]);

    auto* style = m_element->computedStyle(m_pseudoElementSpecifier);
    if (!style)
        return String();

    const auto& inheritedCustomProperties = style->inheritedCustomProperties();

    if (i < numComputedPropertyIDs + inheritedCustomProperties.size()) {
        auto results = copyToVector(inheritedCustomProperties.keys());
        return results.at(i - numComputedPropertyIDs);
    }

    const auto& nonInheritedCustomProperties = style->nonInheritedCustomProperties();
    auto results = copyToVector(nonInheritedCustomProperties.keys());
    return results.at(i - inheritedCustomProperties.size() - numComputedPropertyIDs);
}

bool ComputedStyleExtractor::propertyMatches(CSSPropertyID propertyID, const CSSValue* value)
{
    if (!m_element)
        return false;
    if (propertyID == CSSPropertyFontSize && is<CSSPrimitiveValue>(*value)) {
        m_element->document().updateLayoutIgnorePendingStylesheets();
        if (auto* style = m_element->computedStyle(m_pseudoElementSpecifier)) {
            if (CSSValueID sizeIdentifier = style->fontDescription().keywordSizeAsIdentifier()) {
                auto& primitiveValue = downcast<CSSPrimitiveValue>(*value);
                if (primitiveValue.isValueID() && primitiveValue.valueID() == sizeIdentifier)
                    return true;
            }
        }
    }
    RefPtr<CSSValue> computedValue = propertyValue(propertyID);
    return computedValue && value && computedValue->equals(*value);
}

Ref<CSSValueList> ComputedStyleExtractor::getCSSPropertyValuesForShorthandProperties(const StylePropertyShorthand& shorthand)
{
    auto list = CSSValueList::createSpaceSeparated();
    for (size_t i = 0; i < shorthand.length(); ++i)
        list->append(propertyValue(shorthand.properties()[i], DoNotUpdateLayout).releaseNonNull());
    return list;
}

RefPtr<CSSValueList> ComputedStyleExtractor::getCSSPropertyValuesFor2SidesShorthand(const StylePropertyShorthand& shorthand)
{
    auto list = CSSValueList::createSpaceSeparated();

    // Assume the properties are in the usual order start, end.
    auto startValue = propertyValue(shorthand.properties()[0], DoNotUpdateLayout);
    auto endValue = propertyValue(shorthand.properties()[1], DoNotUpdateLayout);

    // All 2 properties must be specified.
    if (!startValue || !endValue)
        return nullptr;

    bool showEnd = !compareCSSValuePtr(startValue, endValue);

    list->append(startValue.releaseNonNull());
    if (showEnd)
        list->append(endValue.releaseNonNull());

    return list;
}

RefPtr<CSSValueList> ComputedStyleExtractor::getCSSPropertyValuesFor4SidesShorthand(const StylePropertyShorthand& shorthand)
{
    auto list = CSSValueList::createSpaceSeparated();

    // Assume the properties are in the usual order top, right, bottom, left.
    auto topValue = propertyValue(shorthand.properties()[0], DoNotUpdateLayout);
    auto rightValue = propertyValue(shorthand.properties()[1], DoNotUpdateLayout);
    auto bottomValue = propertyValue(shorthand.properties()[2], DoNotUpdateLayout);
    auto leftValue = propertyValue(shorthand.properties()[3], DoNotUpdateLayout);

    // All 4 properties must be specified.
    if (!topValue || !rightValue || !bottomValue || !leftValue)
        return nullptr;

    bool showLeft = !compareCSSValuePtr(rightValue, leftValue);
    bool showBottom = !compareCSSValuePtr(topValue, bottomValue) || showLeft;
    bool showRight = !compareCSSValuePtr(topValue, rightValue) || showBottom;

    list->append(topValue.releaseNonNull());
    if (showRight)
        list->append(rightValue.releaseNonNull());
    if (showBottom)
        list->append(bottomValue.releaseNonNull());
    if (showLeft)
        list->append(leftValue.releaseNonNull());

    return list;
}

Ref<CSSValueList> ComputedStyleExtractor::getCSSPropertyValuesForGridShorthand(const StylePropertyShorthand& shorthand)
{
    auto list = CSSValueList::createSlashSeparated();
    for (size_t i = 0; i < shorthand.length(); ++i)
        list->append(propertyValue(shorthand.properties()[i], DoNotUpdateLayout).releaseNonNull());
    return list;
}

Ref<MutableStyleProperties> ComputedStyleExtractor::copyPropertiesInSet(const CSSPropertyID* set, unsigned length)
{
    Vector<CSSProperty> list;
    list.reserveInitialCapacity(length);
    for (unsigned i = 0; i < length; ++i) {
        if (auto value = propertyValue(set[i]))
            list.append(CSSProperty(set[i], WTFMove(value), false));
    }
    return MutableStyleProperties::create(WTFMove(list));
}

Ref<MutableStyleProperties> ComputedStyleExtractor::copyProperties()
{
    Vector<CSSProperty> list;
    list.reserveInitialCapacity(numCSSProperties);
    for (unsigned i = firstCSSProperty; i < lastCSSProperty; ++i) {
        auto propertyID = convertToCSSPropertyID(i);
        if (auto value = propertyValue(propertyID))
            list.append(CSSProperty(propertyID, WTFMove(value)));
    }
    return MutableStyleProperties::create(WTFMove(list));
}

CSSRule* CSSComputedStyleDeclaration::parentRule() const
{
    return nullptr;
}

RefPtr<DeprecatedCSSOMValue> CSSComputedStyleDeclaration::getPropertyCSSValue(const String& propertyName)
{
    if (isCustomPropertyName(propertyName)) {
        auto value = ComputedStyleExtractor(m_element.ptr(), m_allowVisitedStyle, m_pseudoElementSpecifier).customPropertyValue(propertyName);
        if (!value)
            return nullptr;
        return value->createDeprecatedCSSOMWrapper(*this);
    }

    CSSPropertyID propertyID = cssPropertyID(propertyName);
    if (!propertyID)
        return nullptr;
    auto value = getPropertyCSSValue(propertyID);
    if (!value)
        return nullptr;
    return value->createDeprecatedCSSOMWrapper(*this);
}

String CSSComputedStyleDeclaration::getPropertyValue(const String &propertyName)
{
    if (isCustomPropertyName(propertyName))
        return ComputedStyleExtractor(m_element.ptr(), m_allowVisitedStyle, m_pseudoElementSpecifier).customPropertyText(propertyName);

    CSSPropertyID propertyID = cssPropertyID(propertyName);
    if (!propertyID)
        return String();
    return getPropertyValue(propertyID);
}

String CSSComputedStyleDeclaration::getPropertyPriority(const String&)
{
    // All computed styles have a priority of not "important".
    return emptyString();
}

String CSSComputedStyleDeclaration::getPropertyShorthand(const String&)
{
    return emptyString(); // FIXME: Should this sometimes be null instead of empty, to match a normal style declaration?
}

bool CSSComputedStyleDeclaration::isPropertyImplicit(const String&)
{
    return false;
}

ExceptionOr<void> CSSComputedStyleDeclaration::setProperty(const String&, const String&, const String&)
{
    return Exception { NoModificationAllowedError };
}

ExceptionOr<String> CSSComputedStyleDeclaration::removeProperty(const String&)
{
    return Exception { NoModificationAllowedError };
}
    
RefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValueInternal(CSSPropertyID propertyID)
{
    return getPropertyCSSValue(propertyID);
}

String CSSComputedStyleDeclaration::getPropertyValueInternal(CSSPropertyID propertyID)
{
    return getPropertyValue(propertyID);
}

ExceptionOr<void> CSSComputedStyleDeclaration::setPropertyInternal(CSSPropertyID, const String&, bool)
{
    return Exception { NoModificationAllowedError };
}

Ref<CSSValueList> ComputedStyleExtractor::getBackgroundShorthandValue()
{
    static const CSSPropertyID propertiesBeforeSlashSeperator[5] = { CSSPropertyBackgroundColor, CSSPropertyBackgroundImage, CSSPropertyBackgroundRepeat, CSSPropertyBackgroundAttachment, CSSPropertyBackgroundPosition };
    static const CSSPropertyID propertiesAfterSlashSeperator[3] = { CSSPropertyBackgroundSize, CSSPropertyBackgroundOrigin, CSSPropertyBackgroundClip };

    auto list = CSSValueList::createSlashSeparated();
    list->append(getCSSPropertyValuesForShorthandProperties(StylePropertyShorthand(CSSPropertyBackground, propertiesBeforeSlashSeperator)));
    list->append(getCSSPropertyValuesForShorthandProperties(StylePropertyShorthand(CSSPropertyBackground, propertiesAfterSlashSeperator)));
    return list;
}

} // namespace WebCore
