625961e487b536c1c6734ed6709ebb2169849397
[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 static Ref<CSSValue> paintOrder(PaintOrder paintOrder)
2483 {
2484     if (paintOrder == PaintOrderNormal)
2485         return CSSPrimitiveValue::createIdentifier(CSSValueNormal);
2486     
2487     auto paintOrderList = CSSValueList::createSpaceSeparated();
2488     switch (paintOrder) {
2489     case PaintOrderNormal:
2490         ASSERT_NOT_REACHED();
2491         break;
2492     case PaintOrderFill:
2493         paintOrderList->append(CSSPrimitiveValue::createIdentifier(CSSValueFill));
2494         break;
2495     case PaintOrderFillMarkers:
2496         paintOrderList->append(CSSPrimitiveValue::createIdentifier(CSSValueFill));
2497         paintOrderList->append(CSSPrimitiveValue::createIdentifier(CSSValueMarkers));
2498         break;
2499     case PaintOrderStroke:
2500         paintOrderList->append(CSSPrimitiveValue::createIdentifier(CSSValueStroke));
2501         break;
2502     case PaintOrderStrokeMarkers:
2503         paintOrderList->append(CSSPrimitiveValue::createIdentifier(CSSValueStroke));
2504         paintOrderList->append(CSSPrimitiveValue::createIdentifier(CSSValueMarkers));
2505         break;
2506     case PaintOrderMarkers:
2507         paintOrderList->append(CSSPrimitiveValue::createIdentifier(CSSValueMarkers));
2508         break;
2509     case PaintOrderMarkersStroke:
2510         paintOrderList->append(CSSPrimitiveValue::createIdentifier(CSSValueMarkers));
2511         paintOrderList->append(CSSPrimitiveValue::createIdentifier(CSSValueStroke));
2512         break;
2513     }
2514     return WTFMove(paintOrderList);
2515 }
2516
2517 inline static bool isFlexOrGrid(ContainerNode* element)
2518 {
2519     return element && element->computedStyle() && element->computedStyle()->isDisplayFlexibleOrGridBox();
2520 }
2521
2522 RefPtr<CSSValue> ComputedStyleExtractor::customPropertyValue(const String& propertyName)
2523 {
2524     Element* styledElement = this->styledElement();
2525     if (!styledElement)
2526         return nullptr;
2527     
2528     if (updateStyleIfNeededForProperty(*styledElement, CSSPropertyCustom)) {
2529         // Style update may change styledElement() to PseudoElement or back.
2530         styledElement = this->styledElement();
2531     }
2532
2533     std::unique_ptr<RenderStyle> ownedStyle;
2534     auto* style = computeRenderStyleForProperty(*styledElement, m_pseudoElementSpecifier, CSSPropertyCustom, ownedStyle);
2535     if (!style)
2536         return nullptr;
2537
2538     return style->customProperties().get(propertyName);
2539 }
2540
2541 String ComputedStyleExtractor::customPropertyText(const String& propertyName)
2542 {
2543     RefPtr<CSSValue> propertyValue = customPropertyValue(propertyName);
2544     return propertyValue ? propertyValue->cssText() : emptyString();
2545 }
2546
2547 RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID, EUpdateLayout updateLayout)
2548 {
2549     auto* styledElement = this->styledElement();
2550     if (!styledElement)
2551         return nullptr;
2552
2553     std::unique_ptr<RenderStyle> ownedStyle;
2554     const RenderStyle* style = nullptr;
2555     RenderObject* renderer = nullptr;
2556     bool forceFullLayout = false;
2557     if (updateLayout) {
2558         Document& document = m_element->document();
2559
2560         if (updateStyleIfNeededForProperty(*styledElement, propertyID)) {
2561             // Style update may change styledElement() to PseudoElement or back.
2562             styledElement = this->styledElement();
2563         }
2564         renderer = styledElement->renderer();
2565
2566         if (propertyID == CSSPropertyDisplay && !renderer && is<SVGElement>(*styledElement) && !downcast<SVGElement>(*styledElement).isValid())
2567             return nullptr;
2568
2569         style = computeRenderStyleForProperty(*styledElement, m_pseudoElementSpecifier, propertyID, ownedStyle);
2570
2571         // FIXME: Some of these cases could be narrowed down or optimized better.
2572         forceFullLayout = isLayoutDependent(propertyID, style, renderer)
2573             || styledElement->isInShadowTree()
2574             || (document.styleScope().resolverIfExists() && document.styleScope().resolverIfExists()->hasViewportDependentMediaQueries() && document.ownerElement());
2575
2576         if (forceFullLayout) {
2577             document.updateLayoutIgnorePendingStylesheets();
2578             styledElement = this->styledElement();
2579         }
2580     }
2581
2582     if (!updateLayout || forceFullLayout) {
2583         style = computeRenderStyleForProperty(*styledElement, m_pseudoElementSpecifier, propertyID, ownedStyle);
2584         renderer = styledElement->renderer();
2585     }
2586
2587     if (!style)
2588         return nullptr;
2589
2590     auto& cssValuePool = CSSValuePool::singleton();
2591     propertyID = CSSProperty::resolveDirectionAwareProperty(propertyID, style->direction(), style->writingMode());
2592
2593     switch (propertyID) {
2594         case CSSPropertyInvalid:
2595             break;
2596
2597         case CSSPropertyBackgroundColor:
2598             return cssValuePool.createColorValue(m_allowVisitedStyle? style->visitedDependentColor(CSSPropertyBackgroundColor) : style->backgroundColor());
2599         case CSSPropertyBackgroundImage:
2600         case CSSPropertyWebkitMaskImage: {
2601             auto& layers = propertyID == CSSPropertyWebkitMaskImage ? style->maskLayers() : style->backgroundLayers();
2602             if (!layers.next()) {
2603                 if (layers.image())
2604                     return layers.image()->cssValue();
2605                 return cssValuePool.createIdentifierValue(CSSValueNone);
2606             }
2607             auto list = CSSValueList::createCommaSeparated();
2608             for (auto* currLayer = &layers; currLayer; currLayer = currLayer->next()) {
2609                 if (currLayer->image())
2610                     list->append(currLayer->image()->cssValue());
2611                 else
2612                     list->append(cssValuePool.createIdentifierValue(CSSValueNone));
2613             }
2614             return WTFMove(list);
2615         }
2616         case CSSPropertyBackgroundSize:
2617         case CSSPropertyWebkitBackgroundSize:
2618         case CSSPropertyWebkitMaskSize: {
2619             auto& layers = propertyID == CSSPropertyWebkitMaskSize ? style->maskLayers() : style->backgroundLayers();
2620             if (!layers.next())
2621                 return fillSizeToCSSValue(layers.size(), *style);
2622             auto list = CSSValueList::createCommaSeparated();
2623             for (auto* currLayer = &layers; currLayer; currLayer = currLayer->next())
2624                 list->append(fillSizeToCSSValue(currLayer->size(), *style));
2625             return WTFMove(list);
2626         }
2627         case CSSPropertyBackgroundRepeat:
2628         case CSSPropertyWebkitMaskRepeat: {
2629             auto& layers = propertyID == CSSPropertyWebkitMaskRepeat ? style->maskLayers() : style->backgroundLayers();
2630             if (!layers.next())
2631                 return fillRepeatToCSSValue(layers.repeatX(), layers.repeatY());
2632             auto list = CSSValueList::createCommaSeparated();
2633             for (auto* currLayer = &layers; currLayer; currLayer = currLayer->next())
2634                 list->append(fillRepeatToCSSValue(currLayer->repeatX(), currLayer->repeatY()));
2635             return WTFMove(list);
2636         }
2637         case CSSPropertyWebkitMaskSourceType: {
2638             auto& layers = style->maskLayers();
2639             if (!layers.next())
2640                 return fillSourceTypeToCSSValue(layers.maskSourceType());
2641             auto list = CSSValueList::createCommaSeparated();
2642             for (auto* currLayer = &layers; currLayer; currLayer = currLayer->next())
2643                 list->append(fillSourceTypeToCSSValue(currLayer->maskSourceType()));
2644             return WTFMove(list);
2645         }
2646         case CSSPropertyWebkitBackgroundComposite:
2647         case CSSPropertyWebkitMaskComposite: {
2648             auto& layers = propertyID == CSSPropertyWebkitMaskComposite ? style->maskLayers() : style->backgroundLayers();
2649             if (!layers.next())
2650                 return cssValuePool.createValue(layers.composite());
2651             auto list = CSSValueList::createCommaSeparated();
2652             for (auto* currLayer = &layers; currLayer; currLayer = currLayer->next())
2653                 list->append(cssValuePool.createValue(currLayer->composite()));
2654             return WTFMove(list);
2655         }
2656         case CSSPropertyBackgroundAttachment: {
2657             auto& layers = style->backgroundLayers();
2658             if (!layers.next())
2659                 return cssValuePool.createValue(layers.attachment());
2660             auto list = CSSValueList::createCommaSeparated();
2661             for (auto* currLayer = &layers; currLayer; currLayer = currLayer->next())
2662                 list->append(cssValuePool.createValue(currLayer->attachment()));
2663             return WTFMove(list);
2664         }
2665         case CSSPropertyBackgroundClip:
2666         case CSSPropertyBackgroundOrigin:
2667         case CSSPropertyWebkitBackgroundClip:
2668         case CSSPropertyWebkitBackgroundOrigin:
2669         case CSSPropertyWebkitMaskClip:
2670         case CSSPropertyWebkitMaskOrigin: {
2671             auto& layers = (propertyID == CSSPropertyWebkitMaskClip || propertyID == CSSPropertyWebkitMaskOrigin) ? style->maskLayers() : style->backgroundLayers();
2672             bool isClip = propertyID == CSSPropertyBackgroundClip || propertyID == CSSPropertyWebkitBackgroundClip || propertyID == CSSPropertyWebkitMaskClip;
2673             if (!layers.next())
2674                 return cssValuePool.createValue(isClip ? layers.clip() : layers.origin());
2675             auto list = CSSValueList::createCommaSeparated();
2676             for (auto* currLayer = &layers; currLayer; currLayer = currLayer->next())
2677                 list->append(cssValuePool.createValue(isClip ? currLayer->clip() : currLayer->origin()));
2678             return WTFMove(list);
2679         }
2680         case CSSPropertyBackgroundPosition:
2681         case CSSPropertyWebkitMaskPosition: {
2682             auto& layers = propertyID == CSSPropertyWebkitMaskPosition ? style->maskLayers() : style->backgroundLayers();
2683             if (!layers.next())
2684                 return createPositionListForLayer(propertyID, layers, *style);
2685
2686             auto list = CSSValueList::createCommaSeparated();
2687             for (auto* currLayer = &layers; currLayer; currLayer = currLayer->next())
2688                 list->append(createPositionListForLayer(propertyID, *currLayer, *style));
2689             return WTFMove(list);
2690         }
2691         case CSSPropertyBackgroundPositionX:
2692         case CSSPropertyWebkitMaskPositionX: {
2693             auto& layers = propertyID == CSSPropertyWebkitMaskPositionX ? style->maskLayers() : style->backgroundLayers();
2694             if (!layers.next())
2695                 return cssValuePool.createValue(layers.xPosition());
2696
2697             auto list = CSSValueList::createCommaSeparated();
2698             for (auto* currLayer = &layers; currLayer; currLayer = currLayer->next())
2699                 list->append(cssValuePool.createValue(currLayer->xPosition()));
2700
2701             return WTFMove(list);
2702         }
2703         case CSSPropertyBackgroundPositionY:
2704         case CSSPropertyWebkitMaskPositionY: {
2705             auto& layers = propertyID == CSSPropertyWebkitMaskPositionY ? style->maskLayers() : style->backgroundLayers();
2706             if (!layers.next())
2707                 return cssValuePool.createValue(layers.yPosition());
2708
2709             auto list = CSSValueList::createCommaSeparated();
2710             for (auto* currLayer = &layers; currLayer; currLayer = currLayer->next())
2711                 list->append(cssValuePool.createValue(currLayer->yPosition()));
2712
2713             return WTFMove(list);
2714         }
2715         case CSSPropertyBorderCollapse:
2716             if (style->borderCollapse())
2717                 return cssValuePool.createIdentifierValue(CSSValueCollapse);
2718             return cssValuePool.createIdentifierValue(CSSValueSeparate);
2719         case CSSPropertyBorderSpacing: {
2720             auto list = CSSValueList::createSpaceSeparated();
2721             list->append(zoomAdjustedPixelValue(style->horizontalBorderSpacing(), *style));
2722             list->append(zoomAdjustedPixelValue(style->verticalBorderSpacing(), *style));
2723             return WTFMove(list);
2724         }
2725         case CSSPropertyWebkitBorderHorizontalSpacing:
2726             return zoomAdjustedPixelValue(style->horizontalBorderSpacing(), *style);
2727         case CSSPropertyWebkitBorderVerticalSpacing:
2728             return zoomAdjustedPixelValue(style->verticalBorderSpacing(), *style);
2729         case CSSPropertyBorderImageSource:
2730             if (style->borderImageSource())
2731                 return style->borderImageSource()->cssValue();
2732             return cssValuePool.createIdentifierValue(CSSValueNone);
2733         case CSSPropertyBorderTopColor:
2734             return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyBorderTopColor)) : currentColorOrValidColor(style, style->borderTopColor());
2735         case CSSPropertyBorderRightColor:
2736             return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyBorderRightColor)) : currentColorOrValidColor(style, style->borderRightColor());
2737         case CSSPropertyBorderBottomColor:
2738             return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyBorderBottomColor)) : currentColorOrValidColor(style, style->borderBottomColor());
2739         case CSSPropertyBorderLeftColor:
2740             return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyBorderLeftColor)) : currentColorOrValidColor(style, style->borderLeftColor());
2741         case CSSPropertyBorderTopStyle:
2742             return cssValuePool.createValue(style->borderTopStyle());
2743         case CSSPropertyBorderRightStyle:
2744             return cssValuePool.createValue(style->borderRightStyle());
2745         case CSSPropertyBorderBottomStyle:
2746             return cssValuePool.createValue(style->borderBottomStyle());
2747         case CSSPropertyBorderLeftStyle:
2748             return cssValuePool.createValue(style->borderLeftStyle());
2749         case CSSPropertyBorderTopWidth:
2750             return zoomAdjustedPixelValue(style->borderTopWidth(), *style);
2751         case CSSPropertyBorderRightWidth:
2752             return zoomAdjustedPixelValue(style->borderRightWidth(), *style);
2753         case CSSPropertyBorderBottomWidth:
2754             return zoomAdjustedPixelValue(style->borderBottomWidth(), *style);
2755         case CSSPropertyBorderLeftWidth:
2756             return zoomAdjustedPixelValue(style->borderLeftWidth(), *style);
2757         case CSSPropertyBottom:
2758             return positionOffsetValue(*style, CSSPropertyBottom);
2759         case CSSPropertyWebkitBoxAlign:
2760             return cssValuePool.createValue(style->boxAlign());
2761 #if ENABLE(CSS_BOX_DECORATION_BREAK)
2762         case CSSPropertyWebkitBoxDecorationBreak:
2763             if (style->boxDecorationBreak() == DSLICE)
2764                 return cssValuePool.createIdentifierValue(CSSValueSlice);
2765         return cssValuePool.createIdentifierValue(CSSValueClone);
2766 #endif
2767         case CSSPropertyWebkitBoxDirection:
2768             return cssValuePool.createValue(style->boxDirection());
2769         case CSSPropertyWebkitBoxFlex:
2770             return cssValuePool.createValue(style->boxFlex(), CSSPrimitiveValue::CSS_NUMBER);
2771         case CSSPropertyWebkitBoxFlexGroup:
2772             return cssValuePool.createValue(style->boxFlexGroup(), CSSPrimitiveValue::CSS_NUMBER);
2773         case CSSPropertyWebkitBoxLines:
2774             return cssValuePool.createValue(style->boxLines());
2775         case CSSPropertyWebkitBoxOrdinalGroup:
2776             return cssValuePool.createValue(style->boxOrdinalGroup(), CSSPrimitiveValue::CSS_NUMBER);
2777         case CSSPropertyWebkitBoxOrient:
2778             return cssValuePool.createValue(style->boxOrient());
2779         case CSSPropertyWebkitBoxPack:
2780             return cssValuePool.createValue(style->boxPack());
2781         case CSSPropertyWebkitBoxReflect:
2782             return valueForReflection(style->boxReflect(), *style);
2783         case CSSPropertyBoxShadow:
2784         case CSSPropertyWebkitBoxShadow:
2785             return valueForShadow(style->boxShadow(), propertyID, *style);
2786         case CSSPropertyCaptionSide:
2787             return cssValuePool.createValue(style->captionSide());
2788         case CSSPropertyClear:
2789             return cssValuePool.createValue(style->clear());
2790         case CSSPropertyColor:
2791             return cssValuePool.createColorValue(m_allowVisitedStyle ? style->visitedDependentColor(CSSPropertyColor) : style->color());
2792         case CSSPropertyWebkitPrintColorAdjust:
2793             return cssValuePool.createValue(style->printColorAdjust());
2794         case CSSPropertyWebkitColumnAxis:
2795             return cssValuePool.createValue(style->columnAxis());
2796         case CSSPropertyColumnCount:
2797             if (style->hasAutoColumnCount())
2798                 return cssValuePool.createIdentifierValue(CSSValueAuto);
2799             return cssValuePool.createValue(style->columnCount(), CSSPrimitiveValue::CSS_NUMBER);
2800         case CSSPropertyColumnFill:
2801             return cssValuePool.createValue(style->columnFill());
2802         case CSSPropertyColumnGap:
2803             if (style->hasNormalColumnGap())
2804                 return cssValuePool.createIdentifierValue(CSSValueNormal);
2805             return zoomAdjustedPixelValue(style->columnGap(), *style);
2806         case CSSPropertyWebkitColumnProgression:
2807             return cssValuePool.createValue(style->columnProgression());
2808         case CSSPropertyColumnRuleColor:
2809             return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyOutlineColor)) : currentColorOrValidColor(style, style->columnRuleColor());
2810         case CSSPropertyColumnRuleStyle:
2811             return cssValuePool.createValue(style->columnRuleStyle());
2812         case CSSPropertyColumnRuleWidth:
2813             return zoomAdjustedPixelValue(style->columnRuleWidth(), *style);
2814         case CSSPropertyColumnSpan:
2815             return cssValuePool.createIdentifierValue(style->columnSpan() ? CSSValueAll : CSSValueNone);
2816         case CSSPropertyWebkitColumnBreakAfter:
2817             return cssValuePool.createValue(convertToColumnBreak(style->breakAfter()));
2818         case CSSPropertyWebkitColumnBreakBefore:
2819             return cssValuePool.createValue(convertToColumnBreak(style->breakBefore()));
2820         case CSSPropertyWebkitColumnBreakInside:
2821             return cssValuePool.createValue(convertToColumnBreak(style->breakInside()));
2822         case CSSPropertyColumnWidth:
2823             if (style->hasAutoColumnWidth())
2824                 return cssValuePool.createIdentifierValue(CSSValueAuto);
2825             return zoomAdjustedPixelValue(style->columnWidth(), *style);
2826         case CSSPropertyTabSize:
2827             return cssValuePool.createValue(style->tabSize(), CSSPrimitiveValue::CSS_NUMBER);
2828 #if ENABLE(CSS_REGIONS)
2829         case CSSPropertyWebkitRegionBreakAfter:
2830             return cssValuePool.createValue(convertToRegionBreak(style->breakAfter()));
2831         case CSSPropertyWebkitRegionBreakBefore:
2832             return cssValuePool.createValue(convertToRegionBreak(style->breakBefore()));
2833         case CSSPropertyWebkitRegionBreakInside:
2834             return cssValuePool.createValue(convertToRegionBreak(style->breakInside()));
2835 #endif
2836         case CSSPropertyCursor: {
2837             RefPtr<CSSValueList> list;
2838             auto* cursors = style->cursors();
2839             if (cursors && cursors->size() > 0) {
2840                 list = CSSValueList::createCommaSeparated();
2841                 for (unsigned i = 0; i < cursors->size(); ++i)
2842                     if (StyleImage* image = cursors->at(i).image())
2843                         list->append(image->cssValue());
2844             }
2845             auto value = cssValuePool.createValue(style->cursor());
2846             if (list) {
2847                 list->append(WTFMove(value));
2848                 return list;
2849             }
2850             return WTFMove(value);
2851         }
2852 #if ENABLE(CURSOR_VISIBILITY)
2853         case CSSPropertyWebkitCursorVisibility:
2854             return cssValuePool.createValue(style->cursorVisibility());
2855 #endif
2856         case CSSPropertyDirection:
2857             return cssValuePool.createValue(style->direction());
2858         case CSSPropertyDisplay:
2859             return cssValuePool.createValue(style->display());
2860         case CSSPropertyEmptyCells:
2861             return cssValuePool.createValue(style->emptyCells());
2862         case CSSPropertyAlignContent:
2863             return valueForContentPositionAndDistributionWithOverflowAlignment(style->alignContent(), CSSValueStretch);
2864         case CSSPropertyAlignItems:
2865             return valueForItemPositionWithOverflowAlignment(style->alignItems());
2866         case CSSPropertyAlignSelf:
2867             return valueForItemPositionWithOverflowAlignment(resolveAlignSelfAuto(style->alignSelf(), styledElement->parentNode()));
2868         case CSSPropertyFlex:
2869             return getCSSPropertyValuesForShorthandProperties(flexShorthand());
2870         case CSSPropertyFlexBasis:
2871             return cssValuePool.createValue(style->flexBasis());
2872         case CSSPropertyFlexDirection:
2873             return cssValuePool.createValue(style->flexDirection());
2874         case CSSPropertyFlexFlow:
2875             return getCSSPropertyValuesForShorthandProperties(flexFlowShorthand());
2876         case CSSPropertyFlexGrow:
2877             return cssValuePool.createValue(style->flexGrow());
2878         case CSSPropertyFlexShrink:
2879             return cssValuePool.createValue(style->flexShrink());
2880         case CSSPropertyFlexWrap:
2881             return cssValuePool.createValue(style->flexWrap());
2882         case CSSPropertyJustifyContent:
2883             return valueForContentPositionAndDistributionWithOverflowAlignment(style->justifyContent(), CSSValueFlexStart);
2884 #if ENABLE(CSS_GRID_LAYOUT)
2885         case CSSPropertyJustifyItems:
2886             return valueForItemPositionWithOverflowAlignment(resolveJustifyItemsAuto(style->justifyItems(), styledElement->parentNode()));
2887         case CSSPropertyJustifySelf:
2888             return valueForItemPositionWithOverflowAlignment(resolveJustifySelfAuto(style->justifySelf(), styledElement->parentNode()));
2889 #endif
2890         case CSSPropertyOrder:
2891             return cssValuePool.createValue(style->order(), CSSPrimitiveValue::CSS_NUMBER);
2892         case CSSPropertyFloat:
2893             if (style->display() != NONE && style->hasOutOfFlowPosition())
2894                 return cssValuePool.createIdentifierValue(CSSValueNone);
2895             return cssValuePool.createValue(style->floating());
2896         case CSSPropertyFont: {
2897             auto computedFont = CSSFontValue::create();
2898             computedFont->style = fontStyleFromStyle(*style);
2899             if (style->fontDescription().variantCaps() == FontVariantCaps::Small)
2900                 computedFont->variant = CSSValuePool::singleton().createIdentifierValue(CSSValueSmallCaps);
2901             else
2902                 computedFont->variant = CSSValuePool::singleton().createIdentifierValue(CSSValueNormal);
2903             computedFont->weight = fontWeightFromStyle(*style);
2904             computedFont->size = fontSizeFromStyle(*style);
2905             computedFont->lineHeight = lineHeightFromStyle(*style);
2906             computedFont->family = fontFamilyListFromStyle(*style);
2907             return WTFMove(computedFont);
2908         }
2909         case CSSPropertyFontFamily:
2910             return fontFamilyFromStyle(*style);
2911         case CSSPropertyFontSize:
2912             return fontSizeFromStyle(*style);
2913         case CSSPropertyFontStyle:
2914             return fontStyleFromStyle(*style);
2915         case CSSPropertyFontVariant:
2916             return fontVariantFromStyle(*style);
2917         case CSSPropertyFontWeight:
2918             return fontWeightFromStyle(*style);
2919         case CSSPropertyFontSynthesis:
2920             return fontSynthesisFromStyle(*style);
2921         case CSSPropertyFontFeatureSettings: {
2922             const FontFeatureSettings& featureSettings = style->fontDescription().featureSettings();
2923             if (!featureSettings.size())
2924                 return cssValuePool.createIdentifierValue(CSSValueNormal);
2925             auto list = CSSValueList::createCommaSeparated();
2926             for (auto& feature : featureSettings)
2927                 list->append(CSSFontFeatureValue::create(FontTag(feature.tag()), feature.value()));
2928             return WTFMove(list);
2929         }
2930 #if ENABLE(VARIATION_FONTS)
2931         case CSSPropertyFontVariationSettings: {
2932             const FontVariationSettings& variationSettings = style->fontDescription().variationSettings();
2933             if (variationSettings.isEmpty())
2934                 return cssValuePool.createIdentifierValue(CSSValueNormal);
2935             auto list = CSSValueList::createCommaSeparated();
2936             for (auto& feature : variationSettings)
2937                 list->append(CSSFontVariationValue::create(feature.tag(), feature.value()));
2938             return WTFMove(list);
2939         }
2940 #endif
2941 #if ENABLE(CSS_GRID_LAYOUT)
2942         case CSSPropertyGridAutoFlow: {
2943             auto list = CSSValueList::createSpaceSeparated();
2944             ASSERT(style->isGridAutoFlowDirectionRow() || style->isGridAutoFlowDirectionColumn());
2945             if (style->isGridAutoFlowDirectionRow())
2946                 list->append(cssValuePool.createIdentifierValue(CSSValueRow));
2947             else
2948                 list->append(cssValuePool.createIdentifierValue(CSSValueColumn));
2949
2950             if (style->isGridAutoFlowAlgorithmDense())
2951                 list->append(cssValuePool.createIdentifierValue(CSSValueDense));
2952
2953             return WTFMove(list);
2954         }
2955
2956         // Specs mention that getComputedStyle() should return the used value of the property instead of the computed
2957         // one for grid-template-{rows|columns} but not for the grid-auto-{rows|columns} as things like
2958         // grid-auto-columns: 2fr; cannot be resolved to a value in pixels as the '2fr' means very different things
2959         // depending on the size of the explicit grid or the number of implicit tracks added to the grid. See
2960         // http://lists.w3.org/Archives/Public/www-style/2013Nov/0014.html
2961         case CSSPropertyGridAutoColumns:
2962             return valueForGridTrackSizeList(ForColumns, *style);
2963         case CSSPropertyGridAutoRows:
2964             return valueForGridTrackSizeList(ForRows, *style);
2965
2966         case CSSPropertyGridTemplateColumns:
2967             return valueForGridTrackList(ForColumns, renderer, *style);
2968         case CSSPropertyGridTemplateRows:
2969             return valueForGridTrackList(ForRows, renderer, *style);
2970
2971         case CSSPropertyGridColumnStart:
2972             return valueForGridPosition(style->gridItemColumnStart());
2973         case CSSPropertyGridColumnEnd:
2974             return valueForGridPosition(style->gridItemColumnEnd());
2975         case CSSPropertyGridRowStart:
2976             return valueForGridPosition(style->gridItemRowStart());
2977         case CSSPropertyGridRowEnd:
2978             return valueForGridPosition(style->gridItemRowEnd());
2979         case CSSPropertyGridArea:
2980             return getCSSPropertyValuesForGridShorthand(gridAreaShorthand());
2981         case CSSPropertyGridTemplate:
2982             return getCSSPropertyValuesForGridShorthand(gridTemplateShorthand());
2983         case CSSPropertyGrid:
2984             return getCSSPropertyValuesForGridShorthand(gridShorthand());
2985         case CSSPropertyGridColumn:
2986             return getCSSPropertyValuesForGridShorthand(gridColumnShorthand());
2987         case CSSPropertyGridRow:
2988             return getCSSPropertyValuesForGridShorthand(gridRowShorthand());
2989         case CSSPropertyGridTemplateAreas:
2990             if (!style->namedGridAreaRowCount()) {
2991                 ASSERT(!style->namedGridAreaColumnCount());
2992                 return cssValuePool.createIdentifierValue(CSSValueNone);
2993             }
2994             return CSSGridTemplateAreasValue::create(style->namedGridArea(), style->namedGridAreaRowCount(), style->namedGridAreaColumnCount());
2995         case CSSPropertyGridColumnGap:
2996             return zoomAdjustedPixelValueForLength(style->gridColumnGap(), *style);
2997         case CSSPropertyGridRowGap:
2998             return zoomAdjustedPixelValueForLength(style->gridRowGap(), *style);
2999         case CSSPropertyGridGap:
3000             return getCSSPropertyValuesForGridShorthand(gridGapShorthand());
3001 #endif /* ENABLE(CSS_GRID_LAYOUT) */
3002         case CSSPropertyHeight:
3003             if (renderer && !renderer->isRenderSVGModelObject()) {
3004                 // According to http://www.w3.org/TR/CSS2/visudet.html#the-height-property,
3005                 // the "height" property does not apply for non-replaced inline elements.
3006                 if (!renderer->isReplaced() && renderer->isInline())
3007                     return cssValuePool.createIdentifierValue(CSSValueAuto);
3008                 return zoomAdjustedPixelValue(sizingBox(*renderer).height(), *style);
3009             }
3010             return zoomAdjustedPixelValueForLength(style->height(), *style);
3011         case CSSPropertyWebkitHyphens:
3012             return cssValuePool.createValue(style->hyphens());
3013         case CSSPropertyWebkitHyphenateCharacter:
3014             if (style->hyphenationString().isNull())
3015                 return cssValuePool.createIdentifierValue(CSSValueAuto);
3016             return cssValuePool.createValue(style->hyphenationString(), CSSPrimitiveValue::CSS_STRING);
3017         case CSSPropertyWebkitHyphenateLimitAfter:
3018             if (style->hyphenationLimitAfter() < 0)
3019                 return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
3020             return CSSPrimitiveValue::create(style->hyphenationLimitAfter(), CSSPrimitiveValue::CSS_NUMBER);
3021         case CSSPropertyWebkitHyphenateLimitBefore:
3022             if (style->hyphenationLimitBefore() < 0)
3023                 return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
3024             return CSSPrimitiveValue::create(style->hyphenationLimitBefore(), CSSPrimitiveValue::CSS_NUMBER);
3025         case CSSPropertyWebkitHyphenateLimitLines:
3026             if (style->hyphenationLimitLines() < 0)
3027                 return CSSPrimitiveValue::createIdentifier(CSSValueNoLimit);
3028             return CSSPrimitiveValue::create(style->hyphenationLimitLines(), CSSPrimitiveValue::CSS_NUMBER);
3029         case CSSPropertyWebkitBorderFit:
3030             if (style->borderFit() == BorderFitBorder)
3031                 return cssValuePool.createIdentifierValue(CSSValueBorder);
3032             return cssValuePool.createIdentifierValue(CSSValueLines);
3033 #if ENABLE(CSS_IMAGE_ORIENTATION)
3034         case CSSPropertyImageOrientation:
3035             return cssValuePool.createValue(style->imageOrientation());
3036 #endif
3037         case CSSPropertyImageRendering:
3038             return CSSPrimitiveValue::create(style->imageRendering());
3039 #if ENABLE(CSS_IMAGE_RESOLUTION)
3040         case CSSPropertyImageResolution:
3041             return cssValuePool.createValue(style->imageResolution(), CSSPrimitiveValue::CSS_DPPX);
3042 #endif
3043         case CSSPropertyLeft:
3044             return positionOffsetValue(*style, CSSPropertyLeft);
3045         case CSSPropertyLetterSpacing:
3046             if (!style->letterSpacing())
3047                 return cssValuePool.createIdentifierValue(CSSValueNormal);
3048             return zoomAdjustedPixelValue(style->letterSpacing(), *style);
3049         case CSSPropertyWebkitLineClamp:
3050             if (style->lineClamp().isNone())
3051                 return cssValuePool.createIdentifierValue(CSSValueNone);
3052             return cssValuePool.createValue(style->lineClamp().value(), style->lineClamp().isPercentage() ? CSSPrimitiveValue::CSS_PERCENTAGE : CSSPrimitiveValue::CSS_NUMBER);
3053         case CSSPropertyLineHeight:
3054             return lineHeightFromStyle(*style);
3055         case CSSPropertyListStyleImage:
3056             if (style->listStyleImage())
3057                 return style->listStyleImage()->cssValue();
3058             return cssValuePool.createIdentifierValue(CSSValueNone);
3059         case CSSPropertyListStylePosition:
3060             return cssValuePool.createValue(style->listStylePosition());
3061         case CSSPropertyListStyleType:
3062             return cssValuePool.createValue(style->listStyleType());
3063         case CSSPropertyWebkitLocale:
3064             if (style->locale().isNull())
3065                 return cssValuePool.createIdentifierValue(CSSValueAuto);
3066             return cssValuePool.createValue(style->locale(), CSSPrimitiveValue::CSS_STRING);
3067         case CSSPropertyMarginTop:
3068             return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::marginTop, &RenderBoxModelObject::marginTop>(*style, renderer);
3069         case CSSPropertyMarginRight: {
3070             Length marginRight = style->marginRight();
3071             if (marginRight.isFixed() || !is<RenderBox>(renderer))
3072                 return zoomAdjustedPixelValueForLength(marginRight, *style);
3073             float value;
3074             if (marginRight.isPercentOrCalculated()) {
3075                 // RenderBox gives a marginRight() that is the distance between the right-edge of the child box
3076                 // and the right-edge of the containing box, when display == BLOCK. Let's calculate the absolute
3077                 // value of the specified margin-right % instead of relying on RenderBox's marginRight() value.
3078                 value = minimumValueForLength(marginRight, downcast<RenderBox>(*renderer).containingBlockLogicalWidthForContent());
3079             } else
3080                 value = downcast<RenderBox>(*renderer).marginRight();
3081             return zoomAdjustedPixelValue(value, *style);
3082         }
3083         case CSSPropertyMarginBottom:
3084             return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::marginBottom, &RenderBoxModelObject::marginBottom>(*style, renderer);
3085         case CSSPropertyMarginLeft:
3086             return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::marginLeft, &RenderBoxModelObject::marginLeft>(*style, renderer);
3087         case CSSPropertyWebkitMarqueeDirection:
3088             return cssValuePool.createValue(style->marqueeDirection());
3089         case CSSPropertyWebkitMarqueeIncrement:
3090             return cssValuePool.createValue(style->marqueeIncrement());
3091         case CSSPropertyWebkitMarqueeRepetition:
3092             if (style->marqueeLoopCount() < 0)
3093                 return cssValuePool.createIdentifierValue(CSSValueInfinite);
3094             return cssValuePool.createValue(style->marqueeLoopCount(), CSSPrimitiveValue::CSS_NUMBER);
3095         case CSSPropertyWebkitMarqueeStyle:
3096             return cssValuePool.createValue(style->marqueeBehavior());
3097         case CSSPropertyWebkitUserModify:
3098             return cssValuePool.createValue(style->userModify());
3099         case CSSPropertyMaxHeight: {
3100             const Length& maxHeight = style->maxHeight();
3101             if (maxHeight.isUndefined())
3102                 return cssValuePool.createIdentifierValue(CSSValueNone);
3103             return zoomAdjustedPixelValueForLength(maxHeight, *style);
3104         }
3105         case CSSPropertyMaxWidth: {
3106             const Length& maxWidth = style->maxWidth();
3107             if (maxWidth.isUndefined())
3108                 return cssValuePool.createIdentifierValue(CSSValueNone);
3109             return zoomAdjustedPixelValueForLength(maxWidth, *style);
3110         }
3111         case CSSPropertyMinHeight:
3112             if (style->minHeight().isAuto()) {
3113                 if (isFlexOrGrid(styledElement->parentNode()))
3114                     return cssValuePool.createIdentifierValue(CSSValueAuto);
3115                 return zoomAdjustedPixelValue(0, *style);
3116             }
3117             return zoomAdjustedPixelValueForLength(style->minHeight(), *style);
3118         case CSSPropertyMinWidth:
3119             if (style->minWidth().isAuto()) {
3120                 if (isFlexOrGrid(styledElement->parentNode()))
3121                     return cssValuePool.createIdentifierValue(CSSValueAuto);
3122                 return zoomAdjustedPixelValue(0, *style);
3123             }
3124             return zoomAdjustedPixelValueForLength(style->minWidth(), *style);
3125         case CSSPropertyObjectFit:
3126             return cssValuePool.createValue(style->objectFit());
3127         case CSSPropertyObjectPosition: {
3128             auto list = CSSValueList::createSpaceSeparated();
3129             list->append(zoomAdjustedPixelValueForLength(style->objectPosition().x(), *style));
3130             list->append(zoomAdjustedPixelValueForLength(style->objectPosition().y(), *style));
3131             return WTFMove(list);
3132         }
3133         case CSSPropertyOpacity:
3134             return cssValuePool.createValue(style->opacity(), CSSPrimitiveValue::CSS_NUMBER);
3135         case CSSPropertyOrphans:
3136             if (style->hasAutoOrphans())
3137                 return cssValuePool.createIdentifierValue(CSSValueAuto);
3138             return cssValuePool.createValue(style->orphans(), CSSPrimitiveValue::CSS_NUMBER);
3139         case CSSPropertyOutlineColor:
3140             return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyOutlineColor)) : currentColorOrValidColor(style, style->outlineColor());
3141         case CSSPropertyOutlineOffset:
3142             return zoomAdjustedPixelValue(style->outlineOffset(), *style);
3143         case CSSPropertyOutlineStyle:
3144             if (style->outlineStyleIsAuto())
3145                 return cssValuePool.createIdentifierValue(CSSValueAuto);
3146             return cssValuePool.createValue(style->outlineStyle());
3147         case CSSPropertyOutlineWidth:
3148             return zoomAdjustedPixelValue(style->outlineWidth(), *style);
3149         case CSSPropertyOverflow:
3150             return cssValuePool.createValue(std::max(style->overflowX(), style->overflowY()));
3151         case CSSPropertyOverflowWrap:
3152             return cssValuePool.createValue(style->overflowWrap());
3153         case CSSPropertyOverflowX:
3154             return cssValuePool.createValue(style->overflowX());
3155         case CSSPropertyOverflowY:
3156             return cssValuePool.createValue(style->overflowY());
3157         case CSSPropertyPaddingTop:
3158             return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::paddingTop, &RenderBoxModelObject::computedCSSPaddingTop>(*style, renderer);
3159         case CSSPropertyPaddingRight:
3160             return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::paddingRight, &RenderBoxModelObject::computedCSSPaddingRight>(*style, renderer);
3161         case CSSPropertyPaddingBottom:
3162             return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::paddingBottom, &RenderBoxModelObject::computedCSSPaddingBottom>(*style, renderer);
3163         case CSSPropertyPaddingLeft:
3164             return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::paddingLeft, &RenderBoxModelObject::computedCSSPaddingLeft>(*style, renderer);
3165         case CSSPropertyPageBreakAfter:
3166             return cssValuePool.createValue(convertToPageBreak(style->breakAfter()));
3167         case CSSPropertyPageBreakBefore:
3168             return cssValuePool.createValue(convertToPageBreak(style->breakBefore()));
3169         case CSSPropertyPageBreakInside:
3170             return cssValuePool.createValue(convertToPageBreak(style->breakInside()));
3171         case CSSPropertyBreakAfter:
3172             return cssValuePool.createValue(style->breakAfter());
3173         case CSSPropertyBreakBefore:
3174             return cssValuePool.createValue(style->breakBefore());
3175         case CSSPropertyBreakInside:
3176             return cssValuePool.createValue(style->breakInside());
3177         case CSSPropertyHangingPunctuation:
3178             return hangingPunctuationToCSSValue(style->hangingPunctuation());
3179         case CSSPropertyPosition:
3180             return cssValuePool.createValue(style->position());
3181         case CSSPropertyRight:
3182             return positionOffsetValue(*style, CSSPropertyRight);
3183         case CSSPropertyWebkitRubyPosition:
3184             return cssValuePool.createValue(style->rubyPosition());
3185         case CSSPropertyTableLayout:
3186             return cssValuePool.createValue(style->tableLayout());
3187         case CSSPropertyTextAlign:
3188             return cssValuePool.createValue(style->textAlign());
3189         case CSSPropertyTextDecoration:
3190             return renderTextDecorationFlagsToCSSValue(style->textDecoration());
3191 #if ENABLE(CSS3_TEXT)
3192         case CSSPropertyWebkitTextAlignLast:
3193             return cssValuePool.createValue(style->textAlignLast());
3194         case CSSPropertyWebkitTextJustify:
3195             return cssValuePool.createValue(style->textJustify());
3196 #endif // CSS3_TEXT
3197         case CSSPropertyWebkitTextDecoration:
3198             return getCSSPropertyValuesForShorthandProperties(webkitTextDecorationShorthand());
3199         case CSSPropertyWebkitTextDecorationLine:
3200             return renderTextDecorationFlagsToCSSValue(style->textDecoration());
3201         case CSSPropertyWebkitTextDecorationStyle:
3202             return renderTextDecorationStyleFlagsToCSSValue(style->textDecorationStyle());
3203         case CSSPropertyWebkitTextDecorationColor:
3204             return currentColorOrValidColor(style, style->textDecorationColor());
3205         case CSSPropertyWebkitTextDecorationSkip:
3206             return renderTextDecorationSkipFlagsToCSSValue(style->textDecorationSkip());
3207         case CSSPropertyWebkitTextUnderlinePosition:
3208             return cssValuePool.createValue(style->textUnderlinePosition());
3209         case CSSPropertyWebkitTextDecorationsInEffect:
3210             return renderTextDecorationFlagsToCSSValue(style->textDecorationsInEffect());
3211         case CSSPropertyWebkitTextFillColor:
3212             return currentColorOrValidColor(style, style->textFillColor());
3213         case CSSPropertyWebkitTextEmphasisColor:
3214             return currentColorOrValidColor(style, style->textEmphasisColor());
3215         case CSSPropertyWebkitTextEmphasisPosition:
3216             return renderEmphasisPositionFlagsToCSSValue(style->textEmphasisPosition());
3217         case CSSPropertyWebkitTextEmphasisStyle:
3218             switch (style->textEmphasisMark()) {
3219             case TextEmphasisMarkNone:
3220                 return cssValuePool.createIdentifierValue(CSSValueNone);
3221             case TextEmphasisMarkCustom:
3222                 return cssValuePool.createValue(style->textEmphasisCustomMark(), CSSPrimitiveValue::CSS_STRING);
3223             case TextEmphasisMarkAuto:
3224                 ASSERT_NOT_REACHED();
3225 #if ASSERT_DISABLED
3226                 FALLTHROUGH;
3227 #endif
3228             case TextEmphasisMarkDot:
3229             case TextEmphasisMarkCircle:
3230             case TextEmphasisMarkDoubleCircle:
3231             case TextEmphasisMarkTriangle:
3232             case TextEmphasisMarkSesame:
3233                 auto list = CSSValueList::createSpaceSeparated();
3234                 list->append(cssValuePool.createValue(style->textEmphasisFill()));
3235                 list->append(cssValuePool.createValue(style->textEmphasisMark()));
3236                 return WTFMove(list);
3237             }
3238         case CSSPropertyTextIndent: {
3239             // If CSS3_TEXT is disabled or text-indent has only one value(<length> | <percentage>),
3240             // getPropertyCSSValue() returns CSSValue.
3241             auto textIndent = zoomAdjustedPixelValueForLength(style->textIndent(), *style);
3242 #if ENABLE(CSS3_TEXT)
3243             // If CSS3_TEXT is enabled and text-indent has -webkit-each-line or -webkit-hanging,
3244             // getPropertyCSSValue() returns CSSValueList.
3245             if (style->textIndentLine() == TextIndentEachLine || style->textIndentType() == TextIndentHanging) {
3246                 auto list = CSSValueList::createSpaceSeparated();
3247                 list->append(WTFMove(textIndent));
3248                 if (style->textIndentLine() == TextIndentEachLine)
3249                     list->append(cssValuePool.createIdentifierValue(CSSValueWebkitEachLine));
3250                 if (style->textIndentType() == TextIndentHanging)
3251                     list->append(cssValuePool.createIdentifierValue(CSSValueWebkitHanging));
3252                 return WTFMove(list);
3253             }
3254 #endif
3255             return WTFMove(textIndent);
3256         }
3257         case CSSPropertyTextShadow:
3258             return valueForShadow(style->textShadow(), propertyID, *style);
3259         case CSSPropertyTextRendering:
3260             return cssValuePool.createValue(style->fontDescription().textRenderingMode());
3261         case CSSPropertyTextOverflow:
3262             if (style->textOverflow())
3263                 return cssValuePool.createIdentifierValue(CSSValueEllipsis);
3264             return cssValuePool.createIdentifierValue(CSSValueClip);
3265         case CSSPropertyWebkitTextSecurity:
3266             return cssValuePool.createValue(style->textSecurity());
3267 #if ENABLE(TEXT_AUTOSIZING)
3268         case CSSPropertyWebkitTextSizeAdjust:
3269             if (style->textSizeAdjust().isAuto())
3270                 return cssValuePool.createIdentifierValue(CSSValueAuto);
3271             if (style->textSizeAdjust().isNone())
3272                 return cssValuePool.createIdentifierValue(CSSValueNone);
3273             return CSSPrimitiveValue::create(style->textSizeAdjust().percentage(), CSSPrimitiveValue::CSS_PERCENTAGE);
3274 #endif
3275         case CSSPropertyWebkitTextStrokeColor:
3276             return currentColorOrValidColor(style, style->textStrokeColor());
3277         case CSSPropertyWebkitTextStrokeWidth:
3278             return zoomAdjustedPixelValue(style->textStrokeWidth(), *style);
3279         case CSSPropertyTextTransform:
3280             return cssValuePool.createValue(style->textTransform());
3281         case CSSPropertyTop:
3282             return positionOffsetValue(*style, CSSPropertyTop);
3283         case CSSPropertyUnicodeBidi:
3284             return cssValuePool.createValue(style->unicodeBidi());
3285         case CSSPropertyVerticalAlign:
3286             switch (style->verticalAlign()) {
3287                 case BASELINE:
3288                     return cssValuePool.createIdentifierValue(CSSValueBaseline);
3289                 case MIDDLE:
3290                     return cssValuePool.createIdentifierValue(CSSValueMiddle);
3291                 case SUB:
3292                     return cssValuePool.createIdentifierValue(CSSValueSub);
3293                 case SUPER:
3294                     return cssValuePool.createIdentifierValue(CSSValueSuper);
3295                 case TEXT_TOP:
3296                     return cssValuePool.createIdentifierValue(CSSValueTextTop);
3297                 case TEXT_BOTTOM:
3298                     return cssValuePool.createIdentifierValue(CSSValueTextBottom);
3299                 case TOP:
3300                     return cssValuePool.createIdentifierValue(CSSValueTop);
3301                 case BOTTOM:
3302                     return cssValuePool.createIdentifierValue(CSSValueBottom);
3303                 case BASELINE_MIDDLE:
3304                     return cssValuePool.createIdentifierValue(CSSValueWebkitBaselineMiddle);
3305                 case LENGTH:
3306                     return cssValuePool.createValue(style->verticalAlignLength());
3307             }
3308             ASSERT_NOT_REACHED();
3309             return nullptr;
3310         case CSSPropertyVisibility:
3311             return cssValuePool.createValue(style->visibility());
3312         case CSSPropertyWhiteSpace:
3313             return cssValuePool.createValue(style->whiteSpace());
3314         case CSSPropertyWidows:
3315             if (style->hasAutoWidows())
3316                 return cssValuePool.createIdentifierValue(CSSValueAuto);
3317             return cssValuePool.createValue(style->widows(), CSSPrimitiveValue::CSS_NUMBER);
3318         case CSSPropertyWidth:
3319             if (renderer && !renderer->isRenderSVGModelObject()) {
3320                 // According to http://www.w3.org/TR/CSS2/visudet.html#the-width-property,
3321                 // the "width" property does not apply for non-replaced inline elements.
3322                 if (!renderer->isReplaced() && renderer->isInline())
3323                     return cssValuePool.createIdentifierValue(CSSValueAuto);
3324                 return zoomAdjustedPixelValue(sizingBox(*renderer).width(), *style);
3325             }
3326             return zoomAdjustedPixelValueForLength(style->width(), *style);
3327         case CSSPropertyWillChange:
3328             return willChangePropertyValue(style->willChange());
3329         case CSSPropertyWordBreak:
3330             return cssValuePool.createValue(style->wordBreak());
3331         case CSSPropertyWordSpacing:
3332             return zoomAdjustedPixelValue(style->fontCascade().wordSpacing(), *style);
3333         case CSSPropertyWordWrap:
3334             return cssValuePool.createValue(style->overflowWrap());
3335         case CSSPropertyWebkitLineBreak:
3336             return cssValuePool.createValue(style->lineBreak());
3337         case CSSPropertyWebkitNbspMode:
3338             return cssValuePool.createValue(style->nbspMode());
3339         case CSSPropertyResize:
3340             return cssValuePool.createValue(style->resize());
3341         case CSSPropertyWebkitFontKerning:
3342             return cssValuePool.createValue(style->fontDescription().kerning());
3343         case CSSPropertyWebkitFontSmoothing:
3344             return cssValuePool.createValue(style->fontDescription().fontSmoothing());
3345         case CSSPropertyFontVariantLigatures:
3346             return fontVariantLigaturesPropertyValue(style->fontDescription().variantCommonLigatures(), style->fontDescription().variantDiscretionaryLigatures(), style->fontDescription().variantHistoricalLigatures(), style->fontDescription().variantContextualAlternates());
3347         case CSSPropertyFontVariantPosition:
3348             return fontVariantPositionPropertyValue(style->fontDescription().variantPosition());
3349         case CSSPropertyFontVariantCaps:
3350             return fontVariantCapsPropertyValue(style->fontDescription().variantCaps());
3351         case CSSPropertyFontVariantNumeric:
3352             return fontVariantNumericPropertyValue(style->fontDescription().variantNumericFigure(), style->fontDescription().variantNumericSpacing(), style->fontDescription().variantNumericFraction(), style->fontDescription().variantNumericOrdinal(), style->fontDescription().variantNumericSlashedZero());
3353         case CSSPropertyFontVariantAlternates:
3354             return fontVariantAlternatesPropertyValue(style->fontDescription().variantAlternates());
3355         case CSSPropertyFontVariantEastAsian:
3356             return fontVariantEastAsianPropertyValue(style->fontDescription().variantEastAsianVariant(), style->fontDescription().variantEastAsianWidth(), style->fontDescription().variantEastAsianRuby());
3357         case CSSPropertyZIndex:
3358             if (style->hasAutoZIndex())
3359                 return cssValuePool.createIdentifierValue(CSSValueAuto);
3360             return cssValuePool.createValue(style->zIndex(), CSSPrimitiveValue::CSS_NUMBER);
3361         case CSSPropertyZoom:
3362             return cssValuePool.createValue(style->zoom(), CSSPrimitiveValue::CSS_NUMBER);
3363         case CSSPropertyBoxSizing:
3364             if (style->boxSizing() == CONTENT_BOX)
3365                 return cssValuePool.createIdentifierValue(CSSValueContentBox);
3366             return cssValuePool.createIdentifierValue(CSSValueBorderBox);
3367 #if ENABLE(DASHBOARD_SUPPORT)
3368         case CSSPropertyWebkitDashboardRegion:
3369         {
3370             const Vector<StyleDashboardRegion>& regions = style->dashboardRegions();
3371             unsigned count = regions.size();
3372             if (count == 1 && regions[0].type == StyleDashboardRegion::None)
3373                 return cssValuePool.createIdentifierValue(CSSValueNone);
3374
3375             RefPtr<DashboardRegion> firstRegion;
3376             DashboardRegion* previousRegion = nullptr;
3377             for (unsigned i = 0; i < count; i++) {
3378                 auto region = DashboardRegion::create();
3379                 StyleDashboardRegion styleRegion = regions[i];
3380
3381                 region->m_label = styleRegion.label;
3382                 LengthBox offset = styleRegion.offset;
3383                 region->setTop(zoomAdjustedPixelValue(offset.top().value(), *style));
3384                 region->setRight(zoomAdjustedPixelValue(offset.right().value(), *style));
3385                 region->setBottom(zoomAdjustedPixelValue(offset.bottom().value(), *style));
3386                 region->setLeft(zoomAdjustedPixelValue(offset.left().value(), *style));
3387                 region->m_isRectangle = (styleRegion.type == StyleDashboardRegion::Rectangle);
3388                 region->m_isCircle = (styleRegion.type == StyleDashboardRegion::Circle);
3389
3390                 if (previousRegion)
3391                     previousRegion->m_next = region.copyRef();
3392                 else
3393                     firstRegion = region.copyRef();
3394                 previousRegion = region.ptr();
3395             }
3396             return cssValuePool.createValue(WTFMove(firstRegion));
3397         }
3398 #endif
3399         case CSSPropertyAnimationDelay:
3400             return delayValue(style->animations());
3401         case CSSPropertyAnimationDirection: {
3402             auto list = CSSValueList::createCommaSeparated();
3403             const AnimationList* t = style->animations();
3404             if (t) {
3405                 for (size_t i = 0; i < t->size(); ++i) {
3406                     switch (t->animation(i).direction()) {
3407                     case Animation::AnimationDirectionNormal:
3408                         list->append(cssValuePool.createIdentifierValue(CSSValueNormal));
3409                         break;
3410                     case Animation::AnimationDirectionAlternate:
3411                         list->append(cssValuePool.createIdentifierValue(CSSValueAlternate));
3412                         break;
3413                     case Animation::AnimationDirectionReverse:
3414                         list->append(cssValuePool.createIdentifierValue(CSSValueReverse));
3415                         break;
3416                     case Animation::AnimationDirectionAlternateReverse:
3417                         list->append(cssValuePool.createIdentifierValue(CSSValueAlternateReverse));
3418                         break;
3419                     }
3420                 }
3421             } else
3422                 list->append(cssValuePool.createIdentifierValue(CSSValueNormal));
3423             return WTFMove(list);
3424         }
3425         case CSSPropertyAnimationDuration:
3426             return durationValue(style->animations());
3427         case CSSPropertyAnimationFillMode: {
3428             auto list = CSSValueList::createCommaSeparated();
3429             const AnimationList* t = style->animations();
3430             if (t) {
3431                 for (size_t i = 0; i < t->size(); ++i) {
3432                     switch (t->animation(i).fillMode()) {
3433                     case AnimationFillModeNone:
3434                         list->append(cssValuePool.createIdentifierValue(CSSValueNone));
3435                         break;
3436                     case AnimationFillModeForwards:
3437                         list->append(cssValuePool.createIdentifierValue(CSSValueForwards));
3438                         break;
3439                     case AnimationFillModeBackwards:
3440                         list->append(cssValuePool.createIdentifierValue(CSSValueBackwards));
3441                         break;
3442                     case AnimationFillModeBoth:
3443                         list->append(cssValuePool.createIdentifierValue(CSSValueBoth));
3444                         break;
3445                     }
3446                 }
3447             } else
3448                 list->append(cssValuePool.createIdentifierValue(CSSValueNone));
3449             return WTFMove(list);
3450         }
3451         case CSSPropertyAnimationIterationCount: {
3452             auto list = CSSValueList::createCommaSeparated();
3453             const AnimationList* t = style->animations();
3454             if (t) {
3455                 for (size_t i = 0; i < t->size(); ++i) {
3456                     double iterationCount = t->animation(i).iterationCount();
3457                     if (iterationCount == Animation::IterationCountInfinite)
3458                         list->append(cssValuePool.createIdentifierValue(CSSValueInfinite));
3459                     else
3460                         list->append(cssValuePool.createValue(iterationCount, CSSPrimitiveValue::CSS_NUMBER));
3461                 }
3462             } else
3463                 list->append(cssValuePool.createValue(Animation::initialIterationCount(), CSSPrimitiveValue::CSS_NUMBER));
3464             return WTFMove(list);
3465         }
3466         case CSSPropertyAnimationName: {
3467             auto list = CSSValueList::createCommaSeparated();
3468             const AnimationList* t = style->animations();
3469             if (t) {
3470                 for (size_t i = 0; i < t->size(); ++i)
3471                     list->append(cssValuePool.createValue(t->animation(i).name(), CSSPrimitiveValue::CSS_STRING));
3472             } else
3473                 list->append(cssValuePool.createIdentifierValue(CSSValueNone));
3474             return WTFMove(list);
3475         }
3476         case CSSPropertyAnimationPlayState: {
3477             auto list = CSSValueList::createCommaSeparated();
3478             const AnimationList* t = style->animations();
3479             if (t) {
3480                 for (size_t i = 0; i < t->size(); ++i) {
3481                     int prop = t->animation(i).playState();
3482                     if (prop == AnimPlayStatePlaying)
3483                         list->append(cssValuePool.createIdentifierValue(CSSValueRunning));
3484                     else
3485                         list->append(cssValuePool.createIdentifierValue(CSSValuePaused));
3486                 }
3487             } else
3488                 list->append(cssValuePool.createIdentifierValue(CSSValueRunning));
3489             return WTFMove(list);
3490         }
3491         case CSSPropertyAnimationTimingFunction:
3492             return timingFunctionValue(style->animations());
3493 #if ENABLE(CSS_ANIMATIONS_LEVEL_2)
3494         case CSSPropertyWebkitAnimationTrigger:
3495             return animationTriggerValue(style->animations(), *style);
3496 #endif
3497         case CSSPropertyWebkitAppearance:
3498             return cssValuePool.createValue(style->appearance());
3499         case CSSPropertyWebkitAspectRatio:
3500             if (style->aspectRatioType() == AspectRatioAuto)
3501                 return cssValuePool.createIdentifierValue(CSSValueAuto);
3502             if (style->aspectRatioType() == AspectRatioFromDimensions)
3503                 return cssValuePool.createIdentifierValue(CSSValueFromDimensions);
3504             if (style->aspectRatioType() == AspectRatioFromIntrinsic)
3505                 return cssValuePool.createIdentifierValue(CSSValueFromIntrinsic);
3506             return CSSAspectRatioValue::create(style->aspectRatioNumerator(), style->aspectRatioDenominator());
3507         case CSSPropertyWebkitBackfaceVisibility:
3508             return cssValuePool.createIdentifierValue((style->backfaceVisibility() == BackfaceVisibilityHidden) ? CSSValueHidden : CSSValueVisible);
3509         case CSSPropertyWebkitBorderImage:
3510             return valueForNinePieceImage(style->borderImage());
3511         case CSSPropertyBorderImageOutset:
3512             return valueForNinePieceImageQuad(style->borderImage().outset());
3513         case CSSPropertyBorderImageRepeat:
3514             return valueForNinePieceImageRepeat(style->borderImage());
3515         case CSSPropertyBorderImageSlice:
3516             return valueForNinePieceImageSlice(style->borderImage());
3517         case CSSPropertyBorderImageWidth:
3518             return valueForNinePieceImageQuad(style->borderImage().borderSlices());
3519         case CSSPropertyWebkitMaskBoxImage:
3520             return valueForNinePieceImage(style->maskBoxImage());
3521         case CSSPropertyWebkitMaskBoxImageOutset:
3522             return valueForNinePieceImageQuad(style->maskBoxImage().outset());
3523         case CSSPropertyWebkitMaskBoxImageRepeat:
3524             return valueForNinePieceImageRepeat(style->maskBoxImage());
3525         case CSSPropertyWebkitMaskBoxImageSlice:
3526             return valueForNinePieceImageSlice(style->maskBoxImage());
3527         case CSSPropertyWebkitMaskBoxImageWidth:
3528             return valueForNinePieceImageQuad(style->maskBoxImage().borderSlices());
3529         case CSSPropertyWebkitMaskBoxImageSource:
3530             if (style->maskBoxImageSource())
3531                 return style->maskBoxImageSource()->cssValue();
3532             return cssValuePool.createIdentifierValue(CSSValueNone);
3533         case CSSPropertyWebkitFontSizeDelta:
3534             // Not a real style property -- used by the editing engine -- so has no computed value.
3535             break;
3536         case CSSPropertyWebkitInitialLetter: {
3537             auto drop = !style->initialLetterDrop() ? cssValuePool.createIdentifierValue(CSSValueNormal) : cssValuePool.createValue(style->initialLetterDrop(), CSSPrimitiveValue::CSS_NUMBER);
3538             auto size = !style->initialLetterHeight() ? cssValuePool.createIdentifierValue(CSSValueNormal) : cssValuePool.createValue(style->initialLetterHeight(), CSSPrimitiveValue::CSS_NUMBER);
3539             return cssValuePool.createValue(Pair::create(WTFMove(drop), WTFMove(size)));
3540         }
3541         case CSSPropertyWebkitMarginBottomCollapse:
3542         case CSSPropertyWebkitMarginAfterCollapse:
3543             return cssValuePool.createValue(style->marginAfterCollapse());
3544         case CSSPropertyWebkitMarginTopCollapse:
3545         case CSSPropertyWebkitMarginBeforeCollapse:
3546             return cssValuePool.createValue(style->marginBeforeCollapse());
3547 #if ENABLE(ACCELERATED_OVERFLOW_SCROLLING)
3548         case CSSPropertyWebkitOverflowScrolling:
3549             if (!style->useTouchOverflowScrolling())
3550                 return cssValuePool.createIdentifierValue(CSSValueAuto);
3551             return cssValuePool.createIdentifierValue(CSSValueTouch);
3552 #endif
3553         case CSSPropertyPerspective:
3554             if (!style->hasPerspective())
3555                 return cssValuePool.createIdentifierValue(CSSValueNone);
3556             return zoomAdjustedPixelValue(style->perspective(), *style);
3557         case CSSPropertyPerspectiveOrigin: {
3558             auto list = CSSValueList::createSpaceSeparated();
3559             if (renderer) {
3560                 LayoutRect box;
3561                 if (is<RenderBox>(*renderer))
3562                     box = downcast<RenderBox>(*renderer).borderBoxRect();
3563
3564                 list->append(zoomAdjustedPixelValue(minimumValueForLength(style->perspectiveOriginX(), box.width()), *style));
3565                 list->append(zoomAdjustedPixelValue(minimumValueForLength(style->perspectiveOriginY(), box.height()), *style));
3566             }
3567             else {
3568                 list->append(zoomAdjustedPixelValueForLength(style->perspectiveOriginX(), *style));
3569                 list->append(zoomAdjustedPixelValueForLength(style->perspectiveOriginY(), *style));
3570
3571             }
3572             return WTFMove(list);
3573         }
3574         case CSSPropertyWebkitRtlOrdering:
3575             return cssValuePool.createIdentifierValue(style->rtlOrdering() ? CSSValueVisual : CSSValueLogical);
3576 #if ENABLE(TOUCH_EVENTS)
3577         case CSSPropertyWebkitTapHighlightColor:
3578             return currentColorOrValidColor(style, style->tapHighlightColor());
3579         case CSSPropertyTouchAction:
3580             return cssValuePool.createValue(style->touchAction());
3581 #endif
3582 #if PLATFORM(IOS)
3583         case CSSPropertyWebkitTouchCallout:
3584             return cssValuePool.createIdentifierValue(style->touchCalloutEnabled() ? CSSValueDefault : CSSValueNone);
3585 #endif
3586         case CSSPropertyWebkitUserDrag:
3587             return cssValuePool.createValue(style->userDrag());
3588         case CSSPropertyWebkitUserSelect:
3589             return cssValuePool.createValue(style->userSelect());
3590         case CSSPropertyBorderBottomLeftRadius:
3591             return borderRadiusCornerValue(style->borderBottomLeftRadius(), *style);
3592         case CSSPropertyBorderBottomRightRadius:
3593             return borderRadiusCornerValue(style->borderBottomRightRadius(), *style);
3594         case CSSPropertyBorderTopLeftRadius:
3595             return borderRadiusCornerValue(style->borderTopLeftRadius(), *style);
3596         case CSSPropertyBorderTopRightRadius:
3597             return borderRadiusCornerValue(style->borderTopRightRadius(), *style);
3598         case CSSPropertyClip: {
3599             if (!style->hasClip())
3600                 return cssValuePool.createIdentifierValue(CSSValueAuto);
3601             auto rect = Rect::create();
3602             rect->setTop(autoOrZoomAdjustedValue(style->clip().top(), *style));
3603             rect->setRight(autoOrZoomAdjustedValue(style->clip().right(), *style));
3604             rect->setBottom(autoOrZoomAdjustedValue(style->clip().bottom(), *style));
3605             rect->setLeft(autoOrZoomAdjustedValue(style->clip().left(), *style));
3606             return cssValuePool.createValue(WTFMove(rect));
3607         }
3608         case CSSPropertySpeak:
3609             return cssValuePool.createValue(style->speak());
3610         case CSSPropertyTransform:
3611             return computedTransform(renderer, *style);
3612         case CSSPropertyTransformOrigin: {
3613             auto list = CSSValueList::createSpaceSeparated();
3614             if (renderer) {
3615                 LayoutRect box;
3616                 if (is<RenderBox>(*renderer))
3617                     box = downcast<RenderBox>(*renderer).borderBoxRect();
3618
3619                 list->append(zoomAdjustedPixelValue(minimumValueForLength(style->transformOriginX(), box.width()), *style));
3620                 list->append(zoomAdjustedPixelValue(minimumValueForLength(style->transformOriginY(), box.height()), *style));
3621                 if (style->transformOriginZ() != 0)
3622                     list->append(zoomAdjustedPixelValue(style->transformOriginZ(), *style));
3623             } else {
3624                 list->append(zoomAdjustedPixelValueForLength(style->transformOriginX(), *style));
3625                 list->append(zoomAdjustedPixelValueForLength(style->transformOriginY(), *style));
3626                 if (style->transformOriginZ() != 0)
3627                     list->append(zoomAdjustedPixelValue(style->transformOriginZ(), *style));
3628             }
3629             return WTFMove(list);
3630         }
3631         case CSSPropertyTransformStyle:
3632         case CSSPropertyWebkitTransformStyle:
3633             return cssValuePool.createIdentifierValue((style->transformStyle3D() == TransformStyle3DPreserve3D) ? CSSValuePreserve3d : CSSValueFlat);
3634         case CSSPropertyTransitionDelay:
3635             return delayValue(style->transitions());
3636         case CSSPropertyTransitionDuration:
3637             return durationValue(style->transitions());
3638         case CSSPropertyTransitionProperty:
3639             return transitionPropertyValue(style->transitions());
3640         case CSSPropertyTransitionTimingFunction:
3641             return timingFunctionValue(style->transitions());
3642         case CSSPropertyTransition: {
3643             if (auto* animationList = style->transitions()) {
3644                 auto transitionsList = CSSValueList::createCommaSeparated();
3645                 for (size_t i = 0; i < animationList->size(); ++i) {
3646                     auto list = CSSValueList::createSpaceSeparated();
3647                     auto& animation = animationList->animation(i);
3648                     list->append(createTransitionPropertyValue(animation));
3649                     list->append(cssValuePool.createValue(animation.duration(), CSSPrimitiveValue::CSS_S));
3650                     list->append(createTimingFunctionValue(*animation.timingFunction()));
3651                     list->append(cssValuePool.createValue(animation.delay(), CSSPrimitiveValue::CSS_S));
3652                     transitionsList->append(WTFMove(list));
3653                 }
3654                 return WTFMove(transitionsList);
3655             }
3656
3657             auto list = CSSValueList::createSpaceSeparated();
3658             // transition-property default value.
3659             list->append(cssValuePool.createIdentifierValue(CSSValueAll));
3660             list->append(cssValuePool.createValue(Animation::initialDuration(), CSSPrimitiveValue::CSS_S));
3661             list->append(createTimingFunctionValue(Animation::initialTimingFunction()));
3662             list->append(cssValuePool.createValue(Animation::initialDelay(), CSSPrimitiveValue::CSS_S));
3663             return WTFMove(list);
3664         }
3665         case CSSPropertyPointerEvents:
3666             return cssValuePool.createValue(style->pointerEvents());
3667         case CSSPropertyWebkitLineGrid:
3668             if (style->lineGrid().isNull())
3669                 return cssValuePool.createIdentifierValue(CSSValueNone);
3670             return cssValuePool.createValue(style->lineGrid(), CSSPrimitiveValue::CSS_STRING);
3671         case CSSPropertyWebkitLineSnap:
3672             return CSSPrimitiveValue::create(style->lineSnap());
3673         case CSSPropertyWebkitLineAlign:
3674             return CSSPrimitiveValue::create(style->lineAlign());
3675         case CSSPropertyWritingMode:
3676             return cssValuePool.createValue(style->writingMode());
3677         case CSSPropertyWebkitTextCombine:
3678             return cssValuePool.createValue(style->textCombine());
3679         case CSSPropertyWebkitTextOrientation:
3680             return CSSPrimitiveValue::create(style->textOrientation());
3681         case CSSPropertyWebkitLineBoxContain:
3682             return createLineBoxContainValue(style->lineBoxContain());
3683  &nbs