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