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