/*
 * Copyright (C) 2004 Zack Rusin <zack@kde.org>
 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved.
 * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org>
 * Copyright (C) 2007 Nicholas Shanks <webkit@nickshanks.com>
 * Copyright (C) 2011 Sencha, Inc. All rights reserved.
 * Copyright (C) 2015 Google Inc. 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 "core/css/ComputedStyleCSSValueMapping.h"

#include "core/StylePropertyShorthand.h"
#include "core/animation/css/CSSAnimationData.h"
#include "core/animation/css/CSSTransitionData.h"
#include "core/css/BasicShapeFunctions.h"
#include "core/css/CSSBasicShapeValues.h"
#include "core/css/CSSBorderImage.h"
#include "core/css/CSSBorderImageSliceValue.h"
#include "core/css/CSSColorValue.h"
#include "core/css/CSSCounterValue.h"
#include "core/css/CSSCursorImageValue.h"
#include "core/css/CSSCustomIdentValue.h"
#include "core/css/CSSCustomPropertyDeclaration.h"
#include "core/css/CSSFontFamilyValue.h"
#include "core/css/CSSFontFeatureValue.h"
#include "core/css/CSSFunctionValue.h"
#include "core/css/CSSGridLineNamesValue.h"
#include "core/css/CSSGridTemplateAreasValue.h"
#include "core/css/CSSInitialValue.h"
#include "core/css/CSSPathValue.h"
#include "core/css/CSSPrimitiveValue.h"
#include "core/css/CSSPrimitiveValueMappings.h"
#include "core/css/CSSQuadValue.h"
#include "core/css/CSSReflectValue.h"
#include "core/css/CSSShadowValue.h"
#include "core/css/CSSStringValue.h"
#include "core/css/CSSTimingFunctionValue.h"
#include "core/css/CSSURIValue.h"
#include "core/css/CSSValueList.h"
#include "core/css/CSSValuePair.h"
#include "core/css/PropertyRegistry.h"
#include "core/layout/LayoutBlock.h"
#include "core/layout/LayoutBox.h"
#include "core/layout/LayoutGrid.h"
#include "core/layout/LayoutObject.h"
#include "core/style/ComputedStyle.h"
#include "core/style/ContentData.h"
#include "core/style/CursorData.h"
#include "core/style/QuotesData.h"
#include "core/style/ShadowList.h"
#include "core/style/StyleVariableData.h"
#include "platform/LengthFunctions.h"

namespace blink {

inline static bool isFlexOrGrid(const ComputedStyle* style)
{
    return style && style->isDisplayFlexibleOrGridBox();
}

inline static CSSPrimitiveValue* zoomAdjustedPixelValue(double value, const ComputedStyle& style)
{
    return CSSPrimitiveValue::create(adjustFloatForAbsoluteZoom(value, style), CSSPrimitiveValue::UnitType::Pixels);
}

inline static CSSPrimitiveValue* zoomAdjustedNumberValue(double value, const ComputedStyle& style)
{
    return CSSPrimitiveValue::create(value / style.effectiveZoom(), CSSPrimitiveValue::UnitType::Number);
}

static CSSPrimitiveValue* zoomAdjustedPixelValueForLength(const Length& length, const ComputedStyle& style)
{
    if (length.isFixed())
        return zoomAdjustedPixelValue(length.value(), style);
    return CSSPrimitiveValue::create(length, style);
}

static CSSPrimitiveValue* pixelValueForUnzoomedLength(const UnzoomedLength& unzoomedLength, const ComputedStyle& style)
{
    const Length& length = unzoomedLength.length();
    if (length.isFixed())
        return CSSPrimitiveValue::create(length.value(), CSSPrimitiveValue::UnitType::Pixels);
    return CSSPrimitiveValue::create(length, style);
}

static CSSValueList* createPositionListForLayer(CSSPropertyID propertyID, const FillLayer& layer, const ComputedStyle& style)
{
    CSSValueList* positionList = CSSValueList::createSpaceSeparated();
    if (layer.isBackgroundXOriginSet()) {
        ASSERT_UNUSED(propertyID, propertyID == CSSPropertyBackgroundPosition || propertyID == CSSPropertyWebkitMaskPosition);
        positionList->append(*CSSPrimitiveValue::create(layer.backgroundXOrigin()));
    }
    positionList->append(*zoomAdjustedPixelValueForLength(layer.xPosition(), style));
    if (layer.isBackgroundYOriginSet()) {
        ASSERT(propertyID == CSSPropertyBackgroundPosition || propertyID == CSSPropertyWebkitMaskPosition);
        positionList->append(*CSSPrimitiveValue::create(layer.backgroundYOrigin()));
    }
    positionList->append(*zoomAdjustedPixelValueForLength(layer.yPosition(), style));
    return positionList;
}

CSSValue* ComputedStyleCSSValueMapping::currentColorOrValidColor(const ComputedStyle& style, const StyleColor& color)
{
    // This function does NOT look at visited information, so that computed style doesn't expose that.
    return CSSColorValue::create(color.resolve(style.color()).rgb());
}

static CSSValue* valueForFillSize(const FillSize& fillSize, const ComputedStyle& style)
{
    if (fillSize.type == Contain)
        return CSSPrimitiveValue::createIdentifier(CSSValueContain);

    if (fillSize.type == Cover)
        return CSSPrimitiveValue::createIdentifier(CSSValueCover);

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

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

static CSSValue* valueForFillRepeat(EFillRepeat xRepeat, EFillRepeat yRepeat)
{
    // For backwards compatibility, if both values are equal, just return one of them. And
    // if the two values are equivalent to repeat-x or repeat-y, just return the shorthand.
    if (xRepeat == yRepeat)
        return CSSPrimitiveValue::create(xRepeat);
    if (xRepeat == RepeatFill && yRepeat == NoRepeatFill)
        return CSSPrimitiveValue::createIdentifier(CSSValueRepeatX);
    if (xRepeat == NoRepeatFill && yRepeat == RepeatFill)
        return CSSPrimitiveValue::createIdentifier(CSSValueRepeatY);

    CSSValueList* list = CSSValueList::createSpaceSeparated();
    list->append(*CSSPrimitiveValue::create(xRepeat));
    list->append(*CSSPrimitiveValue::create(yRepeat));
    return list;
}

static CSSValue* valueForFillSourceType(EMaskSourceType type)
{
    switch (type) {
    case MaskAlpha:
        return CSSPrimitiveValue::createIdentifier(CSSValueAlpha);
    case MaskLuminance:
        return CSSPrimitiveValue::createIdentifier(CSSValueLuminance);
    }

    ASSERT_NOT_REACHED();

    return nullptr;
}

static CSSValue* valueForPositionOffset(const ComputedStyle& style, CSSPropertyID propertyID, const LayoutObject* layoutObject)
{
    Length offset, opposite;
    switch (propertyID) {
    case CSSPropertyLeft:
        offset = style.left();
        opposite = style.right();
        break;
    case CSSPropertyRight:
        offset = style.right();
        opposite = style.left();
        break;
    case CSSPropertyTop:
        offset = style.top();
        opposite = style.bottom();
        break;
    case CSSPropertyBottom:
        offset = style.bottom();
        opposite = style.top();
        break;
    default:
        return nullptr;
    }

    if (offset.isPercentOrCalc() && layoutObject && layoutObject->isBox() && layoutObject->isPositioned()) {
        LayoutUnit containingBlockSize = (propertyID == CSSPropertyLeft || propertyID == CSSPropertyRight) ?
            toLayoutBox(layoutObject)->containingBlockLogicalWidthForContent() :
            toLayoutBox(layoutObject)->containingBlockLogicalHeightForGetComputedStyle();
        return zoomAdjustedPixelValue(valueForLength(offset, containingBlockSize), style);
    }

    if (offset.isAuto() && layoutObject) {
        // If the property applies to a positioned element and the resolved value of the display
        // property is not none, the resolved value is the used value.
        if (layoutObject->isInFlowPositioned()) {
            // If e.g. left is auto and right is not auto, then left's computed value is negative right.
            // So we get the opposite length unit and see if it is auto.
            if (opposite.isAuto())
                return CSSPrimitiveValue::create(0, CSSPrimitiveValue::UnitType::Pixels);

            if (opposite.isPercentOrCalc() || opposite.isCalculated()) {
                if (layoutObject->isBox()) {
                    LayoutUnit containingBlockSize =
                        (propertyID == CSSPropertyLeft || propertyID == CSSPropertyRight) ?
                        toLayoutBox(layoutObject)->containingBlockLogicalWidthForContent() :
                        toLayoutBox(layoutObject)->containingBlockLogicalHeightForGetComputedStyle();
                    return zoomAdjustedPixelValue(-floatValueForLength(opposite, containingBlockSize), style);
                }
                // FIXME:  fall back to auto for position:relative, display:inline
                return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
            }

            // Length doesn't provide operator -, so multiply by -1.
            opposite *= -1.f;
            return zoomAdjustedPixelValueForLength(opposite, style);
        }

        if (layoutObject->isOutOfFlowPositioned() && layoutObject->isBox()) {
            // For fixed and absolute positioned elements, the top, left, bottom, and right
            // are defined relative to the corresponding sides of the containing block.
            LayoutBlock* container = layoutObject->containingBlock();
            const LayoutBox* layoutBox = toLayoutBox(layoutObject);

            // clientOffset is the distance from this object's border edge to the container's
            // padding edge. Thus it includes margins which we subtract below.
            const LayoutSize clientOffset =
                layoutBox->locationOffset() - LayoutSize(container->clientLeft(), container->clientTop());
            LayoutUnit position;

            switch (propertyID) {
            case CSSPropertyLeft:
                position = clientOffset.width() - layoutBox->marginLeft();
                break;
            case CSSPropertyTop:
                position = clientOffset.height() - layoutBox->marginTop();
                break;
            case CSSPropertyRight:
                position = container->clientWidth() - layoutBox->marginRight() -
                    (layoutBox->offsetWidth() + clientOffset.width());
                break;
            case CSSPropertyBottom:
                position = container->clientHeight() - layoutBox->marginBottom() -
                    (layoutBox->offsetHeight() + clientOffset.height());
                break;
            default:
                ASSERT_NOT_REACHED();
            }
            return zoomAdjustedPixelValue(position, style);
        }
    }

    if (offset.isAuto())
        return CSSPrimitiveValue::createIdentifier(CSSValueAuto);

    return zoomAdjustedPixelValueForLength(offset, style);
}

static CSSBorderImageSliceValue* valueForNinePieceImageSlice(const NinePieceImage& image)
{
    // Create the slices.
    CSSPrimitiveValue* top = nullptr;
    CSSPrimitiveValue* right = nullptr;
    CSSPrimitiveValue* bottom = nullptr;
    CSSPrimitiveValue* left = nullptr;

    // TODO(alancutter): Make this code aware of calc lengths.
    if (image.imageSlices().top().isPercentOrCalc())
        top = CSSPrimitiveValue::create(image.imageSlices().top().value(), CSSPrimitiveValue::UnitType::Percentage);
    else
        top = CSSPrimitiveValue::create(image.imageSlices().top().value(), CSSPrimitiveValue::UnitType::Number);

    if (image.imageSlices().right() == image.imageSlices().top() && image.imageSlices().bottom() == image.imageSlices().top()
        && image.imageSlices().left() == image.imageSlices().top()) {
        right = top;
        bottom = top;
        left = top;
    } else {
        if (image.imageSlices().right().isPercentOrCalc())
            right = CSSPrimitiveValue::create(image.imageSlices().right().value(), CSSPrimitiveValue::UnitType::Percentage);
        else
            right = CSSPrimitiveValue::create(image.imageSlices().right().value(), CSSPrimitiveValue::UnitType::Number);

        if (image.imageSlices().bottom() == image.imageSlices().top() && image.imageSlices().right() == image.imageSlices().left()) {
            bottom = top;
            left = right;
        } else {
            if (image.imageSlices().bottom().isPercentOrCalc())
                bottom = CSSPrimitiveValue::create(image.imageSlices().bottom().value(), CSSPrimitiveValue::UnitType::Percentage);
            else
                bottom = CSSPrimitiveValue::create(image.imageSlices().bottom().value(), CSSPrimitiveValue::UnitType::Number);

            if (image.imageSlices().left() == image.imageSlices().right()) {
                left = right;
            } else {
                if (image.imageSlices().left().isPercentOrCalc())
                    left = CSSPrimitiveValue::create(image.imageSlices().left().value(), CSSPrimitiveValue::UnitType::Percentage);
                else
                    left = CSSPrimitiveValue::create(image.imageSlices().left().value(), CSSPrimitiveValue::UnitType::Number);
            }
        }
    }

    return CSSBorderImageSliceValue::create(CSSQuadValue::create(top, right, bottom, left, CSSQuadValue::SerializeAsQuad), image.fill());
}

static CSSQuadValue* valueForNinePieceImageQuad(const BorderImageLengthBox& box, const ComputedStyle& style)
{
    // Create the slices.
    CSSPrimitiveValue* top = nullptr;
    CSSPrimitiveValue* right = nullptr;
    CSSPrimitiveValue* bottom = nullptr;
    CSSPrimitiveValue* left = nullptr;

    if (box.top().isNumber())
        top = CSSPrimitiveValue::create(box.top().number(), CSSPrimitiveValue::UnitType::Number);
    else
        top = CSSPrimitiveValue::create(box.top().length(), style);

    if (box.right() == box.top() && box.bottom() == box.top() && box.left() == box.top()) {
        right = top;
        bottom = top;
        left = top;
    } else {
        if (box.right().isNumber())
            right = CSSPrimitiveValue::create(box.right().number(), CSSPrimitiveValue::UnitType::Number);
        else
            right = CSSPrimitiveValue::create(box.right().length(), style);

        if (box.bottom() == box.top() && box.right() == box.left()) {
            bottom = top;
            left = right;
        } else {
            if (box.bottom().isNumber())
                bottom = CSSPrimitiveValue::create(box.bottom().number(), CSSPrimitiveValue::UnitType::Number);
            else
                bottom = CSSPrimitiveValue::create(box.bottom().length(), style);

            if (box.left() == box.right()) {
                left = right;
            } else {
                if (box.left().isNumber())
                    left = CSSPrimitiveValue::create(box.left().number(), CSSPrimitiveValue::UnitType::Number);
                else
                    left = CSSPrimitiveValue::create(box.left().length(), style);
            }
        }
    }

    return CSSQuadValue::create(top, right, bottom, left, CSSQuadValue::SerializeAsQuad);
}

static CSSValueID valueForRepeatRule(int rule)
{
    switch (rule) {
    case RepeatImageRule:
        return CSSValueRepeat;
    case RoundImageRule:
        return CSSValueRound;
    case SpaceImageRule:
        return CSSValueSpace;
    default:
        return CSSValueStretch;
    }
}

static CSSValue* valueForNinePieceImageRepeat(const NinePieceImage& image)
{
    CSSPrimitiveValue* horizontalRepeat = nullptr;
    CSSPrimitiveValue* verticalRepeat = nullptr;

    horizontalRepeat = CSSPrimitiveValue::createIdentifier(valueForRepeatRule(image.horizontalRule()));
    if (image.horizontalRule() == image.verticalRule())
        verticalRepeat = horizontalRepeat;
    else
        verticalRepeat = CSSPrimitiveValue::createIdentifier(valueForRepeatRule(image.verticalRule()));
    return CSSValuePair::create(horizontalRepeat, verticalRepeat, CSSValuePair::DropIdenticalValues);
}

static CSSValue* valueForNinePieceImage(const NinePieceImage& image, const ComputedStyle& style)
{
    if (!image.hasImage())
        return CSSPrimitiveValue::createIdentifier(CSSValueNone);

    // Image first.
    CSSValue* imageValue = nullptr;
    if (image.image())
        imageValue = image.image()->computedCSSValue();

    // Create the image slice.
    CSSBorderImageSliceValue* imageSlices = valueForNinePieceImageSlice(image);

    // Create the border area slices.
    CSSValue* borderSlices = valueForNinePieceImageQuad(image.borderSlices(), style);

    // Create the border outset.
    CSSValue* outset = valueForNinePieceImageQuad(image.outset(), style);

    // Create the repeat rules.
    CSSValue* repeat = valueForNinePieceImageRepeat(image);

    return createBorderImageValue(imageValue, imageSlices, borderSlices, outset, repeat);
}

static CSSValue* valueForReflection(const StyleReflection* reflection, const ComputedStyle& style)
{
    if (!reflection)
        return CSSPrimitiveValue::createIdentifier(CSSValueNone);

    CSSPrimitiveValue* offset = nullptr;
    // TODO(alancutter): Make this work correctly for calc lengths.
    if (reflection->offset().isPercentOrCalc())
        offset = CSSPrimitiveValue::create(reflection->offset().percent(), CSSPrimitiveValue::UnitType::Percentage);
    else
        offset = zoomAdjustedPixelValue(reflection->offset().value(), style);

    CSSPrimitiveValue* direction = nullptr;
    switch (reflection->direction()) {
    case ReflectionBelow:
        direction = CSSPrimitiveValue::createIdentifier(CSSValueBelow);
        break;
    case ReflectionAbove:
        direction = CSSPrimitiveValue::createIdentifier(CSSValueAbove);
        break;
    case ReflectionLeft:
        direction = CSSPrimitiveValue::createIdentifier(CSSValueLeft);
        break;
    case ReflectionRight:
        direction = CSSPrimitiveValue::createIdentifier(CSSValueRight);
        break;
    }

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

static CSSValueList* valueForItemPositionWithOverflowAlignment(const StyleSelfAlignmentData& data)
{
    CSSValueList* result = CSSValueList::createSpaceSeparated();
    if (data.positionType() == LegacyPosition)
        result->append(*CSSPrimitiveValue::createIdentifier(CSSValueLegacy));
    // To avoid needing to copy the RareNonInheritedData, we repurpose the 'auto' flag to not just mean 'auto' prior to running the StyleAdjuster but also mean 'normal' after running it.
    result->append(*CSSPrimitiveValue::create(data.position() == ItemPositionAuto ? ComputedStyle::initialDefaultAlignment().position() : data.position()));
    if (data.position() >= ItemPositionCenter && data.overflow() != OverflowAlignmentDefault)
        result->append(*CSSPrimitiveValue::create(data.overflow()));
    ASSERT(result->length() <= 2);
    return result;
}

static CSSValueList* valuesForGridShorthand(const StylePropertyShorthand& shorthand, const ComputedStyle& style, const LayoutObject* layoutObject, Node* styledNode, bool allowVisitedStyle)
{
    CSSValueList* list = CSSValueList::createSlashSeparated();
    for (size_t i = 0; i < shorthand.length(); ++i) {
        const CSSValue* value = ComputedStyleCSSValueMapping::get(shorthand.properties()[i], style, layoutObject, styledNode, allowVisitedStyle);
        ASSERT(value);
        list->append(*value);
    }
    return list;
}

static CSSValueList* valuesForShorthandProperty(const StylePropertyShorthand& shorthand, const ComputedStyle& style, const LayoutObject* layoutObject, Node* styledNode, bool allowVisitedStyle)
{
    CSSValueList* list = CSSValueList::createSpaceSeparated();
    for (size_t i = 0; i < shorthand.length(); ++i) {
        const CSSValue* value = ComputedStyleCSSValueMapping::get(shorthand.properties()[i], style, layoutObject, styledNode, allowVisitedStyle);
        ASSERT(value);
        list->append(*value);
    }
    return list;
}

static CSSValue* expandNoneLigaturesValue()
{
    CSSValueList* list = CSSValueList::createSpaceSeparated();
    list->append(*CSSPrimitiveValue::createIdentifier(CSSValueNoCommonLigatures));
    list->append(*CSSPrimitiveValue::createIdentifier(CSSValueNoDiscretionaryLigatures));
    list->append(*CSSPrimitiveValue::createIdentifier(CSSValueNoHistoricalLigatures));
    list->append(*CSSPrimitiveValue::createIdentifier(CSSValueNoContextual));
    return list;
}

static CSSValue* valuesForFontVariantProperty(const ComputedStyle& style, const LayoutObject* layoutObject, Node* styledNode, bool allowVisitedStyle)
{
    enum VariantShorthandCases { AllNormal, NoneLigatures, ConcatenateNonNormal };
    VariantShorthandCases shorthandCase = AllNormal;
    for (size_t i = 0; i < fontVariantShorthand().length(); ++i) {
        const CSSValue* value = ComputedStyleCSSValueMapping::get(fontVariantShorthand().properties()[i], style, layoutObject, styledNode, allowVisitedStyle);

        if (shorthandCase == AllNormal
            && value->isPrimitiveValue()
            && toCSSPrimitiveValue(value)->getValueID() == CSSValueNone
            && fontVariantShorthand().properties()[i] == CSSPropertyFontVariantLigatures) {
            shorthandCase = NoneLigatures;
        } else if (!(value->isPrimitiveValue() && toCSSPrimitiveValue(value)->getValueID() == CSSValueNormal)) {
            shorthandCase = ConcatenateNonNormal;
            break;
        }
    }

    switch (shorthandCase) {
    case AllNormal:
        return CSSPrimitiveValue::createIdentifier(CSSValueNormal);
    case NoneLigatures:
        return CSSPrimitiveValue::createIdentifier(CSSValueNone);
    case ConcatenateNonNormal:
        {
        CSSValueList* list = CSSValueList::createSpaceSeparated();
        for (size_t i = 0; i < fontVariantShorthand().length(); ++i) {
            const CSSValue* value = ComputedStyleCSSValueMapping::get(fontVariantShorthand().properties()[i], style, layoutObject, styledNode, allowVisitedStyle);
            ASSERT(value);
            if (value->isPrimitiveValue() && toCSSPrimitiveValue(value)->getValueID() == CSSValueNone) {
                list->append(*expandNoneLigaturesValue());
            } else if (!(value->isPrimitiveValue() && toCSSPrimitiveValue(value)->getValueID() == CSSValueNormal)) {
                list->append(*value);
            }
        }
        return list;
        }
    default:
        NOTREACHED();
        return nullptr;
    }
}

static CSSValueList* valuesForBackgroundShorthand(const ComputedStyle& style, const LayoutObject* layoutObject, Node* styledNode, bool allowVisitedStyle)
{
    CSSValueList* ret = CSSValueList::createCommaSeparated();
    const FillLayer* currLayer = &style.backgroundLayers();
    for (; currLayer; currLayer = currLayer->next()) {
        CSSValueList* list = CSSValueList::createSlashSeparated();
        CSSValueList* beforeSlash = CSSValueList::createSpaceSeparated();
        if (!currLayer->next()) { // color only for final layer
            const CSSValue* value = ComputedStyleCSSValueMapping::get(CSSPropertyBackgroundColor, style, layoutObject, styledNode, allowVisitedStyle);
            ASSERT(value);
            beforeSlash->append(*value);
        }
        beforeSlash->append(currLayer->image() ? *currLayer->image()->computedCSSValue() : *CSSPrimitiveValue::createIdentifier(CSSValueNone));
        beforeSlash->append(*valueForFillRepeat(currLayer->repeatX(), currLayer->repeatY()));
        beforeSlash->append(*CSSPrimitiveValue::create(currLayer->attachment()));
        beforeSlash->append(*createPositionListForLayer(CSSPropertyBackgroundPosition, *currLayer, style));
        list->append(*beforeSlash);
        CSSValueList* afterSlash = CSSValueList::createSpaceSeparated();
        afterSlash->append(*valueForFillSize(currLayer->size(), style));
        afterSlash->append(*CSSPrimitiveValue::create(currLayer->origin()));
        afterSlash->append(*CSSPrimitiveValue::create(currLayer->clip()));
        list->append(*afterSlash);
        ret->append(*list);
    }
    return ret;
}

static CSSValueList* valueForContentPositionAndDistributionWithOverflowAlignment(const StyleContentAlignmentData& data)
{
    CSSValueList* result = CSSValueList::createSpaceSeparated();
    if (data.distribution() != ContentDistributionDefault)
        result->append(*CSSPrimitiveValue::create(data.distribution()));
    if (data.distribution() == ContentDistributionDefault || data.position() != ContentPositionNormal)
        result->append(*CSSPrimitiveValue::create(data.position()));
    if ((data.position() >= ContentPositionCenter || data.distribution() != ContentDistributionDefault) && data.overflow() != OverflowAlignmentDefault)
        result->append(*CSSPrimitiveValue::create(data.overflow()));
    ASSERT(result->length() > 0);
    ASSERT(result->length() <= 3);
    return result;
}

static CSSPrimitiveValue* valueForLineHeight(const ComputedStyle& style)
{
    Length length = style.lineHeight();
    if (length.isNegative())
        return CSSPrimitiveValue::createIdentifier(CSSValueNormal);

    return zoomAdjustedPixelValue(floatValueForLength(length, style.getFontDescription().computedSize()), style);
}

static CSSValueID identifierForFamily(const AtomicString& family)
{
    if (family == FontFamilyNames::webkit_cursive)
        return CSSValueCursive;
    if (family == FontFamilyNames::webkit_fantasy)
        return CSSValueFantasy;
    if (family == FontFamilyNames::webkit_monospace)
        return CSSValueMonospace;
    if (family == FontFamilyNames::webkit_pictograph)
        return CSSValueWebkitPictograph;
    if (family == FontFamilyNames::webkit_sans_serif)
        return CSSValueSansSerif;
    if (family == FontFamilyNames::webkit_serif)
        return CSSValueSerif;
    return CSSValueInvalid;
}

static CSSValue* valueForFamily(const AtomicString& family)
{
    if (CSSValueID familyIdentifier = identifierForFamily(family))
        return CSSPrimitiveValue::createIdentifier(familyIdentifier);
    return CSSFontFamilyValue::create(family.getString());
}

static CSSValueList* valueForFontFamily(const ComputedStyle& style)
{
    const FontFamily& firstFamily = style.getFontDescription().family();
    CSSValueList* list = CSSValueList::createCommaSeparated();
    for (const FontFamily* family = &firstFamily; family; family = family->next())
        list->append(*valueForFamily(family->family()));
    return list;
}

static CSSPrimitiveValue* valueForFontSize(const ComputedStyle& style)
{
    return zoomAdjustedPixelValue(style.getFontDescription().computedSize(), style);
}

static CSSPrimitiveValue* valueForFontStretch(const ComputedStyle& style)
{
    return CSSPrimitiveValue::create(style.getFontDescription().stretch());
}

static CSSPrimitiveValue* valueForFontStyle(const ComputedStyle& style)
{
    return CSSPrimitiveValue::create(style.getFontDescription().style());
}

static CSSPrimitiveValue* valueForFontWeight(const ComputedStyle& style)
{
    return CSSPrimitiveValue::create(style.getFontDescription().weight());
}

static CSSPrimitiveValue* valueForFontVariantCaps(const ComputedStyle& style)
{
    FontDescription::FontVariantCaps variantCaps = style.getFontDescription().variantCaps();
    switch (variantCaps) {
    case FontDescription::CapsNormal:
        return CSSPrimitiveValue::createIdentifier(CSSValueNormal);
    case FontDescription::SmallCaps:
        return CSSPrimitiveValue::createIdentifier(CSSValueSmallCaps);
    case FontDescription::AllSmallCaps:
        return CSSPrimitiveValue::createIdentifier(CSSValueAllSmallCaps);
    case FontDescription::PetiteCaps:
        return CSSPrimitiveValue::createIdentifier(CSSValuePetiteCaps);
    case FontDescription::AllPetiteCaps:
        return CSSPrimitiveValue::createIdentifier(CSSValueAllPetiteCaps);
    case FontDescription::Unicase:
        return CSSPrimitiveValue::createIdentifier(CSSValueUnicase);
    case FontDescription::TitlingCaps:
        return CSSPrimitiveValue::createIdentifier(CSSValueTitlingCaps);
    default:
        NOTREACHED();
        return nullptr;
    }
}

static CSSValue* valueForFontVariantLigatures(const ComputedStyle& style)
{
    FontDescription::LigaturesState commonLigaturesState = style.getFontDescription().commonLigaturesState();
    FontDescription::LigaturesState discretionaryLigaturesState = style.getFontDescription().discretionaryLigaturesState();
    FontDescription::LigaturesState historicalLigaturesState = style.getFontDescription().historicalLigaturesState();
    FontDescription::LigaturesState contextualLigaturesState = style.getFontDescription().contextualLigaturesState();
    if (commonLigaturesState == FontDescription::NormalLigaturesState && discretionaryLigaturesState == FontDescription::NormalLigaturesState
        && historicalLigaturesState == FontDescription::NormalLigaturesState && contextualLigaturesState == FontDescription::NormalLigaturesState)
        return CSSPrimitiveValue::createIdentifier(CSSValueNormal);

    if (commonLigaturesState == FontDescription::DisabledLigaturesState && discretionaryLigaturesState == FontDescription::DisabledLigaturesState
        && historicalLigaturesState == FontDescription::DisabledLigaturesState && contextualLigaturesState == FontDescription::DisabledLigaturesState)
        return CSSPrimitiveValue::createIdentifier(CSSValueNone);

    CSSValueList* valueList = CSSValueList::createSpaceSeparated();
    if (commonLigaturesState != FontDescription::NormalLigaturesState)
        valueList->append(*CSSPrimitiveValue::createIdentifier(commonLigaturesState == FontDescription::DisabledLigaturesState ? CSSValueNoCommonLigatures : CSSValueCommonLigatures));
    if (discretionaryLigaturesState != FontDescription::NormalLigaturesState)
        valueList->append(*CSSPrimitiveValue::createIdentifier(discretionaryLigaturesState == FontDescription::DisabledLigaturesState ? CSSValueNoDiscretionaryLigatures : CSSValueDiscretionaryLigatures));
    if (historicalLigaturesState != FontDescription::NormalLigaturesState)
        valueList->append(*CSSPrimitiveValue::createIdentifier(historicalLigaturesState == FontDescription::DisabledLigaturesState ? CSSValueNoHistoricalLigatures : CSSValueHistoricalLigatures));
    if (contextualLigaturesState != FontDescription::NormalLigaturesState)
        valueList->append(*CSSPrimitiveValue::createIdentifier(contextualLigaturesState == FontDescription::DisabledLigaturesState ? CSSValueNoContextual : CSSValueContextual));
    return valueList;
}

static CSSValue* valueForFontVariantNumeric(const ComputedStyle& style)
{
    FontVariantNumeric variantNumeric = style.getFontDescription().variantNumeric();
    if (variantNumeric.isAllNormal())
        return CSSPrimitiveValue::createIdentifier(CSSValueNormal);

    CSSValueList* valueList = CSSValueList::createSpaceSeparated();
    if (variantNumeric.numericFigureValue() != FontVariantNumeric::NormalFigure)
        valueList->append(*CSSPrimitiveValue::createIdentifier(variantNumeric.numericFigureValue() == FontVariantNumeric::LiningNums ? CSSValueLiningNums : CSSValueOldstyleNums));
    if (variantNumeric.numericSpacingValue() != FontVariantNumeric::NormalSpacing)
        valueList->append(*CSSPrimitiveValue::createIdentifier(variantNumeric.numericSpacingValue() == FontVariantNumeric::ProportionalNums ? CSSValueProportionalNums : CSSValueTabularNums));
    if (variantNumeric.numericFractionValue() != FontVariantNumeric::NormalFraction)
        valueList->append(*CSSPrimitiveValue::createIdentifier(variantNumeric.numericFractionValue() == FontVariantNumeric::DiagonalFractions ? CSSValueDiagonalFractions : CSSValueStackedFractions));
    if (variantNumeric.ordinalValue() == FontVariantNumeric::OrdinalOn)
        valueList->append(*CSSPrimitiveValue::createIdentifier(CSSValueOrdinal));
    if (variantNumeric.slashedZeroValue() == FontVariantNumeric::SlashedZeroOn)
        valueList->append(*CSSPrimitiveValue::createIdentifier(CSSValueSlashedZero));

    return valueList;
}


static CSSValue* specifiedValueForGridTrackBreadth(const GridLength& trackBreadth, const ComputedStyle& style)
{
    if (!trackBreadth.isLength())
        return CSSPrimitiveValue::create(trackBreadth.flex(), CSSPrimitiveValue::UnitType::Fraction);

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

static CSSValue* specifiedValueForGridTrackSize(const GridTrackSize& trackSize, const ComputedStyle& style)
{
    switch (trackSize.type()) {
    case LengthTrackSizing:
        return specifiedValueForGridTrackBreadth(trackSize.minTrackBreadth(), style);
    case MinMaxTrackSizing: {
        auto* minMaxTrackBreadths = CSSFunctionValue::create(CSSValueMinmax);
        minMaxTrackBreadths->append(*specifiedValueForGridTrackBreadth(trackSize.minTrackBreadth(), style));
        minMaxTrackBreadths->append(*specifiedValueForGridTrackBreadth(trackSize.maxTrackBreadth(), style));
        return minMaxTrackBreadths;
    } case FitContentTrackSizing: {
        auto* fitContentTrackBreadth = CSSFunctionValue::create(CSSValueFitContent);
        fitContentTrackBreadth->append(*specifiedValueForGridTrackBreadth(trackSize.fitContentTrackBreadth(), style));
        return fitContentTrackBreadth;
    }
    }
    ASSERT_NOT_REACHED();
    return nullptr;
}

class OrderedNamedLinesCollector {
    STACK_ALLOCATED();
    WTF_MAKE_NONCOPYABLE(OrderedNamedLinesCollector);
public:
    OrderedNamedLinesCollector(const ComputedStyle& style, bool isRowAxis, size_t autoRepeatTracksCount)
        : m_orderedNamedGridLines(isRowAxis ? style.orderedNamedGridColumnLines() : style.orderedNamedGridRowLines())
        , m_orderedNamedAutoRepeatGridLines(isRowAxis ? style.autoRepeatOrderedNamedGridColumnLines() : style.autoRepeatOrderedNamedGridRowLines())
        , m_insertionPoint(isRowAxis ? style.gridAutoRepeatColumnsInsertionPoint() : style.gridAutoRepeatRowsInsertionPoint())
        , m_autoRepeatTotalTracks(autoRepeatTracksCount)
        , m_autoRepeatTrackListLength(isRowAxis ? style.gridAutoRepeatColumns().size() : style.gridAutoRepeatRows().size())
    {
    }

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

private:

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

    const OrderedNamedGridLines& m_orderedNamedGridLines;
    const OrderedNamedGridLines& m_orderedNamedAutoRepeatGridLines;
    size_t m_insertionPoint;
    size_t m_autoRepeatTotalTracks;
    size_t m_autoRepeatTrackListLength;
};

void OrderedNamedLinesCollector::appendLines(CSSGridLineNamesValue& lineNamesValue, size_t 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;

    for (auto lineName : iter->value)
        lineNamesValue.append(*CSSCustomIdentValue::create(AtomicString(lineName)));
}

void OrderedNamedLinesCollector::collectLineNamesForIndex(CSSGridLineNamesValue& lineNamesValue, size_t i) const
{
    DCHECK(!isEmpty());
    if (m_orderedNamedAutoRepeatGridLines.isEmpty() || i < m_insertionPoint) {
        appendLines(lineNamesValue, i, NamedLines);
        return;
    }

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

    size_t 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, size_t i, CSSValueList& list)
{
    if (collector.isEmpty())
        return;

    CSSGridLineNamesValue* lineNames = CSSGridLineNamesValue::create();
    collector.collectLineNamesForIndex(*lineNames, i);
    if (lineNames->length())
        list.append(*lineNames);
}

static CSSValue* valueForGridTrackSizeList(GridTrackSizingDirection direction, const ComputedStyle& style)
{
    const Vector<GridTrackSize>& autoTrackSizes = direction == ForColumns ? style.gridAutoColumns() : style.gridAutoRows();

    CSSValueList* list = CSSValueList::createSpaceSeparated();
    for (auto& trackSize : autoTrackSizes)
        list->append(*specifiedValueForGridTrackSize(trackSize, style));
    return list;
}

static CSSValue* valueForGridTrackList(GridTrackSizingDirection direction, const LayoutObject* layoutObject, const ComputedStyle& style)
{
    bool isRowAxis = direction == ForColumns;
    const Vector<GridTrackSize>& trackSizes = isRowAxis ? style.gridTemplateColumns() : style.gridTemplateRows();
    const Vector<GridTrackSize>& autoRepeatTrackSizes = isRowAxis ? style.gridAutoRepeatColumns() : style.gridAutoRepeatRows();
    bool isLayoutGrid = layoutObject && layoutObject->isLayoutGrid();

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

    if (trackListIsEmpty)
        return CSSPrimitiveValue::createIdentifier(CSSValueNone);

    size_t autoRepeatTotalTracks = isLayoutGrid ? toLayoutGrid(layoutObject)->autoRepeatCountForDirection(direction) : 0;
    OrderedNamedLinesCollector collector(style, isRowAxis, autoRepeatTotalTracks);
    CSSValueList* list = CSSValueList::createSpaceSeparated();
    size_t insertionIndex;
    if (isLayoutGrid) {
        const auto* grid = toLayoutGrid(layoutObject);
        Vector<LayoutUnit> computedTrackSizes = grid->trackSizesForComputedStyle(direction);
        size_t numTracks = computedTrackSizes.size();

        for (size_t i = 0; i < numTracks; ++i) {
            addValuesForNamedGridLinesAtIndex(collector, i, *list);
            list->append(*zoomAdjustedPixelValue(computedTrackSizes[i], style));
        }
        addValuesForNamedGridLinesAtIndex(collector, numTracks + 1, *list);

        insertionIndex = numTracks;
    } else {
        for (size_t i = 0; i < trackSizes.size(); ++i) {
            addValuesForNamedGridLinesAtIndex(collector, i, *list);
            list->append(*specifiedValueForGridTrackSize(trackSizes[i], style));
        }
        insertionIndex = trackSizes.size();
    }
    // Those are the trailing <string>* allowed in the syntax.
    addValuesForNamedGridLinesAtIndex(collector, insertionIndex, *list);
    return list;
}

static CSSValue* valueForGridPosition(const GridPosition& position)
{
    if (position.isAuto())
        return CSSPrimitiveValue::createIdentifier(CSSValueAuto);

    if (position.isNamedGridArea())
        return CSSCustomIdentValue::create(position.namedGridLine());

    CSSValueList* list = CSSValueList::createSpaceSeparated();
    if (position.isSpan()) {
        list->append(*CSSPrimitiveValue::createIdentifier(CSSValueSpan));
        list->append(*CSSPrimitiveValue::create(position.spanPosition(), CSSPrimitiveValue::UnitType::Number));
    } else {
        list->append(*CSSPrimitiveValue::create(position.integerPosition(), CSSPrimitiveValue::UnitType::Number));
    }

    if (!position.namedGridLine().isNull())
        list->append(*CSSCustomIdentValue::create(position.namedGridLine()));
    return list;
}

static LayoutRect sizingBox(const LayoutObject* layoutObject)
{
    if (!layoutObject->isBox())
        return LayoutRect();

    const LayoutBox* box = toLayoutBox(layoutObject);
    return box->style()->boxSizing() == BoxSizingBorderBox ? box->borderBoxRect() : box->computedCSSContentBoxRect();
}

static CSSValue* renderTextDecorationFlagsToCSSValue(int textDecoration)
{
    // Blink value is ignored.
    CSSValueList* list = CSSValueList::createSpaceSeparated();
    if (textDecoration & TextDecorationUnderline)
        list->append(*CSSPrimitiveValue::createIdentifier(CSSValueUnderline));
    if (textDecoration & TextDecorationOverline)
        list->append(*CSSPrimitiveValue::createIdentifier(CSSValueOverline));
    if (textDecoration & TextDecorationLineThrough)
        list->append(*CSSPrimitiveValue::createIdentifier(CSSValueLineThrough));

    if (!list->length())
        return CSSPrimitiveValue::createIdentifier(CSSValueNone);
    return list;
}

static CSSValue* valueForTextDecorationStyle(TextDecorationStyle textDecorationStyle)
{
    switch (textDecorationStyle) {
    case TextDecorationStyleSolid:
        return CSSPrimitiveValue::createIdentifier(CSSValueSolid);
    case TextDecorationStyleDouble:
        return CSSPrimitiveValue::createIdentifier(CSSValueDouble);
    case TextDecorationStyleDotted:
        return CSSPrimitiveValue::createIdentifier(CSSValueDotted);
    case TextDecorationStyleDashed:
        return CSSPrimitiveValue::createIdentifier(CSSValueDashed);
    case TextDecorationStyleWavy:
        return CSSPrimitiveValue::createIdentifier(CSSValueWavy);
    }

    ASSERT_NOT_REACHED();
    return CSSInitialValue::create();
}

static CSSValue* touchActionFlagsToCSSValue(TouchAction touchAction)
{
    CSSValueList* list = CSSValueList::createSpaceSeparated();
    if (touchAction == TouchActionAuto) {
        list->append(*CSSPrimitiveValue::createIdentifier(CSSValueAuto));
    } else if (touchAction == TouchActionNone) {
        list->append(*CSSPrimitiveValue::createIdentifier(CSSValueNone));
    } else if (touchAction == TouchActionManipulation) {
        list->append(*CSSPrimitiveValue::createIdentifier(CSSValueManipulation));
    } else {
        if ((touchAction & TouchActionPanX) == TouchActionPanX)
            list->append(*CSSPrimitiveValue::createIdentifier(CSSValuePanX));
        else if (touchAction & TouchActionPanLeft)
            list->append(*CSSPrimitiveValue::createIdentifier(CSSValuePanLeft));
        else if (touchAction & TouchActionPanRight)
            list->append(*CSSPrimitiveValue::createIdentifier(CSSValuePanRight));

        if ((touchAction & TouchActionPanY) == TouchActionPanY)
            list->append(*CSSPrimitiveValue::createIdentifier(CSSValuePanY));
        else if (touchAction & TouchActionPanUp)
            list->append(*CSSPrimitiveValue::createIdentifier(CSSValuePanUp));
        else if (touchAction & TouchActionPanDown)
            list->append(*CSSPrimitiveValue::createIdentifier(CSSValuePanDown));
    }
    ASSERT(list->length());
    return list;
}

static CSSValue* valueForWillChange(const Vector<CSSPropertyID>& willChangeProperties, bool willChangeContents, bool willChangeScrollPosition)
{
    CSSValueList* list = CSSValueList::createCommaSeparated();
    if (willChangeContents)
        list->append(*CSSPrimitiveValue::createIdentifier(CSSValueContents));
    if (willChangeScrollPosition)
        list->append(*CSSPrimitiveValue::createIdentifier(CSSValueScrollPosition));
    for (size_t i = 0; i < willChangeProperties.size(); ++i)
        list->append(*CSSCustomIdentValue::create(willChangeProperties[i]));
    if (!list->length())
        list->append(*CSSPrimitiveValue::createIdentifier(CSSValueAuto));
    return list;
}

static CSSValue* valueForAnimationDelay(const CSSTimingData* timingData)
{
    CSSValueList* list = CSSValueList::createCommaSeparated();
    if (timingData) {
        for (size_t i = 0; i < timingData->delayList().size(); ++i)
            list->append(*CSSPrimitiveValue::create(timingData->delayList()[i], CSSPrimitiveValue::UnitType::Seconds));
    } else {
        list->append(*CSSPrimitiveValue::create(CSSTimingData::initialDelay(), CSSPrimitiveValue::UnitType::Seconds));
    }
    return list;
}

static CSSValue* valueForAnimationDirection(Timing::PlaybackDirection direction)
{
    switch (direction) {
    case Timing::PlaybackDirection::NORMAL:
        return CSSPrimitiveValue::createIdentifier(CSSValueNormal);
    case Timing::PlaybackDirection::ALTERNATE_NORMAL:
        return CSSPrimitiveValue::createIdentifier(CSSValueAlternate);
    case Timing::PlaybackDirection::REVERSE:
        return CSSPrimitiveValue::createIdentifier(CSSValueReverse);
    case Timing::PlaybackDirection::ALTERNATE_REVERSE:
        return CSSPrimitiveValue::createIdentifier(CSSValueAlternateReverse);
    default:
        ASSERT_NOT_REACHED();
        return nullptr;
    }
}

static CSSValue* valueForAnimationDuration(const CSSTimingData* timingData)
{
    CSSValueList* list = CSSValueList::createCommaSeparated();
    if (timingData) {
        for (size_t i = 0; i < timingData->durationList().size(); ++i)
            list->append(*CSSPrimitiveValue::create(timingData->durationList()[i], CSSPrimitiveValue::UnitType::Seconds));
    } else {
        list->append(*CSSPrimitiveValue::create(CSSTimingData::initialDuration(), CSSPrimitiveValue::UnitType::Seconds));
    }
    return list;
}

static CSSValue* valueForAnimationFillMode(Timing::FillMode fillMode)
{
    switch (fillMode) {
    case Timing::FillMode::NONE:
        return CSSPrimitiveValue::createIdentifier(CSSValueNone);
    case Timing::FillMode::FORWARDS:
        return CSSPrimitiveValue::createIdentifier(CSSValueForwards);
    case Timing::FillMode::BACKWARDS:
        return CSSPrimitiveValue::createIdentifier(CSSValueBackwards);
    case Timing::FillMode::BOTH:
        return CSSPrimitiveValue::createIdentifier(CSSValueBoth);
    default:
        ASSERT_NOT_REACHED();
        return nullptr;
    }
}

static CSSValue* valueForAnimationIterationCount(double iterationCount)
{
    if (iterationCount == std::numeric_limits<double>::infinity())
        return CSSPrimitiveValue::createIdentifier(CSSValueInfinite);
    return CSSPrimitiveValue::create(iterationCount, CSSPrimitiveValue::UnitType::Number);
}

static CSSValue* valueForAnimationPlayState(EAnimPlayState playState)
{
    if (playState == AnimPlayStatePlaying)
        return CSSPrimitiveValue::createIdentifier(CSSValueRunning);
    ASSERT(playState == AnimPlayStatePaused);
    return CSSPrimitiveValue::createIdentifier(CSSValuePaused);
}

static CSSValue* createTimingFunctionValue(const TimingFunction* timingFunction)
{
    switch (timingFunction->getType()) {
    case TimingFunction::Type::CUBIC_BEZIER:
        {
            const CubicBezierTimingFunction* bezierTimingFunction = toCubicBezierTimingFunction(timingFunction);
            if (bezierTimingFunction->getEaseType() != CubicBezierTimingFunction::EaseType::CUSTOM) {
                CSSValueID valueId = CSSValueInvalid;
                switch (bezierTimingFunction->getEaseType()) {
                case CubicBezierTimingFunction::EaseType::EASE:
                    valueId = CSSValueEase;
                    break;
                case CubicBezierTimingFunction::EaseType::EASE_IN:
                    valueId = CSSValueEaseIn;
                    break;
                case CubicBezierTimingFunction::EaseType::EASE_OUT:
                    valueId = CSSValueEaseOut;
                    break;
                case CubicBezierTimingFunction::EaseType::EASE_IN_OUT:
                    valueId = CSSValueEaseInOut;
                    break;
                default:
                    ASSERT_NOT_REACHED();
                    return nullptr;
                }
                return CSSPrimitiveValue::createIdentifier(valueId);
            }
            return CSSCubicBezierTimingFunctionValue::create(bezierTimingFunction->x1(), bezierTimingFunction->y1(), bezierTimingFunction->x2(), bezierTimingFunction->y2());
        }

    case TimingFunction::Type::STEPS:
        {
            const StepsTimingFunction* stepsTimingFunction = toStepsTimingFunction(timingFunction);
            StepsTimingFunction::StepPosition position = stepsTimingFunction->getStepPosition();
            int steps = stepsTimingFunction->numberOfSteps();
            DCHECK(position == StepsTimingFunction::StepPosition::START || position == StepsTimingFunction::StepPosition::END);

            if (steps > 1)
                return CSSStepsTimingFunctionValue::create(steps, position);
            CSSValueID valueId = position == StepsTimingFunction::StepPosition::START ? CSSValueStepStart : CSSValueStepEnd;
            return CSSPrimitiveValue::createIdentifier(valueId);
        }

    default:
        return CSSPrimitiveValue::createIdentifier(CSSValueLinear);
    }
}

static CSSValue* valueForAnimationTimingFunction(const CSSTimingData* timingData)
{
    CSSValueList* list = CSSValueList::createCommaSeparated();
    if (timingData) {
        for (size_t i = 0; i < timingData->timingFunctionList().size(); ++i)
            list->append(*createTimingFunctionValue(timingData->timingFunctionList()[i].get()));
    } else {
        list->append(*createTimingFunctionValue(CSSTimingData::initialTimingFunction().get()));
    }
    return list;
}

static CSSValueList* valuesForBorderRadiusCorner(LengthSize radius, const ComputedStyle& style)
{
    CSSValueList* list = CSSValueList::createSpaceSeparated();
    if (radius.width().type() == Percent)
        list->append(*CSSPrimitiveValue::create(radius.width().percent(), CSSPrimitiveValue::UnitType::Percentage));
    else
        list->append(*zoomAdjustedPixelValueForLength(radius.width(), style));
    if (radius.height().type() == Percent)
        list->append(*CSSPrimitiveValue::create(radius.height().percent(), CSSPrimitiveValue::UnitType::Percentage));
    else
        list->append(*zoomAdjustedPixelValueForLength(radius.height(), style));
    return list;
}

static const CSSValue& valueForBorderRadiusCorner(LengthSize radius, const ComputedStyle& style)
{
    CSSValueList& list = *valuesForBorderRadiusCorner(radius, style);
    if (list.item(0).equals(list.item(1)))
        return list.item(0);
    return list;
}

static CSSFunctionValue* valueForMatrixTransform(const TransformationMatrix& transform, const ComputedStyle& style)
{
    CSSFunctionValue* transformValue = nullptr;
    if (transform.isAffine()) {
        transformValue = CSSFunctionValue::create(CSSValueMatrix);

        transformValue->append(*CSSPrimitiveValue::create(transform.a(), CSSPrimitiveValue::UnitType::Number));
        transformValue->append(*CSSPrimitiveValue::create(transform.b(), CSSPrimitiveValue::UnitType::Number));
        transformValue->append(*CSSPrimitiveValue::create(transform.c(), CSSPrimitiveValue::UnitType::Number));
        transformValue->append(*CSSPrimitiveValue::create(transform.d(), CSSPrimitiveValue::UnitType::Number));
        transformValue->append(*zoomAdjustedNumberValue(transform.e(), style));
        transformValue->append(*zoomAdjustedNumberValue(transform.f(), style));
    } else {
        transformValue = CSSFunctionValue::create(CSSValueMatrix3d);

        transformValue->append(*CSSPrimitiveValue::create(transform.m11(), CSSPrimitiveValue::UnitType::Number));
        transformValue->append(*CSSPrimitiveValue::create(transform.m12(), CSSPrimitiveValue::UnitType::Number));
        transformValue->append(*CSSPrimitiveValue::create(transform.m13(), CSSPrimitiveValue::UnitType::Number));
        transformValue->append(*CSSPrimitiveValue::create(transform.m14(), CSSPrimitiveValue::UnitType::Number));

        transformValue->append(*CSSPrimitiveValue::create(transform.m21(), CSSPrimitiveValue::UnitType::Number));
        transformValue->append(*CSSPrimitiveValue::create(transform.m22(), CSSPrimitiveValue::UnitType::Number));
        transformValue->append(*CSSPrimitiveValue::create(transform.m23(), CSSPrimitiveValue::UnitType::Number));
        transformValue->append(*CSSPrimitiveValue::create(transform.m24(), CSSPrimitiveValue::UnitType::Number));

        transformValue->append(*CSSPrimitiveValue::create(transform.m31(), CSSPrimitiveValue::UnitType::Number));
        transformValue->append(*CSSPrimitiveValue::create(transform.m32(), CSSPrimitiveValue::UnitType::Number));
        transformValue->append(*CSSPrimitiveValue::create(transform.m33(), CSSPrimitiveValue::UnitType::Number));
        transformValue->append(*CSSPrimitiveValue::create(transform.m34(), CSSPrimitiveValue::UnitType::Number));

        transformValue->append(*zoomAdjustedNumberValue(transform.m41(), style));
        transformValue->append(*zoomAdjustedNumberValue(transform.m42(), style));
        transformValue->append(*zoomAdjustedNumberValue(transform.m43(), style));
        transformValue->append(*CSSPrimitiveValue::create(transform.m44(), CSSPrimitiveValue::UnitType::Number));
    }

    return transformValue;
}

static CSSValue* computedTransform(const LayoutObject* layoutObject, const ComputedStyle& style)
{
    if (!layoutObject || !style.hasTransform())
        return CSSPrimitiveValue::createIdentifier(CSSValueNone);

    IntRect box;
    if (layoutObject->isBox())
        box = pixelSnappedIntRect(toLayoutBox(layoutObject)->borderBoxRect());

    TransformationMatrix transform;
    style.applyTransform(transform, LayoutSize(box.size()), ComputedStyle::ExcludeTransformOrigin, ComputedStyle::ExcludeMotionPath, ComputedStyle::ExcludeIndependentTransformProperties);

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

    return list;
}

static CSSValue* createTransitionPropertyValue(const CSSTransitionData::TransitionProperty& property)
{
    if (property.propertyType == CSSTransitionData::TransitionNone)
        return CSSPrimitiveValue::createIdentifier(CSSValueNone);
    if (property.propertyType == CSSTransitionData::TransitionUnknownProperty)
        return CSSCustomIdentValue::create(property.propertyString);
    ASSERT(property.propertyType == CSSTransitionData::TransitionKnownProperty);
    return CSSCustomIdentValue::create(getPropertyNameAtomicString(property.unresolvedProperty));
}

static CSSValue* valueForTransitionProperty(const CSSTransitionData* transitionData)
{
    CSSValueList* list = CSSValueList::createCommaSeparated();
    if (transitionData) {
        for (size_t i = 0; i < transitionData->propertyList().size(); ++i)
            list->append(*createTransitionPropertyValue(transitionData->propertyList()[i]));
    } else {
        list->append(*CSSPrimitiveValue::createIdentifier(CSSValueAll));
    }
    return list;
}

CSSValueID valueForQuoteType(const QuoteType quoteType)
{
    switch (quoteType) {
    case NO_OPEN_QUOTE:
        return CSSValueNoOpenQuote;
    case NO_CLOSE_QUOTE:
        return CSSValueNoCloseQuote;
    case CLOSE_QUOTE:
        return CSSValueCloseQuote;
    case OPEN_QUOTE:
        return CSSValueOpenQuote;
    }
    ASSERT_NOT_REACHED();
    return CSSValueInvalid;
}

static CSSValue* valueForContentData(const ComputedStyle& style)
{
    CSSValueList* list = CSSValueList::createSpaceSeparated();
    for (const ContentData* contentData = style.contentData(); contentData; contentData = contentData->next()) {
        if (contentData->isCounter()) {
            const CounterContent* counter = toCounterContentData(contentData)->counter();
            ASSERT(counter);
            CSSCustomIdentValue* identifier = CSSCustomIdentValue::create(counter->identifier());
            CSSStringValue* separator = CSSStringValue::create(counter->separator());
            CSSValueID listStyleIdent = CSSValueNone;
            if (counter->listStyle() != NoneListStyle)
                listStyleIdent = static_cast<CSSValueID>(CSSValueDisc + counter->listStyle());
            CSSPrimitiveValue* listStyle = CSSPrimitiveValue::createIdentifier(listStyleIdent);
            list->append(*CSSCounterValue::create(identifier, listStyle, separator));
        } else if (contentData->isImage()) {
            const StyleImage* image = toImageContentData(contentData)->image();
            ASSERT(image);
            list->append(*image->computedCSSValue());
        } else if (contentData->isText()) {
            list->append(*CSSStringValue::create(toTextContentData(contentData)->text()));
        } else if (contentData->isQuote()) {
            const QuoteType quoteType = toQuoteContentData(contentData)->quote();
            list->append(*CSSPrimitiveValue::createIdentifier(valueForQuoteType(quoteType)));
        } else {
            ASSERT_NOT_REACHED();
        }
    }
    return list;
}

static CSSValue* valueForCounterDirectives(const ComputedStyle& style, CSSPropertyID propertyID)
{
    const CounterDirectiveMap* map = style.counterDirectives();
    if (!map)
        return CSSPrimitiveValue::createIdentifier(CSSValueNone);

    CSSValueList* list = CSSValueList::createSpaceSeparated();
    for (const auto& item : *map) {
        bool isValidCounterValue = propertyID == CSSPropertyCounterIncrement ? item.value.isIncrement() : item.value.isReset();
        if (!isValidCounterValue)
            continue;

        list->append(*CSSCustomIdentValue::create(item.key));
        short number = propertyID == CSSPropertyCounterIncrement ? item.value.incrementValue() : item.value.resetValue();
        list->append(*CSSPrimitiveValue::create((double)number, CSSPrimitiveValue::UnitType::Integer));
    }

    if (!list->length())
        return CSSPrimitiveValue::createIdentifier(CSSValueNone);

    return list;
}

static CSSValue* valueForShape(const ComputedStyle& style, ShapeValue* shapeValue)
{
    if (!shapeValue)
        return CSSPrimitiveValue::createIdentifier(CSSValueNone);
    if (shapeValue->type() == ShapeValue::Box)
        return CSSPrimitiveValue::create(shapeValue->cssBox());
    if (shapeValue->type() == ShapeValue::Image) {
        if (shapeValue->image())
            return shapeValue->image()->computedCSSValue();
        return CSSPrimitiveValue::createIdentifier(CSSValueNone);
    }

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

    CSSValueList* list = CSSValueList::createSpaceSeparated();
    list->append(*valueForBasicShape(style, shapeValue->shape()));
    if (shapeValue->cssBox() != BoxMissing)
        list->append(*CSSPrimitiveValue::create(shapeValue->cssBox()));
    return list;
}

static CSSValueList* valuesForSidesShorthand(const StylePropertyShorthand& shorthand, const ComputedStyle& style, const LayoutObject* layoutObject, Node* styledNode, bool allowVisitedStyle)
{
    CSSValueList* list = CSSValueList::createSpaceSeparated();
    // Assume the properties are in the usual order top, right, bottom, left.
    const CSSValue* topValue = ComputedStyleCSSValueMapping::get(shorthand.properties()[0], style, layoutObject, styledNode, allowVisitedStyle);
    const CSSValue* rightValue = ComputedStyleCSSValueMapping::get(shorthand.properties()[1], style, layoutObject, styledNode, allowVisitedStyle);
    const CSSValue* bottomValue = ComputedStyleCSSValueMapping::get(shorthand.properties()[2], style, layoutObject, styledNode, allowVisitedStyle);
    const CSSValue* leftValue = ComputedStyleCSSValueMapping::get(shorthand.properties()[3], style, layoutObject, styledNode, allowVisitedStyle);

    // 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);
    if (showRight)
        list->append(*rightValue);
    if (showBottom)
        list->append(*bottomValue);
    if (showLeft)
        list->append(*leftValue);

    return list;
}

static CSSValueList* valueForBorderRadiusShorthand(const ComputedStyle& style)
{
    CSSValueList* 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());

    CSSValueList* topLeftRadius = valuesForBorderRadiusCorner(style.borderTopLeftRadius(), style);
    CSSValueList* topRightRadius = valuesForBorderRadiusCorner(style.borderTopRightRadius(), style);
    CSSValueList* bottomRightRadius = valuesForBorderRadiusCorner(style.borderBottomRightRadius(), style);
    CSSValueList* bottomLeftRadius = valuesForBorderRadiusCorner(style.borderBottomLeftRadius(), style);

    CSSValueList* 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(*horizontalRadii);

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

    if (!verticalRadii->equals(toCSSValueList(list->item(0))))
        list->append(*verticalRadii);

    return list;
}

static CSSValue* strokeDashArrayToCSSValueList(const SVGDashArray& dashes, const ComputedStyle& style)
{
    if (dashes.isEmpty())
        return CSSPrimitiveValue::createIdentifier(CSSValueNone);

    CSSValueList* list = CSSValueList::createCommaSeparated();
    for (const Length& dashLength : dashes.vector())
        list->append(*zoomAdjustedPixelValueForLength(dashLength, style));

    return list;
}

static CSSValue* paintOrderToCSSValueList(const SVGComputedStyle& svgStyle)
{
    CSSValueList* list = CSSValueList::createSpaceSeparated();
    for (int i = 0; i < 3; i++) {
        EPaintOrderType paintOrderType = svgStyle.paintOrderType(i);
        switch (paintOrderType) {
        case PT_FILL:
        case PT_STROKE:
        case PT_MARKERS:
            list->append(*CSSPrimitiveValue::create(paintOrderType));
            break;
        case PT_NONE:
        default:
            ASSERT_NOT_REACHED();
            break;
        }
    }

    return list;
}

static CSSValue* adjustSVGPaintForCurrentColor(SVGPaintType paintType, const String& url, const Color& color, const Color& currentColor)
{
    if (paintType >= SVG_PAINTTYPE_URI_NONE) {
        CSSValueList* values = CSSValueList::createSpaceSeparated();
        values->append(*CSSURIValue::create(url));
        if (paintType == SVG_PAINTTYPE_URI_NONE)
            values->append(*CSSPrimitiveValue::createIdentifier(CSSValueNone));
        else if (paintType == SVG_PAINTTYPE_URI_CURRENTCOLOR)
            values->append(*CSSColorValue::create(currentColor.rgb()));
        else if (paintType == SVG_PAINTTYPE_URI_RGBCOLOR)
            values->append(*CSSColorValue::create(color.rgb()));
        return values;
    }
    if (paintType == SVG_PAINTTYPE_NONE)
        return CSSPrimitiveValue::createIdentifier(CSSValueNone);
    if (paintType == SVG_PAINTTYPE_CURRENTCOLOR)
        return CSSColorValue::create(currentColor.rgb());

    return CSSColorValue::create(color.rgb());
}

static inline String serializeAsFragmentIdentifier(const AtomicString& resource)
{
    return "#" + resource;
}

CSSValue* ComputedStyleCSSValueMapping::valueForShadowData(const ShadowData& shadow, const ComputedStyle& style, bool useSpread)
{
    CSSPrimitiveValue* x = zoomAdjustedPixelValue(shadow.x(), style);
    CSSPrimitiveValue* y = zoomAdjustedPixelValue(shadow.y(), style);
    CSSPrimitiveValue* blur = zoomAdjustedPixelValue(shadow.blur(), style);
    CSSPrimitiveValue* spread = useSpread ? zoomAdjustedPixelValue(shadow.spread(), style) : nullptr;
    CSSPrimitiveValue* shadowStyle = shadow.style() == Normal ? nullptr : CSSPrimitiveValue::createIdentifier(CSSValueInset);
    CSSValue* color = currentColorOrValidColor(style, shadow.color());
    return CSSShadowValue::create(x, y, blur, spread, shadowStyle, color);
}

CSSValue* ComputedStyleCSSValueMapping::valueForShadowList(const ShadowList* shadowList, const ComputedStyle& style, bool useSpread)
{
    if (!shadowList)
        return CSSPrimitiveValue::createIdentifier(CSSValueNone);

    CSSValueList* list = CSSValueList::createCommaSeparated();
    size_t shadowCount = shadowList->shadows().size();
    for (size_t i = 0; i < shadowCount; ++i)
        list->append(*valueForShadowData(shadowList->shadows()[i], style, useSpread));
    return list;
}

CSSValue* ComputedStyleCSSValueMapping::valueForFilter(const ComputedStyle& style, const FilterOperations& filterOperations)
{
    if (filterOperations.operations().isEmpty())
        return CSSPrimitiveValue::createIdentifier(CSSValueNone);

    CSSValueList* list = CSSValueList::createSpaceSeparated();

    CSSFunctionValue* filterValue = nullptr;

    for (const auto& operation : filterOperations.operations()) {
        FilterOperation* filterOperation = operation.get();
        switch (filterOperation->type()) {
        case FilterOperation::REFERENCE:
            filterValue = CSSFunctionValue::create(CSSValueUrl);
            filterValue->append(*CSSStringValue::create(toReferenceFilterOperation(filterOperation)->url()));
            break;
        case FilterOperation::GRAYSCALE:
            filterValue = CSSFunctionValue::create(CSSValueGrayscale);
            filterValue->append(*CSSPrimitiveValue::create(toBasicColorMatrixFilterOperation(filterOperation)->amount(), CSSPrimitiveValue::UnitType::Number));
            break;
        case FilterOperation::SEPIA:
            filterValue = CSSFunctionValue::create(CSSValueSepia);
            filterValue->append(*CSSPrimitiveValue::create(toBasicColorMatrixFilterOperation(filterOperation)->amount(), CSSPrimitiveValue::UnitType::Number));
            break;
        case FilterOperation::SATURATE:
            filterValue = CSSFunctionValue::create(CSSValueSaturate);
            filterValue->append(*CSSPrimitiveValue::create(toBasicColorMatrixFilterOperation(filterOperation)->amount(), CSSPrimitiveValue::UnitType::Number));
            break;
        case FilterOperation::HUE_ROTATE:
            filterValue = CSSFunctionValue::create(CSSValueHueRotate);
            filterValue->append(*CSSPrimitiveValue::create(toBasicColorMatrixFilterOperation(filterOperation)->amount(), CSSPrimitiveValue::UnitType::Degrees));
            break;
        case FilterOperation::INVERT:
            filterValue = CSSFunctionValue::create(CSSValueInvert);
            filterValue->append(*CSSPrimitiveValue::create(toBasicComponentTransferFilterOperation(filterOperation)->amount(), CSSPrimitiveValue::UnitType::Number));
            break;
        case FilterOperation::OPACITY:
            filterValue = CSSFunctionValue::create(CSSValueOpacity);
            filterValue->append(*CSSPrimitiveValue::create(toBasicComponentTransferFilterOperation(filterOperation)->amount(), CSSPrimitiveValue::UnitType::Number));
            break;
        case FilterOperation::BRIGHTNESS:
            filterValue = CSSFunctionValue::create(CSSValueBrightness);
            filterValue->append(*CSSPrimitiveValue::create(toBasicComponentTransferFilterOperation(filterOperation)->amount(), CSSPrimitiveValue::UnitType::Number));
            break;
        case FilterOperation::CONTRAST:
            filterValue = CSSFunctionValue::create(CSSValueContrast);
            filterValue->append(*CSSPrimitiveValue::create(toBasicComponentTransferFilterOperation(filterOperation)->amount(), CSSPrimitiveValue::UnitType::Number));
            break;
        case FilterOperation::BLUR:
            filterValue = CSSFunctionValue::create(CSSValueBlur);
            filterValue->append(*zoomAdjustedPixelValue(toBlurFilterOperation(filterOperation)->stdDeviation().value(), style));
            break;
        case FilterOperation::DROP_SHADOW: {
            DropShadowFilterOperation* dropShadowOperation = toDropShadowFilterOperation(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 shadow(dropShadowOperation->location(), dropShadowOperation->stdDeviation(), 0, Normal, StyleColor(dropShadowOperation->getColor()));
            filterValue->append(*valueForShadowData(shadow, style, false));
            break;
        }
        default:
            ASSERT_NOT_REACHED();
            break;
        }
        list->append(*filterValue);
    }

    return list;
}

CSSValue* ComputedStyleCSSValueMapping::valueForFont(const ComputedStyle& style)
{
    // Add a slash between size and line-height.
    CSSValueList* sizeAndLineHeight = CSSValueList::createSlashSeparated();
    sizeAndLineHeight->append(*valueForFontSize(style));
    sizeAndLineHeight->append(*valueForLineHeight(style));

    CSSValueList* list = CSSValueList::createSpaceSeparated();
    list->append(*valueForFontStyle(style));

    // Check that non-initial font-variant subproperties are not conflicting with this serialization.
    CSSValue* ligaturesValue = valueForFontVariantLigatures(style);
    CSSValue* numericValue = valueForFontVariantNumeric(style);
    if (!ligaturesValue->equals(*CSSPrimitiveValue::createIdentifier(CSSValueNormal))
        || !numericValue->equals(*CSSPrimitiveValue::createIdentifier(CSSValueNormal)))
        return nullptr;

    CSSPrimitiveValue* capsValue = valueForFontVariantCaps(style);
    if (!capsValue->equals(*CSSPrimitiveValue::createIdentifier(CSSValueNormal))
        && !capsValue->equals(*CSSPrimitiveValue::createIdentifier(CSSValueSmallCaps)))
        return nullptr;
    list->append(*capsValue);

    list->append(*valueForFontWeight(style));
    list->append(*valueForFontStretch(style));
    list->append(*sizeAndLineHeight);
    list->append(*valueForFontFamily(style));

    return list;
}

static CSSValue* valueForScrollSnapDestination(const LengthPoint& destination, const ComputedStyle& style)
{
    CSSValueList* list = CSSValueList::createSpaceSeparated();
    list->append(*zoomAdjustedPixelValueForLength(destination.x(), style));
    list->append(*zoomAdjustedPixelValueForLength(destination.y(), style));
    return list;
}

static CSSValue* valueForScrollSnapPoints(const ScrollSnapPoints& points, const ComputedStyle& style)
{
    if (points.hasRepeat) {
        CSSFunctionValue* repeat = CSSFunctionValue::create(CSSValueRepeat);
        repeat->append(*zoomAdjustedPixelValueForLength(points.repeatOffset, style));
        return repeat;
    }

    return CSSPrimitiveValue::createIdentifier(CSSValueNone);
}

static CSSValue* valueForScrollSnapCoordinate(const Vector<LengthPoint>& coordinates, const ComputedStyle& style)
{
    if (coordinates.isEmpty())
        return CSSPrimitiveValue::createIdentifier(CSSValueNone);

    CSSValueList* list = CSSValueList::createCommaSeparated();

    for (auto& coordinate : coordinates) {
        auto pair = CSSValueList::createSpaceSeparated();
        pair->append(*zoomAdjustedPixelValueForLength(coordinate.x(), style));
        pair->append(*zoomAdjustedPixelValueForLength(coordinate.y(), style));
        list->append(*pair);
    }

    return list;
}

static EBreak mapToPageBreakValue(EBreak genericBreakValue)
{
    switch (genericBreakValue) {
    case BreakAvoidColumn:
    case BreakColumn:
    case BreakRecto:
    case BreakVerso:
        return BreakAuto;
    case BreakPage:
        return BreakAlways;
    case BreakAvoidPage:
        return BreakAvoid;
    default:
        return genericBreakValue;
    }
}

static EBreak mapToColumnBreakValue(EBreak genericBreakValue)
{
    switch (genericBreakValue) {
    case BreakAvoidPage:
    case BreakLeft:
    case BreakPage:
    case BreakRecto:
    case BreakRight:
    case BreakVerso:
        return BreakAuto;
    case BreakColumn:
        return BreakAlways;
    case BreakAvoidColumn:
        return BreakAvoid;
    default:
        return genericBreakValue;
    }
}

const CSSValue* ComputedStyleCSSValueMapping::get(const AtomicString customPropertyName, const ComputedStyle& style, const PropertyRegistry* registry)
{
    StyleVariableData* variables = style.variables();
    if (registry) {
        const PropertyRegistry::Registration* registration = registry->registration(customPropertyName);
        if (registration) {
            if (variables) {
                const CSSValue* result = variables->registeredInheritedProperty(customPropertyName);
                if (result)
                    return result;
            }
            return registration->initial();
        }
    }

    if (!variables)
        return nullptr;

    CSSVariableData* data = variables->getVariable(customPropertyName);
    if (!data)
        return nullptr;

    return CSSCustomPropertyDeclaration::create(customPropertyName, data);
}

std::unique_ptr<HashMap<AtomicString, RefPtr<CSSVariableData>>> ComputedStyleCSSValueMapping::getVariables(const ComputedStyle& style)
{
    StyleVariableData* variables = style.variables();
    if (variables)
        return variables->getVariables();
    return nullptr;
}

const CSSValue* ComputedStyleCSSValueMapping::get(CSSPropertyID propertyID, const ComputedStyle& style, const LayoutObject* layoutObject, Node* styledNode, bool allowVisitedStyle)
{
    const SVGComputedStyle& svgStyle = style.svgStyle();
    propertyID = CSSProperty::resolveDirectionAwareProperty(propertyID, style.direction(), style.getWritingMode());
    switch (propertyID) {
    case CSSPropertyInvalid:
        return nullptr;

    case CSSPropertyBackgroundColor:
        return allowVisitedStyle ? CSSColorValue::create(style.visitedDependentColor(CSSPropertyBackgroundColor).rgb()) : currentColorOrValidColor(style, style.backgroundColor());
    case CSSPropertyBackgroundImage:
    case CSSPropertyWebkitMaskImage: {
        CSSValueList* list = CSSValueList::createCommaSeparated();
        const FillLayer* currLayer = propertyID == CSSPropertyWebkitMaskImage ? &style.maskLayers() : &style.backgroundLayers();
        for (; currLayer; currLayer = currLayer->next()) {
            if (currLayer->image())
                list->append(*currLayer->image()->computedCSSValue());
            else
                list->append(*CSSPrimitiveValue::createIdentifier(CSSValueNone));
        }
        return list;
    }
    case CSSPropertyBackgroundSize:
    case CSSPropertyWebkitMaskSize: {
        CSSValueList* list = CSSValueList::createCommaSeparated();
        const FillLayer* currLayer = propertyID == CSSPropertyWebkitMaskSize ? &style.maskLayers() : &style.backgroundLayers();
        for (; currLayer; currLayer = currLayer->next())
            list->append(*valueForFillSize(currLayer->size(), style));
        return list;
    }
    case CSSPropertyBackgroundRepeat:
    case CSSPropertyWebkitMaskRepeat: {
        CSSValueList* list = CSSValueList::createCommaSeparated();
        const FillLayer* currLayer = propertyID == CSSPropertyWebkitMaskRepeat ? &style.maskLayers() : &style.backgroundLayers();
        for (; currLayer; currLayer = currLayer->next())
            list->append(*valueForFillRepeat(currLayer->repeatX(), currLayer->repeatY()));
        return list;
    }
    case CSSPropertyMaskSourceType: {
        CSSValueList* list = CSSValueList::createCommaSeparated();
        for (const FillLayer* currLayer = &style.maskLayers(); currLayer; currLayer = currLayer->next())
            list->append(*valueForFillSourceType(currLayer->maskSourceType()));
        return list;
    }
    case CSSPropertyWebkitMaskComposite: {
        CSSValueList* list = CSSValueList::createCommaSeparated();
        const FillLayer* currLayer = propertyID == CSSPropertyWebkitMaskComposite ? &style.maskLayers() : &style.backgroundLayers();
        for (; currLayer; currLayer = currLayer->next())
            list->append(*CSSPrimitiveValue::create(currLayer->composite()));
        return list;
    }
    case CSSPropertyBackgroundAttachment: {
        CSSValueList* list = CSSValueList::createCommaSeparated();
        for (const FillLayer* currLayer = &style.backgroundLayers(); currLayer; currLayer = currLayer->next())
            list->append(*CSSPrimitiveValue::create(currLayer->attachment()));
        return list;
    }
    case CSSPropertyBackgroundClip:
    case CSSPropertyBackgroundOrigin:
    case CSSPropertyWebkitBackgroundClip:
    case CSSPropertyWebkitBackgroundOrigin:
    case CSSPropertyWebkitMaskClip:
    case CSSPropertyWebkitMaskOrigin: {
        bool isClip = propertyID == CSSPropertyBackgroundClip || propertyID == CSSPropertyWebkitBackgroundClip || propertyID == CSSPropertyWebkitMaskClip;
        CSSValueList* list = CSSValueList::createCommaSeparated();
        const FillLayer* currLayer = (propertyID == CSSPropertyWebkitMaskClip || propertyID == CSSPropertyWebkitMaskOrigin) ? &style.maskLayers() : &style.backgroundLayers();
        for (; currLayer; currLayer = currLayer->next()) {
            EFillBox box = isClip ? currLayer->clip() : currLayer->origin();
            list->append(*CSSPrimitiveValue::create(box));
        }
        return list;
    }
    case CSSPropertyBackgroundPosition:
    case CSSPropertyWebkitMaskPosition: {
        CSSValueList* list = CSSValueList::createCommaSeparated();
        const FillLayer* currLayer = propertyID == CSSPropertyWebkitMaskPosition ? &style.maskLayers() : &style.backgroundLayers();
        for (; currLayer; currLayer = currLayer->next())
            list->append(*createPositionListForLayer(propertyID, *currLayer, style));
        return list;
    }
    case CSSPropertyBackgroundPositionX:
    case CSSPropertyWebkitMaskPositionX: {
        CSSValueList* list = CSSValueList::createCommaSeparated();
        const FillLayer* currLayer = propertyID == CSSPropertyWebkitMaskPositionX ? &style.maskLayers() : &style.backgroundLayers();
        for (; currLayer; currLayer = currLayer->next())
            list->append(*zoomAdjustedPixelValueForLength(currLayer->xPosition(), style));
        return list;
    }
    case CSSPropertyBackgroundPositionY:
    case CSSPropertyWebkitMaskPositionY: {
        CSSValueList* list = CSSValueList::createCommaSeparated();
        const FillLayer* currLayer = propertyID == CSSPropertyWebkitMaskPositionY ? &style.maskLayers() : &style.backgroundLayers();
        for (; currLayer; currLayer = currLayer->next())
            list->append(*zoomAdjustedPixelValueForLength(currLayer->yPosition(), style));
        return list;
    }
    case CSSPropertyBorderCollapse:
        if (style.borderCollapse())
            return CSSPrimitiveValue::createIdentifier(CSSValueCollapse);
        return CSSPrimitiveValue::createIdentifier(CSSValueSeparate);
    case CSSPropertyBorderSpacing: {
        CSSValueList* 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()->computedCSSValue();
        return CSSPrimitiveValue::createIdentifier(CSSValueNone);
    case CSSPropertyBorderTopColor:
        return allowVisitedStyle ? CSSColorValue::create(style.visitedDependentColor(CSSPropertyBorderTopColor).rgb()) : currentColorOrValidColor(style, style.borderTopColor());
    case CSSPropertyBorderRightColor:
        return allowVisitedStyle ? CSSColorValue::create(style.visitedDependentColor(CSSPropertyBorderRightColor).rgb()) : currentColorOrValidColor(style, style.borderRightColor());
    case CSSPropertyBorderBottomColor:
        return allowVisitedStyle ? CSSColorValue::create(style.visitedDependentColor(CSSPropertyBorderBottomColor).rgb()) : currentColorOrValidColor(style, style.borderBottomColor());
    case CSSPropertyBorderLeftColor:
        return allowVisitedStyle ? CSSColorValue::create(style.visitedDependentColor(CSSPropertyBorderLeftColor).rgb()) : currentColorOrValidColor(style, style.borderLeftColor());
    case CSSPropertyBorderTopStyle:
        return CSSPrimitiveValue::create(style.borderTopStyle());
    case CSSPropertyBorderRightStyle:
        return CSSPrimitiveValue::create(style.borderRightStyle());
    case CSSPropertyBorderBottomStyle:
        return CSSPrimitiveValue::create(style.borderBottomStyle());
    case CSSPropertyBorderLeftStyle:
        return CSSPrimitiveValue::create(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 valueForPositionOffset(style, CSSPropertyBottom, layoutObject);
    case CSSPropertyWebkitBoxAlign:
        return CSSPrimitiveValue::create(style.boxAlign());
    case CSSPropertyWebkitBoxDecorationBreak:
        if (style.boxDecorationBreak() == BoxDecorationBreakSlice)
            return CSSPrimitiveValue::createIdentifier(CSSValueSlice);
    return CSSPrimitiveValue::createIdentifier(CSSValueClone);
    case CSSPropertyWebkitBoxDirection:
        return CSSPrimitiveValue::create(style.boxDirection());
    case CSSPropertyWebkitBoxFlex:
        return CSSPrimitiveValue::create(style.boxFlex(), CSSPrimitiveValue::UnitType::Number);
    case CSSPropertyWebkitBoxFlexGroup:
        return CSSPrimitiveValue::create(style.boxFlexGroup(), CSSPrimitiveValue::UnitType::Number);
    case CSSPropertyWebkitBoxLines:
        return CSSPrimitiveValue::create(style.boxLines());
    case CSSPropertyWebkitBoxOrdinalGroup:
        return CSSPrimitiveValue::create(style.boxOrdinalGroup(), CSSPrimitiveValue::UnitType::Number);
    case CSSPropertyWebkitBoxOrient:
        return CSSPrimitiveValue::create(style.boxOrient());
    case CSSPropertyWebkitBoxPack:
        return CSSPrimitiveValue::create(style.boxPack());
    case CSSPropertyWebkitBoxReflect:
        return valueForReflection(style.boxReflect(), style);
    case CSSPropertyBoxShadow:
        return valueForShadowList(style.boxShadow(), style, true);
    case CSSPropertyCaptionSide:
        return CSSPrimitiveValue::create(style.captionSide());
    case CSSPropertyClear:
        return CSSPrimitiveValue::create(style.clear());
    case CSSPropertyColor:
        return CSSColorValue::create(allowVisitedStyle ? style.visitedDependentColor(CSSPropertyColor).rgb() : style.color().rgb());
    case CSSPropertyWebkitPrintColorAdjust:
        return CSSPrimitiveValue::create(style.getPrintColorAdjust());
    case CSSPropertyColumnCount:
        if (style.hasAutoColumnCount())
            return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
        return CSSPrimitiveValue::create(style.columnCount(), CSSPrimitiveValue::UnitType::Number);
    case CSSPropertyColumnFill:
        return CSSPrimitiveValue::create(style.getColumnFill());
    case CSSPropertyColumnGap:
        if (style.hasNormalColumnGap())
            return CSSPrimitiveValue::createIdentifier(CSSValueNormal);
        return zoomAdjustedPixelValue(style.columnGap(), style);
    case CSSPropertyColumnRuleColor:
        return allowVisitedStyle ? CSSColorValue::create(style.visitedDependentColor(CSSPropertyOutlineColor).rgb()) : currentColorOrValidColor(style, style.columnRuleColor());
    case CSSPropertyColumnRuleStyle:
        return CSSPrimitiveValue::create(style.columnRuleStyle());
    case CSSPropertyColumnRuleWidth:
        return zoomAdjustedPixelValue(style.columnRuleWidth(), style);
    case CSSPropertyColumnSpan:
        return CSSPrimitiveValue::createIdentifier(style.getColumnSpan() ? CSSValueAll : CSSValueNone);
    case CSSPropertyWebkitColumnBreakAfter:
        return CSSPrimitiveValue::create(mapToColumnBreakValue(style.breakAfter()));
    case CSSPropertyWebkitColumnBreakBefore:
        return CSSPrimitiveValue::create(mapToColumnBreakValue(style.breakBefore()));
    case CSSPropertyWebkitColumnBreakInside:
        return CSSPrimitiveValue::create(mapToColumnBreakValue(style.breakInside()));
    case CSSPropertyColumnWidth:
        if (style.hasAutoColumnWidth())
            return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
        return zoomAdjustedPixelValue(style.columnWidth(), style);
    case CSSPropertyTabSize:
        return CSSPrimitiveValue::create(
            style.getTabSize().getPixelSize(1.0), style.getTabSize().isSpaces() ? CSSPrimitiveValue::UnitType::Number : CSSPrimitiveValue::UnitType::Pixels);
    case CSSPropertyTextSizeAdjust:
        if (style.getTextSizeAdjust().isAuto())
            return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
        return CSSPrimitiveValue::create(style.getTextSizeAdjust().multiplier() * 100, CSSPrimitiveValue::UnitType::Percentage);
    case CSSPropertyCursor: {
        CSSValueList* list = nullptr;
        CursorList* 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(*CSSCursorImageValue::create(image->computedCSSValue(), cursors->at(i).hotSpotSpecified(), cursors->at(i).hotSpot()));
            }
        }
        CSSValue* value = CSSPrimitiveValue::create(style.cursor());
        if (list) {
            list->append(*value);
            return list;
        }
        return value;
    }
    case CSSPropertyDirection:
        return CSSPrimitiveValue::create(style.direction());
    case CSSPropertyDisplay:
        return CSSPrimitiveValue::create(style.display());
    case CSSPropertyEmptyCells:
        return CSSPrimitiveValue::create(style.emptyCells());
    case CSSPropertyAlignContent:
        return valueForContentPositionAndDistributionWithOverflowAlignment(style.alignContent());
    case CSSPropertyAlignItems:
        return valueForItemPositionWithOverflowAlignment(style.alignItems());
    case CSSPropertyAlignSelf:
        return valueForItemPositionWithOverflowAlignment(style.alignSelf());
    case CSSPropertyFlex:
        return valuesForShorthandProperty(flexShorthand(), style, layoutObject, styledNode, allowVisitedStyle);
    case CSSPropertyFlexBasis:
        return zoomAdjustedPixelValueForLength(style.flexBasis(), style);
    case CSSPropertyFlexDirection:
        return CSSPrimitiveValue::create(style.flexDirection());
    case CSSPropertyFlexFlow:
        return valuesForShorthandProperty(flexFlowShorthand(), style, layoutObject, styledNode, allowVisitedStyle);
    case CSSPropertyFlexGrow:
        return CSSPrimitiveValue::create(style.flexGrow(), CSSPrimitiveValue::UnitType::Number);
    case CSSPropertyFlexShrink:
        return CSSPrimitiveValue::create(style.flexShrink(), CSSPrimitiveValue::UnitType::Number);
    case CSSPropertyFlexWrap:
        return CSSPrimitiveValue::create(style.flexWrap());
    case CSSPropertyJustifyContent:
        return valueForContentPositionAndDistributionWithOverflowAlignment(style.justifyContent());
    case CSSPropertyOrder:
        return CSSPrimitiveValue::create(style.order(), CSSPrimitiveValue::UnitType::Number);
    case CSSPropertyFloat:
        if (style.display() != NONE && style.hasOutOfFlowPosition())
            return CSSPrimitiveValue::createIdentifier(CSSValueNone);
        return CSSPrimitiveValue::create(style.floating());
    case CSSPropertyFont:
        return valueForFont(style);
    case CSSPropertyFontFamily:
        return valueForFontFamily(style);
    case CSSPropertyFontSize:
        return valueForFontSize(style);
    case CSSPropertyFontSizeAdjust:
        if (style.hasFontSizeAdjust())
            return CSSPrimitiveValue::create(style.fontSizeAdjust(), CSSPrimitiveValue::UnitType::Number);
        return CSSPrimitiveValue::createIdentifier(CSSValueNone);
    case CSSPropertyFontStretch:
        return valueForFontStretch(style);
    case CSSPropertyFontStyle:
        return valueForFontStyle(style);
    case CSSPropertyFontVariant:
        return valuesForFontVariantProperty(style, layoutObject, styledNode, allowVisitedStyle);
    case CSSPropertyFontWeight:
        return valueForFontWeight(style);
    case CSSPropertyFontFeatureSettings: {
        const FontFeatureSettings* featureSettings = style.getFontDescription().featureSettings();
        if (!featureSettings || !featureSettings->size())
            return CSSPrimitiveValue::createIdentifier(CSSValueNormal);
        CSSValueList* list = CSSValueList::createCommaSeparated();
        for (unsigned i = 0; i < featureSettings->size(); ++i) {
            const FontFeature& feature = featureSettings->at(i);
            CSSFontFeatureValue* featureValue = CSSFontFeatureValue::create(feature.tag(), feature.value());
            list->append(*featureValue);
        }
        return list;
    }
    case CSSPropertyGridAutoFlow: {
        CSSValueList* list = CSSValueList::createSpaceSeparated();
        switch (style.getGridAutoFlow()) {
        case AutoFlowRow:
        case AutoFlowRowDense:
            list->append(*CSSPrimitiveValue::createIdentifier(CSSValueRow));
            break;
        case AutoFlowColumn:
        case AutoFlowColumnDense:
            list->append(*CSSPrimitiveValue::createIdentifier(CSSValueColumn));
            break;
        default:
            ASSERT_NOT_REACHED();
        }

        switch (style.getGridAutoFlow()) {
        case AutoFlowRowDense:
        case AutoFlowColumnDense:
            list->append(*CSSPrimitiveValue::createIdentifier(CSSValueDense));
            break;
        default:
            // Do nothing.
            break;
        }

        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, layoutObject, style);
    case CSSPropertyGridTemplateRows:
        return valueForGridTrackList(ForRows, layoutObject, style);

    case CSSPropertyGridColumnStart:
        return valueForGridPosition(style.gridColumnStart());
    case CSSPropertyGridColumnEnd:
        return valueForGridPosition(style.gridColumnEnd());
    case CSSPropertyGridRowStart:
        return valueForGridPosition(style.gridRowStart());
    case CSSPropertyGridRowEnd:
        return valueForGridPosition(style.gridRowEnd());
    case CSSPropertyGridColumn:
        return valuesForGridShorthand(gridColumnShorthand(), style, layoutObject, styledNode, allowVisitedStyle);
    case CSSPropertyGridRow:
        return valuesForGridShorthand(gridRowShorthand(), style, layoutObject, styledNode, allowVisitedStyle);
    case CSSPropertyGridArea:
        return valuesForGridShorthand(gridAreaShorthand(), style, layoutObject, styledNode, allowVisitedStyle);
    case CSSPropertyGridTemplate:
        return valuesForGridShorthand(gridTemplateShorthand(), style, layoutObject, styledNode, allowVisitedStyle);
    case CSSPropertyGrid:
        return valuesForGridShorthand(gridShorthand(), style, layoutObject, styledNode, allowVisitedStyle);
    case CSSPropertyGridTemplateAreas:
        if (!style.namedGridAreaRowCount()) {
            ASSERT(!style.namedGridAreaColumnCount());
            return CSSPrimitiveValue::createIdentifier(CSSValueNone);
        }

        return CSSGridTemplateAreasValue::create(style.namedGridArea(), style.namedGridAreaRowCount(), style.namedGridAreaColumnCount());
    case CSSPropertyGridColumnGap:
        return zoomAdjustedPixelValueForLength(style.gridColumnGap(), style);
    case CSSPropertyGridRowGap:
        return zoomAdjustedPixelValueForLength(style.gridRowGap(), style);
    case CSSPropertyGridGap:
        return valuesForShorthandProperty(gridGapShorthand(), style, layoutObject, styledNode, allowVisitedStyle);

    case CSSPropertyHeight:
        if (layoutObject) {
            // According to http://www.w3.org/TR/CSS2/visudet.html#the-height-property,
            // the "height" property does not apply for non-atomic inline elements.
            if (!layoutObject->isAtomicInlineLevel() && layoutObject->isInline())
                return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
            return zoomAdjustedPixelValue(sizingBox(layoutObject).height(), style);
        }
        return zoomAdjustedPixelValueForLength(style.height(), style);
    case CSSPropertyWebkitHighlight:
        if (style.highlight() == nullAtom)
            return CSSPrimitiveValue::createIdentifier(CSSValueNone);
        return CSSStringValue::create(style.highlight());
    case CSSPropertyHyphens:
        return CSSPrimitiveValue::create(style.getHyphens());
    case CSSPropertyWebkitHyphenateCharacter:
        if (style.hyphenationString().isNull())
            return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
        return CSSStringValue::create(style.hyphenationString());
    case CSSPropertyImageRendering:
        return CSSPrimitiveValue::create(style.imageRendering());
    case CSSPropertyImageOrientation:
        if (style.respectImageOrientation() == RespectImageOrientation)
            return CSSPrimitiveValue::createIdentifier(CSSValueFromImage);
        return CSSPrimitiveValue::create(0, CSSPrimitiveValue::UnitType::Degrees);
    case CSSPropertyIsolation:
        return CSSPrimitiveValue::create(style.isolation());
    case CSSPropertyJustifyItems:
        return valueForItemPositionWithOverflowAlignment(style.justifyItems());
    case CSSPropertyJustifySelf:
        return valueForItemPositionWithOverflowAlignment(style.justifySelf());
    case CSSPropertyLeft:
        return valueForPositionOffset(style, CSSPropertyLeft, layoutObject);
    case CSSPropertyLetterSpacing:
        if (!style.letterSpacing())
            return CSSPrimitiveValue::createIdentifier(CSSValueNormal);
        return zoomAdjustedPixelValue(style.letterSpacing(), style);
    case CSSPropertyWebkitLineClamp:
        if (style.lineClamp().isNone())
            return CSSPrimitiveValue::createIdentifier(CSSValueNone);
        return CSSPrimitiveValue::create(style.lineClamp().value(), style.lineClamp().isPercentage() ? CSSPrimitiveValue::UnitType::Percentage : CSSPrimitiveValue::UnitType::Number);
    case CSSPropertyLineHeight:
        return valueForLineHeight(style);
    case CSSPropertyListStyleImage:
        if (style.listStyleImage())
            return style.listStyleImage()->computedCSSValue();
        return CSSPrimitiveValue::createIdentifier(CSSValueNone);
    case CSSPropertyListStylePosition:
        return CSSPrimitiveValue::create(style.listStylePosition());
    case CSSPropertyListStyleType:
        return CSSPrimitiveValue::create(style.listStyleType());
    case CSSPropertyWebkitLocale:
        if (style.locale().isNull())
            return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
        return CSSStringValue::create(style.locale());
    case CSSPropertyMarginTop: {
        Length marginTop = style.marginTop();
        if (marginTop.isFixed() || !layoutObject || !layoutObject->isBox())
            return zoomAdjustedPixelValueForLength(marginTop, style);
        return zoomAdjustedPixelValue(toLayoutBox(layoutObject)->marginTop(), style);
    }
    case CSSPropertyMarginRight: {
        Length marginRight = style.marginRight();
        if (marginRight.isFixed() || !layoutObject || !layoutObject->isBox())
            return zoomAdjustedPixelValueForLength(marginRight, style);
        float value;
        if (marginRight.isPercentOrCalc()) {
            // LayoutBox gives a marginRight() that is the distance between the right-edge of the child box
            // and the right-edge of the containing box, when display == BLOCK. Let's calculate the absolute
            // value of the specified margin-right % instead of relying on LayoutBox's marginRight() value.
            value = minimumValueForLength(marginRight, toLayoutBox(layoutObject)->containingBlockLogicalWidthForContent()).toFloat();
        } else {
            value = toLayoutBox(layoutObject)->marginRight().toFloat();
        }
        return zoomAdjustedPixelValue(value, style);
    }
    case CSSPropertyMarginBottom: {
        Length marginBottom = style.marginBottom();
        if (marginBottom.isFixed() || !layoutObject || !layoutObject->isBox())
            return zoomAdjustedPixelValueForLength(marginBottom, style);
        return zoomAdjustedPixelValue(toLayoutBox(layoutObject)->marginBottom(), style);
    }
    case CSSPropertyMarginLeft: {
        Length marginLeft = style.marginLeft();
        if (marginLeft.isFixed() || !layoutObject || !layoutObject->isBox())
            return zoomAdjustedPixelValueForLength(marginLeft, style);
        return zoomAdjustedPixelValue(toLayoutBox(layoutObject)->marginLeft(), style);
    }
    case CSSPropertyWebkitUserModify:
        return CSSPrimitiveValue::create(style.userModify());
    case CSSPropertyMaxHeight: {
        const Length& maxHeight = style.maxHeight();
        if (maxHeight.isMaxSizeNone())
            return CSSPrimitiveValue::createIdentifier(CSSValueNone);
        return zoomAdjustedPixelValueForLength(maxHeight, style);
    }
    case CSSPropertyMaxWidth: {
        const Length& maxWidth = style.maxWidth();
        if (maxWidth.isMaxSizeNone())
            return CSSPrimitiveValue::createIdentifier(CSSValueNone);
        return zoomAdjustedPixelValueForLength(maxWidth, style);
    }
    case CSSPropertyMinHeight:
        if (style.minHeight().isAuto()) {
            Node* parent = styledNode->parentNode();
            if (isFlexOrGrid(parent ? parent->ensureComputedStyle() : nullptr))
                return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
            return zoomAdjustedPixelValue(0, style);
        }
        return zoomAdjustedPixelValueForLength(style.minHeight(), style);
    case CSSPropertyMinWidth:
        if (style.minWidth().isAuto()) {
            Node* parent = styledNode->parentNode();
            if (isFlexOrGrid(parent ? parent->ensureComputedStyle() : nullptr))
                return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
            return zoomAdjustedPixelValue(0, style);
        }
        return zoomAdjustedPixelValueForLength(style.minWidth(), style);
    case CSSPropertyObjectFit:
        return CSSPrimitiveValue::create(style.getObjectFit());
    case CSSPropertyObjectPosition:
        return CSSValuePair::create(
            zoomAdjustedPixelValueForLength(style.objectPosition().x(), style),
            zoomAdjustedPixelValueForLength(style.objectPosition().y(), style),
            CSSValuePair::KeepIdenticalValues);
    case CSSPropertyOpacity:
        return CSSPrimitiveValue::create(style.opacity(), CSSPrimitiveValue::UnitType::Number);
    case CSSPropertyOrphans:
        return CSSPrimitiveValue::create(style.orphans(), CSSPrimitiveValue::UnitType::Number);
    case CSSPropertyOutlineColor:
        return allowVisitedStyle ? CSSColorValue::create(style.visitedDependentColor(CSSPropertyOutlineColor).rgb()) : currentColorOrValidColor(style, style.outlineColor());
    case CSSPropertyOutlineOffset:
        return zoomAdjustedPixelValue(style.outlineOffset(), style);
    case CSSPropertyOutlineStyle:
        if (style.outlineStyleIsAuto())
            return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
        return CSSPrimitiveValue::create(style.outlineStyle());
    case CSSPropertyOutlineWidth:
        return zoomAdjustedPixelValue(style.outlineWidth(), style);
    case CSSPropertyOverflow:
        return CSSPrimitiveValue::create(max(style.overflowX(), style.overflowY()));
    case CSSPropertyOverflowAnchor:
        return CSSPrimitiveValue::create(style.overflowAnchor());
    case CSSPropertyOverflowWrap:
        return CSSPrimitiveValue::create(style.overflowWrap());
    case CSSPropertyOverflowX:
        return CSSPrimitiveValue::create(style.overflowX());
    case CSSPropertyOverflowY:
        return CSSPrimitiveValue::create(style.overflowY());
    case CSSPropertyPaddingTop: {
        Length paddingTop = style.paddingTop();
        if (paddingTop.isFixed() || !layoutObject || !layoutObject->isBox())
            return zoomAdjustedPixelValueForLength(paddingTop, style);
        return zoomAdjustedPixelValue(toLayoutBox(layoutObject)->computedCSSPaddingTop(), style);
    }
    case CSSPropertyPaddingRight: {
        Length paddingRight = style.paddingRight();
        if (paddingRight.isFixed() || !layoutObject || !layoutObject->isBox())
            return zoomAdjustedPixelValueForLength(paddingRight, style);
        return zoomAdjustedPixelValue(toLayoutBox(layoutObject)->computedCSSPaddingRight(), style);
    }
    case CSSPropertyPaddingBottom: {
        Length paddingBottom = style.paddingBottom();
        if (paddingBottom.isFixed() || !layoutObject || !layoutObject->isBox())
            return zoomAdjustedPixelValueForLength(paddingBottom, style);
        return zoomAdjustedPixelValue(toLayoutBox(layoutObject)->computedCSSPaddingBottom(), style);
    }
    case CSSPropertyPaddingLeft: {
        Length paddingLeft = style.paddingLeft();
        if (paddingLeft.isFixed() || !layoutObject || !layoutObject->isBox())
            return zoomAdjustedPixelValueForLength(paddingLeft, style);
        return zoomAdjustedPixelValue(toLayoutBox(layoutObject)->computedCSSPaddingLeft(), style);
    }
    case CSSPropertyBreakAfter:
        return CSSPrimitiveValue::create(style.breakAfter());
    case CSSPropertyBreakBefore:
        return CSSPrimitiveValue::create(style.breakBefore());
    case CSSPropertyBreakInside:
        return CSSPrimitiveValue::create(style.breakInside());
    case CSSPropertyPageBreakAfter:
        return CSSPrimitiveValue::create(mapToPageBreakValue(style.breakAfter()));
    case CSSPropertyPageBreakBefore:
        return CSSPrimitiveValue::create(mapToPageBreakValue(style.breakBefore()));
    case CSSPropertyPageBreakInside:
        return CSSPrimitiveValue::create(mapToPageBreakValue(style.breakInside()));
    case CSSPropertyPosition:
        return CSSPrimitiveValue::create(style.position());
    case CSSPropertyQuotes:
        if (!style.quotes()) {
            // TODO(ramya.v): We should return the quote values that we're actually using.
            return nullptr;
        }
        if (style.quotes()->size()) {
            CSSValueList* list = CSSValueList::createSpaceSeparated();
            for (int i = 0; i < style.quotes()->size(); i++) {
                list->append(*CSSStringValue::create(style.quotes()->getOpenQuote(i)));
                list->append(*CSSStringValue::create(style.quotes()->getCloseQuote(i)));
            }
            return list;
        }
        return CSSPrimitiveValue::createIdentifier(CSSValueNone);
    case CSSPropertyRight:
        return valueForPositionOffset(style, CSSPropertyRight, layoutObject);
    case CSSPropertyWebkitRubyPosition:
        return CSSPrimitiveValue::create(style.getRubyPosition());
    case CSSPropertyScrollBehavior:
        return CSSPrimitiveValue::create(style.getScrollBehavior());
    case CSSPropertyTableLayout:
        return CSSPrimitiveValue::create(style.tableLayout());
    case CSSPropertyTextAlign:
        return CSSPrimitiveValue::create(style.textAlign());
    case CSSPropertyTextAlignLast:
        return CSSPrimitiveValue::create(style.getTextAlignLast());
    case CSSPropertyTextDecoration:
        if (RuntimeEnabledFeatures::css3TextDecorationsEnabled())
            return valuesForShorthandProperty(textDecorationShorthand(), style, layoutObject, styledNode, allowVisitedStyle);
        // Fall through.
    case CSSPropertyTextDecorationLine:
        return renderTextDecorationFlagsToCSSValue(style.getTextDecoration());
    case CSSPropertyTextDecorationStyle:
        return valueForTextDecorationStyle(style.getTextDecorationStyle());
    case CSSPropertyTextDecorationColor:
        return currentColorOrValidColor(style, style.textDecorationColor());
    case CSSPropertyTextJustify:
        return CSSPrimitiveValue::create(style.getTextJustify());
    case CSSPropertyTextUnderlinePosition:
        return CSSPrimitiveValue::create(style.getTextUnderlinePosition());
    case CSSPropertyWebkitTextDecorationsInEffect:
        return renderTextDecorationFlagsToCSSValue(style.textDecorationsInEffect());
    case CSSPropertyWebkitTextFillColor:
        return currentColorOrValidColor(style, style.textFillColor());
    case CSSPropertyWebkitTextEmphasisColor:
        return currentColorOrValidColor(style, style.textEmphasisColor());
    case CSSPropertyWebkitTextEmphasisPosition:
        return CSSPrimitiveValue::create(style.getTextEmphasisPosition());
    case CSSPropertyWebkitTextEmphasisStyle:
        switch (style.getTextEmphasisMark()) {
        case TextEmphasisMarkNone:
            return CSSPrimitiveValue::createIdentifier(CSSValueNone);
        case TextEmphasisMarkCustom:
            return CSSStringValue::create(style.textEmphasisCustomMark());
        case TextEmphasisMarkAuto:
            ASSERT_NOT_REACHED();
            // Fall through
        case TextEmphasisMarkDot:
        case TextEmphasisMarkCircle:
        case TextEmphasisMarkDoubleCircle:
        case TextEmphasisMarkTriangle:
        case TextEmphasisMarkSesame: {
            CSSValueList* list = CSSValueList::createSpaceSeparated();
            list->append(*CSSPrimitiveValue::create(style.getTextEmphasisFill()));
            list->append(*CSSPrimitiveValue::create(style.getTextEmphasisMark()));
            return list;
        }
        }
    case CSSPropertyTextIndent: {
        CSSValueList* list = CSSValueList::createSpaceSeparated();
        list->append(*zoomAdjustedPixelValueForLength(style.textIndent(), style));
        if (RuntimeEnabledFeatures::css3TextEnabled() && (style.getTextIndentLine() == TextIndentEachLine || style.getTextIndentType() == TextIndentHanging)) {
            if (style.getTextIndentLine() == TextIndentEachLine)
                list->append(*CSSPrimitiveValue::createIdentifier(CSSValueEachLine));
            if (style.getTextIndentType() == TextIndentHanging)
                list->append(*CSSPrimitiveValue::createIdentifier(CSSValueHanging));
        }
        return list;
    }
    case CSSPropertyTextShadow:
        return valueForShadowList(style.textShadow(), style, false);
    case CSSPropertyTextRendering:
        return CSSPrimitiveValue::create(style.getFontDescription().textRendering());
    case CSSPropertyTextOverflow:
        if (style.getTextOverflow())
            return CSSPrimitiveValue::createIdentifier(CSSValueEllipsis);
        return CSSPrimitiveValue::createIdentifier(CSSValueClip);
    case CSSPropertyWebkitTextSecurity:
        return CSSPrimitiveValue::create(style.textSecurity());
    case CSSPropertyWebkitTextStrokeColor:
        return currentColorOrValidColor(style, style.textStrokeColor());
    case CSSPropertyWebkitTextStrokeWidth:
        return zoomAdjustedPixelValue(style.textStrokeWidth(), style);
    case CSSPropertyTextTransform:
        return CSSPrimitiveValue::create(style.textTransform());
    case CSSPropertyTop:
        return valueForPositionOffset(style, CSSPropertyTop, layoutObject);
    case CSSPropertyTouchAction:
        return touchActionFlagsToCSSValue(style.getTouchAction());
    case CSSPropertyUnicodeBidi:
        return CSSPrimitiveValue::create(style.unicodeBidi());
    case CSSPropertyVerticalAlign:
        switch (style.verticalAlign()) {
        case VerticalAlignBaseline:
            return CSSPrimitiveValue::createIdentifier(CSSValueBaseline);
        case VerticalAlignMiddle:
            return CSSPrimitiveValue::createIdentifier(CSSValueMiddle);
        case VerticalAlignSub:
            return CSSPrimitiveValue::createIdentifier(CSSValueSub);
        case VerticalAlignSuper:
            return CSSPrimitiveValue::createIdentifier(CSSValueSuper);
        case VerticalAlignTextTop:
            return CSSPrimitiveValue::createIdentifier(CSSValueTextTop);
        case VerticalAlignTextBottom:
            return CSSPrimitiveValue::createIdentifier(CSSValueTextBottom);
        case VerticalAlignTop:
            return CSSPrimitiveValue::createIdentifier(CSSValueTop);
        case VerticalAlignBottom:
            return CSSPrimitiveValue::createIdentifier(CSSValueBottom);
        case VerticalAlignBaselineMiddle:
            return CSSPrimitiveValue::createIdentifier(CSSValueWebkitBaselineMiddle);
        case VerticalAlignLength:
            return zoomAdjustedPixelValueForLength(style.getVerticalAlignLength(), style);
        }
        ASSERT_NOT_REACHED();
        return nullptr;
    case CSSPropertyVisibility:
        return CSSPrimitiveValue::create(style.visibility());
    case CSSPropertyWhiteSpace:
        return CSSPrimitiveValue::create(style.whiteSpace());
    case CSSPropertyWidows:
        return CSSPrimitiveValue::create(style.widows(), CSSPrimitiveValue::UnitType::Number);
    case CSSPropertyWidth:
        if (layoutObject) {
            // According to http://www.w3.org/TR/CSS2/visudet.html#the-width-property,
            // the "width" property does not apply for non-atomic inline elements.
            if (!layoutObject->isAtomicInlineLevel() && layoutObject->isInline())
                return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
            return zoomAdjustedPixelValue(sizingBox(layoutObject).width(), style);
        }
        return zoomAdjustedPixelValueForLength(style.width(), style);
    case CSSPropertyWillChange:
        return valueForWillChange(style.willChangeProperties(), style.willChangeContents(), style.willChangeScrollPosition());
    case CSSPropertyWordBreak:
        return CSSPrimitiveValue::create(style.wordBreak());
    case CSSPropertyWordSpacing:
        return zoomAdjustedPixelValue(style.wordSpacing(), style);
    case CSSPropertyWordWrap:
        return CSSPrimitiveValue::create(style.overflowWrap());
    case CSSPropertyWebkitLineBreak:
        return CSSPrimitiveValue::create(style.getLineBreak());
    case CSSPropertyResize:
        return CSSPrimitiveValue::create(style.resize());
    case CSSPropertyFontKerning:
        return CSSPrimitiveValue::create(style.getFontDescription().getKerning());
    case CSSPropertyWebkitFontSmoothing:
        return CSSPrimitiveValue::create(style.getFontDescription().fontSmoothing());
    case CSSPropertyFontVariantLigatures:
        return valueForFontVariantLigatures(style);
    case CSSPropertyFontVariantCaps:
        return valueForFontVariantCaps(style);
    case CSSPropertyFontVariantNumeric:
        return valueForFontVariantNumeric(style);
    case CSSPropertyZIndex:
        if (style.hasAutoZIndex())
            return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
        return CSSPrimitiveValue::create(style.zIndex(), CSSPrimitiveValue::UnitType::Integer);
    case CSSPropertyZoom:
        return CSSPrimitiveValue::create(style.zoom(), CSSPrimitiveValue::UnitType::Number);
    case CSSPropertyBoxSizing:
        if (style.boxSizing() == BoxSizingContentBox)
            return CSSPrimitiveValue::createIdentifier(CSSValueContentBox);
        return CSSPrimitiveValue::createIdentifier(CSSValueBorderBox);
    case CSSPropertyWebkitAppRegion:
        return CSSPrimitiveValue::createIdentifier(style.getDraggableRegionMode() == DraggableRegionDrag ? CSSValueDrag : CSSValueNoDrag);
    case CSSPropertyAnimationDelay:
        return valueForAnimationDelay(style.animations());
    case CSSPropertyAnimationDirection: {
        CSSValueList* list = CSSValueList::createCommaSeparated();
        const CSSAnimationData* animationData = style.animations();
        if (animationData) {
            for (size_t i = 0; i < animationData->directionList().size(); ++i)
                list->append(*valueForAnimationDirection(animationData->directionList()[i]));
        } else {
            list->append(*CSSPrimitiveValue::createIdentifier(CSSValueNormal));
        }
        return list;
    }
    case CSSPropertyAnimationDuration:
        return valueForAnimationDuration(style.animations());
    case CSSPropertyAnimationFillMode: {
        CSSValueList* list = CSSValueList::createCommaSeparated();
        const CSSAnimationData* animationData = style.animations();
        if (animationData) {
            for (size_t i = 0; i < animationData->fillModeList().size(); ++i)
                list->append(*valueForAnimationFillMode(animationData->fillModeList()[i]));
        } else {
            list->append(*CSSPrimitiveValue::createIdentifier(CSSValueNone));
        }
        return list;
    }
    case CSSPropertyAnimationIterationCount: {
        CSSValueList* list = CSSValueList::createCommaSeparated();
        const CSSAnimationData* animationData = style.animations();
        if (animationData) {
            for (size_t i = 0; i < animationData->iterationCountList().size(); ++i)
                list->append(*valueForAnimationIterationCount(animationData->iterationCountList()[i]));
        } else {
            list->append(*CSSPrimitiveValue::create(CSSAnimationData::initialIterationCount(), CSSPrimitiveValue::UnitType::Number));
        }
        return list;
    }
    case CSSPropertyAnimationName: {
        CSSValueList* list = CSSValueList::createCommaSeparated();
        const CSSAnimationData* animationData = style.animations();
        if (animationData) {
            for (size_t i = 0; i < animationData->nameList().size(); ++i)
                list->append(*CSSCustomIdentValue::create(animationData->nameList()[i]));
        } else {
            list->append(*CSSPrimitiveValue::createIdentifier(CSSValueNone));
        }
        return list;
    }
    case CSSPropertyAnimationPlayState: {
        CSSValueList* list = CSSValueList::createCommaSeparated();
        const CSSAnimationData* animationData = style.animations();
        if (animationData) {
            for (size_t i = 0; i < animationData->playStateList().size(); ++i)
                list->append(*valueForAnimationPlayState(animationData->playStateList()[i]));
        } else {
            list->append(*CSSPrimitiveValue::createIdentifier(CSSValueRunning));
        }
        return list;
    }
    case CSSPropertyAnimationTimingFunction:
        return valueForAnimationTimingFunction(style.animations());
    case CSSPropertyAnimation: {
        const CSSAnimationData* animationData = style.animations();
        if (animationData) {
            CSSValueList* animationsList = CSSValueList::createCommaSeparated();
            for (size_t i = 0; i < animationData->nameList().size(); ++i) {
                CSSValueList* list = CSSValueList::createSpaceSeparated();
                list->append(*CSSCustomIdentValue::create(animationData->nameList()[i]));
                list->append(*CSSPrimitiveValue::create(CSSTimingData::getRepeated(animationData->durationList(), i), CSSPrimitiveValue::UnitType::Seconds));
                list->append(*createTimingFunctionValue(CSSTimingData::getRepeated(animationData->timingFunctionList(), i).get()));
                list->append(*CSSPrimitiveValue::create(CSSTimingData::getRepeated(animationData->delayList(), i), CSSPrimitiveValue::UnitType::Seconds));
                list->append(*valueForAnimationIterationCount(CSSTimingData::getRepeated(animationData->iterationCountList(), i)));
                list->append(*valueForAnimationDirection(CSSTimingData::getRepeated(animationData->directionList(), i)));
                list->append(*valueForAnimationFillMode(CSSTimingData::getRepeated(animationData->fillModeList(), i)));
                list->append(*valueForAnimationPlayState(CSSTimingData::getRepeated(animationData->playStateList(), i)));
                animationsList->append(*list);
            }
            return animationsList;
        }

        CSSValueList* list = CSSValueList::createSpaceSeparated();
        // animation-name default value.
        list->append(*CSSPrimitiveValue::createIdentifier(CSSValueNone));
        list->append(*CSSPrimitiveValue::create(CSSAnimationData::initialDuration(), CSSPrimitiveValue::UnitType::Seconds));
        list->append(*createTimingFunctionValue(CSSAnimationData::initialTimingFunction().get()));
        list->append(*CSSPrimitiveValue::create(CSSAnimationData::initialDelay(), CSSPrimitiveValue::UnitType::Seconds));
        list->append(*CSSPrimitiveValue::create(CSSAnimationData::initialIterationCount(), CSSPrimitiveValue::UnitType::Number));
        list->append(*valueForAnimationDirection(CSSAnimationData::initialDirection()));
        list->append(*valueForAnimationFillMode(CSSAnimationData::initialFillMode()));
        // Initial animation-play-state.
        list->append(*CSSPrimitiveValue::createIdentifier(CSSValueRunning));
        return list;
    }
    case CSSPropertyWebkitAppearance:
        return CSSPrimitiveValue::create(style.appearance());
    case CSSPropertyBackfaceVisibility:
        return CSSPrimitiveValue::createIdentifier((style.backfaceVisibility() == BackfaceVisibilityHidden) ? 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()->computedCSSValue();
        return CSSPrimitiveValue::createIdentifier(CSSValueNone);
    case CSSPropertyWebkitFontSizeDelta:
        // Not a real style property -- used by the editing engine -- so has no computed value.
        return nullptr;
    case CSSPropertyWebkitMarginBottomCollapse:
    case CSSPropertyWebkitMarginAfterCollapse:
        return CSSPrimitiveValue::create(style.marginAfterCollapse());
    case CSSPropertyWebkitMarginTopCollapse:
    case CSSPropertyWebkitMarginBeforeCollapse:
        return CSSPrimitiveValue::create(style.marginBeforeCollapse());
    case CSSPropertyPerspective:
        if (!style.hasPerspective())
            return CSSPrimitiveValue::createIdentifier(CSSValueNone);
        return zoomAdjustedPixelValue(style.perspective(), style);
    case CSSPropertyPerspectiveOrigin: {
        CSSValueList* list = CSSValueList::createSpaceSeparated();
        if (layoutObject) {
            LayoutRect box;
            if (layoutObject->isBox())
                box = toLayoutBox(layoutObject)->borderBoxRect();

            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 CSSPrimitiveValue::createIdentifier(style.rtlOrdering() ? CSSValueVisual : CSSValueLogical);
    case CSSPropertyWebkitTapHighlightColor:
        return currentColorOrValidColor(style, style.tapHighlightColor());
    case CSSPropertyWebkitUserDrag:
        return CSSPrimitiveValue::create(style.userDrag());
    case CSSPropertyUserSelect:
        return CSSPrimitiveValue::create(style.userSelect());
    case CSSPropertyBorderBottomLeftRadius:
        return &valueForBorderRadiusCorner(style.borderBottomLeftRadius(), style);
    case CSSPropertyBorderBottomRightRadius:
        return &valueForBorderRadiusCorner(style.borderBottomRightRadius(), style);
    case CSSPropertyBorderTopLeftRadius:
        return &valueForBorderRadiusCorner(style.borderTopLeftRadius(), style);
    case CSSPropertyBorderTopRightRadius:
        return &valueForBorderRadiusCorner(style.borderTopRightRadius(), style);
    case CSSPropertyClip: {
        if (style.hasAutoClip())
            return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
        CSSPrimitiveValue* top = style.clip().top().isAuto()
            ? CSSPrimitiveValue::createIdentifier(CSSValueAuto)
            : zoomAdjustedPixelValue(style.clip().top().value(), style);
        CSSPrimitiveValue* right = style.clip().right().isAuto()
            ? CSSPrimitiveValue::createIdentifier(CSSValueAuto)
            : zoomAdjustedPixelValue(style.clip().right().value(), style);
        CSSPrimitiveValue* bottom = style.clip().bottom().isAuto()
            ? CSSPrimitiveValue::createIdentifier(CSSValueAuto)
            : zoomAdjustedPixelValue(style.clip().bottom().value(), style);
        CSSPrimitiveValue* left = style.clip().left().isAuto()
            ? CSSPrimitiveValue::createIdentifier(CSSValueAuto)
            : zoomAdjustedPixelValue(style.clip().left().value(), style);
        return CSSQuadValue::create(top, right, bottom, left, CSSQuadValue::SerializeAsRect);
    }
    case CSSPropertySpeak:
        return CSSPrimitiveValue::create(style.speak());
    case CSSPropertyTransform:
        return computedTransform(layoutObject, style);
    case CSSPropertyTransformOrigin: {
        CSSValueList* list = CSSValueList::createSpaceSeparated();
        if (layoutObject) {
            LayoutRect box;
            if (layoutObject->isBox())
                box = toLayoutBox(layoutObject)->borderBoxRect();

            list->append(*zoomAdjustedPixelValue(minimumValueForLength(style.transformOriginX(), box.width()), style));
            list->append(*zoomAdjustedPixelValue(minimumValueForLength(style.transformOriginY(), box.height()), style));
            if (style.transformOriginZ() != 0)
                list->append(*zoomAdjustedPixelValue(style.transformOriginZ(), style));
        } else {
            list->append(*zoomAdjustedPixelValueForLength(style.transformOriginX(), style));
            list->append(*zoomAdjustedPixelValueForLength(style.transformOriginY(), style));
            if (style.transformOriginZ() != 0)
                list->append(*zoomAdjustedPixelValue(style.transformOriginZ(), style));
        }
        return list;
    }
    case CSSPropertyTransformStyle:
        return CSSPrimitiveValue::createIdentifier((style.transformStyle3D() == TransformStyle3DPreserve3D) ? CSSValuePreserve3d : CSSValueFlat);
    case CSSPropertyTransitionDelay:
        return valueForAnimationDelay(style.transitions());
    case CSSPropertyTransitionDuration:
        return valueForAnimationDuration(style.transitions());
    case CSSPropertyTransitionProperty:
        return valueForTransitionProperty(style.transitions());
    case CSSPropertyTransitionTimingFunction:
        return valueForAnimationTimingFunction(style.transitions());
    case CSSPropertyTransition: {
        const CSSTransitionData* transitionData = style.transitions();
        if (transitionData) {
            CSSValueList* transitionsList = CSSValueList::createCommaSeparated();
            for (size_t i = 0; i < transitionData->propertyList().size(); ++i) {
                CSSValueList* list = CSSValueList::createSpaceSeparated();
                list->append(*createTransitionPropertyValue(transitionData->propertyList()[i]));
                list->append(*CSSPrimitiveValue::create(CSSTimingData::getRepeated(transitionData->durationList(), i), CSSPrimitiveValue::UnitType::Seconds));
                list->append(*createTimingFunctionValue(CSSTimingData::getRepeated(transitionData->timingFunctionList(), i).get()));
                list->append(*CSSPrimitiveValue::create(CSSTimingData::getRepeated(transitionData->delayList(), i), CSSPrimitiveValue::UnitType::Seconds));
                transitionsList->append(*list);
            }
            return transitionsList;
        }

        CSSValueList* list = CSSValueList::createSpaceSeparated();
        // transition-property default value.
        list->append(*CSSPrimitiveValue::createIdentifier(CSSValueAll));
        list->append(*CSSPrimitiveValue::create(CSSTransitionData::initialDuration(), CSSPrimitiveValue::UnitType::Seconds));
        list->append(*createTimingFunctionValue(CSSTransitionData::initialTimingFunction().get()));
        list->append(*CSSPrimitiveValue::create(CSSTransitionData::initialDelay(), CSSPrimitiveValue::UnitType::Seconds));
        return list;
    }
    case CSSPropertyPointerEvents:
        return CSSPrimitiveValue::create(style.pointerEvents());
    case CSSPropertyWritingMode:
    case CSSPropertyWebkitWritingMode:
        return CSSPrimitiveValue::create(style.getWritingMode());
    case CSSPropertyWebkitTextCombine:
        if (style.getTextCombine() == TextCombineAll)
            return CSSPrimitiveValue::createIdentifier(CSSValueHorizontal);
    case CSSPropertyTextCombineUpright:
        return CSSPrimitiveValue::create(style.getTextCombine());
    case CSSPropertyWebkitTextOrientation:
        if (style.getTextOrientation() == TextOrientationMixed)
            return CSSPrimitiveValue::createIdentifier(CSSValueVerticalRight);
    case CSSPropertyTextOrientation:
        return CSSPrimitiveValue::create(style.getTextOrientation());
    case CSSPropertyContent:
        return valueForContentData(style);
    case CSSPropertyCounterIncrement:
        return valueForCounterDirectives(style, propertyID);
    case CSSPropertyCounterReset:
        return valueForCounterDirectives(style, propertyID);
    case CSSPropertyWebkitClipPath:
        if (ClipPathOperation* operation = style.clipPath()) {
            if (operation->type() == ClipPathOperation::SHAPE)
                return valueForBasicShape(style, toShapeClipPathOperation(operation)->basicShape());
            if (operation->type() == ClipPathOperation::REFERENCE)
                return CSSURIValue::create(toReferenceClipPathOperation(operation)->url());
        }
        return CSSPrimitiveValue::createIdentifier(CSSValueNone);
    case CSSPropertyShapeMargin:
        return CSSPrimitiveValue::create(style.shapeMargin(), style);
    case CSSPropertyShapeImageThreshold:
        return CSSPrimitiveValue::create(style.shapeImageThreshold(), CSSPrimitiveValue::UnitType::Number);
    case CSSPropertyShapeOutside:
        return valueForShape(style, style.shapeOutside());
    case CSSPropertyFilter:
        return valueForFilter(style, style.filter());
    case CSSPropertyBackdropFilter:
        return valueForFilter(style, style.backdropFilter());
    case CSSPropertyMixBlendMode:
        return CSSPrimitiveValue::create(style.blendMode());

    case CSSPropertyBackgroundBlendMode: {
        CSSValueList* list = CSSValueList::createCommaSeparated();
        for (const FillLayer* currLayer = &style.backgroundLayers(); currLayer; currLayer = currLayer->next())
            list->append(*CSSPrimitiveValue::create(currLayer->blendMode()));
        return list;
    }
    case CSSPropertyBackground:
        return valuesForBackgroundShorthand(style, layoutObject, styledNode, allowVisitedStyle);
    case CSSPropertyBorder: {
        const CSSValue* value = get(CSSPropertyBorderTop, style, layoutObject, styledNode, allowVisitedStyle);
        const CSSPropertyID properties[] = {
            CSSPropertyBorderRight,
            CSSPropertyBorderBottom,
            CSSPropertyBorderLeft
        };
        for (size_t i = 0; i < WTF_ARRAY_LENGTH(properties); ++i) {
            if (!compareCSSValuePtr<CSSValue>(value, get(properties[i], style, layoutObject, styledNode, allowVisitedStyle)))
                return nullptr;
        }
        return value;
    }
    case CSSPropertyBorderBottom:
        return valuesForShorthandProperty(borderBottomShorthand(), style, layoutObject, styledNode, allowVisitedStyle);
    case CSSPropertyBorderColor:
        return valuesForSidesShorthand(borderColorShorthand(), style, layoutObject, styledNode, allowVisitedStyle);
    case CSSPropertyBorderLeft:
        return valuesForShorthandProperty(borderLeftShorthand(), style, layoutObject, styledNode, allowVisitedStyle);
    case CSSPropertyBorderImage:
        return valueForNinePieceImage(style.borderImage(), style);
    case CSSPropertyBorderRadius:
        return valueForBorderRadiusShorthand(style);
    case CSSPropertyBorderRight:
        return valuesForShorthandProperty(borderRightShorthand(), style, layoutObject, styledNode, allowVisitedStyle);
    case CSSPropertyBorderStyle:
        return valuesForSidesShorthand(borderStyleShorthand(), style, layoutObject, styledNode, allowVisitedStyle);
    case CSSPropertyBorderTop:
        return valuesForShorthandProperty(borderTopShorthand(), style, layoutObject, styledNode, allowVisitedStyle);
    case CSSPropertyBorderWidth:
        return valuesForSidesShorthand(borderWidthShorthand(), style, layoutObject, styledNode, allowVisitedStyle);
    case CSSPropertyColumnRule:
        return valuesForShorthandProperty(columnRuleShorthand(), style, layoutObject, styledNode, allowVisitedStyle);
    case CSSPropertyColumns:
        return valuesForShorthandProperty(columnsShorthand(), style, layoutObject, styledNode, allowVisitedStyle);
    case CSSPropertyListStyle:
        return valuesForShorthandProperty(listStyleShorthand(), style, layoutObject, styledNode, allowVisitedStyle);
    case CSSPropertyMargin:
        return valuesForSidesShorthand(marginShorthand(), style, layoutObject, styledNode, allowVisitedStyle);
    case CSSPropertyOutline:
        return valuesForShorthandProperty(outlineShorthand(), style, layoutObject, styledNode, allowVisitedStyle);
    case CSSPropertyPadding:
        return valuesForSidesShorthand(paddingShorthand(), style, layoutObject, styledNode, allowVisitedStyle);
    // Individual properties not part of the spec.
    case CSSPropertyBackgroundRepeatX:
    case CSSPropertyBackgroundRepeatY:
        return nullptr;

    case CSSPropertyMotion:
        return valuesForShorthandProperty(motionShorthand(), style, layoutObject, styledNode, allowVisitedStyle);

    case CSSPropertyMotionPath:
        if (const StylePath* styleMotionPath = style.motionPath())
            return styleMotionPath->computedCSSValue();
        return CSSPrimitiveValue::createIdentifier(CSSValueNone);

    case CSSPropertyMotionOffset:
        return zoomAdjustedPixelValueForLength(style.motionOffset(), style);

    case CSSPropertyMotionRotation: {
        CSSValueList* list = CSSValueList::createSpaceSeparated();
        if (style.motionRotation().type == MotionRotationAuto)
            list->append(*CSSPrimitiveValue::createIdentifier(CSSValueAuto));
        list->append(*CSSPrimitiveValue::create(style.motionRotation().angle, CSSPrimitiveValue::UnitType::Degrees));
        return list;
    }

    // Unimplemented CSS 3 properties (including CSS3 shorthand properties).
    case CSSPropertyWebkitTextEmphasis:
        return nullptr;

    // Directional properties are resolved by resolveDirectionAwareProperty() before the switch.
    case CSSPropertyWebkitBorderEnd:
    case CSSPropertyWebkitBorderEndColor:
    case CSSPropertyWebkitBorderEndStyle:
    case CSSPropertyWebkitBorderEndWidth:
    case CSSPropertyWebkitBorderStart:
    case CSSPropertyWebkitBorderStartColor:
    case CSSPropertyWebkitBorderStartStyle:
    case CSSPropertyWebkitBorderStartWidth:
    case CSSPropertyWebkitBorderAfter:
    case CSSPropertyWebkitBorderAfterColor:
    case CSSPropertyWebkitBorderAfterStyle:
    case CSSPropertyWebkitBorderAfterWidth:
    case CSSPropertyWebkitBorderBefore:
    case CSSPropertyWebkitBorderBeforeColor:
    case CSSPropertyWebkitBorderBeforeStyle:
    case CSSPropertyWebkitBorderBeforeWidth:
    case CSSPropertyWebkitMarginEnd:
    case CSSPropertyWebkitMarginStart:
    case CSSPropertyWebkitMarginAfter:
    case CSSPropertyWebkitMarginBefore:
    case CSSPropertyWebkitPaddingEnd:
    case CSSPropertyWebkitPaddingStart:
    case CSSPropertyWebkitPaddingAfter:
    case CSSPropertyWebkitPaddingBefore:
    case CSSPropertyWebkitLogicalWidth:
    case CSSPropertyWebkitLogicalHeight:
    case CSSPropertyWebkitMinLogicalWidth:
    case CSSPropertyWebkitMinLogicalHeight:
    case CSSPropertyWebkitMaxLogicalWidth:
    case CSSPropertyWebkitMaxLogicalHeight:
        ASSERT_NOT_REACHED();
        return nullptr;

    // Unimplemented @font-face properties.
    case CSSPropertySrc:
    case CSSPropertyUnicodeRange:
        return nullptr;

    // Other unimplemented properties.
    case CSSPropertyPage: // for @page
    case CSSPropertySize: // for @page
        return nullptr;

    // Unimplemented -webkit- properties.
    case CSSPropertyWebkitMarginCollapse:
    case CSSPropertyWebkitMask:
    case CSSPropertyWebkitMaskRepeatX:
    case CSSPropertyWebkitMaskRepeatY:
    case CSSPropertyWebkitPerspectiveOriginX:
    case CSSPropertyWebkitPerspectiveOriginY:
    case CSSPropertyWebkitTextStroke:
    case CSSPropertyWebkitTransformOriginX:
    case CSSPropertyWebkitTransformOriginY:
    case CSSPropertyWebkitTransformOriginZ:
        return nullptr;

    // @viewport rule properties.
    case CSSPropertyMaxZoom:
    case CSSPropertyMinZoom:
    case CSSPropertyOrientation:
    case CSSPropertyUserZoom:
        return nullptr;

    // SVG properties.
    case CSSPropertyClipRule:
        return CSSPrimitiveValue::create(svgStyle.clipRule());
    case CSSPropertyFloodOpacity:
        return CSSPrimitiveValue::create(svgStyle.floodOpacity(), CSSPrimitiveValue::UnitType::Number);
    case CSSPropertyStopOpacity:
        return CSSPrimitiveValue::create(svgStyle.stopOpacity(), CSSPrimitiveValue::UnitType::Number);
    case CSSPropertyColorInterpolation:
        return CSSPrimitiveValue::create(svgStyle.colorInterpolation());
    case CSSPropertyColorInterpolationFilters:
        return CSSPrimitiveValue::create(svgStyle.colorInterpolationFilters());
    case CSSPropertyFillOpacity:
        return CSSPrimitiveValue::create(svgStyle.fillOpacity(), CSSPrimitiveValue::UnitType::Number);
    case CSSPropertyFillRule:
        return CSSPrimitiveValue::create(svgStyle.fillRule());
    case CSSPropertyColorRendering:
        return CSSPrimitiveValue::create(svgStyle.colorRendering());
    case CSSPropertyShapeRendering:
        return CSSPrimitiveValue::create(svgStyle.shapeRendering());
    case CSSPropertyStrokeLinecap:
        return CSSPrimitiveValue::create(svgStyle.capStyle());
    case CSSPropertyStrokeLinejoin:
        return CSSPrimitiveValue::create(svgStyle.joinStyle());
    case CSSPropertyStrokeMiterlimit:
        return CSSPrimitiveValue::create(svgStyle.strokeMiterLimit(), CSSPrimitiveValue::UnitType::Number);
    case CSSPropertyStrokeOpacity:
        return CSSPrimitiveValue::create(svgStyle.strokeOpacity(), CSSPrimitiveValue::UnitType::Number);
    case CSSPropertyAlignmentBaseline:
        return CSSPrimitiveValue::create(svgStyle.alignmentBaseline());
    case CSSPropertyDominantBaseline:
        return CSSPrimitiveValue::create(svgStyle.dominantBaseline());
    case CSSPropertyTextAnchor:
        return CSSPrimitiveValue::create(svgStyle.textAnchor());
    case CSSPropertyClipPath:
        if (!svgStyle.clipperResource().isEmpty())
            return CSSURIValue::create(serializeAsFragmentIdentifier(svgStyle.clipperResource()));
        return CSSPrimitiveValue::createIdentifier(CSSValueNone);
    case CSSPropertyMask:
        if (!svgStyle.maskerResource().isEmpty())
            return CSSURIValue::create(serializeAsFragmentIdentifier(svgStyle.maskerResource()));
        return CSSPrimitiveValue::createIdentifier(CSSValueNone);
    case CSSPropertyFloodColor:
        return currentColorOrValidColor(style, svgStyle.floodColor());
    case CSSPropertyLightingColor:
        return currentColorOrValidColor(style, svgStyle.lightingColor());
    case CSSPropertyStopColor:
        return currentColorOrValidColor(style, svgStyle.stopColor());
    case CSSPropertyFill:
        return adjustSVGPaintForCurrentColor(svgStyle.fillPaintType(), svgStyle.fillPaintUri(), svgStyle.fillPaintColor(), style.color());
    case CSSPropertyMarkerEnd:
        if (!svgStyle.markerEndResource().isEmpty())
            return CSSURIValue::create(serializeAsFragmentIdentifier(svgStyle.markerEndResource()));
        return CSSPrimitiveValue::createIdentifier(CSSValueNone);
    case CSSPropertyMarkerMid:
        if (!svgStyle.markerMidResource().isEmpty())
            return CSSURIValue::create(serializeAsFragmentIdentifier(svgStyle.markerMidResource()));
        return CSSPrimitiveValue::createIdentifier(CSSValueNone);
    case CSSPropertyMarkerStart:
        if (!svgStyle.markerStartResource().isEmpty())
            return CSSURIValue::create(serializeAsFragmentIdentifier(svgStyle.markerStartResource()));
        return CSSPrimitiveValue::createIdentifier(CSSValueNone);
    case CSSPropertyStroke:
        return adjustSVGPaintForCurrentColor(svgStyle.strokePaintType(), svgStyle.strokePaintUri(), svgStyle.strokePaintColor(), style.color());
    case CSSPropertyStrokeDasharray:
        return strokeDashArrayToCSSValueList(*svgStyle.strokeDashArray(), style);
    case CSSPropertyStrokeDashoffset:
        return zoomAdjustedPixelValueForLength(svgStyle.strokeDashOffset(), style);
    case CSSPropertyStrokeWidth:
        return pixelValueForUnzoomedLength(svgStyle.strokeWidth(), style);
    case CSSPropertyBaselineShift: {
        switch (svgStyle.baselineShift()) {
        case BS_SUPER:
            return CSSPrimitiveValue::createIdentifier(CSSValueSuper);
        case BS_SUB:
            return CSSPrimitiveValue::createIdentifier(CSSValueSub);
        case BS_LENGTH:
            return zoomAdjustedPixelValueForLength(svgStyle.baselineShiftValue(), style);
        }
        ASSERT_NOT_REACHED();
        return nullptr;
    }
    case CSSPropertyBufferedRendering:
        return CSSPrimitiveValue::create(svgStyle.bufferedRendering());
    case CSSPropertyPaintOrder:
        return paintOrderToCSSValueList(svgStyle);
    case CSSPropertyVectorEffect:
        return CSSPrimitiveValue::create(svgStyle.vectorEffect());
    case CSSPropertyMaskType:
        return CSSPrimitiveValue::create(svgStyle.maskType());
    case CSSPropertyMarker:
        // the above properties are not yet implemented in the engine
        return nullptr;
    case CSSPropertyD:
        if (const StylePath* stylePath = svgStyle.d())
            return stylePath->computedCSSValue();
        return CSSPrimitiveValue::createIdentifier(CSSValueNone);
    case CSSPropertyCx:
        return zoomAdjustedPixelValueForLength(svgStyle.cx(), style);
    case CSSPropertyCy:
        return zoomAdjustedPixelValueForLength(svgStyle.cy(), style);
    case CSSPropertyX:
        return zoomAdjustedPixelValueForLength(svgStyle.x(), style);
    case CSSPropertyY:
        return zoomAdjustedPixelValueForLength(svgStyle.y(), style);
    case CSSPropertyR:
        return zoomAdjustedPixelValueForLength(svgStyle.r(), style);
    case CSSPropertyRx:
        return zoomAdjustedPixelValueForLength(svgStyle.rx(), style);
    case CSSPropertyRy:
        return zoomAdjustedPixelValueForLength(svgStyle.ry(), style);
    case CSSPropertyScrollSnapType:
        return CSSPrimitiveValue::create(style.getScrollSnapType());
    case CSSPropertyScrollSnapPointsX:
        return valueForScrollSnapPoints(style.scrollSnapPointsX(), style);
    case CSSPropertyScrollSnapPointsY:
        return valueForScrollSnapPoints(style.scrollSnapPointsY(), style);
    case CSSPropertyScrollSnapCoordinate:
        return valueForScrollSnapCoordinate(style.scrollSnapCoordinate(), style);
    case CSSPropertyScrollSnapDestination:
        return valueForScrollSnapDestination(style.scrollSnapDestination(), style);
    case CSSPropertyTranslate: {
        if (!style.translate())
            return CSSPrimitiveValue::create(0, CSSPrimitiveValue::UnitType::Pixels);

        CSSValueList* list = CSSValueList::createSpaceSeparated();
        if (layoutObject && layoutObject->isBox()) {
            LayoutRect box = toLayoutBox(layoutObject)->borderBoxRect();
            list->append(*zoomAdjustedPixelValue(floatValueForLength(style.translate()->x(), box.width().toFloat()), style));

            if (!style.translate()->y().isZero() || style.translate()->z() != 0)
                list->append(*zoomAdjustedPixelValue(floatValueForLength(style.translate()->y(), box.height().toFloat()), style));

        } else {
            // No box to resolve the percentage values
            list->append(*zoomAdjustedPixelValueForLength(style.translate()->x(), style));

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

        if (style.translate()->z() != 0)
            list->append(*zoomAdjustedPixelValue(style.translate()->z(), style));

        return list;
    }
    case CSSPropertyRotate: {
        if (!style.rotate())
            return CSSPrimitiveValue::create(0, CSSPrimitiveValue::UnitType::Degrees);

        CSSValueList* list = CSSValueList::createSpaceSeparated();
        list->append(*CSSPrimitiveValue::create(style.rotate()->angle(), CSSPrimitiveValue::UnitType::Degrees));
        if (style.rotate()->x() != 0 || style.rotate()->y() != 0 || style.rotate()->z() != 1) {
            list->append(*CSSPrimitiveValue::create(style.rotate()->x(), CSSPrimitiveValue::UnitType::Number));
            list->append(*CSSPrimitiveValue::create(style.rotate()->y(), CSSPrimitiveValue::UnitType::Number));
            list->append(*CSSPrimitiveValue::create(style.rotate()->z(), CSSPrimitiveValue::UnitType::Number));
        }
        return list;
    }
    case CSSPropertyScale: {
        if (!style.scale())
            return CSSPrimitiveValue::create(1, CSSPrimitiveValue::UnitType::Number);
        CSSValueList* list = CSSValueList::createSpaceSeparated();
        list->append(*CSSPrimitiveValue::create(style.scale()->x(), CSSPrimitiveValue::UnitType::Number));
        if (style.scale()->y() == 1 && style.scale()->z() == 1)
            return list;
        list->append(*CSSPrimitiveValue::create(style.scale()->y(), CSSPrimitiveValue::UnitType::Number));
        if (style.scale()->z() != 1)
            list->append(*CSSPrimitiveValue::create(style.scale()->z(), CSSPrimitiveValue::UnitType::Number));
        return list;
    }
    case CSSPropertyContain: {
        if (!style.contain())
            return CSSPrimitiveValue::createIdentifier(CSSValueNone);
        if (style.contain() == ContainsStrict)
            return CSSPrimitiveValue::createIdentifier(CSSValueStrict);
        if (style.contain() == ContainsContent)
            return CSSPrimitiveValue::createIdentifier(CSSValueContent);

        CSSValueList* list = CSSValueList::createSpaceSeparated();
        if (style.containsStyle())
            list->append(*CSSPrimitiveValue::createIdentifier(CSSValueStyle));
        if (style.contain() & ContainsLayout)
            list->append(*CSSPrimitiveValue::createIdentifier(CSSValueLayout));
        if (style.containsPaint())
            list->append(*CSSPrimitiveValue::createIdentifier(CSSValuePaint));
        if (style.containsSize())
            list->append(*CSSPrimitiveValue::createIdentifier(CSSValueSize));
        ASSERT(list->length());
        return list;
    }
    case CSSPropertySnapHeight: {
        if (!style.snapHeightUnit())
            return CSSPrimitiveValue::create(0, CSSPrimitiveValue::UnitType::Pixels);
        CSSValueList* list = CSSValueList::createSpaceSeparated();
        list->append(*CSSPrimitiveValue::create(style.snapHeightUnit(), CSSPrimitiveValue::UnitType::Pixels));
        if (style.snapHeightPosition())
            list->append(*CSSPrimitiveValue::create(style.snapHeightPosition(), CSSPrimitiveValue::UnitType::Integer));
        return list;
    }
    case CSSPropertyVariable:
        // Variables are retrieved via get(AtomicString).
        ASSERT_NOT_REACHED();
        return nullptr;
    case CSSPropertyAll:
        return nullptr;
    default:
        break;
    }
    ASSERT_NOT_REACHED();
    return nullptr;
}

} // namespace blink
