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