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