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