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