1/*
2 * Copyright (C) 2004 Zack Rusin <zack@kde.org>
3 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved.
4 * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org>
5 * Copyright (C) 2007 Nicholas Shanks <webkit@nickshanks.com>
6 * Copyright (C) 2011 Sencha, Inc. All rights reserved.
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 * 02110-1301  USA
22 */
23
24#include "config.h"
25#include "core/css/CSSComputedStyleDeclaration.h"
26
27#include "CSSPropertyNames.h"
28#include "FontFamilyNames.h"
29#include "RuntimeEnabledFeatures.h"
30#include "StylePropertyShorthand.h"
31#include "bindings/v8/ExceptionState.h"
32#include "core/animation/DocumentAnimations.h"
33#include "core/css/BasicShapeFunctions.h"
34#include "core/css/CSSArrayFunctionValue.h"
35#include "core/css/CSSAspectRatioValue.h"
36#include "core/css/CSSBorderImage.h"
37#include "core/css/CSSFilterValue.h"
38#include "core/css/CSSFontFeatureValue.h"
39#include "core/css/CSSFontValue.h"
40#include "core/css/CSSFunctionValue.h"
41#include "core/css/CSSGridLineNamesValue.h"
42#include "core/css/CSSGridTemplateValue.h"
43#include "core/css/CSSLineBoxContainValue.h"
44#include "core/css/CSSMixFunctionValue.h"
45#include "core/css/CSSParser.h"
46#include "core/css/CSSPrimitiveValue.h"
47#include "core/css/CSSPrimitiveValueMappings.h"
48#include "core/css/CSSReflectValue.h"
49#include "core/css/CSSSelector.h"
50#include "core/css/CSSShadowValue.h"
51#include "core/css/CSSTimingFunctionValue.h"
52#include "core/css/CSSTransformValue.h"
53#include "core/css/CSSValueList.h"
54#include "core/css/CSSValuePool.h"
55#include "core/css/Pair.h"
56#include "core/css/Rect.h"
57#include "core/css/RuntimeCSSEnabled.h"
58#include "core/css/StylePropertySet.h"
59#include "core/css/resolver/StyleResolver.h"
60#include "core/dom/Document.h"
61#include "core/dom/ExceptionCode.h"
62#include "core/dom/PseudoElement.h"
63#include "core/frame/animation/AnimationController.h"
64#include "core/rendering/RenderBox.h"
65#include "core/rendering/RenderGrid.h"
66#include "core/rendering/RenderView.h"
67#include "core/rendering/style/ContentData.h"
68#include "core/rendering/style/CounterContent.h"
69#include "core/rendering/style/CursorList.h"
70#include "core/rendering/style/RenderStyle.h"
71#include "core/rendering/style/ShadowList.h"
72#include "core/rendering/style/ShapeValue.h"
73#include "core/rendering/style/StyleCustomFilterProgram.h"
74#include "platform/fonts/FontFeatureSettings.h"
75#include "platform/graphics/filters/custom/CustomFilterArrayParameter.h"
76#include "platform/graphics/filters/custom/CustomFilterNumberParameter.h"
77#include "platform/graphics/filters/custom/CustomFilterOperation.h"
78#include "platform/graphics/filters/custom/CustomFilterParameter.h"
79#include "platform/graphics/filters/custom/CustomFilterTransformParameter.h"
80#include "wtf/text/StringBuilder.h"
81
82namespace WebCore {
83
84// List of all properties we know how to compute, omitting shorthands.
85// NOTE: Do not use this list, use computableProperties() instead
86// to respect runtime enabling of CSS properties.
87static const CSSPropertyID staticComputableProperties[] = {
88    CSSPropertyAnimationDelay,
89    CSSPropertyAnimationDirection,
90    CSSPropertyAnimationDuration,
91    CSSPropertyAnimationFillMode,
92    CSSPropertyAnimationIterationCount,
93    CSSPropertyAnimationName,
94    CSSPropertyAnimationPlayState,
95    CSSPropertyAnimationTimingFunction,
96    CSSPropertyBackgroundAttachment,
97    CSSPropertyBackgroundBlendMode,
98    CSSPropertyBackgroundClip,
99    CSSPropertyBackgroundColor,
100    CSSPropertyBackgroundImage,
101    CSSPropertyBackgroundOrigin,
102    CSSPropertyBackgroundPosition, // more-specific background-position-x/y are non-standard
103    CSSPropertyBackgroundRepeat,
104    CSSPropertyBackgroundSize,
105    CSSPropertyBorderBottomColor,
106    CSSPropertyBorderBottomLeftRadius,
107    CSSPropertyBorderBottomRightRadius,
108    CSSPropertyBorderBottomStyle,
109    CSSPropertyBorderBottomWidth,
110    CSSPropertyBorderCollapse,
111    CSSPropertyBorderImageOutset,
112    CSSPropertyBorderImageRepeat,
113    CSSPropertyBorderImageSlice,
114    CSSPropertyBorderImageSource,
115    CSSPropertyBorderImageWidth,
116    CSSPropertyBorderLeftColor,
117    CSSPropertyBorderLeftStyle,
118    CSSPropertyBorderLeftWidth,
119    CSSPropertyBorderRightColor,
120    CSSPropertyBorderRightStyle,
121    CSSPropertyBorderRightWidth,
122    CSSPropertyBorderTopColor,
123    CSSPropertyBorderTopLeftRadius,
124    CSSPropertyBorderTopRightRadius,
125    CSSPropertyBorderTopStyle,
126    CSSPropertyBorderTopWidth,
127    CSSPropertyBottom,
128    CSSPropertyBoxShadow,
129    CSSPropertyBoxSizing,
130    CSSPropertyCaptionSide,
131    CSSPropertyClear,
132    CSSPropertyClip,
133    CSSPropertyColor,
134    CSSPropertyCursor,
135    CSSPropertyDirection,
136    CSSPropertyDisplay,
137    CSSPropertyEmptyCells,
138    CSSPropertyFloat,
139    CSSPropertyFontFamily,
140    CSSPropertyFontKerning,
141    CSSPropertyFontSize,
142    CSSPropertyFontStyle,
143    CSSPropertyFontVariant,
144    CSSPropertyFontWeight,
145    CSSPropertyHeight,
146    CSSPropertyImageRendering,
147    CSSPropertyIsolation,
148    CSSPropertyLeft,
149    CSSPropertyLetterSpacing,
150    CSSPropertyLineHeight,
151    CSSPropertyListStyleImage,
152    CSSPropertyListStylePosition,
153    CSSPropertyListStyleType,
154    CSSPropertyMarginBottom,
155    CSSPropertyMarginLeft,
156    CSSPropertyMarginRight,
157    CSSPropertyMarginTop,
158    CSSPropertyMaxHeight,
159    CSSPropertyMaxWidth,
160    CSSPropertyMinHeight,
161    CSSPropertyMinWidth,
162    CSSPropertyMixBlendMode,
163    CSSPropertyObjectFit,
164    CSSPropertyObjectPosition,
165    CSSPropertyOpacity,
166    CSSPropertyOrphans,
167    CSSPropertyOutlineColor,
168    CSSPropertyOutlineOffset,
169    CSSPropertyOutlineStyle,
170    CSSPropertyOutlineWidth,
171    CSSPropertyOverflowWrap,
172    CSSPropertyOverflowX,
173    CSSPropertyOverflowY,
174    CSSPropertyPaddingBottom,
175    CSSPropertyPaddingLeft,
176    CSSPropertyPaddingRight,
177    CSSPropertyPaddingTop,
178    CSSPropertyPageBreakAfter,
179    CSSPropertyPageBreakBefore,
180    CSSPropertyPageBreakInside,
181    CSSPropertyPointerEvents,
182    CSSPropertyPosition,
183    CSSPropertyResize,
184    CSSPropertyRight,
185    CSSPropertySpeak,
186    CSSPropertyTableLayout,
187    CSSPropertyTabSize,
188    CSSPropertyTextAlign,
189    CSSPropertyTextAlignLast,
190    CSSPropertyTextDecoration,
191    CSSPropertyTextDecorationLine,
192    CSSPropertyTextDecorationStyle,
193    CSSPropertyTextDecorationColor,
194    CSSPropertyTextJustify,
195    CSSPropertyTextUnderlinePosition,
196    CSSPropertyTextIndent,
197    CSSPropertyTextRendering,
198    CSSPropertyTextShadow,
199    CSSPropertyTextOverflow,
200    CSSPropertyTextTransform,
201    CSSPropertyTop,
202    CSSPropertyTouchAction,
203    CSSPropertyTouchActionDelay,
204    CSSPropertyTransitionDelay,
205    CSSPropertyTransitionDuration,
206    CSSPropertyTransitionProperty,
207    CSSPropertyTransitionTimingFunction,
208    CSSPropertyUnicodeBidi,
209    CSSPropertyVerticalAlign,
210    CSSPropertyVisibility,
211    CSSPropertyWhiteSpace,
212    CSSPropertyWidows,
213    CSSPropertyWidth,
214    CSSPropertyWordBreak,
215    CSSPropertyWordSpacing,
216    CSSPropertyWordWrap,
217    CSSPropertyZIndex,
218    CSSPropertyZoom,
219
220    CSSPropertyWebkitAnimationDelay,
221    CSSPropertyWebkitAnimationDirection,
222    CSSPropertyWebkitAnimationDuration,
223    CSSPropertyWebkitAnimationFillMode,
224    CSSPropertyWebkitAnimationIterationCount,
225    CSSPropertyWebkitAnimationName,
226    CSSPropertyWebkitAnimationPlayState,
227    CSSPropertyWebkitAnimationTimingFunction,
228    CSSPropertyWebkitAppearance,
229    CSSPropertyWebkitBackfaceVisibility,
230    CSSPropertyWebkitBackgroundClip,
231    CSSPropertyWebkitBackgroundComposite,
232    CSSPropertyWebkitBackgroundOrigin,
233    CSSPropertyWebkitBackgroundSize,
234    CSSPropertyWebkitBorderFit,
235    CSSPropertyWebkitBorderHorizontalSpacing,
236    CSSPropertyWebkitBorderImage,
237    CSSPropertyWebkitBorderVerticalSpacing,
238    CSSPropertyWebkitBoxAlign,
239    CSSPropertyWebkitBoxDecorationBreak,
240    CSSPropertyWebkitBoxDirection,
241    CSSPropertyWebkitBoxFlex,
242    CSSPropertyWebkitBoxFlexGroup,
243    CSSPropertyWebkitBoxLines,
244    CSSPropertyWebkitBoxOrdinalGroup,
245    CSSPropertyWebkitBoxOrient,
246    CSSPropertyWebkitBoxPack,
247    CSSPropertyWebkitBoxReflect,
248    CSSPropertyWebkitBoxShadow,
249    CSSPropertyWebkitClipPath,
250    CSSPropertyWebkitColumnBreakAfter,
251    CSSPropertyWebkitColumnBreakBefore,
252    CSSPropertyWebkitColumnBreakInside,
253    CSSPropertyWebkitColumnAxis,
254    CSSPropertyWebkitColumnCount,
255    CSSPropertyWebkitColumnGap,
256    CSSPropertyWebkitColumnProgression,
257    CSSPropertyWebkitColumnRuleColor,
258    CSSPropertyWebkitColumnRuleStyle,
259    CSSPropertyWebkitColumnRuleWidth,
260    CSSPropertyWebkitColumnSpan,
261    CSSPropertyWebkitColumnWidth,
262    CSSPropertyWebkitFilter,
263    CSSPropertyAlignContent,
264    CSSPropertyAlignItems,
265    CSSPropertyAlignSelf,
266    CSSPropertyFlexBasis,
267    CSSPropertyFlexGrow,
268    CSSPropertyFlexShrink,
269    CSSPropertyFlexDirection,
270    CSSPropertyFlexWrap,
271    CSSPropertyJustifyContent,
272    CSSPropertyWebkitFontSmoothing,
273    CSSPropertyWebkitFontVariantLigatures,
274    CSSPropertyGridAutoColumns,
275    CSSPropertyGridAutoFlow,
276    CSSPropertyGridAutoRows,
277    CSSPropertyGridColumnEnd,
278    CSSPropertyGridColumnStart,
279    CSSPropertyGridDefinitionColumns,
280    CSSPropertyGridDefinitionRows,
281    CSSPropertyGridRowEnd,
282    CSSPropertyGridRowStart,
283    CSSPropertyWebkitHighlight,
284    CSSPropertyWebkitHyphenateCharacter,
285    CSSPropertyWebkitLineAlign,
286    CSSPropertyWebkitLineBoxContain,
287    CSSPropertyWebkitLineBreak,
288    CSSPropertyWebkitLineClamp,
289    CSSPropertyWebkitLineGrid,
290    CSSPropertyWebkitLineSnap,
291    CSSPropertyWebkitLocale,
292    CSSPropertyWebkitMarginBeforeCollapse,
293    CSSPropertyWebkitMarginAfterCollapse,
294    CSSPropertyWebkitMaskBoxImage,
295    CSSPropertyWebkitMaskBoxImageOutset,
296    CSSPropertyWebkitMaskBoxImageRepeat,
297    CSSPropertyWebkitMaskBoxImageSlice,
298    CSSPropertyWebkitMaskBoxImageSource,
299    CSSPropertyWebkitMaskBoxImageWidth,
300    CSSPropertyWebkitMaskClip,
301    CSSPropertyWebkitMaskComposite,
302    CSSPropertyWebkitMaskImage,
303    CSSPropertyWebkitMaskOrigin,
304    CSSPropertyWebkitMaskPosition,
305    CSSPropertyWebkitMaskRepeat,
306    CSSPropertyWebkitMaskSize,
307    CSSPropertyOrder,
308    CSSPropertyWebkitPerspective,
309    CSSPropertyWebkitPerspectiveOrigin,
310    CSSPropertyWebkitPrintColorAdjust,
311    CSSPropertyWebkitRtlOrdering,
312    CSSPropertyShapeInside,
313    CSSPropertyShapeOutside,
314    CSSPropertyShapePadding,
315    CSSPropertyShapeImageThreshold,
316    CSSPropertyShapeMargin,
317    CSSPropertyWebkitTapHighlightColor,
318    CSSPropertyWebkitTextCombine,
319    CSSPropertyWebkitTextDecorationsInEffect,
320    CSSPropertyWebkitTextEmphasisColor,
321    CSSPropertyWebkitTextEmphasisPosition,
322    CSSPropertyWebkitTextEmphasisStyle,
323    CSSPropertyWebkitTextFillColor,
324    CSSPropertyWebkitTextOrientation,
325    CSSPropertyWebkitTextSecurity,
326    CSSPropertyWebkitTextStrokeColor,
327    CSSPropertyWebkitTextStrokeWidth,
328    CSSPropertyWebkitTransform,
329    CSSPropertyWebkitTransformOrigin,
330    CSSPropertyWebkitTransformStyle,
331    CSSPropertyWebkitTransitionDelay,
332    CSSPropertyWebkitTransitionDuration,
333    CSSPropertyWebkitTransitionProperty,
334    CSSPropertyWebkitTransitionTimingFunction,
335    CSSPropertyWebkitUserDrag,
336    CSSPropertyWebkitUserModify,
337    CSSPropertyWebkitUserSelect,
338    CSSPropertyWebkitWritingMode,
339    CSSPropertyWebkitFlowInto,
340    CSSPropertyWebkitFlowFrom,
341    CSSPropertyWebkitRegionBreakAfter,
342    CSSPropertyWebkitRegionBreakBefore,
343    CSSPropertyWebkitRegionBreakInside,
344    CSSPropertyWebkitRegionFragment,
345    CSSPropertyWebkitAppRegion,
346    CSSPropertyWebkitWrapFlow,
347    CSSPropertyWebkitWrapThrough,
348    CSSPropertyBufferedRendering,
349    CSSPropertyClipPath,
350    CSSPropertyClipRule,
351    CSSPropertyMask,
352    CSSPropertyFilter,
353    CSSPropertyFloodColor,
354    CSSPropertyFloodOpacity,
355    CSSPropertyLightingColor,
356    CSSPropertyStopColor,
357    CSSPropertyStopOpacity,
358    CSSPropertyColorInterpolation,
359    CSSPropertyColorInterpolationFilters,
360    CSSPropertyColorRendering,
361    CSSPropertyFill,
362    CSSPropertyFillOpacity,
363    CSSPropertyFillRule,
364    CSSPropertyMarkerEnd,
365    CSSPropertyMarkerMid,
366    CSSPropertyMarkerStart,
367    CSSPropertyMaskType,
368    CSSPropertyMaskSourceType,
369    CSSPropertyShapeRendering,
370    CSSPropertyStroke,
371    CSSPropertyStrokeDasharray,
372    CSSPropertyStrokeDashoffset,
373    CSSPropertyStrokeLinecap,
374    CSSPropertyStrokeLinejoin,
375    CSSPropertyStrokeMiterlimit,
376    CSSPropertyStrokeOpacity,
377    CSSPropertyStrokeWidth,
378    CSSPropertyAlignmentBaseline,
379    CSSPropertyBaselineShift,
380    CSSPropertyDominantBaseline,
381    CSSPropertyKerning,
382    CSSPropertyTextAnchor,
383    CSSPropertyWritingMode,
384    CSSPropertyGlyphOrientationHorizontal,
385    CSSPropertyGlyphOrientationVertical,
386    CSSPropertyVectorEffect,
387    CSSPropertyPaintOrder
388};
389
390static const Vector<CSSPropertyID>& computableProperties()
391{
392    DEFINE_STATIC_LOCAL(Vector<CSSPropertyID>, properties, ());
393    if (properties.isEmpty())
394        RuntimeCSSEnabled::filterEnabledCSSPropertiesIntoVector(staticComputableProperties, WTF_ARRAY_LENGTH(staticComputableProperties), properties);
395    return properties;
396}
397
398static CSSValueID valueForRepeatRule(int rule)
399{
400    switch (rule) {
401        case RepeatImageRule:
402            return CSSValueRepeat;
403        case RoundImageRule:
404            return CSSValueRound;
405        case SpaceImageRule:
406            return CSSValueSpace;
407        default:
408            return CSSValueStretch;
409    }
410}
411
412static PassRefPtr<CSSBorderImageSliceValue> valueForNinePieceImageSlice(const NinePieceImage& image)
413{
414    // Create the slices.
415    RefPtr<CSSPrimitiveValue> top;
416    RefPtr<CSSPrimitiveValue> right;
417    RefPtr<CSSPrimitiveValue> bottom;
418    RefPtr<CSSPrimitiveValue> left;
419
420    if (image.imageSlices().top().isPercent())
421        top = cssValuePool().createValue(image.imageSlices().top().value(), CSSPrimitiveValue::CSS_PERCENTAGE);
422    else
423        top = cssValuePool().createValue(image.imageSlices().top().value(), CSSPrimitiveValue::CSS_NUMBER);
424
425    if (image.imageSlices().right() == image.imageSlices().top() && image.imageSlices().bottom() == image.imageSlices().top()
426        && image.imageSlices().left() == image.imageSlices().top()) {
427        right = top;
428        bottom = top;
429        left = top;
430    } else {
431        if (image.imageSlices().right().isPercent())
432            right = cssValuePool().createValue(image.imageSlices().right().value(), CSSPrimitiveValue::CSS_PERCENTAGE);
433        else
434            right = cssValuePool().createValue(image.imageSlices().right().value(), CSSPrimitiveValue::CSS_NUMBER);
435
436        if (image.imageSlices().bottom() == image.imageSlices().top() && image.imageSlices().right() == image.imageSlices().left()) {
437            bottom = top;
438            left = right;
439        } else {
440            if (image.imageSlices().bottom().isPercent())
441                bottom = cssValuePool().createValue(image.imageSlices().bottom().value(), CSSPrimitiveValue::CSS_PERCENTAGE);
442            else
443                bottom = cssValuePool().createValue(image.imageSlices().bottom().value(), CSSPrimitiveValue::CSS_NUMBER);
444
445            if (image.imageSlices().left() == image.imageSlices().right())
446                left = right;
447            else {
448                if (image.imageSlices().left().isPercent())
449                    left = cssValuePool().createValue(image.imageSlices().left().value(), CSSPrimitiveValue::CSS_PERCENTAGE);
450                else
451                    left = cssValuePool().createValue(image.imageSlices().left().value(), CSSPrimitiveValue::CSS_NUMBER);
452            }
453        }
454    }
455
456    RefPtr<Quad> quad = Quad::create();
457    quad->setTop(top);
458    quad->setRight(right);
459    quad->setBottom(bottom);
460    quad->setLeft(left);
461
462    return CSSBorderImageSliceValue::create(cssValuePool().createValue(quad.release()), image.fill());
463}
464
465static PassRefPtr<CSSPrimitiveValue> valueForNinePieceImageQuad(const BorderImageLengthBox& box, const RenderStyle& style)
466{
467    // Create the slices.
468    RefPtr<CSSPrimitiveValue> top;
469    RefPtr<CSSPrimitiveValue> right;
470    RefPtr<CSSPrimitiveValue> bottom;
471    RefPtr<CSSPrimitiveValue> left;
472
473    if (box.top().isNumber())
474        top = cssValuePool().createValue(box.top().number(), CSSPrimitiveValue::CSS_NUMBER);
475    else
476        top = cssValuePool().createValue(box.top().length(), style);
477
478    if (box.right() == box.top() && box.bottom() == box.top() && box.left() == box.top()) {
479        right = top;
480        bottom = top;
481        left = top;
482    } else {
483        if (box.right().isNumber())
484            right = cssValuePool().createValue(box.right().number(), CSSPrimitiveValue::CSS_NUMBER);
485        else
486            right = cssValuePool().createValue(box.right().length(), style);
487
488        if (box.bottom() == box.top() && box.right() == box.left()) {
489            bottom = top;
490            left = right;
491        } else {
492            if (box.bottom().isNumber())
493                bottom = cssValuePool().createValue(box.bottom().number(), CSSPrimitiveValue::CSS_NUMBER);
494            else
495                bottom = cssValuePool().createValue(box.bottom().length(), style);
496
497            if (box.left() == box.right())
498                left = right;
499            else {
500                if (box.left().isNumber())
501                    left = cssValuePool().createValue(box.left().number(), CSSPrimitiveValue::CSS_NUMBER);
502                else
503                    left = cssValuePool().createValue(box.left().length(), style);
504            }
505        }
506    }
507
508    RefPtr<Quad> quad = Quad::create();
509    quad->setTop(top);
510    quad->setRight(right);
511    quad->setBottom(bottom);
512    quad->setLeft(left);
513
514    return cssValuePool().createValue(quad.release());
515}
516
517static PassRefPtr<CSSValue> valueForNinePieceImageRepeat(const NinePieceImage& image)
518{
519    RefPtr<CSSPrimitiveValue> horizontalRepeat;
520    RefPtr<CSSPrimitiveValue> verticalRepeat;
521
522    horizontalRepeat = cssValuePool().createIdentifierValue(valueForRepeatRule(image.horizontalRule()));
523    if (image.horizontalRule() == image.verticalRule())
524        verticalRepeat = horizontalRepeat;
525    else
526        verticalRepeat = cssValuePool().createIdentifierValue(valueForRepeatRule(image.verticalRule()));
527    return cssValuePool().createValue(Pair::create(horizontalRepeat.release(), verticalRepeat.release(), Pair::DropIdenticalValues));
528}
529
530static PassRefPtr<CSSValue> valueForNinePieceImage(const NinePieceImage& image, const RenderStyle& style)
531{
532    if (!image.hasImage())
533        return cssValuePool().createIdentifierValue(CSSValueNone);
534
535    // Image first.
536    RefPtr<CSSValue> imageValue;
537    if (image.image())
538        imageValue = image.image()->cssValue();
539
540    // Create the image slice.
541    RefPtr<CSSBorderImageSliceValue> imageSlices = valueForNinePieceImageSlice(image);
542
543    // Create the border area slices.
544    RefPtr<CSSValue> borderSlices = valueForNinePieceImageQuad(image.borderSlices(), style);
545
546    // Create the border outset.
547    RefPtr<CSSValue> outset = valueForNinePieceImageQuad(image.outset(), style);
548
549    // Create the repeat rules.
550    RefPtr<CSSValue> repeat = valueForNinePieceImageRepeat(image);
551
552    return createBorderImageValue(imageValue.release(), imageSlices.release(), borderSlices.release(), outset.release(), repeat.release());
553}
554
555inline static PassRefPtr<CSSPrimitiveValue> zoomAdjustedPixelValue(double value, const RenderStyle& style)
556{
557    return cssValuePool().createValue(adjustFloatForAbsoluteZoom(value, style), CSSPrimitiveValue::CSS_PX);
558}
559
560inline static PassRefPtr<CSSPrimitiveValue> zoomAdjustedNumberValue(double value, const RenderStyle& style)
561{
562    return cssValuePool().createValue(value / style.effectiveZoom(), CSSPrimitiveValue::CSS_NUMBER);
563}
564
565static PassRefPtr<CSSPrimitiveValue> zoomAdjustedPixelValueForLength(const Length& length, const RenderStyle& style)
566{
567    if (length.isFixed())
568        return zoomAdjustedPixelValue(length.value(), style);
569    return cssValuePool().createValue(length, style);
570}
571
572static PassRefPtr<CSSValue> valueForReflection(const StyleReflection* reflection, const RenderStyle& style)
573{
574    if (!reflection)
575        return cssValuePool().createIdentifierValue(CSSValueNone);
576
577    RefPtr<CSSPrimitiveValue> offset;
578    if (reflection->offset().isPercent())
579        offset = cssValuePool().createValue(reflection->offset().percent(), CSSPrimitiveValue::CSS_PERCENTAGE);
580    else
581        offset = zoomAdjustedPixelValue(reflection->offset().value(), style);
582
583    RefPtr<CSSPrimitiveValue> direction;
584    switch (reflection->direction()) {
585    case ReflectionBelow:
586        direction = cssValuePool().createIdentifierValue(CSSValueBelow);
587        break;
588    case ReflectionAbove:
589        direction = cssValuePool().createIdentifierValue(CSSValueAbove);
590        break;
591    case ReflectionLeft:
592        direction = cssValuePool().createIdentifierValue(CSSValueLeft);
593        break;
594    case ReflectionRight:
595        direction = cssValuePool().createIdentifierValue(CSSValueRight);
596        break;
597    }
598
599    return CSSReflectValue::create(direction.release(), offset.release(), valueForNinePieceImage(reflection->mask(), style));
600}
601
602static PassRefPtr<CSSValueList> createPositionListForLayer(CSSPropertyID propertyID, const FillLayer* layer, const RenderStyle& style)
603{
604    RefPtr<CSSValueList> positionList = CSSValueList::createSpaceSeparated();
605    if (layer->isBackgroundXOriginSet()) {
606        ASSERT_UNUSED(propertyID, propertyID == CSSPropertyBackgroundPosition || propertyID == CSSPropertyWebkitMaskPosition);
607        positionList->append(cssValuePool().createValue(layer->backgroundXOrigin()));
608    }
609    positionList->append(zoomAdjustedPixelValueForLength(layer->xPosition(), style));
610    if (layer->isBackgroundYOriginSet()) {
611        ASSERT(propertyID == CSSPropertyBackgroundPosition || propertyID == CSSPropertyWebkitMaskPosition);
612        positionList->append(cssValuePool().createValue(layer->backgroundYOrigin()));
613    }
614    positionList->append(zoomAdjustedPixelValueForLength(layer->yPosition(), style));
615    return positionList.release();
616}
617
618static PassRefPtr<CSSValue> valueForPositionOffset(RenderStyle& style, CSSPropertyID propertyID, const RenderObject* renderer, RenderView* renderView)
619{
620    Length l;
621    switch (propertyID) {
622        case CSSPropertyLeft:
623            l = style.left();
624            break;
625        case CSSPropertyRight:
626            l = style.right();
627            break;
628        case CSSPropertyTop:
629            l = style.top();
630            break;
631        case CSSPropertyBottom:
632            l = style.bottom();
633            break;
634        default:
635            return 0;
636    }
637
638    if (l.isPercent() && renderer && renderer->isBox()) {
639        LayoutUnit containingBlockSize = (propertyID == CSSPropertyLeft || propertyID == CSSPropertyRight) ?
640            toRenderBox(renderer)->containingBlockLogicalWidthForContent() :
641            toRenderBox(renderer)->containingBlockLogicalHeightForContent(ExcludeMarginBorderPadding);
642        return zoomAdjustedPixelValue(valueForLength(l, containingBlockSize, 0), style);
643    }
644    if (l.isViewportPercentage())
645        return zoomAdjustedPixelValue(valueForLength(l, 0, renderView), style);
646    if (l.isAuto()) {
647        // FIXME: It's not enough to simply return "auto" values for one offset if the other side is defined.
648        // In other words if left is auto and right is not auto, then left's computed value is negative right().
649        // So we should get the opposite length unit and see if it is auto.
650        return cssValuePool().createValue(l);
651    }
652
653    return zoomAdjustedPixelValueForLength(l, style);
654}
655
656PassRefPtr<CSSPrimitiveValue> CSSComputedStyleDeclaration::currentColorOrValidColor(const RenderStyle& style, const Color& color) const
657{
658    // This function does NOT look at visited information, so that computed style doesn't expose that.
659    if (!color.isValid())
660        return cssValuePool().createColorValue(style.color().rgb());
661    return cssValuePool().createColorValue(color.rgb());
662}
663
664static PassRefPtr<CSSValueList> valuesForBorderRadiusCorner(LengthSize radius, const RenderStyle& style)
665{
666    RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
667    if (radius.width().type() == Percent)
668        list->append(cssValuePool().createValue(radius.width().percent(), CSSPrimitiveValue::CSS_PERCENTAGE));
669    else
670        list->append(zoomAdjustedPixelValueForLength(radius.width(), style));
671    if (radius.height().type() == Percent)
672        list->append(cssValuePool().createValue(radius.height().percent(), CSSPrimitiveValue::CSS_PERCENTAGE));
673    else
674        list->append(zoomAdjustedPixelValueForLength(radius.height(), style));
675    return list.release();
676}
677
678static PassRefPtr<CSSValue> valueForBorderRadiusCorner(LengthSize radius, const RenderStyle& style)
679{
680    RefPtr<CSSValueList> list = valuesForBorderRadiusCorner(radius, style);
681    if (list->item(0)->equals(*list->item(1)))
682        return list->item(0);
683    return list.release();
684}
685
686static PassRefPtr<CSSValueList> valueForBorderRadiusShorthand(const RenderStyle& style)
687{
688    RefPtr<CSSValueList> list = CSSValueList::createSlashSeparated();
689
690    bool showHorizontalBottomLeft = style.borderTopRightRadius().width() != style.borderBottomLeftRadius().width();
691    bool showHorizontalBottomRight = showHorizontalBottomLeft || (style.borderBottomRightRadius().width() != style.borderTopLeftRadius().width());
692    bool showHorizontalTopRight = showHorizontalBottomRight || (style.borderTopRightRadius().width() != style.borderTopLeftRadius().width());
693
694    bool showVerticalBottomLeft = style.borderTopRightRadius().height() != style.borderBottomLeftRadius().height();
695    bool showVerticalBottomRight = showVerticalBottomLeft || (style.borderBottomRightRadius().height() != style.borderTopLeftRadius().height());
696    bool showVerticalTopRight = showVerticalBottomRight || (style.borderTopRightRadius().height() != style.borderTopLeftRadius().height());
697
698    RefPtr<CSSValueList> topLeftRadius = valuesForBorderRadiusCorner(style.borderTopLeftRadius(), style);
699    RefPtr<CSSValueList> topRightRadius = valuesForBorderRadiusCorner(style.borderTopRightRadius(), style);
700    RefPtr<CSSValueList> bottomRightRadius = valuesForBorderRadiusCorner(style.borderBottomRightRadius(), style);
701    RefPtr<CSSValueList> bottomLeftRadius = valuesForBorderRadiusCorner(style.borderBottomLeftRadius(), style);
702
703    RefPtr<CSSValueList> horizontalRadii = CSSValueList::createSpaceSeparated();
704    horizontalRadii->append(topLeftRadius->item(0));
705    if (showHorizontalTopRight)
706        horizontalRadii->append(topRightRadius->item(0));
707    if (showHorizontalBottomRight)
708        horizontalRadii->append(bottomRightRadius->item(0));
709    if (showHorizontalBottomLeft)
710        horizontalRadii->append(bottomLeftRadius->item(0));
711
712    list->append(horizontalRadii.release());
713
714    RefPtr<CSSValueList> verticalRadii = CSSValueList::createSpaceSeparated();
715    verticalRadii->append(topLeftRadius->item(1));
716    if (showVerticalTopRight)
717        verticalRadii->append(topRightRadius->item(1));
718    if (showVerticalBottomRight)
719        verticalRadii->append(bottomRightRadius->item(1));
720    if (showVerticalBottomLeft)
721        verticalRadii->append(bottomLeftRadius->item(1));
722
723    if (!verticalRadii->equals(*toCSSValueList(list->item(0))))
724        list->append(verticalRadii.release());
725
726    return list.release();
727}
728
729static LayoutRect sizingBox(RenderObject* renderer)
730{
731    if (!renderer->isBox())
732        return LayoutRect();
733
734    RenderBox* box = toRenderBox(renderer);
735    return box->style()->boxSizing() == BORDER_BOX ? box->borderBoxRect() : box->computedCSSContentBoxRect();
736}
737
738static PassRefPtr<CSSTransformValue> valueForMatrixTransform(const TransformationMatrix& transform, const RenderStyle& style)
739{
740    RefPtr<CSSTransformValue> transformValue;
741    if (transform.isAffine()) {
742        transformValue = CSSTransformValue::create(CSSTransformValue::MatrixTransformOperation);
743
744        transformValue->append(cssValuePool().createValue(transform.a(), CSSPrimitiveValue::CSS_NUMBER));
745        transformValue->append(cssValuePool().createValue(transform.b(), CSSPrimitiveValue::CSS_NUMBER));
746        transformValue->append(cssValuePool().createValue(transform.c(), CSSPrimitiveValue::CSS_NUMBER));
747        transformValue->append(cssValuePool().createValue(transform.d(), CSSPrimitiveValue::CSS_NUMBER));
748        transformValue->append(zoomAdjustedNumberValue(transform.e(), style));
749        transformValue->append(zoomAdjustedNumberValue(transform.f(), style));
750    } else {
751        transformValue = CSSTransformValue::create(CSSTransformValue::Matrix3DTransformOperation);
752
753        transformValue->append(cssValuePool().createValue(transform.m11(), CSSPrimitiveValue::CSS_NUMBER));
754        transformValue->append(cssValuePool().createValue(transform.m12(), CSSPrimitiveValue::CSS_NUMBER));
755        transformValue->append(cssValuePool().createValue(transform.m13(), CSSPrimitiveValue::CSS_NUMBER));
756        transformValue->append(cssValuePool().createValue(transform.m14(), CSSPrimitiveValue::CSS_NUMBER));
757
758        transformValue->append(cssValuePool().createValue(transform.m21(), CSSPrimitiveValue::CSS_NUMBER));
759        transformValue->append(cssValuePool().createValue(transform.m22(), CSSPrimitiveValue::CSS_NUMBER));
760        transformValue->append(cssValuePool().createValue(transform.m23(), CSSPrimitiveValue::CSS_NUMBER));
761        transformValue->append(cssValuePool().createValue(transform.m24(), CSSPrimitiveValue::CSS_NUMBER));
762
763        transformValue->append(cssValuePool().createValue(transform.m31(), CSSPrimitiveValue::CSS_NUMBER));
764        transformValue->append(cssValuePool().createValue(transform.m32(), CSSPrimitiveValue::CSS_NUMBER));
765        transformValue->append(cssValuePool().createValue(transform.m33(), CSSPrimitiveValue::CSS_NUMBER));
766        transformValue->append(cssValuePool().createValue(transform.m34(), CSSPrimitiveValue::CSS_NUMBER));
767
768        transformValue->append(zoomAdjustedNumberValue(transform.m41(), style));
769        transformValue->append(zoomAdjustedNumberValue(transform.m42(), style));
770        transformValue->append(zoomAdjustedNumberValue(transform.m43(), style));
771        transformValue->append(cssValuePool().createValue(transform.m44(), CSSPrimitiveValue::CSS_NUMBER));
772    }
773
774    return transformValue.release();
775}
776
777static PassRefPtr<CSSValue> computedTransform(RenderObject* renderer, const RenderStyle& style)
778{
779    if (!renderer || !renderer->hasTransform() || !style.hasTransform())
780        return cssValuePool().createIdentifierValue(CSSValueNone);
781
782    IntRect box;
783    if (renderer->isBox())
784        box = pixelSnappedIntRect(toRenderBox(renderer)->borderBoxRect());
785
786    TransformationMatrix transform;
787    style.applyTransform(transform, box.size(), RenderStyle::ExcludeTransformOrigin);
788
789    // FIXME: Need to print out individual functions (https://bugs.webkit.org/show_bug.cgi?id=23924)
790    RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
791    list->append(valueForMatrixTransform(transform, style));
792
793    return list.release();
794}
795
796static PassRefPtr<CSSValue> valueForCustomFilterArrayParameter(const CustomFilterArrayParameter* arrayParameter)
797{
798    RefPtr<CSSArrayFunctionValue> arrayParameterValue = CSSArrayFunctionValue::create();
799    for (unsigned i = 0, size = arrayParameter->size(); i < size; ++i)
800        arrayParameterValue->append(cssValuePool().createValue(arrayParameter->valueAt(i), CSSPrimitiveValue::CSS_NUMBER));
801    return arrayParameterValue.release();
802}
803
804static PassRefPtr<CSSValue> valueForCustomFilterNumberParameter(const CustomFilterNumberParameter* numberParameter)
805{
806    RefPtr<CSSValueList> numberParameterValue = CSSValueList::createSpaceSeparated();
807    for (unsigned i = 0; i < numberParameter->size(); ++i)
808        numberParameterValue->append(cssValuePool().createValue(numberParameter->valueAt(i), CSSPrimitiveValue::CSS_NUMBER));
809    return numberParameterValue.release();
810}
811
812static PassRefPtr<CSSValue> valueForCustomFilterTransformParameter(const RenderObject* renderer, const RenderStyle& style, const CustomFilterTransformParameter* transformParameter)
813{
814    IntSize size;
815    if (renderer && renderer->isBox())
816        size = pixelSnappedIntRect(toRenderBox(renderer)->borderBoxRect()).size();
817
818    TransformationMatrix transform;
819    transformParameter->applyTransform(transform, size);
820    // FIXME: Need to print out individual functions (https://bugs.webkit.org/show_bug.cgi?id=23924)
821    return valueForMatrixTransform(transform, style);
822}
823
824static PassRefPtr<CSSValue> valueForCustomFilterParameter(const RenderObject* renderer, const RenderStyle& style, const CustomFilterParameter* parameter)
825{
826    // FIXME: Add here computed style for the other types: boolean, transform, matrix, texture.
827    ASSERT(parameter);
828    switch (parameter->parameterType()) {
829    case CustomFilterParameter::Array:
830        return valueForCustomFilterArrayParameter(static_cast<const CustomFilterArrayParameter*>(parameter));
831    case CustomFilterParameter::Number:
832        return valueForCustomFilterNumberParameter(static_cast<const CustomFilterNumberParameter*>(parameter));
833    case CustomFilterParameter::Transform:
834        return valueForCustomFilterTransformParameter(renderer, style, static_cast<const CustomFilterTransformParameter*>(parameter));
835    }
836
837    ASSERT_NOT_REACHED();
838    return 0;
839}
840
841PassRefPtr<CSSValue> CSSComputedStyleDeclaration::valueForFilter(const RenderObject* renderer, const RenderStyle& style) const
842{
843    if (style.filter().operations().isEmpty())
844        return cssValuePool().createIdentifierValue(CSSValueNone);
845
846    RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
847
848    RefPtr<CSSFilterValue> filterValue;
849
850    Vector<RefPtr<FilterOperation> >::const_iterator end = style.filter().operations().end();
851    for (Vector<RefPtr<FilterOperation> >::const_iterator it = style.filter().operations().begin(); it != end; ++it) {
852        FilterOperation* filterOperation = (*it).get();
853        switch (filterOperation->type()) {
854        case FilterOperation::REFERENCE:
855            filterValue = CSSFilterValue::create(CSSFilterValue::ReferenceFilterOperation);
856            filterValue->append(cssValuePool().createValue(toReferenceFilterOperation(filterOperation)->url(), CSSPrimitiveValue::CSS_STRING));
857            break;
858        case FilterOperation::GRAYSCALE:
859            filterValue = CSSFilterValue::create(CSSFilterValue::GrayscaleFilterOperation);
860            filterValue->append(cssValuePool().createValue(toBasicColorMatrixFilterOperation(filterOperation)->amount(), CSSPrimitiveValue::CSS_NUMBER));
861            break;
862        case FilterOperation::SEPIA:
863            filterValue = CSSFilterValue::create(CSSFilterValue::SepiaFilterOperation);
864            filterValue->append(cssValuePool().createValue(toBasicColorMatrixFilterOperation(filterOperation)->amount(), CSSPrimitiveValue::CSS_NUMBER));
865            break;
866        case FilterOperation::SATURATE:
867            filterValue = CSSFilterValue::create(CSSFilterValue::SaturateFilterOperation);
868            filterValue->append(cssValuePool().createValue(toBasicColorMatrixFilterOperation(filterOperation)->amount(), CSSPrimitiveValue::CSS_NUMBER));
869            break;
870        case FilterOperation::HUE_ROTATE:
871            filterValue = CSSFilterValue::create(CSSFilterValue::HueRotateFilterOperation);
872            filterValue->append(cssValuePool().createValue(toBasicColorMatrixFilterOperation(filterOperation)->amount(), CSSPrimitiveValue::CSS_DEG));
873            break;
874        case FilterOperation::INVERT:
875            filterValue = CSSFilterValue::create(CSSFilterValue::InvertFilterOperation);
876            filterValue->append(cssValuePool().createValue(toBasicComponentTransferFilterOperation(filterOperation)->amount(), CSSPrimitiveValue::CSS_NUMBER));
877            break;
878        case FilterOperation::OPACITY:
879            filterValue = CSSFilterValue::create(CSSFilterValue::OpacityFilterOperation);
880            filterValue->append(cssValuePool().createValue(toBasicComponentTransferFilterOperation(filterOperation)->amount(), CSSPrimitiveValue::CSS_NUMBER));
881            break;
882        case FilterOperation::BRIGHTNESS:
883            filterValue = CSSFilterValue::create(CSSFilterValue::BrightnessFilterOperation);
884            filterValue->append(cssValuePool().createValue(toBasicComponentTransferFilterOperation(filterOperation)->amount(), CSSPrimitiveValue::CSS_NUMBER));
885            break;
886        case FilterOperation::CONTRAST:
887            filterValue = CSSFilterValue::create(CSSFilterValue::ContrastFilterOperation);
888            filterValue->append(cssValuePool().createValue(toBasicComponentTransferFilterOperation(filterOperation)->amount(), CSSPrimitiveValue::CSS_NUMBER));
889            break;
890        case FilterOperation::BLUR:
891            filterValue = CSSFilterValue::create(CSSFilterValue::BlurFilterOperation);
892            filterValue->append(zoomAdjustedPixelValue(toBlurFilterOperation(filterOperation)->stdDeviation().value(), style));
893            break;
894        case FilterOperation::DROP_SHADOW: {
895            DropShadowFilterOperation* dropShadowOperation = toDropShadowFilterOperation(filterOperation);
896            filterValue = CSSFilterValue::create(CSSFilterValue::DropShadowFilterOperation);
897            // We want our computed style to look like that of a text shadow (has neither spread nor inset style).
898            ShadowData shadow(dropShadowOperation->location(), dropShadowOperation->stdDeviation(), 0, Normal, dropShadowOperation->color());
899            filterValue->append(valueForShadowData(shadow, style, false));
900            break;
901        }
902        case FilterOperation::VALIDATED_CUSTOM:
903            // ValidatedCustomFilterOperation is not supposed to end up in the RenderStyle.
904            ASSERT_NOT_REACHED();
905            break;
906        case FilterOperation::CUSTOM: {
907            CustomFilterOperation* customOperation = toCustomFilterOperation(filterOperation);
908            filterValue = CSSFilterValue::create(CSSFilterValue::CustomFilterOperation);
909
910            // The output should be verbose, even if the values are the default ones.
911
912            ASSERT(customOperation->program());
913            StyleCustomFilterProgram* program = static_cast<StyleCustomFilterProgram*>(customOperation->program());
914
915            RefPtr<CSSValueList> shadersList = CSSValueList::createSpaceSeparated();
916            if (program->vertexShader())
917                shadersList->append(program->vertexShader()->cssValue());
918            else
919                shadersList->append(cssValuePool().createIdentifierValue(CSSValueNone));
920
921            const CustomFilterProgramMixSettings mixSettings = program->mixSettings();
922            if (program->fragmentShader()) {
923                if (program->programType() == ProgramTypeBlendsElementTexture) {
924                    RefPtr<CSSMixFunctionValue> mixFunction = CSSMixFunctionValue::create();
925                    mixFunction->append(program->fragmentShader()->cssValue());
926                    mixFunction->append(cssValuePool().createValue(mixSettings.blendMode));
927                    mixFunction->append(cssValuePool().createValue(mixSettings.compositeOperator));
928                    shadersList->append(mixFunction.release());
929                } else
930                    shadersList->append(program->fragmentShader()->cssValue());
931            }
932            else
933                shadersList->append(cssValuePool().createIdentifierValue(CSSValueNone));
934
935            filterValue->append(shadersList.release());
936
937            RefPtr<CSSValueList> meshParameters = CSSValueList::createSpaceSeparated();
938            meshParameters->append(cssValuePool().createValue(customOperation->meshColumns(), CSSPrimitiveValue::CSS_NUMBER));
939            meshParameters->append(cssValuePool().createValue(customOperation->meshRows(), CSSPrimitiveValue::CSS_NUMBER));
940
941            // FIXME: The specification doesn't have any "attached" identifier. Should we add one?
942            // https://bugs.webkit.org/show_bug.cgi?id=72700
943            if (customOperation->meshType() == MeshTypeDetached)
944                meshParameters->append(cssValuePool().createIdentifierValue(CSSValueDetached));
945
946            filterValue->append(meshParameters.release());
947
948            const CustomFilterParameterList& parameters = customOperation->parameters();
949            size_t parametersSize = parameters.size();
950            if (!parametersSize)
951                break;
952            RefPtr<CSSValueList> parametersCSSValue = CSSValueList::createCommaSeparated();
953            for (size_t i = 0; i < parametersSize; ++i) {
954                const CustomFilterParameter* parameter = parameters.at(i).get();
955                RefPtr<CSSValueList> parameterCSSNameAndValue = CSSValueList::createSpaceSeparated();
956                parameterCSSNameAndValue->append(cssValuePool().createValue(parameter->name(), CSSPrimitiveValue::CSS_STRING));
957                parameterCSSNameAndValue->append(valueForCustomFilterParameter(renderer, style, parameter));
958                parametersCSSValue->append(parameterCSSNameAndValue.release());
959            }
960
961            filterValue->append(parametersCSSValue.release());
962            break;
963        }
964        default:
965            filterValue = CSSFilterValue::create(CSSFilterValue::UnknownFilterOperation);
966            break;
967        }
968        list->append(filterValue.release());
969    }
970
971    return list.release();
972}
973
974static PassRefPtr<CSSValue> specifiedValueForGridTrackBreadth(const GridLength& trackBreadth, const RenderStyle& style, RenderView* renderView)
975{
976    if (!trackBreadth.isLength())
977        return cssValuePool().createValue(trackBreadth.flex(), CSSPrimitiveValue::CSS_FR);
978
979    const Length& trackBreadthLength = trackBreadth.length();
980    if (trackBreadthLength.isAuto())
981        return cssValuePool().createIdentifierValue(CSSValueAuto);
982    if (trackBreadthLength.isViewportPercentage())
983        return zoomAdjustedPixelValue(valueForLength(trackBreadthLength, 0, renderView), style);
984    return zoomAdjustedPixelValueForLength(trackBreadthLength, style);
985}
986
987static PassRefPtr<CSSValue> specifiedValueForGridTrackSize(const GridTrackSize& trackSize, const RenderStyle& style, RenderView* renderView)
988{
989    switch (trackSize.type()) {
990    case LengthTrackSizing:
991        return specifiedValueForGridTrackBreadth(trackSize.length(), style, renderView);
992    case MinMaxTrackSizing:
993        RefPtr<CSSValueList> minMaxTrackBreadths = CSSValueList::createCommaSeparated();
994        minMaxTrackBreadths->append(specifiedValueForGridTrackBreadth(trackSize.minTrackBreadth(), style, renderView));
995        minMaxTrackBreadths->append(specifiedValueForGridTrackBreadth(trackSize.maxTrackBreadth(), style, renderView));
996        return CSSFunctionValue::create("minmax(", minMaxTrackBreadths);
997    }
998    ASSERT_NOT_REACHED();
999    return 0;
1000}
1001
1002static void addValuesForNamedGridLinesAtIndex(const OrderedNamedGridLines& orderedNamedGridLines, size_t i, CSSValueList& list)
1003{
1004    const Vector<String>& namedGridLines = orderedNamedGridLines.get(i);
1005    if (namedGridLines.isEmpty())
1006        return;
1007
1008    RefPtr<CSSGridLineNamesValue> lineNames = CSSGridLineNamesValue::create();
1009    for (size_t j = 0; j < namedGridLines.size(); ++j)
1010        lineNames->append(cssValuePool().createValue(namedGridLines[j], CSSPrimitiveValue::CSS_STRING));
1011    list.append(lineNames.release());
1012}
1013
1014static PassRefPtr<CSSValue> valueForGridTrackList(GridTrackSizingDirection direction, RenderObject* renderer, const RenderStyle& style, RenderView* renderView)
1015{
1016    const Vector<GridTrackSize>& trackSizes = direction == ForColumns ? style.gridDefinitionColumns() : style.gridDefinitionRows();
1017    const OrderedNamedGridLines& orderedNamedGridLines = direction == ForColumns ? style.orderedNamedGridColumnLines() : style.orderedNamedGridRowLines();
1018
1019    // Handle the 'none' case here.
1020    if (!trackSizes.size()) {
1021        ASSERT(orderedNamedGridLines.isEmpty());
1022        return cssValuePool().createIdentifierValue(CSSValueNone);
1023    }
1024
1025    RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
1026    if (renderer && renderer->isRenderGrid()) {
1027        const Vector<LayoutUnit>& trackPositions = direction == ForColumns ? toRenderGrid(renderer)->columnPositions() : toRenderGrid(renderer)->rowPositions();
1028        // There are at least #tracks + 1 grid lines (trackPositions). Apart from that, the grid container can generate implicit grid tracks,
1029        // so we'll have more trackPositions than trackSizes as the latter only contain the explicit grid.
1030        ASSERT(trackPositions.size() - 1 >= trackSizes.size());
1031
1032        for (size_t i = 0; i < trackSizes.size(); ++i) {
1033            addValuesForNamedGridLinesAtIndex(orderedNamedGridLines, i, *list);
1034            list->append(zoomAdjustedPixelValue(trackPositions[i + 1] - trackPositions[i], style));
1035        }
1036    } else {
1037        for (size_t i = 0; i < trackSizes.size(); ++i) {
1038            addValuesForNamedGridLinesAtIndex(orderedNamedGridLines, i, *list);
1039            list->append(specifiedValueForGridTrackSize(trackSizes[i], style, renderView));
1040        }
1041    }
1042    // Those are the trailing <string>* allowed in the syntax.
1043    addValuesForNamedGridLinesAtIndex(orderedNamedGridLines, trackSizes.size(), *list);
1044    return list.release();
1045}
1046
1047static PassRefPtr<CSSValue> valueForGridPosition(const GridPosition& position)
1048{
1049    if (position.isAuto())
1050        return cssValuePool().createIdentifierValue(CSSValueAuto);
1051
1052    if (position.isNamedGridArea())
1053        return cssValuePool().createValue(position.namedGridLine(), CSSPrimitiveValue::CSS_STRING);
1054
1055    RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
1056    if (position.isSpan()) {
1057        list->append(cssValuePool().createIdentifierValue(CSSValueSpan));
1058        list->append(cssValuePool().createValue(position.spanPosition(), CSSPrimitiveValue::CSS_NUMBER));
1059    } else
1060        list->append(cssValuePool().createValue(position.integerPosition(), CSSPrimitiveValue::CSS_NUMBER));
1061
1062    if (!position.namedGridLine().isNull())
1063        list->append(cssValuePool().createValue(position.namedGridLine(), CSSPrimitiveValue::CSS_STRING));
1064    return list;
1065}
1066static PassRefPtr<CSSValue> createTransitionPropertyValue(const CSSAnimationData* animation)
1067{
1068    RefPtr<CSSValue> propertyValue;
1069    if (animation->animationMode() == CSSAnimationData::AnimateNone)
1070        propertyValue = cssValuePool().createIdentifierValue(CSSValueNone);
1071    else if (animation->animationMode() == CSSAnimationData::AnimateAll)
1072        propertyValue = cssValuePool().createIdentifierValue(CSSValueAll);
1073    else
1074        propertyValue = cssValuePool().createValue(getPropertyNameString(animation->property()), CSSPrimitiveValue::CSS_STRING);
1075    return propertyValue.release();
1076}
1077static PassRefPtr<CSSValue> valueForTransitionProperty(const CSSAnimationDataList* animList)
1078{
1079    RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1080    if (animList) {
1081        for (size_t i = 0; i < animList->size(); ++i)
1082            list->append(createTransitionPropertyValue(animList->animation(i)));
1083    } else
1084        list->append(cssValuePool().createIdentifierValue(CSSValueAll));
1085    return list.release();
1086}
1087
1088static PassRefPtr<CSSValue> valueForAnimationDelay(const CSSAnimationDataList* animList)
1089{
1090    RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1091    if (animList) {
1092        for (size_t i = 0; i < animList->size(); ++i)
1093            list->append(cssValuePool().createValue(animList->animation(i)->delay(), CSSPrimitiveValue::CSS_S));
1094    } else {
1095        // Note that initialAnimationDelay() is used for both transitions and animations
1096        list->append(cssValuePool().createValue(CSSAnimationData::initialAnimationDelay(), CSSPrimitiveValue::CSS_S));
1097    }
1098    return list.release();
1099}
1100
1101static PassRefPtr<CSSValue> valueForAnimationDuration(const CSSAnimationDataList* animList)
1102{
1103    RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1104    if (animList) {
1105        for (size_t i = 0; i < animList->size(); ++i)
1106            list->append(cssValuePool().createValue(animList->animation(i)->duration(), CSSPrimitiveValue::CSS_S));
1107    } else {
1108        // Note that initialAnimationDuration() is used for both transitions and animations
1109        list->append(cssValuePool().createValue(CSSAnimationData::initialAnimationDuration(), CSSPrimitiveValue::CSS_S));
1110    }
1111    return list.release();
1112}
1113
1114static PassRefPtr<CSSValue> createTimingFunctionValue(const TimingFunction* timingFunction)
1115{
1116    switch (timingFunction->type()) {
1117    case TimingFunction::CubicBezierFunction:
1118        {
1119            const CubicBezierTimingFunction* bezierTimingFunction = toCubicBezierTimingFunction(timingFunction);
1120            if (bezierTimingFunction->subType() != CubicBezierTimingFunction::Custom) {
1121                CSSValueID valueId = CSSValueInvalid;
1122                switch (bezierTimingFunction->subType()) {
1123                case CubicBezierTimingFunction::Ease:
1124                    valueId = CSSValueEase;
1125                    break;
1126                case CubicBezierTimingFunction::EaseIn:
1127                    valueId = CSSValueEaseIn;
1128                    break;
1129                case CubicBezierTimingFunction::EaseOut:
1130                    valueId = CSSValueEaseOut;
1131                    break;
1132                case CubicBezierTimingFunction::EaseInOut:
1133                    valueId = CSSValueEaseInOut;
1134                    break;
1135                default:
1136                    ASSERT_NOT_REACHED();
1137                    return 0;
1138                }
1139                return cssValuePool().createIdentifierValue(valueId);
1140            }
1141            return CSSCubicBezierTimingFunctionValue::create(bezierTimingFunction->x1(), bezierTimingFunction->y1(), bezierTimingFunction->x2(), bezierTimingFunction->y2());
1142        }
1143
1144    case TimingFunction::StepsFunction:
1145        {
1146            const StepsTimingFunction* stepsTimingFunction = toStepsTimingFunction(timingFunction);
1147            if (stepsTimingFunction->subType() == StepsTimingFunction::Custom)
1148                return CSSStepsTimingFunctionValue::create(stepsTimingFunction->numberOfSteps(), stepsTimingFunction->stepAtStart());
1149            CSSValueID valueId;
1150            switch (stepsTimingFunction->subType()) {
1151            case StepsTimingFunction::Start:
1152                valueId = CSSValueStepStart;
1153                break;
1154            case StepsTimingFunction::End:
1155                valueId = CSSValueStepEnd;
1156                break;
1157            default:
1158                ASSERT_NOT_REACHED();
1159                return 0;
1160            }
1161            return cssValuePool().createIdentifierValue(valueId);
1162        }
1163
1164    default:
1165        return cssValuePool().createIdentifierValue(CSSValueLinear);
1166    }
1167}
1168
1169static PassRefPtr<CSSValue> valueForAnimationTimingFunction(const CSSAnimationDataList* animList)
1170{
1171    RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1172    if (animList) {
1173        for (size_t i = 0; i < animList->size(); ++i)
1174            list->append(createTimingFunctionValue(animList->animation(i)->timingFunction()));
1175    } else
1176        // Note that initialAnimationTimingFunction() is used for both transitions and animations
1177        list->append(createTimingFunctionValue(CSSAnimationData::initialAnimationTimingFunction().get()));
1178    return list.release();
1179}
1180
1181static PassRefPtr<CSSValue> valueForAnimationFillMode(unsigned fillMode)
1182{
1183    switch (fillMode) {
1184    case AnimationFillModeNone:
1185        return cssValuePool().createIdentifierValue(CSSValueNone);
1186    case AnimationFillModeForwards:
1187        return cssValuePool().createIdentifierValue(CSSValueForwards);
1188    case AnimationFillModeBackwards:
1189        return cssValuePool().createIdentifierValue(CSSValueBackwards);
1190    case AnimationFillModeBoth:
1191        return cssValuePool().createIdentifierValue(CSSValueBoth);
1192    default:
1193        ASSERT_NOT_REACHED();
1194        return 0;
1195    }
1196}
1197
1198static PassRefPtr<CSSValue> valueForAnimationDirection(CSSAnimationData::AnimationDirection direction)
1199{
1200    switch (direction) {
1201    case CSSAnimationData::AnimationDirectionNormal:
1202        return cssValuePool().createIdentifierValue(CSSValueNormal);
1203    case CSSAnimationData::AnimationDirectionAlternate:
1204        return cssValuePool().createIdentifierValue(CSSValueAlternate);
1205    case CSSAnimationData::AnimationDirectionReverse:
1206        return cssValuePool().createIdentifierValue(CSSValueReverse);
1207    case CSSAnimationData::AnimationDirectionAlternateReverse:
1208        return cssValuePool().createIdentifierValue(CSSValueAlternateReverse);
1209    default:
1210        ASSERT_NOT_REACHED();
1211        return 0;
1212    }
1213}
1214
1215static PassRefPtr<CSSValue> createLineBoxContainValue(unsigned lineBoxContain)
1216{
1217    if (!lineBoxContain)
1218        return cssValuePool().createIdentifierValue(CSSValueNone);
1219    return CSSLineBoxContainValue::create(lineBoxContain);
1220}
1221
1222CSSComputedStyleDeclaration::CSSComputedStyleDeclaration(PassRefPtr<Node> n, bool allowVisitedStyle, const String& pseudoElementName)
1223    : m_node(n)
1224    , m_allowVisitedStyle(allowVisitedStyle)
1225    , m_refCount(1)
1226{
1227    unsigned nameWithoutColonsStart = pseudoElementName[0] == ':' ? (pseudoElementName[1] == ':' ? 2 : 1) : 0;
1228    m_pseudoElementSpecifier = CSSSelector::pseudoId(CSSSelector::parsePseudoType(
1229        AtomicString(pseudoElementName.substring(nameWithoutColonsStart))));
1230}
1231
1232CSSComputedStyleDeclaration::~CSSComputedStyleDeclaration()
1233{
1234}
1235
1236void CSSComputedStyleDeclaration::ref()
1237{
1238    ++m_refCount;
1239}
1240
1241void CSSComputedStyleDeclaration::deref()
1242{
1243    ASSERT(m_refCount);
1244    if (!--m_refCount)
1245        delete this;
1246}
1247
1248String CSSComputedStyleDeclaration::cssText() const
1249{
1250    StringBuilder result;
1251    const Vector<CSSPropertyID>& properties = computableProperties();
1252
1253    for (unsigned i = 0; i < properties.size(); i++) {
1254        if (i)
1255            result.append(' ');
1256        result.append(getPropertyName(properties[i]));
1257        result.append(": ", 2);
1258        result.append(getPropertyValue(properties[i]));
1259        result.append(';');
1260    }
1261
1262    return result.toString();
1263}
1264
1265void CSSComputedStyleDeclaration::setCSSText(const String&, ExceptionState& exceptionState)
1266{
1267    exceptionState.throwDOMException(NoModificationAllowedError, "These styles are computed, and therefore read-only.");
1268}
1269
1270static CSSValueID cssIdentifierForFontSizeKeyword(int keywordSize)
1271{
1272    ASSERT_ARG(keywordSize, keywordSize);
1273    ASSERT_ARG(keywordSize, keywordSize <= 8);
1274    return static_cast<CSSValueID>(CSSValueXxSmall + keywordSize - 1);
1275}
1276
1277PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getFontSizeCSSValuePreferringKeyword() const
1278{
1279    if (!m_node)
1280        return 0;
1281
1282    m_node->document().updateLayoutIgnorePendingStylesheets();
1283
1284    RefPtr<RenderStyle> style = m_node->computedStyle(m_pseudoElementSpecifier);
1285    if (!style)
1286        return 0;
1287
1288    if (int keywordSize = style->fontDescription().keywordSize())
1289        return cssValuePool().createIdentifierValue(cssIdentifierForFontSizeKeyword(keywordSize));
1290
1291
1292    return zoomAdjustedPixelValue(style->fontDescription().computedPixelSize(), *style);
1293}
1294
1295bool CSSComputedStyleDeclaration::useFixedFontDefaultSize() const
1296{
1297    if (!m_node)
1298        return false;
1299
1300    RefPtr<RenderStyle> style = m_node->computedStyle(m_pseudoElementSpecifier);
1301    if (!style)
1302        return false;
1303
1304    return style->fontDescription().useFixedDefaultSize();
1305}
1306
1307PassRefPtr<CSSValue> CSSComputedStyleDeclaration::valueForShadowData(const ShadowData& shadow, const RenderStyle& style, bool useSpread) const
1308{
1309    RefPtr<CSSPrimitiveValue> x = zoomAdjustedPixelValue(shadow.x(), style);
1310    RefPtr<CSSPrimitiveValue> y = zoomAdjustedPixelValue(shadow.y(), style);
1311    RefPtr<CSSPrimitiveValue> blur = zoomAdjustedPixelValue(shadow.blur(), style);
1312    RefPtr<CSSPrimitiveValue> spread = useSpread ? zoomAdjustedPixelValue(shadow.spread(), style) : PassRefPtr<CSSPrimitiveValue>();
1313    RefPtr<CSSPrimitiveValue> shadowStyle = shadow.style() == Normal ? PassRefPtr<CSSPrimitiveValue>() : cssValuePool().createIdentifierValue(CSSValueInset);
1314    RefPtr<CSSPrimitiveValue> color = currentColorOrValidColor(style, shadow.color());
1315    return CSSShadowValue::create(x.release(), y.release(), blur.release(), spread.release(), shadowStyle.release(), color.release());
1316}
1317
1318PassRefPtr<CSSValue> CSSComputedStyleDeclaration::valueForShadowList(const ShadowList* shadowList, const RenderStyle& style, bool useSpread) const
1319{
1320    if (!shadowList)
1321        return cssValuePool().createIdentifierValue(CSSValueNone);
1322
1323    RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1324    size_t shadowCount = shadowList->shadows().size();
1325    for (size_t i = 0; i < shadowCount; ++i)
1326        list->append(valueForShadowData(shadowList->shadows()[i], style, useSpread));
1327    return list.release();
1328}
1329
1330PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropertyID propertyID) const
1331{
1332    return getPropertyCSSValue(propertyID, UpdateLayout);
1333}
1334
1335static CSSValueID identifierForFamily(const AtomicString& family)
1336{
1337    if (family == FontFamilyNames::webkit_cursive)
1338        return CSSValueCursive;
1339    if (family == FontFamilyNames::webkit_fantasy)
1340        return CSSValueFantasy;
1341    if (family == FontFamilyNames::webkit_monospace)
1342        return CSSValueMonospace;
1343    if (family == FontFamilyNames::webkit_pictograph)
1344        return CSSValueWebkitPictograph;
1345    if (family == FontFamilyNames::webkit_sans_serif)
1346        return CSSValueSansSerif;
1347    if (family == FontFamilyNames::webkit_serif)
1348        return CSSValueSerif;
1349    return CSSValueInvalid;
1350}
1351
1352static PassRefPtr<CSSPrimitiveValue> valueForFamily(const AtomicString& family)
1353{
1354    if (CSSValueID familyIdentifier = identifierForFamily(family))
1355        return cssValuePool().createIdentifierValue(familyIdentifier);
1356    return cssValuePool().createValue(family.string(), CSSPrimitiveValue::CSS_STRING);
1357}
1358
1359static PassRefPtr<CSSValue> renderTextDecorationFlagsToCSSValue(int textDecoration)
1360{
1361    // Blink value is ignored.
1362    RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
1363    if (textDecoration & TextDecorationUnderline)
1364        list->append(cssValuePool().createIdentifierValue(CSSValueUnderline));
1365    if (textDecoration & TextDecorationOverline)
1366        list->append(cssValuePool().createIdentifierValue(CSSValueOverline));
1367    if (textDecoration & TextDecorationLineThrough)
1368        list->append(cssValuePool().createIdentifierValue(CSSValueLineThrough));
1369
1370    if (!list->length())
1371        return cssValuePool().createIdentifierValue(CSSValueNone);
1372    return list.release();
1373}
1374
1375static PassRefPtr<CSSValue> valueForTextDecorationStyle(TextDecorationStyle textDecorationStyle)
1376{
1377    switch (textDecorationStyle) {
1378    case TextDecorationStyleSolid:
1379        return cssValuePool().createIdentifierValue(CSSValueSolid);
1380    case TextDecorationStyleDouble:
1381        return cssValuePool().createIdentifierValue(CSSValueDouble);
1382    case TextDecorationStyleDotted:
1383        return cssValuePool().createIdentifierValue(CSSValueDotted);
1384    case TextDecorationStyleDashed:
1385        return cssValuePool().createIdentifierValue(CSSValueDashed);
1386    case TextDecorationStyleWavy:
1387        return cssValuePool().createIdentifierValue(CSSValueWavy);
1388    }
1389
1390    ASSERT_NOT_REACHED();
1391    return cssValuePool().createExplicitInitialValue();
1392}
1393
1394static PassRefPtr<CSSValue> valueForFillRepeat(EFillRepeat xRepeat, EFillRepeat yRepeat)
1395{
1396    // For backwards compatibility, if both values are equal, just return one of them. And
1397    // if the two values are equivalent to repeat-x or repeat-y, just return the shorthand.
1398    if (xRepeat == yRepeat)
1399        return cssValuePool().createValue(xRepeat);
1400    if (xRepeat == RepeatFill && yRepeat == NoRepeatFill)
1401        return cssValuePool().createIdentifierValue(CSSValueRepeatX);
1402    if (xRepeat == NoRepeatFill && yRepeat == RepeatFill)
1403        return cssValuePool().createIdentifierValue(CSSValueRepeatY);
1404
1405    RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
1406    list->append(cssValuePool().createValue(xRepeat));
1407    list->append(cssValuePool().createValue(yRepeat));
1408    return list.release();
1409}
1410
1411static PassRefPtr<CSSValue> valueForFillSourceType(EMaskSourceType type)
1412{
1413    switch (type) {
1414    case MaskAlpha:
1415        return cssValuePool().createValue(CSSValueAlpha);
1416    case MaskLuminance:
1417        return cssValuePool().createValue(CSSValueLuminance);
1418    }
1419
1420    ASSERT_NOT_REACHED();
1421
1422    return 0;
1423}
1424
1425static PassRefPtr<CSSValue> valueForFillSize(const FillSize& fillSize, const RenderStyle& style)
1426{
1427    if (fillSize.type == Contain)
1428        return cssValuePool().createIdentifierValue(CSSValueContain);
1429
1430    if (fillSize.type == Cover)
1431        return cssValuePool().createIdentifierValue(CSSValueCover);
1432
1433    if (fillSize.size.height().isAuto())
1434        return zoomAdjustedPixelValueForLength(fillSize.size.width(), style);
1435
1436    RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
1437    list->append(zoomAdjustedPixelValueForLength(fillSize.size.width(), style));
1438    list->append(zoomAdjustedPixelValueForLength(fillSize.size.height(), style));
1439    return list.release();
1440}
1441
1442static PassRefPtr<CSSValue> valueForContentData(const RenderStyle& style)
1443{
1444    RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
1445    for (const ContentData* contentData = style.contentData(); contentData; contentData = contentData->next()) {
1446        if (contentData->isCounter()) {
1447            const CounterContent* counter = static_cast<const CounterContentData*>(contentData)->counter();
1448            ASSERT(counter);
1449            list->append(cssValuePool().createValue(counter->identifier(), CSSPrimitiveValue::CSS_COUNTER_NAME));
1450        } else if (contentData->isImage()) {
1451            const StyleImage* image = static_cast<const ImageContentData*>(contentData)->image();
1452            ASSERT(image);
1453            list->append(image->cssValue());
1454        } else if (contentData->isText())
1455            list->append(cssValuePool().createValue(static_cast<const TextContentData*>(contentData)->text(), CSSPrimitiveValue::CSS_STRING));
1456    }
1457    if (style.hasFlowFrom())
1458        list->append(cssValuePool().createValue(style.regionThread(), CSSPrimitiveValue::CSS_STRING));
1459    return list.release();
1460}
1461
1462static PassRefPtr<CSSValue> valueForCounterDirectives(const RenderStyle& style, CSSPropertyID propertyID)
1463{
1464    const CounterDirectiveMap* map = style.counterDirectives();
1465    if (!map)
1466        return 0;
1467
1468    RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
1469    for (CounterDirectiveMap::const_iterator it = map->begin(); it != map->end(); ++it) {
1470        list->append(cssValuePool().createValue(it->key, CSSPrimitiveValue::CSS_STRING));
1471        short number = propertyID == CSSPropertyCounterIncrement ? it->value.incrementValue() : it->value.resetValue();
1472        list->append(cssValuePool().createValue((double)number, CSSPrimitiveValue::CSS_NUMBER));
1473    }
1474    return list.release();
1475}
1476
1477static void logUnimplementedPropertyID(CSSPropertyID propertyID)
1478{
1479    DEFINE_STATIC_LOCAL(HashSet<CSSPropertyID>, propertyIDSet, ());
1480    if (!propertyIDSet.add(propertyID).isNewEntry)
1481        return;
1482
1483    WTF_LOG_ERROR("WebKit does not yet implement getComputedStyle for '%s'.", getPropertyName(propertyID));
1484}
1485
1486static PassRefPtr<CSSValueList> valueForFontFamily(RenderStyle& style)
1487{
1488    const FontFamily& firstFamily = style.fontDescription().family();
1489    RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1490    for (const FontFamily* family = &firstFamily; family; family = family->next())
1491        list->append(valueForFamily(family->family()));
1492    return list.release();
1493}
1494
1495static PassRefPtr<CSSPrimitiveValue> valueForLineHeight(RenderStyle& style, RenderView* renderView)
1496{
1497    Length length = style.lineHeight();
1498    if (length.isNegative())
1499        return cssValuePool().createIdentifierValue(CSSValueNormal);
1500
1501    return zoomAdjustedPixelValue(floatValueForLength(length, style.fontDescription().specifiedSize(), renderView), style);
1502}
1503
1504static PassRefPtr<CSSPrimitiveValue> valueForFontSize(RenderStyle& style)
1505{
1506    return zoomAdjustedPixelValue(style.fontDescription().computedPixelSize(), style);
1507}
1508
1509static PassRefPtr<CSSPrimitiveValue> valueForFontStyle(RenderStyle& style)
1510{
1511    if (style.fontDescription().italic())
1512        return cssValuePool().createIdentifierValue(CSSValueItalic);
1513    return cssValuePool().createIdentifierValue(CSSValueNormal);
1514}
1515
1516static PassRefPtr<CSSPrimitiveValue> valueForFontVariant(RenderStyle& style)
1517{
1518    if (style.fontDescription().smallCaps())
1519        return cssValuePool().createIdentifierValue(CSSValueSmallCaps);
1520    return cssValuePool().createIdentifierValue(CSSValueNormal);
1521}
1522
1523static PassRefPtr<CSSPrimitiveValue> valueForFontWeight(RenderStyle& style)
1524{
1525    switch (style.fontDescription().weight()) {
1526    case FontWeight100:
1527        return cssValuePool().createIdentifierValue(CSSValue100);
1528    case FontWeight200:
1529        return cssValuePool().createIdentifierValue(CSSValue200);
1530    case FontWeight300:
1531        return cssValuePool().createIdentifierValue(CSSValue300);
1532    case FontWeightNormal:
1533        return cssValuePool().createIdentifierValue(CSSValueNormal);
1534    case FontWeight500:
1535        return cssValuePool().createIdentifierValue(CSSValue500);
1536    case FontWeight600:
1537        return cssValuePool().createIdentifierValue(CSSValue600);
1538    case FontWeightBold:
1539        return cssValuePool().createIdentifierValue(CSSValueBold);
1540    case FontWeight800:
1541        return cssValuePool().createIdentifierValue(CSSValue800);
1542    case FontWeight900:
1543        return cssValuePool().createIdentifierValue(CSSValue900);
1544    }
1545    ASSERT_NOT_REACHED();
1546    return cssValuePool().createIdentifierValue(CSSValueNormal);
1547}
1548
1549static PassRefPtr<CSSValue> touchActionFlagsToCSSValue(TouchAction touchAction)
1550{
1551    RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
1552    if (touchAction == TouchActionAuto)
1553        list->append(cssValuePool().createIdentifierValue(CSSValueAuto));
1554    if (touchAction & TouchActionNone) {
1555        ASSERT(touchAction == TouchActionNone);
1556        list->append(cssValuePool().createIdentifierValue(CSSValueNone));
1557    }
1558    if (touchAction & TouchActionPanX)
1559        list->append(cssValuePool().createIdentifierValue(CSSValuePanX));
1560    if (touchAction & TouchActionPanY)
1561        list->append(cssValuePool().createIdentifierValue(CSSValuePanY));
1562
1563    ASSERT(list->length());
1564    return list.release();
1565}
1566
1567static bool isLayoutDependent(CSSPropertyID propertyID, PassRefPtr<RenderStyle> style, RenderObject* renderer)
1568{
1569    // Some properties only depend on layout in certain conditions which
1570    // are specified in the main switch statement below. So we can avoid
1571    // forcing layout in those conditions. The conditions in this switch
1572    // statement must remain in sync with the conditions in the main switch.
1573    // FIXME: Some of these cases could be narrowed down or optimized better.
1574    switch (propertyID) {
1575    case CSSPropertyBottom:
1576    case CSSPropertyGridDefinitionColumns:
1577    case CSSPropertyGridDefinitionRows:
1578    case CSSPropertyHeight:
1579    case CSSPropertyLeft:
1580    case CSSPropertyRight:
1581    case CSSPropertyTop:
1582    case CSSPropertyWebkitPerspectiveOrigin:
1583    case CSSPropertyWebkitTransform:
1584    case CSSPropertyWebkitTransformOrigin:
1585    case CSSPropertyWidth:
1586    case CSSPropertyWebkitFilter:
1587        return true;
1588    case CSSPropertyMargin:
1589        return renderer && renderer->isBox() && (!style || !style->marginBottom().isFixed() || !style->marginTop().isFixed() || !style->marginLeft().isFixed() || !style->marginRight().isFixed());
1590    case CSSPropertyMarginLeft:
1591        return renderer && renderer->isBox() && (!style || !style->marginLeft().isFixed());
1592    case CSSPropertyMarginRight:
1593        return renderer && renderer->isBox() && (!style || !style->marginRight().isFixed());
1594    case CSSPropertyMarginTop:
1595        return renderer && renderer->isBox() && (!style || !style->marginTop().isFixed());
1596    case CSSPropertyMarginBottom:
1597        return renderer && renderer->isBox() && (!style || !style->marginBottom().isFixed());
1598    case CSSPropertyPadding:
1599        return renderer && renderer->isBox() && (!style || !style->paddingBottom().isFixed() || !style->paddingTop().isFixed() || !style->paddingLeft().isFixed() || !style->paddingRight().isFixed());
1600    case CSSPropertyPaddingBottom:
1601        return renderer && renderer->isBox() && (!style || !style->paddingBottom().isFixed());
1602    case CSSPropertyPaddingLeft:
1603        return renderer && renderer->isBox() && (!style || !style->paddingLeft().isFixed());
1604    case CSSPropertyPaddingRight:
1605        return renderer && renderer->isBox() && (!style || !style->paddingRight().isFixed());
1606    case CSSPropertyPaddingTop:
1607        return renderer && renderer->isBox() && (!style || !style->paddingTop().isFixed());
1608    default:
1609        return false;
1610    }
1611}
1612
1613PassRefPtr<RenderStyle> CSSComputedStyleDeclaration::computeRenderStyle(CSSPropertyID propertyID) const
1614{
1615    Node* styledNode = this->styledNode();
1616    ASSERT(styledNode);
1617    RenderObject* renderer = styledNode->renderer();
1618    if (renderer && renderer->compositingState() == PaintsIntoOwnBacking
1619        && !RuntimeEnabledFeatures::webAnimationsCSSEnabled() && AnimationController::supportsAcceleratedAnimationOfProperty(propertyID)) {
1620        AnimationUpdateBlock animationUpdateBlock(renderer->animation());
1621        if (m_pseudoElementSpecifier && !styledNode->isPseudoElement()) {
1622            // FIXME: This cached pseudo style will only exist if the animation has been run at least once.
1623            return renderer->animation().getAnimatedStyleForRenderer(renderer)->getCachedPseudoStyle(m_pseudoElementSpecifier);
1624        }
1625        return renderer->animation().getAnimatedStyleForRenderer(renderer);
1626    }
1627    return styledNode->computedStyle(styledNode->isPseudoElement() ? NOPSEUDO : m_pseudoElementSpecifier);
1628}
1629
1630Node* CSSComputedStyleDeclaration::styledNode() const
1631{
1632    if (!m_node)
1633        return 0;
1634    if (m_node->isElementNode()) {
1635        if (PseudoElement* element = toElement(m_node)->pseudoElement(m_pseudoElementSpecifier))
1636            return element;
1637    }
1638    return m_node.get();
1639}
1640
1641PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropertyID propertyID, EUpdateLayout updateLayout) const
1642{
1643    Node* styledNode = this->styledNode();
1644    if (!styledNode)
1645        return 0;
1646    RenderObject* renderer = styledNode->renderer();
1647    RefPtr<RenderStyle> style;
1648
1649    if (updateLayout) {
1650        Document& document = styledNode->document();
1651
1652        // If a compositor animation is running we may need to service animations
1653        // in order to generate an up to date value.
1654        DocumentAnimations::serviceBeforeGetComputedStyle(*styledNode, propertyID);
1655
1656        document.updateStyleForNodeIfNeeded(styledNode);
1657
1658        // The style recalc could have caused the styled node to be discarded or replaced
1659        // if it was a PseudoElement so we need to update it.
1660        styledNode = this->styledNode();
1661        renderer = styledNode->renderer();
1662
1663        style = computeRenderStyle(propertyID);
1664
1665        bool forceFullLayout = isLayoutDependent(propertyID, style, renderer)
1666            || styledNode->isInShadowTree()
1667            || (document.ownerElement() && document.ensureStyleResolver().hasViewportDependentMediaQueries())
1668            || document.seamlessParentIFrame();
1669
1670        if (forceFullLayout) {
1671            document.updateLayoutIgnorePendingStylesheets();
1672            styledNode = this->styledNode();
1673            style = computeRenderStyle(propertyID);
1674            renderer = styledNode->renderer();
1675        }
1676    } else {
1677        style = computeRenderStyle(propertyID);
1678    }
1679
1680    if (!style)
1681        return 0;
1682
1683    propertyID = CSSProperty::resolveDirectionAwareProperty(propertyID, style->direction(), style->writingMode());
1684
1685    switch (propertyID) {
1686        case CSSPropertyInvalid:
1687        case CSSPropertyVariable:
1688            break;
1689
1690        case CSSPropertyBackgroundColor:
1691            return cssValuePool().createColorValue(m_allowVisitedStyle? style->visitedDependentColor(CSSPropertyBackgroundColor).rgb() : style->backgroundColor().rgb());
1692        case CSSPropertyBackgroundImage:
1693        case CSSPropertyWebkitMaskImage: {
1694            const FillLayer* layers = propertyID == CSSPropertyWebkitMaskImage ? style->maskLayers() : style->backgroundLayers();
1695            if (!layers)
1696                return cssValuePool().createIdentifierValue(CSSValueNone);
1697
1698            if (!layers->next()) {
1699                if (layers->image())
1700                    return layers->image()->cssValue();
1701
1702                return cssValuePool().createIdentifierValue(CSSValueNone);
1703            }
1704
1705            RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1706            for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) {
1707                if (currLayer->image())
1708                    list->append(currLayer->image()->cssValue());
1709                else
1710                    list->append(cssValuePool().createIdentifierValue(CSSValueNone));
1711            }
1712            return list.release();
1713        }
1714        case CSSPropertyBackgroundSize:
1715        case CSSPropertyWebkitBackgroundSize:
1716        case CSSPropertyWebkitMaskSize: {
1717            const FillLayer* layers = propertyID == CSSPropertyWebkitMaskSize ? style->maskLayers() : style->backgroundLayers();
1718            if (!layers->next())
1719                return valueForFillSize(layers->size(), *style);
1720
1721            RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1722            for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
1723                list->append(valueForFillSize(currLayer->size(), *style));
1724
1725            return list.release();
1726        }
1727        case CSSPropertyBackgroundRepeat:
1728        case CSSPropertyWebkitMaskRepeat: {
1729            const FillLayer* layers = propertyID == CSSPropertyWebkitMaskRepeat ? style->maskLayers() : style->backgroundLayers();
1730            if (!layers->next())
1731                return valueForFillRepeat(layers->repeatX(), layers->repeatY());
1732
1733            RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1734            for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
1735                list->append(valueForFillRepeat(currLayer->repeatX(), currLayer->repeatY()));
1736
1737            return list.release();
1738        }
1739        case CSSPropertyMaskSourceType: {
1740            const FillLayer* layers = style->maskLayers();
1741
1742            if (!layers)
1743                return cssValuePool().createIdentifierValue(CSSValueNone);
1744
1745            if (!layers->next())
1746                return valueForFillSourceType(layers->maskSourceType());
1747
1748            RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1749            for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
1750                list->append(valueForFillSourceType(currLayer->maskSourceType()));
1751
1752            return list.release();
1753        }
1754        case CSSPropertyWebkitBackgroundComposite:
1755        case CSSPropertyWebkitMaskComposite: {
1756            const FillLayer* layers = propertyID == CSSPropertyWebkitMaskComposite ? style->maskLayers() : style->backgroundLayers();
1757            if (!layers->next())
1758                return cssValuePool().createValue(layers->composite());
1759
1760            RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1761            for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
1762                list->append(cssValuePool().createValue(currLayer->composite()));
1763
1764            return list.release();
1765        }
1766        case CSSPropertyBackgroundAttachment: {
1767            const FillLayer* layers = style->backgroundLayers();
1768            if (!layers->next())
1769                return cssValuePool().createValue(layers->attachment());
1770
1771            RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1772            for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
1773                list->append(cssValuePool().createValue(currLayer->attachment()));
1774
1775            return list.release();
1776        }
1777        case CSSPropertyBackgroundClip:
1778        case CSSPropertyBackgroundOrigin:
1779        case CSSPropertyWebkitBackgroundClip:
1780        case CSSPropertyWebkitBackgroundOrigin:
1781        case CSSPropertyWebkitMaskClip:
1782        case CSSPropertyWebkitMaskOrigin: {
1783            const FillLayer* layers = (propertyID == CSSPropertyWebkitMaskClip || propertyID == CSSPropertyWebkitMaskOrigin) ? style->maskLayers() : style->backgroundLayers();
1784            bool isClip = propertyID == CSSPropertyBackgroundClip || propertyID == CSSPropertyWebkitBackgroundClip || propertyID == CSSPropertyWebkitMaskClip;
1785            if (!layers->next()) {
1786                EFillBox box = isClip ? layers->clip() : layers->origin();
1787                return cssValuePool().createValue(box);
1788            }
1789
1790            RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1791            for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) {
1792                EFillBox box = isClip ? currLayer->clip() : currLayer->origin();
1793                list->append(cssValuePool().createValue(box));
1794            }
1795
1796            return list.release();
1797        }
1798        case CSSPropertyBackgroundPosition:
1799        case CSSPropertyWebkitMaskPosition: {
1800            const FillLayer* layers = propertyID == CSSPropertyWebkitMaskPosition ? style->maskLayers() : style->backgroundLayers();
1801            if (!layers->next())
1802                return createPositionListForLayer(propertyID, layers, *style);
1803
1804            RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1805            for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
1806                list->append(createPositionListForLayer(propertyID, currLayer, *style));
1807            return list.release();
1808        }
1809        case CSSPropertyBackgroundPositionX:
1810        case CSSPropertyWebkitMaskPositionX: {
1811            const FillLayer* layers = propertyID == CSSPropertyWebkitMaskPositionX ? style->maskLayers() : style->backgroundLayers();
1812            if (!layers->next())
1813                return cssValuePool().createValue(layers->xPosition());
1814
1815            RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1816            for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
1817                list->append(cssValuePool().createValue(currLayer->xPosition()));
1818
1819            return list.release();
1820        }
1821        case CSSPropertyBackgroundPositionY:
1822        case CSSPropertyWebkitMaskPositionY: {
1823            const FillLayer* layers = propertyID == CSSPropertyWebkitMaskPositionY ? style->maskLayers() : style->backgroundLayers();
1824            if (!layers->next())
1825                return cssValuePool().createValue(layers->yPosition());
1826
1827            RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1828            for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
1829                list->append(cssValuePool().createValue(currLayer->yPosition()));
1830
1831            return list.release();
1832        }
1833        case CSSPropertyBorderCollapse:
1834            if (style->borderCollapse())
1835                return cssValuePool().createIdentifierValue(CSSValueCollapse);
1836            return cssValuePool().createIdentifierValue(CSSValueSeparate);
1837        case CSSPropertyBorderSpacing: {
1838            RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
1839            list->append(zoomAdjustedPixelValue(style->horizontalBorderSpacing(), *style));
1840            list->append(zoomAdjustedPixelValue(style->verticalBorderSpacing(), *style));
1841            return list.release();
1842        }
1843        case CSSPropertyWebkitBorderHorizontalSpacing:
1844            return zoomAdjustedPixelValue(style->horizontalBorderSpacing(), *style);
1845        case CSSPropertyWebkitBorderVerticalSpacing:
1846            return zoomAdjustedPixelValue(style->verticalBorderSpacing(), *style);
1847        case CSSPropertyBorderImageSource:
1848            if (style->borderImageSource())
1849                return style->borderImageSource()->cssValue();
1850            return cssValuePool().createIdentifierValue(CSSValueNone);
1851        case CSSPropertyBorderTopColor:
1852            return m_allowVisitedStyle ? cssValuePool().createColorValue(style->visitedDependentColor(CSSPropertyBorderTopColor).rgb()) : currentColorOrValidColor(*style, style->borderTopColor());
1853        case CSSPropertyBorderRightColor:
1854            return m_allowVisitedStyle ? cssValuePool().createColorValue(style->visitedDependentColor(CSSPropertyBorderRightColor).rgb()) : currentColorOrValidColor(*style, style->borderRightColor());
1855        case CSSPropertyBorderBottomColor:
1856            return m_allowVisitedStyle ? cssValuePool().createColorValue(style->visitedDependentColor(CSSPropertyBorderBottomColor).rgb()) : currentColorOrValidColor(*style, style->borderBottomColor());
1857        case CSSPropertyBorderLeftColor:
1858            return m_allowVisitedStyle ? cssValuePool().createColorValue(style->visitedDependentColor(CSSPropertyBorderLeftColor).rgb()) : currentColorOrValidColor(*style, style->borderLeftColor());
1859        case CSSPropertyBorderTopStyle:
1860            return cssValuePool().createValue(style->borderTopStyle());
1861        case CSSPropertyBorderRightStyle:
1862            return cssValuePool().createValue(style->borderRightStyle());
1863        case CSSPropertyBorderBottomStyle:
1864            return cssValuePool().createValue(style->borderBottomStyle());
1865        case CSSPropertyBorderLeftStyle:
1866            return cssValuePool().createValue(style->borderLeftStyle());
1867        case CSSPropertyBorderTopWidth:
1868            return zoomAdjustedPixelValue(style->borderTopWidth(), *style);
1869        case CSSPropertyBorderRightWidth:
1870            return zoomAdjustedPixelValue(style->borderRightWidth(), *style);
1871        case CSSPropertyBorderBottomWidth:
1872            return zoomAdjustedPixelValue(style->borderBottomWidth(), *style);
1873        case CSSPropertyBorderLeftWidth:
1874            return zoomAdjustedPixelValue(style->borderLeftWidth(), *style);
1875        case CSSPropertyBottom:
1876            return valueForPositionOffset(*style, CSSPropertyBottom, renderer, m_node->document().renderView());
1877        case CSSPropertyWebkitBoxAlign:
1878            return cssValuePool().createValue(style->boxAlign());
1879        case CSSPropertyWebkitBoxDecorationBreak:
1880            if (style->boxDecorationBreak() == DSLICE)
1881                return cssValuePool().createIdentifierValue(CSSValueSlice);
1882        return cssValuePool().createIdentifierValue(CSSValueClone);
1883        case CSSPropertyWebkitBoxDirection:
1884            return cssValuePool().createValue(style->boxDirection());
1885        case CSSPropertyWebkitBoxFlex:
1886            return cssValuePool().createValue(style->boxFlex(), CSSPrimitiveValue::CSS_NUMBER);
1887        case CSSPropertyWebkitBoxFlexGroup:
1888            return cssValuePool().createValue(style->boxFlexGroup(), CSSPrimitiveValue::CSS_NUMBER);
1889        case CSSPropertyWebkitBoxLines:
1890            return cssValuePool().createValue(style->boxLines());
1891        case CSSPropertyWebkitBoxOrdinalGroup:
1892            return cssValuePool().createValue(style->boxOrdinalGroup(), CSSPrimitiveValue::CSS_NUMBER);
1893        case CSSPropertyWebkitBoxOrient:
1894            return cssValuePool().createValue(style->boxOrient());
1895        case CSSPropertyWebkitBoxPack:
1896            return cssValuePool().createValue(style->boxPack());
1897        case CSSPropertyWebkitBoxReflect:
1898            return valueForReflection(style->boxReflect(), *style);
1899        case CSSPropertyBoxShadow:
1900        case CSSPropertyWebkitBoxShadow:
1901            return valueForShadowList(style->boxShadow(), *style, true);
1902        case CSSPropertyCaptionSide:
1903            return cssValuePool().createValue(style->captionSide());
1904        case CSSPropertyClear:
1905            return cssValuePool().createValue(style->clear());
1906        case CSSPropertyColor:
1907            return cssValuePool().createColorValue(m_allowVisitedStyle ? style->visitedDependentColor(CSSPropertyColor).rgb() : style->color().rgb());
1908        case CSSPropertyWebkitPrintColorAdjust:
1909            return cssValuePool().createValue(style->printColorAdjust());
1910        case CSSPropertyWebkitColumnAxis:
1911            return cssValuePool().createValue(style->columnAxis());
1912        case CSSPropertyWebkitColumnCount:
1913            if (style->hasAutoColumnCount())
1914                return cssValuePool().createIdentifierValue(CSSValueAuto);
1915            return cssValuePool().createValue(style->columnCount(), CSSPrimitiveValue::CSS_NUMBER);
1916        case CSSPropertyColumnFill:
1917            if (RuntimeEnabledFeatures::regionBasedColumnsEnabled())
1918                return cssValuePool().createValue(style->columnFill());
1919            return 0;
1920        case CSSPropertyWebkitColumnGap:
1921            if (style->hasNormalColumnGap())
1922                return cssValuePool().createIdentifierValue(CSSValueNormal);
1923            return zoomAdjustedPixelValue(style->columnGap(), *style);
1924        case CSSPropertyWebkitColumnProgression:
1925            return cssValuePool().createValue(style->columnProgression());
1926        case CSSPropertyWebkitColumnRuleColor:
1927            return m_allowVisitedStyle ? cssValuePool().createColorValue(style->visitedDependentColor(CSSPropertyOutlineColor).rgb()) : currentColorOrValidColor(*style, style->columnRuleColor());
1928        case CSSPropertyWebkitColumnRuleStyle:
1929            return cssValuePool().createValue(style->columnRuleStyle());
1930        case CSSPropertyWebkitColumnRuleWidth:
1931            return zoomAdjustedPixelValue(style->columnRuleWidth(), *style);
1932        case CSSPropertyWebkitColumnSpan:
1933            return cssValuePool().createIdentifierValue(style->columnSpan() ? CSSValueAll : CSSValueNone);
1934        case CSSPropertyWebkitColumnBreakAfter:
1935            return cssValuePool().createValue(style->columnBreakAfter());
1936        case CSSPropertyWebkitColumnBreakBefore:
1937            return cssValuePool().createValue(style->columnBreakBefore());
1938        case CSSPropertyWebkitColumnBreakInside:
1939            return cssValuePool().createValue(style->columnBreakInside());
1940        case CSSPropertyWebkitColumnWidth:
1941            if (style->hasAutoColumnWidth())
1942                return cssValuePool().createIdentifierValue(CSSValueAuto);
1943            return zoomAdjustedPixelValue(style->columnWidth(), *style);
1944        case CSSPropertyTabSize:
1945            return cssValuePool().createValue(style->tabSize(), CSSPrimitiveValue::CSS_NUMBER);
1946        case CSSPropertyWebkitRegionBreakAfter:
1947            return cssValuePool().createValue(style->regionBreakAfter());
1948        case CSSPropertyWebkitRegionBreakBefore:
1949            return cssValuePool().createValue(style->regionBreakBefore());
1950        case CSSPropertyWebkitRegionBreakInside:
1951            return cssValuePool().createValue(style->regionBreakInside());
1952        case CSSPropertyCursor: {
1953            RefPtr<CSSValueList> list;
1954            CursorList* cursors = style->cursors();
1955            if (cursors && cursors->size() > 0) {
1956                list = CSSValueList::createCommaSeparated();
1957                for (unsigned i = 0; i < cursors->size(); ++i)
1958                    if (StyleImage* image = cursors->at(i).image())
1959                        list->append(image->cssValue());
1960            }
1961            RefPtr<CSSValue> value = cssValuePool().createValue(style->cursor());
1962            if (list) {
1963                list->append(value.release());
1964                return list.release();
1965            }
1966            return value.release();
1967        }
1968        case CSSPropertyDirection:
1969            return cssValuePool().createValue(style->direction());
1970        case CSSPropertyDisplay:
1971            return cssValuePool().createValue(style->display());
1972        case CSSPropertyEmptyCells:
1973            return cssValuePool().createValue(style->emptyCells());
1974        case CSSPropertyAlignContent:
1975            return cssValuePool().createValue(style->alignContent());
1976        case CSSPropertyAlignItems:
1977            return cssValuePool().createValue(style->alignItems());
1978        case CSSPropertyAlignSelf:
1979            if (style->alignSelf() == AlignAuto) {
1980                Node* parent = styledNode->parentNode();
1981                if (parent && parent->computedStyle())
1982                    return cssValuePool().createValue(parent->computedStyle()->alignItems());
1983                return cssValuePool().createValue(AlignStretch);
1984            }
1985            return cssValuePool().createValue(style->alignSelf());
1986        case CSSPropertyFlex:
1987            return valuesForShorthandProperty(flexShorthand());
1988        case CSSPropertyFlexBasis:
1989            return cssValuePool().createValue(style->flexBasis());
1990        case CSSPropertyFlexDirection:
1991            return cssValuePool().createValue(style->flexDirection());
1992        case CSSPropertyFlexFlow:
1993            return valuesForShorthandProperty(flexFlowShorthand());
1994        case CSSPropertyFlexGrow:
1995            return cssValuePool().createValue(style->flexGrow());
1996        case CSSPropertyFlexShrink:
1997            return cssValuePool().createValue(style->flexShrink());
1998        case CSSPropertyFlexWrap:
1999            return cssValuePool().createValue(style->flexWrap());
2000        case CSSPropertyJustifyContent:
2001            return cssValuePool().createValue(style->justifyContent());
2002        case CSSPropertyOrder:
2003            return cssValuePool().createValue(style->order(), CSSPrimitiveValue::CSS_NUMBER);
2004        case CSSPropertyFloat:
2005            if (style->display() != NONE && style->hasOutOfFlowPosition())
2006                return cssValuePool().createIdentifierValue(CSSValueNone);
2007            return cssValuePool().createValue(style->floating());
2008        case CSSPropertyFont: {
2009            RefPtr<CSSFontValue> computedFont = CSSFontValue::create();
2010            computedFont->style = valueForFontStyle(*style);
2011            computedFont->variant = valueForFontVariant(*style);
2012            computedFont->weight = valueForFontWeight(*style);
2013            computedFont->size = valueForFontSize(*style);
2014            computedFont->lineHeight = valueForLineHeight(*style, m_node->document().renderView());
2015            computedFont->family = valueForFontFamily(*style);
2016            return computedFont.release();
2017        }
2018        case CSSPropertyFontFamily: {
2019            RefPtr<CSSValueList> fontFamilyList = valueForFontFamily(*style);
2020            // If there's only a single family, return that as a CSSPrimitiveValue.
2021            // NOTE: Gecko always returns this as a comma-separated CSSPrimitiveValue string.
2022            if (fontFamilyList->length() == 1)
2023                return fontFamilyList->item(0);
2024            return fontFamilyList.release();
2025        }
2026        case CSSPropertyFontSize:
2027            return valueForFontSize(*style);
2028        case CSSPropertyFontStyle:
2029            return valueForFontStyle(*style);
2030        case CSSPropertyFontVariant:
2031            return valueForFontVariant(*style);
2032        case CSSPropertyFontWeight:
2033            return valueForFontWeight(*style);
2034        case CSSPropertyWebkitFontFeatureSettings: {
2035            const FontFeatureSettings* featureSettings = style->fontDescription().featureSettings();
2036            if (!featureSettings || !featureSettings->size())
2037                return cssValuePool().createIdentifierValue(CSSValueNormal);
2038            RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2039            for (unsigned i = 0; i < featureSettings->size(); ++i) {
2040                const FontFeature& feature = featureSettings->at(i);
2041                RefPtr<CSSFontFeatureValue> featureValue = CSSFontFeatureValue::create(feature.tag(), feature.value());
2042                list->append(featureValue.release());
2043            }
2044            return list.release();
2045        }
2046        case CSSPropertyGridAutoFlow:
2047            return cssValuePool().createValue(style->gridAutoFlow());
2048
2049        // Specs mention that getComputedStyle() should return the used value of the property instead of the computed
2050        // one for grid-definition-{rows|columns} but not for the grid-auto-{rows|columns} as things like
2051        // grid-auto-columns: 2fr; cannot be resolved to a value in pixels as the '2fr' means very different things
2052        // depending on the size of the explicit grid or the number of implicit tracks added to the grid. See
2053        // http://lists.w3.org/Archives/Public/www-style/2013Nov/0014.html
2054        case CSSPropertyGridAutoColumns:
2055            return specifiedValueForGridTrackSize(style->gridAutoColumns(), *style, m_node->document().renderView());
2056        case CSSPropertyGridAutoRows:
2057            return specifiedValueForGridTrackSize(style->gridAutoRows(), *style, m_node->document().renderView());
2058
2059        case CSSPropertyGridDefinitionColumns:
2060            return valueForGridTrackList(ForColumns, renderer, *style, m_node->document().renderView());
2061        case CSSPropertyGridDefinitionRows:
2062            return valueForGridTrackList(ForRows, renderer, *style, m_node->document().renderView());
2063
2064        case CSSPropertyGridColumnStart:
2065            return valueForGridPosition(style->gridColumnStart());
2066        case CSSPropertyGridColumnEnd:
2067            return valueForGridPosition(style->gridColumnEnd());
2068        case CSSPropertyGridRowStart:
2069            return valueForGridPosition(style->gridRowStart());
2070        case CSSPropertyGridRowEnd:
2071            return valueForGridPosition(style->gridRowEnd());
2072        case CSSPropertyGridColumn:
2073            return valuesForGridShorthand(gridColumnShorthand());
2074        case CSSPropertyGridRow:
2075            return valuesForGridShorthand(gridRowShorthand());
2076        case CSSPropertyGridArea:
2077            return valuesForGridShorthand(gridAreaShorthand());
2078
2079        case CSSPropertyGridTemplate:
2080            if (!style->namedGridAreaRowCount()) {
2081                ASSERT(!style->namedGridAreaColumnCount());
2082                return cssValuePool().createIdentifierValue(CSSValueNone);
2083            }
2084
2085            return CSSGridTemplateValue::create(style->namedGridArea(), style->namedGridAreaRowCount(), style->namedGridAreaColumnCount());
2086
2087        case CSSPropertyHeight:
2088            if (renderer) {
2089                // According to http://www.w3.org/TR/CSS2/visudet.html#the-height-property,
2090                // the "height" property does not apply for non-replaced inline elements.
2091                if (!renderer->isReplaced() && renderer->isInline())
2092                    return cssValuePool().createIdentifierValue(CSSValueAuto);
2093                return zoomAdjustedPixelValue(sizingBox(renderer).height(), *style);
2094            }
2095            return zoomAdjustedPixelValueForLength(style->height(), *style);
2096        case CSSPropertyWebkitHighlight:
2097            if (style->highlight() == nullAtom)
2098                return cssValuePool().createIdentifierValue(CSSValueNone);
2099            return cssValuePool().createValue(style->highlight(), CSSPrimitiveValue::CSS_STRING);
2100        case CSSPropertyWebkitHyphenateCharacter:
2101            if (style->hyphenationString().isNull())
2102                return cssValuePool().createIdentifierValue(CSSValueAuto);
2103            return cssValuePool().createValue(style->hyphenationString(), CSSPrimitiveValue::CSS_STRING);
2104        case CSSPropertyWebkitBorderFit:
2105            if (style->borderFit() == BorderFitBorder)
2106                return cssValuePool().createIdentifierValue(CSSValueBorder);
2107            return cssValuePool().createIdentifierValue(CSSValueLines);
2108        case CSSPropertyImageRendering:
2109            return CSSPrimitiveValue::create(style->imageRendering());
2110        case CSSPropertyIsolation:
2111            return cssValuePool().createValue(style->isolation());
2112        case CSSPropertyLeft:
2113            return valueForPositionOffset(*style, CSSPropertyLeft, renderer, m_node->document().renderView());
2114        case CSSPropertyLetterSpacing:
2115            if (!style->letterSpacing())
2116                return cssValuePool().createIdentifierValue(CSSValueNormal);
2117            return zoomAdjustedPixelValue(style->letterSpacing(), *style);
2118        case CSSPropertyWebkitLineClamp:
2119            if (style->lineClamp().isNone())
2120                return cssValuePool().createIdentifierValue(CSSValueNone);
2121            return cssValuePool().createValue(style->lineClamp().value(), style->lineClamp().isPercentage() ? CSSPrimitiveValue::CSS_PERCENTAGE : CSSPrimitiveValue::CSS_NUMBER);
2122        case CSSPropertyLineHeight:
2123            return valueForLineHeight(*style, m_node->document().renderView());
2124        case CSSPropertyListStyleImage:
2125            if (style->listStyleImage())
2126                return style->listStyleImage()->cssValue();
2127            return cssValuePool().createIdentifierValue(CSSValueNone);
2128        case CSSPropertyListStylePosition:
2129            return cssValuePool().createValue(style->listStylePosition());
2130        case CSSPropertyListStyleType:
2131            return cssValuePool().createValue(style->listStyleType());
2132        case CSSPropertyWebkitLocale:
2133            if (style->locale().isNull())
2134                return cssValuePool().createIdentifierValue(CSSValueAuto);
2135            return cssValuePool().createValue(style->locale(), CSSPrimitiveValue::CSS_STRING);
2136        case CSSPropertyMarginTop: {
2137            Length marginTop = style->marginTop();
2138            if (marginTop.isFixed() || !renderer || !renderer->isBox())
2139                return zoomAdjustedPixelValueForLength(marginTop, *style);
2140            return zoomAdjustedPixelValue(toRenderBox(renderer)->marginTop(), *style);
2141        }
2142        case CSSPropertyMarginRight: {
2143            Length marginRight = style->marginRight();
2144            if (marginRight.isFixed() || !renderer || !renderer->isBox())
2145                return zoomAdjustedPixelValueForLength(marginRight, *style);
2146            float value;
2147            if (marginRight.isPercent() || marginRight.isViewportPercentage()) {
2148                // RenderBox gives a marginRight() that is the distance between the right-edge of the child box
2149                // and the right-edge of the containing box, when display == BLOCK. Let's calculate the absolute
2150                // value of the specified margin-right % instead of relying on RenderBox's marginRight() value.
2151                value = minimumValueForLength(marginRight, toRenderBox(renderer)->containingBlockLogicalWidthForContent(), m_node->document().renderView());
2152            } else {
2153                value = toRenderBox(renderer)->marginRight();
2154            }
2155            return zoomAdjustedPixelValue(value, *style);
2156        }
2157        case CSSPropertyMarginBottom: {
2158            Length marginBottom = style->marginBottom();
2159            if (marginBottom.isFixed() || !renderer || !renderer->isBox())
2160                return zoomAdjustedPixelValueForLength(marginBottom, *style);
2161            return zoomAdjustedPixelValue(toRenderBox(renderer)->marginBottom(), *style);
2162        }
2163        case CSSPropertyMarginLeft: {
2164            Length marginLeft = style->marginLeft();
2165            if (marginLeft.isFixed() || !renderer || !renderer->isBox())
2166                return zoomAdjustedPixelValueForLength(marginLeft, *style);
2167            return zoomAdjustedPixelValue(toRenderBox(renderer)->marginLeft(), *style);
2168        }
2169        case CSSPropertyWebkitUserModify:
2170            return cssValuePool().createValue(style->userModify());
2171        case CSSPropertyMaxHeight: {
2172            const Length& maxHeight = style->maxHeight();
2173            if (maxHeight.isUndefined())
2174                return cssValuePool().createIdentifierValue(CSSValueNone);
2175            return zoomAdjustedPixelValueForLength(maxHeight, *style);
2176        }
2177        case CSSPropertyMaxWidth: {
2178            const Length& maxWidth = style->maxWidth();
2179            if (maxWidth.isUndefined())
2180                return cssValuePool().createIdentifierValue(CSSValueNone);
2181            return zoomAdjustedPixelValueForLength(maxWidth, *style);
2182        }
2183        case CSSPropertyMinHeight:
2184            // FIXME: For flex-items, min-height:auto should compute to min-content.
2185            if (style->minHeight().isAuto())
2186                return zoomAdjustedPixelValue(0, *style);
2187            return zoomAdjustedPixelValueForLength(style->minHeight(), *style);
2188        case CSSPropertyMinWidth:
2189            // FIXME: For flex-items, min-width:auto should compute to min-content.
2190            if (style->minWidth().isAuto())
2191                return zoomAdjustedPixelValue(0, *style);
2192            return zoomAdjustedPixelValueForLength(style->minWidth(), *style);
2193        case CSSPropertyObjectFit:
2194            return cssValuePool().createValue(style->objectFit());
2195        case CSSPropertyObjectPosition:
2196            return cssValuePool().createValue(
2197                Pair::create(
2198                    zoomAdjustedPixelValueForLength(style->objectPosition().x(), *style),
2199                    zoomAdjustedPixelValueForLength(style->objectPosition().y(), *style),
2200                    Pair::KeepIdenticalValues));
2201        case CSSPropertyOpacity:
2202            return cssValuePool().createValue(style->opacity(), CSSPrimitiveValue::CSS_NUMBER);
2203        case CSSPropertyOrphans:
2204            if (style->hasAutoOrphans())
2205                return cssValuePool().createIdentifierValue(CSSValueAuto);
2206            return cssValuePool().createValue(style->orphans(), CSSPrimitiveValue::CSS_NUMBER);
2207        case CSSPropertyOutlineColor:
2208            return m_allowVisitedStyle ? cssValuePool().createColorValue(style->visitedDependentColor(CSSPropertyOutlineColor).rgb()) : currentColorOrValidColor(*style, style->outlineColor());
2209        case CSSPropertyOutlineOffset:
2210            return zoomAdjustedPixelValue(style->outlineOffset(), *style);
2211        case CSSPropertyOutlineStyle:
2212            if (style->outlineStyleIsAuto())
2213                return cssValuePool().createIdentifierValue(CSSValueAuto);
2214            return cssValuePool().createValue(style->outlineStyle());
2215        case CSSPropertyOutlineWidth:
2216            return zoomAdjustedPixelValue(style->outlineWidth(), *style);
2217        case CSSPropertyOverflow:
2218            return cssValuePool().createValue(max(style->overflowX(), style->overflowY()));
2219        case CSSPropertyOverflowWrap:
2220            return cssValuePool().createValue(style->overflowWrap());
2221        case CSSPropertyOverflowX:
2222            return cssValuePool().createValue(style->overflowX());
2223        case CSSPropertyOverflowY:
2224            return cssValuePool().createValue(style->overflowY());
2225        case CSSPropertyPaddingTop: {
2226            Length paddingTop = style->paddingTop();
2227            if (paddingTop.isFixed() || !renderer || !renderer->isBox())
2228                return zoomAdjustedPixelValueForLength(paddingTop, *style);
2229            return zoomAdjustedPixelValue(toRenderBox(renderer)->computedCSSPaddingTop(), *style);
2230        }
2231        case CSSPropertyPaddingRight: {
2232            Length paddingRight = style->paddingRight();
2233            if (paddingRight.isFixed() || !renderer || !renderer->isBox())
2234                return zoomAdjustedPixelValueForLength(paddingRight, *style);
2235            return zoomAdjustedPixelValue(toRenderBox(renderer)->computedCSSPaddingRight(), *style);
2236        }
2237        case CSSPropertyPaddingBottom: {
2238            Length paddingBottom = style->paddingBottom();
2239            if (paddingBottom.isFixed() || !renderer || !renderer->isBox())
2240                return zoomAdjustedPixelValueForLength(paddingBottom, *style);
2241            return zoomAdjustedPixelValue(toRenderBox(renderer)->computedCSSPaddingBottom(), *style);
2242        }
2243        case CSSPropertyPaddingLeft: {
2244            Length paddingLeft = style->paddingLeft();
2245            if (paddingLeft.isFixed() || !renderer || !renderer->isBox())
2246                return zoomAdjustedPixelValueForLength(paddingLeft, *style);
2247            return zoomAdjustedPixelValue(toRenderBox(renderer)->computedCSSPaddingLeft(), *style);
2248        }
2249        case CSSPropertyPageBreakAfter:
2250            return cssValuePool().createValue(style->pageBreakAfter());
2251        case CSSPropertyPageBreakBefore:
2252            return cssValuePool().createValue(style->pageBreakBefore());
2253        case CSSPropertyPageBreakInside: {
2254            EPageBreak pageBreak = style->pageBreakInside();
2255            ASSERT(pageBreak != PBALWAYS);
2256            if (pageBreak == PBALWAYS)
2257                return 0;
2258            return cssValuePool().createValue(style->pageBreakInside());
2259        }
2260        case CSSPropertyPosition:
2261            return cssValuePool().createValue(style->position());
2262        case CSSPropertyRight:
2263            return valueForPositionOffset(*style, CSSPropertyRight, renderer, m_node->document().renderView());
2264        case CSSPropertyWebkitRubyPosition:
2265            return cssValuePool().createValue(style->rubyPosition());
2266        case CSSPropertyTableLayout:
2267            return cssValuePool().createValue(style->tableLayout());
2268        case CSSPropertyTextAlign:
2269            return cssValuePool().createValue(style->textAlign());
2270        case CSSPropertyTextAlignLast:
2271            return cssValuePool().createValue(style->textAlignLast());
2272        case CSSPropertyTextDecoration:
2273            return valuesForShorthandProperty(textDecorationShorthand());
2274        case CSSPropertyTextDecorationLine:
2275            return renderTextDecorationFlagsToCSSValue(style->textDecoration());
2276        case CSSPropertyTextDecorationStyle:
2277            return valueForTextDecorationStyle(style->textDecorationStyle());
2278        case CSSPropertyTextDecorationColor:
2279            return currentColorOrValidColor(*style, style->textDecorationColor());
2280        case CSSPropertyTextJustify:
2281            return cssValuePool().createValue(style->textJustify());
2282        case CSSPropertyTextUnderlinePosition:
2283            return cssValuePool().createValue(style->textUnderlinePosition());
2284        case CSSPropertyWebkitTextDecorationsInEffect:
2285            return renderTextDecorationFlagsToCSSValue(style->textDecorationsInEffect());
2286        case CSSPropertyWebkitTextFillColor:
2287            return currentColorOrValidColor(*style, style->textFillColor());
2288        case CSSPropertyWebkitTextEmphasisColor:
2289            return currentColorOrValidColor(*style, style->textEmphasisColor());
2290        case CSSPropertyWebkitTextEmphasisPosition:
2291            return cssValuePool().createValue(style->textEmphasisPosition());
2292        case CSSPropertyWebkitTextEmphasisStyle:
2293            switch (style->textEmphasisMark()) {
2294            case TextEmphasisMarkNone:
2295                return cssValuePool().createIdentifierValue(CSSValueNone);
2296            case TextEmphasisMarkCustom:
2297                return cssValuePool().createValue(style->textEmphasisCustomMark(), CSSPrimitiveValue::CSS_STRING);
2298            case TextEmphasisMarkAuto:
2299                ASSERT_NOT_REACHED();
2300                // Fall through
2301            case TextEmphasisMarkDot:
2302            case TextEmphasisMarkCircle:
2303            case TextEmphasisMarkDoubleCircle:
2304            case TextEmphasisMarkTriangle:
2305            case TextEmphasisMarkSesame: {
2306                RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2307                list->append(cssValuePool().createValue(style->textEmphasisFill()));
2308                list->append(cssValuePool().createValue(style->textEmphasisMark()));
2309                return list.release();
2310            }
2311            }
2312        case CSSPropertyTextIndent: {
2313            RefPtr<CSSValue> textIndent = zoomAdjustedPixelValueForLength(style->textIndent(), *style);
2314            if (RuntimeEnabledFeatures::css3TextEnabled() && style->textIndentLine() == TextIndentEachLine) {
2315                RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2316                list->append(textIndent.release());
2317                list->append(cssValuePool().createIdentifierValue(CSSValueEachLine));
2318                return list.release();
2319            }
2320            return textIndent.release();
2321        }
2322        case CSSPropertyTextShadow:
2323            return valueForShadowList(style->textShadow(), *style, false);
2324        case CSSPropertyTextRendering:
2325            return cssValuePool().createValue(style->fontDescription().textRenderingMode());
2326        case CSSPropertyTextOverflow:
2327            if (style->textOverflow())
2328                return cssValuePool().createIdentifierValue(CSSValueEllipsis);
2329            return cssValuePool().createIdentifierValue(CSSValueClip);
2330        case CSSPropertyWebkitTextSecurity:
2331            return cssValuePool().createValue(style->textSecurity());
2332        case CSSPropertyWebkitTextStrokeColor:
2333            return currentColorOrValidColor(*style, style->textStrokeColor());
2334        case CSSPropertyWebkitTextStrokeWidth:
2335            return zoomAdjustedPixelValue(style->textStrokeWidth(), *style);
2336        case CSSPropertyTextTransform:
2337            return cssValuePool().createValue(style->textTransform());
2338        case CSSPropertyTop:
2339            return valueForPositionOffset(*style, CSSPropertyTop, renderer, m_node->document().renderView());
2340        case CSSPropertyTouchAction:
2341            return touchActionFlagsToCSSValue(style->touchAction());
2342        case CSSPropertyTouchActionDelay:
2343            return cssValuePool().createValue(style->touchActionDelay());
2344        case CSSPropertyUnicodeBidi:
2345            return cssValuePool().createValue(style->unicodeBidi());
2346        case CSSPropertyVerticalAlign:
2347            switch (style->verticalAlign()) {
2348                case BASELINE:
2349                    return cssValuePool().createIdentifierValue(CSSValueBaseline);
2350                case MIDDLE:
2351                    return cssValuePool().createIdentifierValue(CSSValueMiddle);
2352                case SUB:
2353                    return cssValuePool().createIdentifierValue(CSSValueSub);
2354                case SUPER:
2355                    return cssValuePool().createIdentifierValue(CSSValueSuper);
2356                case TEXT_TOP:
2357                    return cssValuePool().createIdentifierValue(CSSValueTextTop);
2358                case TEXT_BOTTOM:
2359                    return cssValuePool().createIdentifierValue(CSSValueTextBottom);
2360                case TOP:
2361                    return cssValuePool().createIdentifierValue(CSSValueTop);
2362                case BOTTOM:
2363                    return cssValuePool().createIdentifierValue(CSSValueBottom);
2364                case BASELINE_MIDDLE:
2365                    return cssValuePool().createIdentifierValue(CSSValueWebkitBaselineMiddle);
2366                case LENGTH:
2367                    return cssValuePool().createValue(style->verticalAlignLength());
2368            }
2369            ASSERT_NOT_REACHED();
2370            return 0;
2371        case CSSPropertyVisibility:
2372            return cssValuePool().createValue(style->visibility());
2373        case CSSPropertyWhiteSpace:
2374            return cssValuePool().createValue(style->whiteSpace());
2375        case CSSPropertyWidows:
2376            if (style->hasAutoWidows())
2377                return cssValuePool().createIdentifierValue(CSSValueAuto);
2378            return cssValuePool().createValue(style->widows(), CSSPrimitiveValue::CSS_NUMBER);
2379        case CSSPropertyWidth:
2380            if (renderer) {
2381                // According to http://www.w3.org/TR/CSS2/visudet.html#the-width-property,
2382                // the "width" property does not apply for non-replaced inline elements.
2383                if (!renderer->isReplaced() && renderer->isInline())
2384                    return cssValuePool().createIdentifierValue(CSSValueAuto);
2385                return zoomAdjustedPixelValue(sizingBox(renderer).width(), *style);
2386            }
2387            return zoomAdjustedPixelValueForLength(style->width(), *style);
2388        case CSSPropertyWordBreak:
2389            return cssValuePool().createValue(style->wordBreak());
2390        case CSSPropertyWordSpacing:
2391            return zoomAdjustedPixelValue(style->wordSpacing(), *style);
2392        case CSSPropertyWordWrap:
2393            return cssValuePool().createValue(style->overflowWrap());
2394        case CSSPropertyWebkitLineBreak:
2395            return cssValuePool().createValue(style->lineBreak());
2396        case CSSPropertyResize:
2397            return cssValuePool().createValue(style->resize());
2398        case CSSPropertyFontKerning:
2399            return cssValuePool().createValue(style->fontDescription().kerning());
2400        case CSSPropertyWebkitFontSmoothing:
2401            return cssValuePool().createValue(style->fontDescription().fontSmoothing());
2402        case CSSPropertyWebkitFontVariantLigatures: {
2403            FontDescription::LigaturesState commonLigaturesState = style->fontDescription().commonLigaturesState();
2404            FontDescription::LigaturesState discretionaryLigaturesState = style->fontDescription().discretionaryLigaturesState();
2405            FontDescription::LigaturesState historicalLigaturesState = style->fontDescription().historicalLigaturesState();
2406            if (commonLigaturesState == FontDescription::NormalLigaturesState && discretionaryLigaturesState == FontDescription::NormalLigaturesState
2407                && historicalLigaturesState == FontDescription::NormalLigaturesState)
2408                return cssValuePool().createIdentifierValue(CSSValueNormal);
2409
2410            RefPtr<CSSValueList> valueList = CSSValueList::createSpaceSeparated();
2411            if (commonLigaturesState != FontDescription::NormalLigaturesState)
2412                valueList->append(cssValuePool().createIdentifierValue(commonLigaturesState == FontDescription::DisabledLigaturesState ? CSSValueNoCommonLigatures : CSSValueCommonLigatures));
2413            if (discretionaryLigaturesState != FontDescription::NormalLigaturesState)
2414                valueList->append(cssValuePool().createIdentifierValue(discretionaryLigaturesState == FontDescription::DisabledLigaturesState ? CSSValueNoDiscretionaryLigatures : CSSValueDiscretionaryLigatures));
2415            if (historicalLigaturesState != FontDescription::NormalLigaturesState)
2416                valueList->append(cssValuePool().createIdentifierValue(historicalLigaturesState == FontDescription::DisabledLigaturesState ? CSSValueNoHistoricalLigatures : CSSValueHistoricalLigatures));
2417            return valueList;
2418        }
2419        case CSSPropertyZIndex:
2420            if (style->hasAutoZIndex())
2421                return cssValuePool().createIdentifierValue(CSSValueAuto);
2422            return cssValuePool().createValue(style->zIndex(), CSSPrimitiveValue::CSS_NUMBER);
2423        case CSSPropertyZoom:
2424            return cssValuePool().createValue(style->zoom(), CSSPrimitiveValue::CSS_NUMBER);
2425        case CSSPropertyBoxSizing:
2426            if (style->boxSizing() == CONTENT_BOX)
2427                return cssValuePool().createIdentifierValue(CSSValueContentBox);
2428            return cssValuePool().createIdentifierValue(CSSValueBorderBox);
2429        case CSSPropertyWebkitAppRegion:
2430            return cssValuePool().createIdentifierValue(style->getDraggableRegionMode() == DraggableRegionDrag ? CSSValueDrag : CSSValueNoDrag);
2431        case CSSPropertyAnimationDelay:
2432            ASSERT(RuntimeEnabledFeatures::cssAnimationUnprefixedEnabled());
2433        case CSSPropertyWebkitAnimationDelay:
2434            return valueForAnimationDelay(style->animations());
2435        case CSSPropertyAnimationDirection:
2436            ASSERT(RuntimeEnabledFeatures::cssAnimationUnprefixedEnabled());
2437        case CSSPropertyWebkitAnimationDirection: {
2438            RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2439            const CSSAnimationDataList* t = style->animations();
2440            if (t) {
2441                for (size_t i = 0; i < t->size(); ++i)
2442                    list->append(valueForAnimationDirection(t->animation(i)->direction()));
2443            } else
2444                list->append(cssValuePool().createIdentifierValue(CSSValueNormal));
2445            return list.release();
2446        }
2447        case CSSPropertyAnimationDuration:
2448            ASSERT(RuntimeEnabledFeatures::cssAnimationUnprefixedEnabled());
2449        case CSSPropertyWebkitAnimationDuration:
2450            return valueForAnimationDuration(style->animations());
2451        case CSSPropertyAnimationFillMode:
2452            ASSERT(RuntimeEnabledFeatures::cssAnimationUnprefixedEnabled());
2453        case CSSPropertyWebkitAnimationFillMode: {
2454            RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2455            const CSSAnimationDataList* t = style->animations();
2456            if (t) {
2457                for (size_t i = 0; i < t->size(); ++i)
2458                    list->append(valueForAnimationFillMode(t->animation(i)->fillMode()));
2459            } else
2460                list->append(cssValuePool().createIdentifierValue(CSSValueNone));
2461            return list.release();
2462        }
2463        case CSSPropertyAnimationIterationCount:
2464            ASSERT(RuntimeEnabledFeatures::cssAnimationUnprefixedEnabled());
2465        case CSSPropertyWebkitAnimationIterationCount: {
2466            RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2467            const CSSAnimationDataList* t = style->animations();
2468            if (t) {
2469                for (size_t i = 0; i < t->size(); ++i) {
2470                    double iterationCount = t->animation(i)->iterationCount();
2471                    if (iterationCount == CSSAnimationData::IterationCountInfinite)
2472                        list->append(cssValuePool().createIdentifierValue(CSSValueInfinite));
2473                    else
2474                        list->append(cssValuePool().createValue(iterationCount, CSSPrimitiveValue::CSS_NUMBER));
2475                }
2476            } else
2477                list->append(cssValuePool().createValue(CSSAnimationData::initialAnimationIterationCount(), CSSPrimitiveValue::CSS_NUMBER));
2478            return list.release();
2479        }
2480        case CSSPropertyAnimationName:
2481            ASSERT(RuntimeEnabledFeatures::cssAnimationUnprefixedEnabled());
2482        case CSSPropertyWebkitAnimationName: {
2483            RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2484            const CSSAnimationDataList* t = style->animations();
2485            if (t) {
2486                for (size_t i = 0; i < t->size(); ++i)
2487                    list->append(cssValuePool().createValue(t->animation(i)->name(), CSSPrimitiveValue::CSS_STRING));
2488            } else
2489                list->append(cssValuePool().createIdentifierValue(CSSValueNone));
2490            return list.release();
2491        }
2492        case CSSPropertyAnimationPlayState:
2493            ASSERT(RuntimeEnabledFeatures::cssAnimationUnprefixedEnabled());
2494        case CSSPropertyWebkitAnimationPlayState: {
2495            RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2496            const CSSAnimationDataList* t = style->animations();
2497            if (t) {
2498                for (size_t i = 0; i < t->size(); ++i) {
2499                    int prop = t->animation(i)->playState();
2500                    if (prop == AnimPlayStatePlaying)
2501                        list->append(cssValuePool().createIdentifierValue(CSSValueRunning));
2502                    else
2503                        list->append(cssValuePool().createIdentifierValue(CSSValuePaused));
2504                }
2505            } else
2506                list->append(cssValuePool().createIdentifierValue(CSSValueRunning));
2507            return list.release();
2508        }
2509        case CSSPropertyAnimationTimingFunction:
2510            ASSERT(RuntimeEnabledFeatures::cssAnimationUnprefixedEnabled());
2511        case CSSPropertyWebkitAnimationTimingFunction:
2512            return valueForAnimationTimingFunction(style->animations());
2513        case CSSPropertyAnimation:
2514        case CSSPropertyWebkitAnimation: {
2515            const CSSAnimationDataList* animations = style->animations();
2516            if (animations) {
2517                RefPtr<CSSValueList> animationsList = CSSValueList::createCommaSeparated();
2518                for (size_t i = 0; i < animations->size(); ++i) {
2519                    RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2520                    const CSSAnimationData* animation = animations->animation(i);
2521                    list->append(cssValuePool().createValue(animation->name(), CSSPrimitiveValue::CSS_STRING));
2522                    list->append(cssValuePool().createValue(animation->duration(), CSSPrimitiveValue::CSS_S));
2523                    list->append(createTimingFunctionValue(animation->timingFunction()));
2524                    list->append(cssValuePool().createValue(animation->delay(), CSSPrimitiveValue::CSS_S));
2525                    if (animation->iterationCount() == CSSAnimationData::IterationCountInfinite)
2526                        list->append(cssValuePool().createIdentifierValue(CSSValueInfinite));
2527                    else
2528                        list->append(cssValuePool().createValue(animation->iterationCount(), CSSPrimitiveValue::CSS_NUMBER));
2529                    list->append(valueForAnimationDirection(animation->direction()));
2530                    list->append(valueForAnimationFillMode(animation->fillMode()));
2531                    if (animation->playState() == AnimPlayStatePaused)
2532                        list->append(cssValuePool().createIdentifierValue(CSSValuePaused));
2533                    else
2534                        list->append(cssValuePool().createIdentifierValue(CSSValueRunning));
2535                    animationsList->append(list);
2536                }
2537                return animationsList.release();
2538            }
2539
2540            RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2541            // animation-name default value.
2542            list->append(cssValuePool().createIdentifierValue(CSSValueNone));
2543            list->append(cssValuePool().createValue(CSSAnimationData::initialAnimationDuration(), CSSPrimitiveValue::CSS_S));
2544            list->append(createTimingFunctionValue(CSSAnimationData::initialAnimationTimingFunction().get()));
2545            list->append(cssValuePool().createValue(CSSAnimationData::initialAnimationDelay(), CSSPrimitiveValue::CSS_S));
2546            list->append(cssValuePool().createValue(CSSAnimationData::initialAnimationIterationCount(), CSSPrimitiveValue::CSS_NUMBER));
2547            list->append(valueForAnimationDirection(CSSAnimationData::initialAnimationDirection()));
2548            list->append(valueForAnimationFillMode(CSSAnimationData::initialAnimationFillMode()));
2549            // Initial animation-play-state.
2550            list->append(cssValuePool().createIdentifierValue(CSSValueRunning));
2551            return list.release();
2552        }
2553        case CSSPropertyWebkitAppearance:
2554            return cssValuePool().createValue(style->appearance());
2555        case CSSPropertyWebkitAspectRatio:
2556            if (!style->hasAspectRatio())
2557                return cssValuePool().createIdentifierValue(CSSValueNone);
2558            return CSSAspectRatioValue::create(style->aspectRatioNumerator(), style->aspectRatioDenominator());
2559        case CSSPropertyWebkitBackfaceVisibility:
2560            return cssValuePool().createIdentifierValue((style->backfaceVisibility() == BackfaceVisibilityHidden) ? CSSValueHidden : CSSValueVisible);
2561        case CSSPropertyWebkitBorderImage:
2562            return valueForNinePieceImage(style->borderImage(), *style);
2563        case CSSPropertyBorderImageOutset:
2564            return valueForNinePieceImageQuad(style->borderImage().outset(), *style);
2565        case CSSPropertyBorderImageRepeat:
2566            return valueForNinePieceImageRepeat(style->borderImage());
2567        case CSSPropertyBorderImageSlice:
2568            return valueForNinePieceImageSlice(style->borderImage());
2569        case CSSPropertyBorderImageWidth:
2570            return valueForNinePieceImageQuad(style->borderImage().borderSlices(), *style);
2571        case CSSPropertyWebkitMaskBoxImage:
2572            return valueForNinePieceImage(style->maskBoxImage(), *style);
2573        case CSSPropertyWebkitMaskBoxImageOutset:
2574            return valueForNinePieceImageQuad(style->maskBoxImage().outset(), *style);
2575        case CSSPropertyWebkitMaskBoxImageRepeat:
2576            return valueForNinePieceImageRepeat(style->maskBoxImage());
2577        case CSSPropertyWebkitMaskBoxImageSlice:
2578            return valueForNinePieceImageSlice(style->maskBoxImage());
2579        case CSSPropertyWebkitMaskBoxImageWidth:
2580            return valueForNinePieceImageQuad(style->maskBoxImage().borderSlices(), *style);
2581        case CSSPropertyWebkitMaskBoxImageSource:
2582            if (style->maskBoxImageSource())
2583                return style->maskBoxImageSource()->cssValue();
2584            return cssValuePool().createIdentifierValue(CSSValueNone);
2585        case CSSPropertyWebkitFontSizeDelta:
2586            // Not a real style property -- used by the editing engine -- so has no computed value.
2587            break;
2588        case CSSPropertyWebkitMarginBottomCollapse:
2589        case CSSPropertyWebkitMarginAfterCollapse:
2590            return cssValuePool().createValue(style->marginAfterCollapse());
2591        case CSSPropertyWebkitMarginTopCollapse:
2592        case CSSPropertyWebkitMarginBeforeCollapse:
2593            return cssValuePool().createValue(style->marginBeforeCollapse());
2594        case CSSPropertyWebkitPerspective:
2595            if (!style->hasPerspective())
2596                return cssValuePool().createIdentifierValue(CSSValueNone);
2597            return zoomAdjustedPixelValue(style->perspective(), *style);
2598        case CSSPropertyWebkitPerspectiveOrigin: {
2599            RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2600            if (renderer) {
2601                LayoutRect box;
2602                if (renderer->isBox())
2603                    box = toRenderBox(renderer)->borderBoxRect();
2604
2605                RenderView* renderView = m_node->document().renderView();
2606                list->append(zoomAdjustedPixelValue(minimumValueForLength(style->perspectiveOriginX(), box.width(), renderView), *style));
2607                list->append(zoomAdjustedPixelValue(minimumValueForLength(style->perspectiveOriginY(), box.height(), renderView), *style));
2608            }
2609            else {
2610                list->append(zoomAdjustedPixelValueForLength(style->perspectiveOriginX(), *style));
2611                list->append(zoomAdjustedPixelValueForLength(style->perspectiveOriginY(), *style));
2612
2613            }
2614            return list.release();
2615        }
2616        case CSSPropertyWebkitRtlOrdering:
2617            return cssValuePool().createIdentifierValue(style->rtlOrdering() ? CSSValueVisual : CSSValueLogical);
2618        case CSSPropertyWebkitTapHighlightColor:
2619            return currentColorOrValidColor(*style, style->tapHighlightColor());
2620        case CSSPropertyWebkitUserDrag:
2621            return cssValuePool().createValue(style->userDrag());
2622        case CSSPropertyWebkitUserSelect:
2623            return cssValuePool().createValue(style->userSelect());
2624        case CSSPropertyBorderBottomLeftRadius:
2625            return valueForBorderRadiusCorner(style->borderBottomLeftRadius(), *style);
2626        case CSSPropertyBorderBottomRightRadius:
2627            return valueForBorderRadiusCorner(style->borderBottomRightRadius(), *style);
2628        case CSSPropertyBorderTopLeftRadius:
2629            return valueForBorderRadiusCorner(style->borderTopLeftRadius(), *style);
2630        case CSSPropertyBorderTopRightRadius:
2631            return valueForBorderRadiusCorner(style->borderTopRightRadius(), *style);
2632        case CSSPropertyClip: {
2633            if (!style->hasClip())
2634                return cssValuePool().createIdentifierValue(CSSValueAuto);
2635            RefPtr<Rect> rect = Rect::create();
2636            rect->setTop(zoomAdjustedPixelValue(style->clip().top().value(), *style));
2637            rect->setRight(zoomAdjustedPixelValue(style->clip().right().value(), *style));
2638            rect->setBottom(zoomAdjustedPixelValue(style->clip().bottom().value(), *style));
2639            rect->setLeft(zoomAdjustedPixelValue(style->clip().left().value(), *style));
2640            return cssValuePool().createValue(rect.release());
2641        }
2642        case CSSPropertySpeak:
2643            return cssValuePool().createValue(style->speak());
2644        case CSSPropertyWebkitTransform:
2645            return computedTransform(renderer, *style);
2646        case CSSPropertyWebkitTransformOrigin: {
2647            RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2648            if (renderer) {
2649                LayoutRect box;
2650                if (renderer->isBox())
2651                    box = toRenderBox(renderer)->borderBoxRect();
2652
2653                RenderView* renderView = m_node->document().renderView();
2654                list->append(zoomAdjustedPixelValue(minimumValueForLength(style->transformOriginX(), box.width(), renderView), *style));
2655                list->append(zoomAdjustedPixelValue(minimumValueForLength(style->transformOriginY(), box.height(), renderView), *style));
2656                if (style->transformOriginZ() != 0)
2657                    list->append(zoomAdjustedPixelValue(style->transformOriginZ(), *style));
2658            } else {
2659                list->append(zoomAdjustedPixelValueForLength(style->transformOriginX(), *style));
2660                list->append(zoomAdjustedPixelValueForLength(style->transformOriginY(), *style));
2661                if (style->transformOriginZ() != 0)
2662                    list->append(zoomAdjustedPixelValue(style->transformOriginZ(), *style));
2663            }
2664            return list.release();
2665        }
2666        case CSSPropertyWebkitTransformStyle:
2667            return cssValuePool().createIdentifierValue((style->transformStyle3D() == TransformStyle3DPreserve3D) ? CSSValuePreserve3d : CSSValueFlat);
2668        case CSSPropertyTransitionDelay:
2669        case CSSPropertyWebkitTransitionDelay:
2670            return valueForAnimationDelay(style->transitions());
2671        case CSSPropertyTransitionDuration:
2672        case CSSPropertyWebkitTransitionDuration:
2673            return valueForAnimationDuration(style->transitions());
2674        case CSSPropertyTransitionProperty:
2675        case CSSPropertyWebkitTransitionProperty:
2676            return valueForTransitionProperty(style->transitions());
2677        case CSSPropertyTransitionTimingFunction:
2678        case CSSPropertyWebkitTransitionTimingFunction:
2679            return valueForAnimationTimingFunction(style->transitions());
2680        case CSSPropertyTransition:
2681        case CSSPropertyWebkitTransition: {
2682            const CSSAnimationDataList* animList = style->transitions();
2683            if (animList) {
2684                RefPtr<CSSValueList> transitionsList = CSSValueList::createCommaSeparated();
2685                for (size_t i = 0; i < animList->size(); ++i) {
2686                    RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2687                    const CSSAnimationData* animation = animList->animation(i);
2688                    list->append(createTransitionPropertyValue(animation));
2689                    list->append(cssValuePool().createValue(animation->duration(), CSSPrimitiveValue::CSS_S));
2690                    list->append(createTimingFunctionValue(animation->timingFunction()));
2691                    list->append(cssValuePool().createValue(animation->delay(), CSSPrimitiveValue::CSS_S));
2692                    transitionsList->append(list);
2693                }
2694                return transitionsList.release();
2695            }
2696
2697            RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2698            // transition-property default value.
2699            list->append(cssValuePool().createIdentifierValue(CSSValueAll));
2700            list->append(cssValuePool().createValue(CSSAnimationData::initialAnimationDuration(), CSSPrimitiveValue::CSS_S));
2701            list->append(createTimingFunctionValue(CSSAnimationData::initialAnimationTimingFunction().get()));
2702            list->append(cssValuePool().createValue(CSSAnimationData::initialAnimationDelay(), CSSPrimitiveValue::CSS_S));
2703            return list.release();
2704        }
2705        case CSSPropertyPointerEvents:
2706            return cssValuePool().createValue(style->pointerEvents());
2707        case CSSPropertyWebkitLineGrid:
2708            if (style->lineGrid().isNull())
2709                return cssValuePool().createIdentifierValue(CSSValueNone);
2710            return cssValuePool().createValue(style->lineGrid(), CSSPrimitiveValue::CSS_STRING);
2711        case CSSPropertyWebkitLineSnap:
2712            return CSSPrimitiveValue::create(style->lineSnap());
2713        case CSSPropertyWebkitLineAlign:
2714            return CSSPrimitiveValue::create(style->lineAlign());
2715        case CSSPropertyWebkitWritingMode:
2716            return cssValuePool().createValue(style->writingMode());
2717        case CSSPropertyWebkitTextCombine:
2718            return cssValuePool().createValue(style->textCombine());
2719        case CSSPropertyWebkitTextOrientation:
2720            return CSSPrimitiveValue::create(style->textOrientation());
2721        case CSSPropertyWebkitLineBoxContain:
2722            return createLineBoxContainValue(style->lineBoxContain());
2723        case CSSPropertyContent:
2724            return valueForContentData(*style);
2725        case CSSPropertyCounterIncrement:
2726            return valueForCounterDirectives(*style, propertyID);
2727        case CSSPropertyCounterReset:
2728            return valueForCounterDirectives(*style, propertyID);
2729        case CSSPropertyWebkitClipPath:
2730            if (ClipPathOperation* operation = style->clipPath()) {
2731                if (operation->type() == ClipPathOperation::SHAPE)
2732                    return valueForBasicShape(*style, toShapeClipPathOperation(operation)->basicShape());
2733                if (operation->type() == ClipPathOperation::REFERENCE)
2734                    return CSSPrimitiveValue::create(toReferenceClipPathOperation(operation)->url(), CSSPrimitiveValue::CSS_URI);
2735            }
2736            return cssValuePool().createIdentifierValue(CSSValueNone);
2737        case CSSPropertyWebkitFlowInto:
2738            if (style->flowThread().isNull())
2739                return cssValuePool().createIdentifierValue(CSSValueNone);
2740            return cssValuePool().createValue(style->flowThread(), CSSPrimitiveValue::CSS_STRING);
2741        case CSSPropertyWebkitFlowFrom:
2742            if (!style->hasFlowFrom())
2743                return cssValuePool().createIdentifierValue(CSSValueNone);
2744            return cssValuePool().createValue(style->regionThread(), CSSPrimitiveValue::CSS_STRING);
2745        case CSSPropertyWebkitRegionFragment:
2746            return cssValuePool().createValue(style->regionFragment());
2747        case CSSPropertyWebkitWrapFlow:
2748            return cssValuePool().createValue(style->wrapFlow());
2749        case CSSPropertyShapeMargin:
2750            return cssValuePool().createValue(style->shapeMargin());
2751        case CSSPropertyShapePadding:
2752            return cssValuePool().createValue(style->shapePadding());
2753        case CSSPropertyShapeImageThreshold:
2754            return cssValuePool().createValue(style->shapeImageThreshold(), CSSPrimitiveValue::CSS_NUMBER);
2755        case CSSPropertyShapeInside:
2756            if (!style->shapeInside())
2757                return cssValuePool().createIdentifierValue(CSSValueAuto);
2758            if (style->shapeInside()->type() == ShapeValue::Box)
2759                return cssValuePool().createValue(style->shapeInside()->layoutBox());
2760            if (style->shapeInside()->type() == ShapeValue::Outside)
2761                return cssValuePool().createIdentifierValue(CSSValueOutsideShape);
2762            if (style->shapeInside()->type() == ShapeValue::Image) {
2763                if (style->shapeInside()->image())
2764                    return style->shapeInside()->image()->cssValue();
2765                return cssValuePool().createIdentifierValue(CSSValueNone);
2766            }
2767            ASSERT(style->shapeInside()->type() == ShapeValue::Shape);
2768            return valueForBasicShape(*style, style->shapeInside()->shape());
2769        case CSSPropertyShapeOutside:
2770            if (!style->shapeOutside())
2771                return cssValuePool().createIdentifierValue(CSSValueAuto);
2772            if (style->shapeOutside()->type() == ShapeValue::Box)
2773                return cssValuePool().createValue(style->shapeOutside()->layoutBox());
2774            if (style->shapeOutside()->type() == ShapeValue::Image) {
2775                if (style->shapeOutside()->image())
2776                    return style->shapeOutside()->image()->cssValue();
2777                return cssValuePool().createIdentifierValue(CSSValueNone);
2778            }
2779            ASSERT(style->shapeOutside()->type() == ShapeValue::Shape);
2780            return valueForBasicShape(*style, style->shapeOutside()->shape());
2781        case CSSPropertyWebkitWrapThrough:
2782            return cssValuePool().createValue(style->wrapThrough());
2783        case CSSPropertyWebkitFilter:
2784            return valueForFilter(renderer, *style);
2785        case CSSPropertyMixBlendMode:
2786            return cssValuePool().createValue(style->blendMode());
2787
2788        case CSSPropertyBackgroundBlendMode: {
2789            const FillLayer* layers = style->backgroundLayers();
2790            if (!layers->next())
2791                return cssValuePool().createValue(layers->blendMode());
2792
2793            RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2794            for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
2795                list->append(cssValuePool().createValue(currLayer->blendMode()));
2796
2797            return list.release();
2798        }
2799        case CSSPropertyBackground:
2800            return valuesForBackgroundShorthand();
2801        case CSSPropertyBorder: {
2802            RefPtr<CSSValue> value = getPropertyCSSValue(CSSPropertyBorderTop, DoNotUpdateLayout);
2803            const CSSPropertyID properties[3] = { CSSPropertyBorderRight, CSSPropertyBorderBottom,
2804                                        CSSPropertyBorderLeft };
2805            for (size_t i = 0; i < WTF_ARRAY_LENGTH(properties); ++i) {
2806                if (!compareCSSValuePtr<CSSValue>(value, getPropertyCSSValue(properties[i], DoNotUpdateLayout)))
2807                    return 0;
2808            }
2809            return value.release();
2810        }
2811        case CSSPropertyBorderBottom:
2812            return valuesForShorthandProperty(borderBottomShorthand());
2813        case CSSPropertyBorderColor:
2814            return valuesForSidesShorthand(borderColorShorthand());
2815        case CSSPropertyBorderLeft:
2816            return valuesForShorthandProperty(borderLeftShorthand());
2817        case CSSPropertyBorderImage:
2818            return valueForNinePieceImage(style->borderImage(), *style);
2819        case CSSPropertyBorderRadius:
2820            return valueForBorderRadiusShorthand(*style);
2821        case CSSPropertyBorderRight:
2822            return valuesForShorthandProperty(borderRightShorthand());
2823        case CSSPropertyBorderStyle:
2824            return valuesForSidesShorthand(borderStyleShorthand());
2825        case CSSPropertyBorderTop:
2826            return valuesForShorthandProperty(borderTopShorthand());
2827        case CSSPropertyBorderWidth:
2828            return valuesForSidesShorthand(borderWidthShorthand());
2829        case CSSPropertyWebkitColumnRule:
2830            return valuesForShorthandProperty(webkitColumnRuleShorthand());
2831        case CSSPropertyWebkitColumns:
2832            return valuesForShorthandProperty(webkitColumnsShorthand());
2833        case CSSPropertyListStyle:
2834            return valuesForShorthandProperty(listStyleShorthand());
2835        case CSSPropertyMargin:
2836            return valuesForSidesShorthand(marginShorthand());
2837        case CSSPropertyOutline:
2838            return valuesForShorthandProperty(outlineShorthand());
2839        case CSSPropertyPadding:
2840            return valuesForSidesShorthand(paddingShorthand());
2841        /* Individual properties not part of the spec */
2842        case CSSPropertyBackgroundRepeatX:
2843        case CSSPropertyBackgroundRepeatY:
2844            break;
2845        case CSSPropertyInternalCallback:
2846            // This property is hidden from the web.
2847            return 0;
2848
2849        /* Unimplemented CSS 3 properties (including CSS3 shorthand properties) */
2850        case CSSPropertyWebkitTextEmphasis:
2851        case CSSPropertyTextLineThroughColor:
2852        case CSSPropertyTextLineThroughMode:
2853        case CSSPropertyTextLineThroughStyle:
2854        case CSSPropertyTextLineThroughWidth:
2855        case CSSPropertyTextOverlineColor:
2856        case CSSPropertyTextOverlineMode:
2857        case CSSPropertyTextOverlineStyle:
2858        case CSSPropertyTextOverlineWidth:
2859        case CSSPropertyTextUnderlineColor:
2860        case CSSPropertyTextUnderlineMode:
2861        case CSSPropertyTextUnderlineStyle:
2862        case CSSPropertyTextUnderlineWidth:
2863            break;
2864
2865        /* Directional properties are resolved by resolveDirectionAwareProperty() before the switch. */
2866        case CSSPropertyWebkitBorderEnd:
2867        case CSSPropertyWebkitBorderEndColor:
2868        case CSSPropertyWebkitBorderEndStyle:
2869        case CSSPropertyWebkitBorderEndWidth:
2870        case CSSPropertyWebkitBorderStart:
2871        case CSSPropertyWebkitBorderStartColor:
2872        case CSSPropertyWebkitBorderStartStyle:
2873        case CSSPropertyWebkitBorderStartWidth:
2874        case CSSPropertyWebkitBorderAfter:
2875        case CSSPropertyWebkitBorderAfterColor:
2876        case CSSPropertyWebkitBorderAfterStyle:
2877        case CSSPropertyWebkitBorderAfterWidth:
2878        case CSSPropertyWebkitBorderBefore:
2879        case CSSPropertyWebkitBorderBeforeColor:
2880        case CSSPropertyWebkitBorderBeforeStyle:
2881        case CSSPropertyWebkitBorderBeforeWidth:
2882        case CSSPropertyWebkitMarginEnd:
2883        case CSSPropertyWebkitMarginStart:
2884        case CSSPropertyWebkitMarginAfter:
2885        case CSSPropertyWebkitMarginBefore:
2886        case CSSPropertyWebkitPaddingEnd:
2887        case CSSPropertyWebkitPaddingStart:
2888        case CSSPropertyWebkitPaddingAfter:
2889        case CSSPropertyWebkitPaddingBefore:
2890        case CSSPropertyWebkitLogicalWidth:
2891        case CSSPropertyWebkitLogicalHeight:
2892        case CSSPropertyWebkitMinLogicalWidth:
2893        case CSSPropertyWebkitMinLogicalHeight:
2894        case CSSPropertyWebkitMaxLogicalWidth:
2895        case CSSPropertyWebkitMaxLogicalHeight:
2896            ASSERT_NOT_REACHED();
2897            break;
2898
2899        /* Unimplemented @font-face properties */
2900        case CSSPropertyFontStretch:
2901        case CSSPropertySrc:
2902        case CSSPropertyUnicodeRange:
2903            break;
2904
2905        /* Other unimplemented properties */
2906        case CSSPropertyPage: // for @page
2907        case CSSPropertyQuotes: // FIXME: needs implementation
2908        case CSSPropertySize: // for @page
2909            break;
2910
2911        /* Unimplemented -webkit- properties */
2912        case CSSPropertyWebkitBorderRadius:
2913        case CSSPropertyWebkitMarginCollapse:
2914        case CSSPropertyWebkitMask:
2915        case CSSPropertyWebkitMaskRepeatX:
2916        case CSSPropertyWebkitMaskRepeatY:
2917        case CSSPropertyWebkitPerspectiveOriginX:
2918        case CSSPropertyWebkitPerspectiveOriginY:
2919        case CSSPropertyWebkitTextStroke:
2920        case CSSPropertyWebkitTransformOriginX:
2921        case CSSPropertyWebkitTransformOriginY:
2922        case CSSPropertyWebkitTransformOriginZ:
2923            break;
2924
2925        /* @viewport rule properties */
2926        case CSSPropertyMaxZoom:
2927        case CSSPropertyMinZoom:
2928        case CSSPropertyOrientation:
2929        case CSSPropertyUserZoom:
2930            break;
2931
2932        // Internal properties that shouldn't be exposed throught getComputedStyle.
2933        case CSSPropertyInternalMarqueeDirection:
2934        case CSSPropertyInternalMarqueeIncrement:
2935        case CSSPropertyInternalMarqueeRepetition:
2936        case CSSPropertyInternalMarqueeSpeed:
2937        case CSSPropertyInternalMarqueeStyle:
2938            ASSERT_NOT_REACHED();
2939            return 0;
2940
2941        case CSSPropertyBufferedRendering:
2942        case CSSPropertyClipPath:
2943        case CSSPropertyClipRule:
2944        case CSSPropertyMask:
2945        case CSSPropertyEnableBackground:
2946        case CSSPropertyFilter:
2947        case CSSPropertyFloodColor:
2948        case CSSPropertyFloodOpacity:
2949        case CSSPropertyLightingColor:
2950        case CSSPropertyStopColor:
2951        case CSSPropertyStopOpacity:
2952        case CSSPropertyColorInterpolation:
2953        case CSSPropertyColorInterpolationFilters:
2954        case CSSPropertyColorProfile:
2955        case CSSPropertyColorRendering:
2956        case CSSPropertyFill:
2957        case CSSPropertyFillOpacity:
2958        case CSSPropertyFillRule:
2959        case CSSPropertyMarker:
2960        case CSSPropertyMarkerEnd:
2961        case CSSPropertyMarkerMid:
2962        case CSSPropertyMarkerStart:
2963        case CSSPropertyMaskType:
2964        case CSSPropertyShapeRendering:
2965        case CSSPropertyStroke:
2966        case CSSPropertyStrokeDasharray:
2967        case CSSPropertyStrokeDashoffset:
2968        case CSSPropertyStrokeLinecap:
2969        case CSSPropertyStrokeLinejoin:
2970        case CSSPropertyStrokeMiterlimit:
2971        case CSSPropertyStrokeOpacity:
2972        case CSSPropertyStrokeWidth:
2973        case CSSPropertyAlignmentBaseline:
2974        case CSSPropertyBaselineShift:
2975        case CSSPropertyDominantBaseline:
2976        case CSSPropertyGlyphOrientationHorizontal:
2977        case CSSPropertyGlyphOrientationVertical:
2978        case CSSPropertyKerning:
2979        case CSSPropertyTextAnchor:
2980        case CSSPropertyVectorEffect:
2981        case CSSPropertyPaintOrder:
2982        case CSSPropertyWritingMode:
2983            return getSVGPropertyCSSValue(propertyID, DoNotUpdateLayout);
2984    }
2985
2986    logUnimplementedPropertyID(propertyID);
2987    return 0;
2988}
2989
2990String CSSComputedStyleDeclaration::getPropertyValue(CSSPropertyID propertyID) const
2991{
2992    RefPtr<CSSValue> value = getPropertyCSSValue(propertyID);
2993    if (value)
2994        return value->cssText();
2995    return "";
2996}
2997
2998
2999unsigned CSSComputedStyleDeclaration::length() const
3000{
3001    Node* node = m_node.get();
3002    if (!node)
3003        return 0;
3004
3005    RenderStyle* style = node->computedStyle(m_pseudoElementSpecifier);
3006    if (!style)
3007        return 0;
3008
3009    return computableProperties().size();
3010}
3011
3012String CSSComputedStyleDeclaration::item(unsigned i) const
3013{
3014    if (i >= length())
3015        return "";
3016
3017    return getPropertyNameString(computableProperties()[i]);
3018}
3019
3020bool CSSComputedStyleDeclaration::cssPropertyMatches(CSSPropertyID propertyID, const CSSValue* propertyValue) const
3021{
3022    if (propertyID == CSSPropertyFontSize && propertyValue->isPrimitiveValue() && m_node) {
3023        m_node->document().updateLayoutIgnorePendingStylesheets();
3024        RenderStyle* style = m_node->computedStyle(m_pseudoElementSpecifier);
3025        if (style && style->fontDescription().keywordSize()) {
3026            CSSValueID sizeValue = cssIdentifierForFontSizeKeyword(style->fontDescription().keywordSize());
3027            const CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(propertyValue);
3028            if (primitiveValue->isValueID() && primitiveValue->getValueID() == sizeValue)
3029                return true;
3030        }
3031    }
3032    RefPtr<CSSValue> value = getPropertyCSSValue(propertyID);
3033    return value && propertyValue && value->equals(*propertyValue);
3034}
3035
3036PassRefPtr<MutableStylePropertySet> CSSComputedStyleDeclaration::copyProperties() const
3037{
3038    return copyPropertiesInSet(computableProperties());
3039}
3040
3041PassRefPtr<CSSValueList> CSSComputedStyleDeclaration::valuesForShorthandProperty(const StylePropertyShorthand& shorthand) const
3042{
3043    RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
3044    for (size_t i = 0; i < shorthand.length(); ++i) {
3045        RefPtr<CSSValue> value = getPropertyCSSValue(shorthand.properties()[i], DoNotUpdateLayout);
3046        list->append(value);
3047    }
3048    return list.release();
3049}
3050
3051PassRefPtr<CSSValueList> CSSComputedStyleDeclaration::valuesForSidesShorthand(const StylePropertyShorthand& shorthand) const
3052{
3053    RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
3054    // Assume the properties are in the usual order top, right, bottom, left.
3055    RefPtr<CSSValue> topValue = getPropertyCSSValue(shorthand.properties()[0], DoNotUpdateLayout);
3056    RefPtr<CSSValue> rightValue = getPropertyCSSValue(shorthand.properties()[1], DoNotUpdateLayout);
3057    RefPtr<CSSValue> bottomValue = getPropertyCSSValue(shorthand.properties()[2], DoNotUpdateLayout);
3058    RefPtr<CSSValue> leftValue = getPropertyCSSValue(shorthand.properties()[3], DoNotUpdateLayout);
3059
3060    // All 4 properties must be specified.
3061    if (!topValue || !rightValue || !bottomValue || !leftValue)
3062        return 0;
3063
3064    bool showLeft = !compareCSSValuePtr(rightValue, leftValue);
3065    bool showBottom = !compareCSSValuePtr(topValue, bottomValue) || showLeft;
3066    bool showRight = !compareCSSValuePtr(topValue, rightValue) || showBottom;
3067
3068    list->append(topValue.release());
3069    if (showRight)
3070        list->append(rightValue.release());
3071    if (showBottom)
3072        list->append(bottomValue.release());
3073    if (showLeft)
3074        list->append(leftValue.release());
3075
3076    return list.release();
3077}
3078
3079PassRefPtr<CSSValueList> CSSComputedStyleDeclaration::valuesForGridShorthand(const StylePropertyShorthand& shorthand) const
3080{
3081    RefPtr<CSSValueList> list = CSSValueList::createSlashSeparated();
3082    for (size_t i = 0; i < shorthand.length(); ++i) {
3083        RefPtr<CSSValue> value = getPropertyCSSValue(shorthand.properties()[i], DoNotUpdateLayout);
3084        list->append(value.release());
3085    }
3086    return list.release();
3087}
3088
3089PassRefPtr<MutableStylePropertySet> CSSComputedStyleDeclaration::copyPropertiesInSet(const Vector<CSSPropertyID>& properties) const
3090{
3091    Vector<CSSProperty, 256> list;
3092    list.reserveInitialCapacity(properties.size());
3093    for (unsigned i = 0; i < properties.size(); ++i) {
3094        RefPtr<CSSValue> value = getPropertyCSSValue(properties[i]);
3095        if (value)
3096            list.append(CSSProperty(properties[i], value.release(), false));
3097    }
3098    return MutableStylePropertySet::create(list.data(), list.size());
3099}
3100
3101CSSRule* CSSComputedStyleDeclaration::parentRule() const
3102{
3103    return 0;
3104}
3105
3106PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(const String& propertyName)
3107{
3108    CSSPropertyID propertyID = cssPropertyID(propertyName);
3109    if (!propertyID)
3110        return 0;
3111    RefPtr<CSSValue> value = getPropertyCSSValue(propertyID);
3112    return value ? value->cloneForCSSOM() : 0;
3113}
3114
3115String CSSComputedStyleDeclaration::getPropertyValue(const String& propertyName)
3116{
3117    CSSPropertyID propertyID = cssPropertyID(propertyName);
3118    if (!propertyID || !RuntimeCSSEnabled::isCSSPropertyEnabled(propertyID))
3119        return String();
3120    return getPropertyValue(propertyID);
3121}
3122
3123String CSSComputedStyleDeclaration::getPropertyPriority(const String&)
3124{
3125    // All computed styles have a priority of not "important".
3126    return "";
3127}
3128
3129String CSSComputedStyleDeclaration::getPropertyShorthand(const String&)
3130{
3131    return "";
3132}
3133
3134bool CSSComputedStyleDeclaration::isPropertyImplicit(const String&)
3135{
3136    return false;
3137}
3138
3139void CSSComputedStyleDeclaration::setProperty(const String& name, const String&, const String&, ExceptionState& exceptionState)
3140{
3141    exceptionState.throwDOMException(NoModificationAllowedError, "These styles are computed, and therefore the '" + name + "' property is read-only.");
3142}
3143
3144String CSSComputedStyleDeclaration::removeProperty(const String& name, ExceptionState& exceptionState)
3145{
3146    exceptionState.throwDOMException(NoModificationAllowedError, "These styles are computed, and therefore the '" + name + "' property is read-only.");
3147    return String();
3148}
3149
3150PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValueInternal(CSSPropertyID propertyID)
3151{
3152    return getPropertyCSSValue(propertyID);
3153}
3154
3155String CSSComputedStyleDeclaration::getPropertyValueInternal(CSSPropertyID propertyID)
3156{
3157    return getPropertyValue(propertyID);
3158}
3159
3160void CSSComputedStyleDeclaration::setPropertyInternal(CSSPropertyID id, const String&, bool, ExceptionState& exceptionState)
3161{
3162    exceptionState.throwDOMException(NoModificationAllowedError, "These styles are computed, and therefore the '" + getPropertyNameString(id) + "' property is read-only.");
3163}
3164
3165const HashMap<AtomicString, String>* CSSComputedStyleDeclaration::variableMap() const
3166{
3167    ASSERT(RuntimeEnabledFeatures::cssVariablesEnabled());
3168    Node* styledNode = this->styledNode();
3169    if (!styledNode)
3170        return 0;
3171    RefPtr<RenderStyle> style = styledNode->computedStyle(styledNode->isPseudoElement() ? NOPSEUDO : m_pseudoElementSpecifier);
3172    if (!style)
3173        return 0;
3174    return style->variables();
3175}
3176
3177unsigned CSSComputedStyleDeclaration::variableCount() const
3178{
3179    ASSERT(RuntimeEnabledFeatures::cssVariablesEnabled());
3180    const HashMap<AtomicString, String>* variables = variableMap();
3181    if (!variables)
3182        return 0;
3183    return variables->size();
3184}
3185
3186String CSSComputedStyleDeclaration::variableValue(const AtomicString& name) const
3187{
3188    ASSERT(RuntimeEnabledFeatures::cssVariablesEnabled());
3189    const HashMap<AtomicString, String>* variables = variableMap();
3190    if (!variables)
3191        return emptyString();
3192    HashMap<AtomicString, String>::const_iterator it = variables->find(name);
3193    if (it == variables->end())
3194        return emptyString();
3195    return it->value;
3196}
3197
3198bool CSSComputedStyleDeclaration::setVariableValue(const AtomicString& name, const String&, ExceptionState& exceptionState)
3199{
3200    ASSERT(RuntimeEnabledFeatures::cssVariablesEnabled());
3201    exceptionState.throwDOMException(NoModificationAllowedError, "These styles are computed, and therefore the '" + name + "' property is read-only.");
3202    return false;
3203}
3204
3205bool CSSComputedStyleDeclaration::removeVariable(const AtomicString&)
3206{
3207    ASSERT(RuntimeEnabledFeatures::cssVariablesEnabled());
3208    return false;
3209}
3210
3211bool CSSComputedStyleDeclaration::clearVariables(ExceptionState& exceptionState)
3212{
3213    ASSERT(RuntimeEnabledFeatures::cssVariablesEnabled());
3214    exceptionState.throwDOMException(NoModificationAllowedError, "These styles are computed, and therefore variables may not be cleared.");
3215    return false;
3216}
3217
3218CSSComputedStyleDeclaration::ComputedCSSVariablesIterator::ComputedCSSVariablesIterator(const HashMap<AtomicString, String>* variables)
3219    : m_active(variables)
3220{
3221    ASSERT(RuntimeEnabledFeatures::cssVariablesEnabled());
3222    if (m_active) {
3223        m_it = variables->begin();
3224        m_end = variables->end();
3225    }
3226}
3227
3228void CSSComputedStyleDeclaration::ComputedCSSVariablesIterator::advance()
3229{
3230    ASSERT(m_active);
3231    ++m_it;
3232    m_active = !atEnd();
3233}
3234
3235AtomicString CSSComputedStyleDeclaration::ComputedCSSVariablesIterator::name() const
3236{
3237    ASSERT(m_active);
3238    return m_it->key;
3239}
3240
3241String CSSComputedStyleDeclaration::ComputedCSSVariablesIterator::value() const
3242{
3243    ASSERT(m_active);
3244    return m_it->value;
3245}
3246
3247PassRefPtr<CSSValueList> CSSComputedStyleDeclaration::valuesForBackgroundShorthand() const
3248{
3249    static const CSSPropertyID propertiesBeforeSlashSeperator[5] = { CSSPropertyBackgroundColor, CSSPropertyBackgroundImage,
3250                                                                     CSSPropertyBackgroundRepeat, CSSPropertyBackgroundAttachment,
3251                                                                     CSSPropertyBackgroundPosition };
3252    static const CSSPropertyID propertiesAfterSlashSeperator[3] = { CSSPropertyBackgroundSize, CSSPropertyBackgroundOrigin,
3253                                                                    CSSPropertyBackgroundClip };
3254
3255    RefPtr<CSSValueList> list = CSSValueList::createSlashSeparated();
3256    list->append(valuesForShorthandProperty(StylePropertyShorthand(CSSPropertyBackground, propertiesBeforeSlashSeperator, WTF_ARRAY_LENGTH(propertiesBeforeSlashSeperator))));
3257    list->append(valuesForShorthandProperty(StylePropertyShorthand(CSSPropertyBackground, propertiesAfterSlashSeperator, WTF_ARRAY_LENGTH(propertiesAfterSlashSeperator))));
3258    return list.release();
3259}
3260
3261} // namespace WebCore
3262