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