void StylePropertySerializer::appendBackgroundPropertyAsText(StringBuilder& result, unsigned& numDecls) const
{
    if (isPropertyShorthandAvailable(backgroundShorthand())) {
        String backgroundValue = getPropertyValue(CSSPropertyBackground);
        result.append(getPropertyText(CSSPropertyBackground, backgroundValue, numDecls++));
        return;
    }
    if (shorthandHasOnlyInitialOrInheritedValue(backgroundShorthand())) {
        RefPtr<CSSValue> value = m_propertySet.getPropertyCSSValue(CSSPropertyBackgroundImage);
        result.append(getPropertyText(CSSPropertyBackground, value->cssText(), numDecls++));
        return;
    }

    // backgroundShorthandProperty without layered shorhand properties
    const CSSPropertyID backgroundPropertyIds[] = {
        CSSPropertyBackgroundImage,
        CSSPropertyBackgroundAttachment,
        CSSPropertyBackgroundColor,
        CSSPropertyBackgroundSize,
        CSSPropertyBackgroundOrigin,
        CSSPropertyBackgroundClip
    };

    for (unsigned i = 0; i < WTF_ARRAY_LENGTH(backgroundPropertyIds); ++i) {
        CSSPropertyID propertyID = backgroundPropertyIds[i];
        RefPtr<CSSValue> value = m_propertySet.getPropertyCSSValue(propertyID);
        if (!value)
            continue;
        result.append(getPropertyText(propertyID, value->cssText(), numDecls++));
    }

    // FIXME: This is a not-so-nice way to turn x/y positions into single background-position in output.
    // It is required because background-position-x/y are non-standard properties and WebKit generated output
    // would not work in Firefox (<rdar://problem/5143183>)
    // It would be a better solution if background-position was CSS_PAIR.
    if (shorthandHasOnlyInitialOrInheritedValue(backgroundPositionShorthand())) {
        RefPtr<CSSValue> value = m_propertySet.getPropertyCSSValue(CSSPropertyBackgroundPositionX);
        result.append(getPropertyText(CSSPropertyBackgroundPosition, value->cssText(), numDecls++));
    } else if (isPropertyShorthandAvailable(backgroundPositionShorthand())) {
        String positionValue = m_propertySet.getPropertyValue(CSSPropertyBackgroundPosition);
        if (!positionValue.isNull())
            result.append(getPropertyText(CSSPropertyBackgroundPosition, positionValue, numDecls++));
    } else {
        // should check background-position-x or background-position-y.
        if (RefPtr<CSSValue> value = m_propertySet.getPropertyCSSValue(CSSPropertyBackgroundPositionX)) {
            if (!value->isImplicitInitialValue()) {
                result.append(getPropertyText(CSSPropertyBackgroundPositionX, value->cssText(), numDecls++));
            }
        }
        if (RefPtr<CSSValue> value = m_propertySet.getPropertyCSSValue(CSSPropertyBackgroundPositionY)) {
            if (!value->isImplicitInitialValue()) {
                result.append(getPropertyText(CSSPropertyBackgroundPositionY, value->cssText(), numDecls++));
            }
        }
    }

    String repeatValue = m_propertySet.getPropertyValue(CSSPropertyBackgroundRepeat);
    if (!repeatValue.isNull())
        result.append(getPropertyText(CSSPropertyBackgroundRepeat, repeatValue, numDecls++));
}
String StylePropertySerializer::getPropertyValue(CSSPropertyID propertyID) const
{
    // Shorthand and 4-values properties
    switch (propertyID) {
    case CSSPropertyAnimation:
        return getLayeredShorthandValue(animationShorthand());
    case CSSPropertyBorderSpacing:
        return borderSpacingValue(borderSpacingShorthand());
    case CSSPropertyBackgroundPosition:
        return getLayeredShorthandValue(backgroundPositionShorthand());
    case CSSPropertyBackgroundRepeat:
        return backgroundRepeatPropertyValue();
    case CSSPropertyBackground:
        return getLayeredShorthandValue(backgroundShorthand());
    case CSSPropertyBorder:
        return borderPropertyValue(OmitUncommonValues);
    case CSSPropertyBorderTop:
        return getShorthandValue(borderTopShorthand());
    case CSSPropertyBorderRight:
        return getShorthandValue(borderRightShorthand());
    case CSSPropertyBorderBottom:
        return getShorthandValue(borderBottomShorthand());
    case CSSPropertyBorderLeft:
        return getShorthandValue(borderLeftShorthand());
    case CSSPropertyOutline:
        return getShorthandValue(outlineShorthand());
    case CSSPropertyBorderColor:
        return get4Values(borderColorShorthand());
    case CSSPropertyBorderWidth:
        return get4Values(borderWidthShorthand());
    case CSSPropertyBorderStyle:
        return get4Values(borderStyleShorthand());
    case CSSPropertyWebkitColumnRule:
        return getShorthandValue(webkitColumnRuleShorthand());
    case CSSPropertyWebkitColumns:
        return getShorthandValue(webkitColumnsShorthand());
    case CSSPropertyFlex:
        return getShorthandValue(flexShorthand());
    case CSSPropertyFlexFlow:
        return getShorthandValue(flexFlowShorthand());
    case CSSPropertyGridColumn:
        return getShorthandValue(gridColumnShorthand());
    case CSSPropertyGridRow:
        return getShorthandValue(gridRowShorthand());
    case CSSPropertyGridArea:
        return getShorthandValue(gridAreaShorthand());
    case CSSPropertyFont:
        return fontValue();
    case CSSPropertyMargin:
        return get4Values(marginShorthand());
    case CSSPropertyWebkitMarginCollapse:
        return getShorthandValue(webkitMarginCollapseShorthand());
    case CSSPropertyOverflow:
        return getCommonValue(overflowShorthand());
    case CSSPropertyPadding:
        return get4Values(paddingShorthand());
    case CSSPropertyTransition:
        return getLayeredShorthandValue(transitionShorthand());
    case CSSPropertyListStyle:
        return getShorthandValue(listStyleShorthand());
    case CSSPropertyWebkitMaskPosition:
        return getLayeredShorthandValue(webkitMaskPositionShorthand());
    case CSSPropertyWebkitMaskRepeat:
        return getLayeredShorthandValue(webkitMaskRepeatShorthand());
    case CSSPropertyWebkitMask:
        return getLayeredShorthandValue(webkitMaskShorthand());
    case CSSPropertyWebkitTextEmphasis:
        return getShorthandValue(webkitTextEmphasisShorthand());
    case CSSPropertyWebkitTextStroke:
        return getShorthandValue(webkitTextStrokeShorthand());
    case CSSPropertyTransformOrigin:
    case CSSPropertyWebkitTransformOrigin:
        return getShorthandValue(webkitTransformOriginShorthand());
    case CSSPropertyWebkitTransition:
        return getLayeredShorthandValue(webkitTransitionShorthand());
    case CSSPropertyWebkitAnimation:
        return getLayeredShorthandValue(webkitAnimationShorthand());
    case CSSPropertyMarker: {
        RefPtrWillBeRawPtr<CSSValue> value = m_propertySet.getPropertyCSSValue(CSSPropertyMarkerStart);
        if (value)
            return value->cssText();
        return String();
    }
    case CSSPropertyBorderRadius:
        return get4Values(borderRadiusShorthand());
    default:
        return String();
    }
}
String StylePropertySerializer::getPropertyValue(CSSPropertyID propertyID) const
{
    // Shorthand and 4-values properties
    switch (propertyID) {
    case CSSPropertyAnimation:
        return getLayeredShorthandValue(animationShorthand());
    case CSSPropertyBorderSpacing:
        return borderSpacingValue(borderSpacingShorthand());
    case CSSPropertyBackgroundPosition:
        return getLayeredShorthandValue(backgroundPositionShorthand());
    case CSSPropertyBackgroundRepeat:
        return backgroundRepeatPropertyValue();
    case CSSPropertyBackground:
        return getLayeredShorthandValue(backgroundShorthand());
    case CSSPropertyBorder:
        return borderPropertyValue(OmitUncommonValues);
    case CSSPropertyBorderTop:
        return getShorthandValue(borderTopShorthand());
    case CSSPropertyBorderRight:
        return getShorthandValue(borderRightShorthand());
    case CSSPropertyBorderBottom:
        return getShorthandValue(borderBottomShorthand());
    case CSSPropertyBorderLeft:
        return getShorthandValue(borderLeftShorthand());
    case CSSPropertyOutline:
        return getShorthandValue(outlineShorthand());
    case CSSPropertyBorderColor:
        return get4Values(borderColorShorthand());
    case CSSPropertyBorderWidth:
        return get4Values(borderWidthShorthand());
    case CSSPropertyBorderStyle:
        return get4Values(borderStyleShorthand());
    case CSSPropertyFlex:
        return getShorthandValue(flexShorthand());
    case CSSPropertyFlexFlow:
        return getShorthandValue(flexFlowShorthand());
    case CSSPropertyFont:
        return fontValue();
    case CSSPropertyMargin:
        return get4Values(marginShorthand());
    case CSSPropertyOverflow:
        return getCommonValue(overflowShorthand());
    case CSSPropertyPadding:
        return get4Values(paddingShorthand());
    case CSSPropertyTransition:
        return getLayeredShorthandValue(transitionShorthand());
    case CSSPropertyListStyle:
        return getShorthandValue(listStyleShorthand());
    case CSSPropertyWebkitTextEmphasis:
        return getShorthandValue(webkitTextEmphasisShorthand());
    case CSSPropertyWebkitTextStroke:
        return getShorthandValue(webkitTextStrokeShorthand());
    case CSSPropertyTransformOrigin:
    case CSSPropertyWebkitTransformOrigin:
        return getShorthandValue(webkitTransformOriginShorthand());
    case CSSPropertyBorderRadius:
        return get4Values(borderRadiusShorthand());
    default:
        return String();
    }
}