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