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