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