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