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