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