Add experimental support for spring based CSS animations
[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 "StyleInheritedData.h"
66 #include "StyleProperties.h"
67 #include "StylePropertyShorthand.h"
68 #include "StylePropertyShorthandFunctions.h"
69 #include "StyleResolver.h"
70 #include "WebKitCSSFilterValue.h"
71 #include "WebKitCSSTransformValue.h"
72 #include "WebKitFontFamilyNames.h"
73 #include "WillChangeData.h"
74 #include <wtf/NeverDestroyed.h>
75 #include <wtf/text/StringBuilder.h>
76
77 #if ENABLE(CSS_GRID_LAYOUT)
78 #include "CSSGridLineNamesValue.h"
79 #include "CSSGridTemplateAreasValue.h"
80 #include "RenderGrid.h"
81 #endif
82
83 #if ENABLE(CSS_SHAPES)
84 #include "ShapeValue.h"
85 #endif
86
87 #if ENABLE(DASHBOARD_SUPPORT)
88 #include "DashboardRegion.h"
89 #endif
90
91 #if ENABLE(CSS_SCROLL_SNAP)
92 #include "LengthRepeat.h"
93 #include "StyleScrollSnapPoints.h"
94 #endif
95
96 #if ENABLE(CSS_ANIMATIONS_LEVEL_2)
97 #include "AnimationTrigger.h"
98 #endif
99
100 namespace WebCore {
101
102 // List of all properties we know how to compute, omitting shorthands.
103 static const CSSPropertyID computedProperties[] = {
104     CSSPropertyAlt,
105     CSSPropertyAnimationDelay,
106     CSSPropertyAnimationDirection,
107     CSSPropertyAnimationDuration,
108     CSSPropertyAnimationFillMode,
109     CSSPropertyAnimationIterationCount,
110     CSSPropertyAnimationName,
111     CSSPropertyAnimationPlayState,
112     CSSPropertyAnimationTimingFunction,
113     CSSPropertyBackgroundAttachment,
114     CSSPropertyBackgroundBlendMode,
115     CSSPropertyBackgroundClip,
116     CSSPropertyBackgroundColor,
117     CSSPropertyBackgroundImage,
118     CSSPropertyBackgroundOrigin,
119     CSSPropertyBackgroundPosition, // more-specific background-position-x/y are non-standard
120     CSSPropertyBackgroundRepeat,
121     CSSPropertyBackgroundSize,
122     CSSPropertyBorderBottomColor,
123     CSSPropertyBorderBottomLeftRadius,
124     CSSPropertyBorderBottomRightRadius,
125     CSSPropertyBorderBottomStyle,
126     CSSPropertyBorderBottomWidth,
127     CSSPropertyBorderCollapse,
128     CSSPropertyBorderImageOutset,
129     CSSPropertyBorderImageRepeat,
130     CSSPropertyBorderImageSlice,
131     CSSPropertyBorderImageSource,
132     CSSPropertyBorderImageWidth,
133     CSSPropertyBorderLeftColor,
134     CSSPropertyBorderLeftStyle,
135     CSSPropertyBorderLeftWidth,
136     CSSPropertyBorderRightColor,
137     CSSPropertyBorderRightStyle,
138     CSSPropertyBorderRightWidth,
139     CSSPropertyBorderTopColor,
140     CSSPropertyBorderTopLeftRadius,
141     CSSPropertyBorderTopRightRadius,
142     CSSPropertyBorderTopStyle,
143     CSSPropertyBorderTopWidth,
144     CSSPropertyBottom,
145     CSSPropertyBoxShadow,
146     CSSPropertyBoxSizing,
147     CSSPropertyCaptionSide,
148     CSSPropertyClear,
149     CSSPropertyClip,
150     CSSPropertyColor,
151     CSSPropertyContent,
152     CSSPropertyCursor,
153     CSSPropertyDirection,
154     CSSPropertyDisplay,
155     CSSPropertyEmptyCells,
156     CSSPropertyFloat,
157     CSSPropertyFontFamily,
158     CSSPropertyFontSize,
159     CSSPropertyFontStyle,
160     CSSPropertyFontSynthesis,
161     CSSPropertyFontVariant,
162     CSSPropertyFontWeight,
163     CSSPropertyHeight,
164 #if ENABLE(CSS_IMAGE_ORIENTATION)
165     CSSPropertyImageOrientation,
166 #endif
167     CSSPropertyImageRendering,
168 #if ENABLE(CSS_IMAGE_RESOLUTION)
169     CSSPropertyImageResolution,
170 #endif
171     CSSPropertyLeft,
172     CSSPropertyLetterSpacing,
173     CSSPropertyLineHeight,
174     CSSPropertyListStyleImage,
175     CSSPropertyListStylePosition,
176     CSSPropertyListStyleType,
177     CSSPropertyMarginBottom,
178     CSSPropertyMarginLeft,
179     CSSPropertyMarginRight,
180     CSSPropertyMarginTop,
181     CSSPropertyMaxHeight,
182     CSSPropertyMaxWidth,
183     CSSPropertyMinHeight,
184     CSSPropertyMinWidth,
185     CSSPropertyOpacity,
186     CSSPropertyOrphans,
187     CSSPropertyOutlineColor,
188     CSSPropertyOutlineOffset,
189     CSSPropertyOutlineStyle,
190     CSSPropertyOutlineWidth,
191     CSSPropertyOverflowWrap,
192     CSSPropertyOverflowX,
193     CSSPropertyOverflowY,
194     CSSPropertyPaddingBottom,
195     CSSPropertyPaddingLeft,
196     CSSPropertyPaddingRight,
197     CSSPropertyPaddingTop,
198     CSSPropertyPageBreakAfter,
199     CSSPropertyPageBreakBefore,
200     CSSPropertyPageBreakInside,
201     CSSPropertyPointerEvents,
202     CSSPropertyPosition,
203     CSSPropertyResize,
204     CSSPropertyRight,
205     CSSPropertySpeak,
206     CSSPropertyTableLayout,
207     CSSPropertyTabSize,
208     CSSPropertyTextAlign,
209     CSSPropertyTextDecoration,
210 #if ENABLE(CSS3_TEXT)
211     CSSPropertyWebkitTextAlignLast,
212     CSSPropertyWebkitTextJustify,
213 #endif // CSS3_TEXT
214     CSSPropertyWebkitTextDecorationLine,
215     CSSPropertyWebkitTextDecorationStyle,
216     CSSPropertyWebkitTextDecorationColor,
217     CSSPropertyWebkitTextDecorationSkip,
218     CSSPropertyWebkitTextUnderlinePosition,
219     CSSPropertyTextIndent,
220     CSSPropertyTextRendering,
221     CSSPropertyTextShadow,
222     CSSPropertyTextOverflow,
223     CSSPropertyTextTransform,
224     CSSPropertyTop,
225     CSSPropertyTransform,
226     CSSPropertyTransformOrigin,
227     CSSPropertyTransformStyle,
228     CSSPropertyTransitionDelay,
229     CSSPropertyTransitionDuration,
230     CSSPropertyTransitionProperty,
231     CSSPropertyTransitionTimingFunction,
232     CSSPropertyUnicodeBidi,
233     CSSPropertyVerticalAlign,
234     CSSPropertyVisibility,
235     CSSPropertyWhiteSpace,
236     CSSPropertyWidows,
237     CSSPropertyWidth,
238     CSSPropertyWordBreak,
239     CSSPropertyWordSpacing,
240     CSSPropertyWordWrap,
241 #if ENABLE(CSS_SCROLL_SNAP)
242     CSSPropertyWebkitScrollSnapType,
243     CSSPropertyWebkitScrollSnapPointsX,
244     CSSPropertyWebkitScrollSnapPointsY,
245     CSSPropertyWebkitScrollSnapDestination,
246     CSSPropertyWebkitScrollSnapCoordinate,
247 #endif
248     CSSPropertyZIndex,
249     CSSPropertyZoom,
250     CSSPropertyWebkitAnimationDelay,
251     CSSPropertyWebkitAnimationDirection,
252     CSSPropertyWebkitAnimationDuration,
253     CSSPropertyWebkitAnimationFillMode,
254     CSSPropertyWebkitAnimationIterationCount,
255     CSSPropertyWebkitAnimationName,
256     CSSPropertyWebkitAnimationPlayState,
257     CSSPropertyWebkitAnimationTimingFunction,
258 #if ENABLE(CSS_ANIMATIONS_LEVEL_2)
259     CSSPropertyWebkitAnimationTrigger,
260 #endif
261     CSSPropertyWebkitAppearance,
262     CSSPropertyWebkitBackfaceVisibility,
263     CSSPropertyWebkitBackgroundClip,
264     CSSPropertyWebkitBackgroundComposite,
265     CSSPropertyWebkitBackgroundOrigin,
266     CSSPropertyWebkitBackgroundSize,
267 #if ENABLE(CSS_COMPOSITING)
268     CSSPropertyMixBlendMode,
269     CSSPropertyIsolation,
270 #endif
271     CSSPropertyWebkitBorderFit,
272     CSSPropertyWebkitBorderHorizontalSpacing,
273     CSSPropertyWebkitBorderImage,
274     CSSPropertyWebkitBorderVerticalSpacing,
275     CSSPropertyWebkitBoxAlign,
276 #if ENABLE(CSS_BOX_DECORATION_BREAK)
277     CSSPropertyWebkitBoxDecorationBreak,
278 #endif
279     CSSPropertyWebkitBoxDirection,
280     CSSPropertyWebkitBoxFlex,
281     CSSPropertyWebkitBoxFlexGroup,
282     CSSPropertyWebkitBoxLines,
283     CSSPropertyWebkitBoxOrdinalGroup,
284     CSSPropertyWebkitBoxOrient,
285     CSSPropertyWebkitBoxPack,
286     CSSPropertyWebkitBoxReflect,
287     CSSPropertyWebkitBoxShadow,
288     CSSPropertyWebkitClipPath,
289     CSSPropertyWebkitColumnBreakAfter,
290     CSSPropertyWebkitColumnBreakBefore,
291     CSSPropertyWebkitColumnBreakInside,
292     CSSPropertyWebkitColumnAxis,
293     CSSPropertyColumnCount,
294     CSSPropertyColumnFill,
295     CSSPropertyColumnGap,
296     CSSPropertyColumnProgression,
297     CSSPropertyColumnRuleColor,
298     CSSPropertyColumnRuleStyle,
299     CSSPropertyColumnRuleWidth,
300     CSSPropertyColumnSpan,
301     CSSPropertyColumnWidth,
302 #if ENABLE(CURSOR_VISIBILITY)
303     CSSPropertyWebkitCursorVisibility,
304 #endif
305 #if ENABLE(DASHBOARD_SUPPORT)
306     CSSPropertyWebkitDashboardRegion,
307 #endif
308     CSSPropertyAlignContent,
309     CSSPropertyAlignItems,
310     CSSPropertyAlignSelf,
311     CSSPropertyFilter,
312     CSSPropertyFlexBasis,
313     CSSPropertyFlexGrow,
314     CSSPropertyFlexShrink,
315     CSSPropertyFlexDirection,
316     CSSPropertyFlexWrap,
317     CSSPropertyJustifyContent,
318     CSSPropertyJustifySelf,
319     CSSPropertyJustifyItems,
320 #if ENABLE(FILTERS_LEVEL_2)
321     CSSPropertyWebkitBackdropFilter,
322 #endif
323     CSSPropertyWebkitFontKerning,
324     CSSPropertyWebkitFontSmoothing,
325     CSSPropertyFontVariantLigatures,
326     CSSPropertyFontVariantPosition,
327     CSSPropertyFontVariantCaps,
328     CSSPropertyFontVariantNumeric,
329     CSSPropertyFontVariantAlternates,
330     CSSPropertyFontVariantEastAsian,
331 #if ENABLE(CSS_GRID_LAYOUT)
332     CSSPropertyGridAutoColumns,
333     CSSPropertyGridAutoFlow,
334     CSSPropertyGridAutoRows,
335     CSSPropertyGridColumnEnd,
336     CSSPropertyGridColumnStart,
337     CSSPropertyGridTemplateAreas,
338     CSSPropertyGridTemplateColumns,
339     CSSPropertyGridTemplateRows,
340     CSSPropertyGridRowEnd,
341     CSSPropertyGridRowStart,
342     CSSPropertyGridColumnGap,
343     CSSPropertyGridRowGap,
344 #endif
345     CSSPropertyWebkitHyphenateCharacter,
346     CSSPropertyWebkitHyphenateLimitAfter,
347     CSSPropertyWebkitHyphenateLimitBefore,
348     CSSPropertyWebkitHyphenateLimitLines,
349     CSSPropertyWebkitHyphens,
350     CSSPropertyWebkitInitialLetter,
351     CSSPropertyWebkitLineAlign,
352     CSSPropertyWebkitLineBoxContain,
353     CSSPropertyWebkitLineBreak,
354     CSSPropertyWebkitLineClamp,
355     CSSPropertyWebkitLineGrid,
356     CSSPropertyWebkitLineSnap,
357     CSSPropertyWebkitLocale,
358     CSSPropertyWebkitMarginBeforeCollapse,
359     CSSPropertyWebkitMarginAfterCollapse,
360     CSSPropertyWebkitMarqueeDirection,
361     CSSPropertyWebkitMarqueeIncrement,
362     CSSPropertyWebkitMarqueeRepetition,
363     CSSPropertyWebkitMarqueeStyle,
364     CSSPropertyWebkitMaskBoxImage,
365     CSSPropertyWebkitMaskBoxImageOutset,
366     CSSPropertyWebkitMaskBoxImageRepeat,
367     CSSPropertyWebkitMaskBoxImageSlice,
368     CSSPropertyWebkitMaskBoxImageSource,
369     CSSPropertyWebkitMaskBoxImageWidth,
370     CSSPropertyWebkitMaskClip,
371     CSSPropertyWebkitMaskComposite,
372     CSSPropertyWebkitMaskImage,
373     CSSPropertyWebkitMaskOrigin,
374     CSSPropertyWebkitMaskPosition,
375     CSSPropertyWebkitMaskRepeat,
376     CSSPropertyWebkitMaskSize,
377     CSSPropertyWebkitMaskSourceType,
378     CSSPropertyWebkitNbspMode,
379     CSSPropertyOrder,
380 #if ENABLE(ACCELERATED_OVERFLOW_SCROLLING)
381     CSSPropertyWebkitOverflowScrolling,
382 #endif
383     CSSPropertyPerspective,
384     CSSPropertyPerspectiveOrigin,
385     CSSPropertyWebkitPrintColorAdjust,
386     CSSPropertyWebkitRtlOrdering,
387 #if PLATFORM(IOS)
388     CSSPropertyWebkitTouchCallout,
389 #endif
390 #if ENABLE(CSS_SHAPES)
391     CSSPropertyWebkitShapeOutside,
392 #endif
393 #if ENABLE(TOUCH_EVENTS)
394     CSSPropertyWebkitTapHighlightColor,
395 #endif
396     CSSPropertyWebkitTextCombine,
397     CSSPropertyWebkitTextDecorationsInEffect,
398     CSSPropertyWebkitTextEmphasisColor,
399     CSSPropertyWebkitTextEmphasisPosition,
400     CSSPropertyWebkitTextEmphasisStyle,
401     CSSPropertyWebkitTextFillColor,
402     CSSPropertyWebkitTextOrientation,
403     CSSPropertyWebkitTextSecurity,
404 #if ENABLE(IOS_TEXT_AUTOSIZING)
405     CSSPropertyWebkitTextSizeAdjust,
406 #endif
407     CSSPropertyWebkitTextStrokeColor,
408     CSSPropertyWebkitTextStrokeWidth,
409     CSSPropertyWebkitTextZoom,
410     CSSPropertyWebkitTransformStyle,
411     CSSPropertyWebkitTransitionDelay,
412     CSSPropertyWebkitTransitionDuration,
413     CSSPropertyWebkitTransitionProperty,
414     CSSPropertyWebkitTransitionTimingFunction,
415     CSSPropertyWebkitUserDrag,
416     CSSPropertyWebkitUserModify,
417     CSSPropertyWebkitUserSelect,
418     CSSPropertyWebkitWritingMode,
419 #if ENABLE(CSS_REGIONS)
420     CSSPropertyWebkitFlowInto,
421     CSSPropertyWebkitFlowFrom,
422     CSSPropertyWebkitRegionBreakAfter,
423     CSSPropertyWebkitRegionBreakBefore,
424     CSSPropertyWebkitRegionBreakInside,
425     CSSPropertyWebkitRegionFragment,
426 #endif
427 #if ENABLE(CSS_SHAPES)
428     CSSPropertyWebkitShapeMargin,
429     CSSPropertyWebkitShapeImageThreshold,
430 #endif
431     CSSPropertyBufferedRendering,
432     CSSPropertyClipPath,
433     CSSPropertyClipRule,
434     CSSPropertyCx,
435     CSSPropertyCy,
436     CSSPropertyMask,
437     CSSPropertyFilter,
438     CSSPropertyFloodColor,
439     CSSPropertyFloodOpacity,
440     CSSPropertyLightingColor,
441     CSSPropertyStopColor,
442     CSSPropertyStopOpacity,
443     CSSPropertyColorInterpolation,
444     CSSPropertyColorInterpolationFilters,
445     CSSPropertyColorRendering,
446     CSSPropertyFill,
447     CSSPropertyFillOpacity,
448     CSSPropertyFillRule,
449     CSSPropertyMarkerEnd,
450     CSSPropertyMarkerMid,
451     CSSPropertyMarkerStart,
452     CSSPropertyMaskType,
453     CSSPropertyPaintOrder,
454     CSSPropertyR,
455     CSSPropertyRx,
456     CSSPropertyRy,
457     CSSPropertyShapeRendering,
458     CSSPropertyStroke,
459     CSSPropertyStrokeDasharray,
460     CSSPropertyStrokeDashoffset,
461     CSSPropertyStrokeLinecap,
462     CSSPropertyStrokeLinejoin,
463     CSSPropertyStrokeMiterlimit,
464     CSSPropertyStrokeOpacity,
465     CSSPropertyStrokeWidth,
466     CSSPropertyAlignmentBaseline,
467     CSSPropertyBaselineShift,
468     CSSPropertyDominantBaseline,
469     CSSPropertyKerning,
470     CSSPropertyTextAnchor,
471     CSSPropertyWritingMode,
472     CSSPropertyGlyphOrientationHorizontal,
473     CSSPropertyGlyphOrientationVertical,
474     CSSPropertyWebkitSvgShadow,
475     CSSPropertyVectorEffect,
476     CSSPropertyX,
477     CSSPropertyY
478 };
479
480 const unsigned numComputedProperties = WTF_ARRAY_LENGTH(computedProperties);
481
482 static CSSValueID valueForRepeatRule(int rule)
483 {
484     switch (rule) {
485         case RepeatImageRule:
486             return CSSValueRepeat;
487         case RoundImageRule:
488             return CSSValueRound;
489         case SpaceImageRule:
490             return CSSValueSpace;
491         default:
492             return CSSValueStretch;
493     }
494 }
495
496 static Ref<CSSPrimitiveValue> valueForImageSliceSide(const Length& length)
497 {
498     // These values can be percentages, numbers, or while an animation of mixed types is in progress,
499     // a calculation that combines a percentage and a number.
500     if (length.isPercent())
501         return CSSValuePool::singleton().createValue(length.percent(), CSSPrimitiveValue::CSS_PERCENTAGE);
502     if (length.isFixed())
503         return CSSValuePool::singleton().createValue(length.value(), CSSPrimitiveValue::CSS_NUMBER);
504
505     // Calculating the actual length currently in use would require most of the code from RenderBoxModelObject::paintNinePieceImage.
506     // And even if we could do that, it's not clear if that's exactly what we'd want during animation.
507     // FIXME: For now, just return 0.
508     ASSERT(length.isCalculated());
509     return CSSValuePool::singleton().createValue(0, CSSPrimitiveValue::CSS_NUMBER);
510 }
511
512 static Ref<CSSBorderImageSliceValue> valueForNinePieceImageSlice(const NinePieceImage& image)
513 {
514     auto& slices = image.imageSlices();
515
516     RefPtr<CSSPrimitiveValue> top = valueForImageSliceSide(slices.top());
517
518     RefPtr<CSSPrimitiveValue> right;
519     RefPtr<CSSPrimitiveValue> bottom;
520     RefPtr<CSSPrimitiveValue> left;
521
522     if (slices.right() == slices.top() && slices.bottom() == slices.top() && slices.left() == slices.top()) {
523         right = top;
524         bottom = top;
525         left = top;
526     } else {
527         right = valueForImageSliceSide(slices.right());
528
529         if (slices.bottom() == slices.top() && slices.right() == slices.left()) {
530             bottom = top;
531             left = right;
532         } else {
533             bottom = valueForImageSliceSide(slices.bottom());
534
535             if (slices.left() == slices.right())
536                 left = right;
537             else
538                 left = valueForImageSliceSide(slices.left());
539         }
540     }
541
542     auto quad = Quad::create();
543     quad->setTop(WTFMove(top));
544     quad->setRight(WTFMove(right));
545     quad->setBottom(WTFMove(bottom));
546     quad->setLeft(WTFMove(left));
547
548     return CSSBorderImageSliceValue::create(CSSValuePool::singleton().createValue(WTFMove(quad)), image.fill());
549 }
550
551 static Ref<CSSPrimitiveValue> valueForNinePieceImageQuad(const LengthBox& box)
552 {
553     RefPtr<CSSPrimitiveValue> top;
554     RefPtr<CSSPrimitiveValue> right;
555     RefPtr<CSSPrimitiveValue> bottom;
556     RefPtr<CSSPrimitiveValue> left;
557
558     auto& cssValuePool = CSSValuePool::singleton();
559
560     if (box.top().isRelative())
561         top = cssValuePool.createValue(box.top().value(), CSSPrimitiveValue::CSS_NUMBER);
562     else
563         top = cssValuePool.createValue(box.top());
564
565     if (box.right() == box.top() && box.bottom() == box.top() && box.left() == box.top()) {
566         right = top;
567         bottom = top;
568         left = top;
569     } else {
570         if (box.right().isRelative())
571             right = cssValuePool.createValue(box.right().value(), CSSPrimitiveValue::CSS_NUMBER);
572         else
573             right = cssValuePool.createValue(box.right());
574
575         if (box.bottom() == box.top() && box.right() == box.left()) {
576             bottom = top;
577             left = right;
578         } else {
579             if (box.bottom().isRelative())
580                 bottom = cssValuePool.createValue(box.bottom().value(), CSSPrimitiveValue::CSS_NUMBER);
581             else
582                 bottom = cssValuePool.createValue(box.bottom());
583
584             if (box.left() == box.right())
585                 left = right;
586             else {
587                 if (box.left().isRelative())
588                     left = cssValuePool.createValue(box.left().value(), CSSPrimitiveValue::CSS_NUMBER);
589                 else
590                     left = cssValuePool.createValue(box.left());
591             }
592         }
593     }
594
595     auto quad = Quad::create();
596     quad->setTop(WTFMove(top));
597     quad->setRight(WTFMove(right));
598     quad->setBottom(WTFMove(bottom));
599     quad->setLeft(WTFMove(left));
600
601     return cssValuePool.createValue(WTFMove(quad));
602 }
603
604 static Ref<CSSValue> valueForNinePieceImageRepeat(const NinePieceImage& image)
605 {
606     auto& cssValuePool = CSSValuePool::singleton();
607     RefPtr<CSSPrimitiveValue> horizontalRepeat = cssValuePool.createIdentifierValue(valueForRepeatRule(image.horizontalRule()));
608
609     RefPtr<CSSPrimitiveValue> verticalRepeat;
610     if (image.horizontalRule() == image.verticalRule())
611         verticalRepeat = horizontalRepeat;
612     else
613         verticalRepeat = cssValuePool.createIdentifierValue(valueForRepeatRule(image.verticalRule()));
614     return cssValuePool.createValue(Pair::create(WTFMove(horizontalRepeat), WTFMove(verticalRepeat)));
615 }
616
617 static Ref<CSSValue> valueForNinePieceImage(const NinePieceImage& image)
618 {
619     if (!image.hasImage())
620         return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
621
622     // Image first.
623     RefPtr<CSSValue> imageValue;
624     if (image.image())
625         imageValue = image.image()->cssValue();
626
627     // Create the image slice.
628     RefPtr<CSSBorderImageSliceValue> imageSlices = valueForNinePieceImageSlice(image);
629
630     // Create the border area slices.
631     RefPtr<CSSValue> borderSlices = valueForNinePieceImageQuad(image.borderSlices());
632
633     // Create the border outset.
634     RefPtr<CSSValue> outset = valueForNinePieceImageQuad(image.outset());
635
636     // Create the repeat rules.
637     RefPtr<CSSValue> repeat = valueForNinePieceImageRepeat(image);
638
639     return createBorderImageValue(WTFMove(imageValue), WTFMove(imageSlices), WTFMove(borderSlices), WTFMove(outset), WTFMove(repeat));
640 }
641
642 inline static Ref<CSSPrimitiveValue> zoomAdjustedPixelValue(double value, const RenderStyle& style)
643 {
644     return CSSValuePool::singleton().createValue(adjustFloatForAbsoluteZoom(value, style), CSSPrimitiveValue::CSS_PX);
645 }
646
647 inline static Ref<CSSPrimitiveValue> zoomAdjustedNumberValue(double value, const RenderStyle& style)
648 {
649     return CSSValuePool::singleton().createValue(value / style.effectiveZoom(), CSSPrimitiveValue::CSS_NUMBER);
650 }
651
652 static Ref<CSSValue> zoomAdjustedPixelValueForLength(const Length& length, const RenderStyle& style)
653 {
654     if (length.isFixed())
655         return zoomAdjustedPixelValue(length.value(), style);
656     return CSSValuePool::singleton().createValue(length, style);
657 }
658
659 static Ref<CSSValue> valueForReflection(const StyleReflection* reflection, const RenderStyle& style)
660 {
661     if (!reflection)
662         return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
663
664     RefPtr<CSSPrimitiveValue> offset;
665     if (reflection->offset().isPercentOrCalculated())
666         offset = CSSValuePool::singleton().createValue(reflection->offset().percent(), CSSPrimitiveValue::CSS_PERCENTAGE);
667     else
668         offset = zoomAdjustedPixelValue(reflection->offset().value(), style);
669
670     RefPtr<CSSPrimitiveValue> direction;
671     switch (reflection->direction()) {
672     case ReflectionBelow:
673         direction = CSSValuePool::singleton().createIdentifierValue(CSSValueBelow);
674         break;
675     case ReflectionAbove:
676         direction = CSSValuePool::singleton().createIdentifierValue(CSSValueAbove);
677         break;
678     case ReflectionLeft:
679         direction = CSSValuePool::singleton().createIdentifierValue(CSSValueLeft);
680         break;
681     case ReflectionRight:
682         direction = CSSValuePool::singleton().createIdentifierValue(CSSValueRight);
683         break;
684     }
685
686     return CSSReflectValue::create(direction.releaseNonNull(), offset.releaseNonNull(), valueForNinePieceImage(reflection->mask()));
687 }
688
689 static Ref<CSSValueList> createPositionListForLayer(CSSPropertyID propertyID, const FillLayer* layer, const RenderStyle& style)
690 {
691     auto positionList = CSSValueList::createSpaceSeparated();
692     if (layer->isBackgroundOriginSet()) {
693         ASSERT_UNUSED(propertyID, propertyID == CSSPropertyBackgroundPosition || propertyID == CSSPropertyWebkitMaskPosition);
694         positionList.get().append(CSSValuePool::singleton().createValue(layer->backgroundXOrigin()));
695     }
696     positionList.get().append(zoomAdjustedPixelValueForLength(layer->xPosition(), style));
697     if (layer->isBackgroundOriginSet()) {
698         ASSERT(propertyID == CSSPropertyBackgroundPosition || propertyID == CSSPropertyWebkitMaskPosition);
699         positionList.get().append(CSSValuePool::singleton().createValue(layer->backgroundYOrigin()));
700     }
701     positionList.get().append(zoomAdjustedPixelValueForLength(layer->yPosition(), style));
702     return positionList;
703 }
704
705 static RefPtr<CSSValue> positionOffsetValue(const RenderStyle& style, CSSPropertyID propertyID)
706 {
707     Length length;
708     switch (propertyID) {
709         case CSSPropertyLeft:
710             length = style.left();
711             break;
712         case CSSPropertyRight:
713             length = style.right();
714             break;
715         case CSSPropertyTop:
716             length = style.top();
717             break;
718         case CSSPropertyBottom:
719             length = style.bottom();
720             break;
721         default:
722             return nullptr;
723     }
724
725     if (style.hasOutOfFlowPosition()) {
726         if (length.isFixed())
727             return zoomAdjustedPixelValue(length.value(), style);
728
729         return CSSValuePool::singleton().createValue(length);
730     }
731
732     if (style.hasInFlowPosition()) {
733         // FIXME: It's not enough to simply return "auto" values for one offset if the other side is defined.
734         // In other words if left is auto and right is not auto, then left's computed value is negative right().
735         // So we should get the opposite length unit and see if it is auto.
736         return CSSValuePool::singleton().createValue(length);
737     }
738
739     return CSSValuePool::singleton().createIdentifierValue(CSSValueAuto);
740 }
741
742 RefPtr<CSSPrimitiveValue> ComputedStyleExtractor::currentColorOrValidColor(const RenderStyle* style, const Color& color) const
743 {
744     // This function does NOT look at visited information, so that computed style doesn't expose that.
745     if (!color.isValid())
746         return CSSValuePool::singleton().createColorValue(style->color().rgb());
747     return CSSValuePool::singleton().createColorValue(color.rgb());
748 }
749
750 static Ref<CSSPrimitiveValue> percentageOrZoomAdjustedValue(Length length, const RenderStyle& style)
751 {
752     if (length.isPercent())
753         return CSSValuePool::singleton().createValue(length.percent(), CSSPrimitiveValue::CSS_PERCENTAGE);
754     
755     return zoomAdjustedPixelValue(valueForLength(length, 0), style);
756 }
757
758 static Ref<CSSPrimitiveValue> autoOrZoomAdjustedValue(Length length, const RenderStyle& style)
759 {
760     if (length.isAuto())
761         return CSSValuePool::singleton().createIdentifierValue(CSSValueAuto);
762
763     return zoomAdjustedPixelValue(valueForLength(length, 0), style);
764 }
765
766 static Ref<CSSValueList> getBorderRadiusCornerValues(const LengthSize& radius, const RenderStyle& style)
767 {
768     auto list = CSSValueList::createSpaceSeparated();
769     list.get().append(percentageOrZoomAdjustedValue(radius.width(), style));
770     list.get().append(percentageOrZoomAdjustedValue(radius.height(), style));
771     return list;
772 }
773
774 static Ref<CSSValue> getBorderRadiusCornerValue(const LengthSize& radius, const RenderStyle& style)
775 {
776     if (radius.width() == radius.height())
777         return percentageOrZoomAdjustedValue(radius.width(), style);
778
779     return getBorderRadiusCornerValues(radius, style);
780 }
781
782 static Ref<CSSValueList> getBorderRadiusShorthandValue(const RenderStyle& style)
783 {
784     auto list = CSSValueList::createSlashSeparated();
785     bool showHorizontalBottomLeft = style.borderTopRightRadius().width() != style.borderBottomLeftRadius().width();
786     bool showHorizontalBottomRight = showHorizontalBottomLeft || (style.borderBottomRightRadius().width() != style.borderTopLeftRadius().width());
787     bool showHorizontalTopRight = showHorizontalBottomRight || (style.borderTopRightRadius().width() != style.borderTopLeftRadius().width());
788
789     bool showVerticalBottomLeft = style.borderTopRightRadius().height() != style.borderBottomLeftRadius().height();
790     bool showVerticalBottomRight = showVerticalBottomLeft || (style.borderBottomRightRadius().height() != style.borderTopLeftRadius().height());
791     bool showVerticalTopRight = showVerticalBottomRight || (style.borderTopRightRadius().height() != style.borderTopLeftRadius().height());
792
793     RefPtr<CSSValueList> topLeftRadius = getBorderRadiusCornerValues(style.borderTopLeftRadius(), style);
794     RefPtr<CSSValueList> topRightRadius = getBorderRadiusCornerValues(style.borderTopRightRadius(), style);
795     RefPtr<CSSValueList> bottomRightRadius = getBorderRadiusCornerValues(style.borderBottomRightRadius(), style);
796     RefPtr<CSSValueList> bottomLeftRadius = getBorderRadiusCornerValues(style.borderBottomLeftRadius(), style);
797
798     RefPtr<CSSValueList> horizontalRadii = CSSValueList::createSpaceSeparated();
799     horizontalRadii->append(*topLeftRadius->item(0));
800     if (showHorizontalTopRight)
801         horizontalRadii->append(*topRightRadius->item(0));
802     if (showHorizontalBottomRight)
803         horizontalRadii->append(*bottomRightRadius->item(0));
804     if (showHorizontalBottomLeft)
805         horizontalRadii->append(*bottomLeftRadius->item(0));
806
807     list.get().append(horizontalRadii.releaseNonNull());
808
809     RefPtr<CSSValueList> verticalRadiiList = CSSValueList::createSpaceSeparated();
810     verticalRadiiList->append(*topLeftRadius->item(1));
811     if (showVerticalTopRight)
812         verticalRadiiList->append(*topRightRadius->item(1));
813     if (showVerticalBottomRight)
814         verticalRadiiList->append(*bottomRightRadius->item(1));
815     if (showVerticalBottomLeft)
816         verticalRadiiList->append(*bottomLeftRadius->item(1));
817
818     if (!verticalRadiiList->equals(downcast<CSSValueList>(*list.get().item(0))))
819         list.get().append(verticalRadiiList.releaseNonNull());
820
821     return list;
822 }
823
824 static LayoutRect sizingBox(RenderObject& renderer)
825 {
826     if (!is<RenderBox>(renderer))
827         return LayoutRect();
828
829     auto& box = downcast<RenderBox>(renderer);
830     return box.style().boxSizing() == BORDER_BOX ? box.borderBoxRect() : box.computedCSSContentBoxRect();
831 }
832
833 static Ref<WebKitCSSTransformValue> matrixTransformValue(const TransformationMatrix& transform, const RenderStyle& style)
834 {
835     RefPtr<WebKitCSSTransformValue> transformValue;
836     auto& cssValuePool = CSSValuePool::singleton();
837     if (transform.isAffine()) {
838         transformValue = WebKitCSSTransformValue::create(WebKitCSSTransformValue::MatrixTransformOperation);
839
840         transformValue->append(cssValuePool.createValue(transform.a(), CSSPrimitiveValue::CSS_NUMBER));
841         transformValue->append(cssValuePool.createValue(transform.b(), CSSPrimitiveValue::CSS_NUMBER));
842         transformValue->append(cssValuePool.createValue(transform.c(), CSSPrimitiveValue::CSS_NUMBER));
843         transformValue->append(cssValuePool.createValue(transform.d(), CSSPrimitiveValue::CSS_NUMBER));
844         transformValue->append(zoomAdjustedNumberValue(transform.e(), style));
845         transformValue->append(zoomAdjustedNumberValue(transform.f(), style));
846     } else {
847         transformValue = WebKitCSSTransformValue::create(WebKitCSSTransformValue::Matrix3DTransformOperation);
848
849         transformValue->append(cssValuePool.createValue(transform.m11(), CSSPrimitiveValue::CSS_NUMBER));
850         transformValue->append(cssValuePool.createValue(transform.m12(), CSSPrimitiveValue::CSS_NUMBER));
851         transformValue->append(cssValuePool.createValue(transform.m13(), CSSPrimitiveValue::CSS_NUMBER));
852         transformValue->append(cssValuePool.createValue(transform.m14(), CSSPrimitiveValue::CSS_NUMBER));
853
854         transformValue->append(cssValuePool.createValue(transform.m21(), CSSPrimitiveValue::CSS_NUMBER));
855         transformValue->append(cssValuePool.createValue(transform.m22(), CSSPrimitiveValue::CSS_NUMBER));
856         transformValue->append(cssValuePool.createValue(transform.m23(), CSSPrimitiveValue::CSS_NUMBER));
857         transformValue->append(cssValuePool.createValue(transform.m24(), CSSPrimitiveValue::CSS_NUMBER));
858
859         transformValue->append(cssValuePool.createValue(transform.m31(), CSSPrimitiveValue::CSS_NUMBER));
860         transformValue->append(cssValuePool.createValue(transform.m32(), CSSPrimitiveValue::CSS_NUMBER));
861         transformValue->append(cssValuePool.createValue(transform.m33(), CSSPrimitiveValue::CSS_NUMBER));
862         transformValue->append(cssValuePool.createValue(transform.m34(), CSSPrimitiveValue::CSS_NUMBER));
863
864         transformValue->append(zoomAdjustedNumberValue(transform.m41(), style));
865         transformValue->append(zoomAdjustedNumberValue(transform.m42(), style));
866         transformValue->append(zoomAdjustedNumberValue(transform.m43(), style));
867         transformValue->append(cssValuePool.createValue(transform.m44(), CSSPrimitiveValue::CSS_NUMBER));
868     }
869
870     return transformValue.releaseNonNull();
871 }
872
873 static Ref<CSSValue> computedTransform(RenderObject* renderer, const RenderStyle& style)
874 {
875     if (!renderer || !renderer->hasTransform())
876         return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
877
878     FloatRect pixelSnappedRect;
879     if (is<RenderBox>(*renderer))
880         pixelSnappedRect = snapRectToDevicePixels(downcast<RenderBox>(*renderer).borderBoxRect(), renderer->document().deviceScaleFactor());
881
882     TransformationMatrix transform;
883     style.applyTransform(transform, pixelSnappedRect, RenderStyle::ExcludeTransformOrigin);
884     // Note that this does not flatten to an affine transform if ENABLE(3D_TRANSFORMS) is off, by design.
885
886     // FIXME: Need to print out individual functions (https://bugs.webkit.org/show_bug.cgi?id=23924)
887     auto list = CSSValueList::createSpaceSeparated();
888     list.get().append(matrixTransformValue(transform, style));
889     return WTFMove(list);
890 }
891
892 static inline Ref<CSSPrimitiveValue> adjustLengthForZoom(double length, const RenderStyle& style, AdjustPixelValuesForComputedStyle adjust)
893 {
894     return adjust == AdjustPixelValues ? zoomAdjustedPixelValue(length, style) : CSSValuePool::singleton().createValue(length, CSSPrimitiveValue::CSS_PX);
895 }
896
897 static inline Ref<CSSPrimitiveValue> adjustLengthForZoom(const Length& length, const RenderStyle& style, AdjustPixelValuesForComputedStyle adjust)
898 {
899     return adjust == AdjustPixelValues ? zoomAdjustedPixelValue(length.value(), style) : CSSValuePool::singleton().createValue(length);
900 }
901
902 Ref<CSSValue> ComputedStyleExtractor::valueForShadow(const ShadowData* shadow, CSSPropertyID propertyID, const RenderStyle& style, AdjustPixelValuesForComputedStyle adjust)
903 {
904     auto& cssValuePool = CSSValuePool::singleton();
905     if (!shadow)
906         return cssValuePool.createIdentifierValue(CSSValueNone);
907
908     auto list = CSSValueList::createCommaSeparated();
909     for (const ShadowData* currShadowData = shadow; currShadowData; currShadowData = currShadowData->next()) {
910         auto x = adjustLengthForZoom(currShadowData->x(), style, adjust);
911         auto y = adjustLengthForZoom(currShadowData->y(), style, adjust);
912         auto blur = adjustLengthForZoom(currShadowData->radius(), style, adjust);
913         auto spread = propertyID == CSSPropertyTextShadow ? RefPtr<CSSPrimitiveValue>() : adjustLengthForZoom(currShadowData->spread(), style, adjust);
914         auto style = propertyID == CSSPropertyTextShadow || currShadowData->style() == Normal ? RefPtr<CSSPrimitiveValue>() : cssValuePool.createIdentifierValue(CSSValueInset);
915         auto color = cssValuePool.createColorValue(currShadowData->color().rgb());
916         list->prepend(CSSShadowValue::create(WTFMove(x), WTFMove(y), WTFMove(blur), WTFMove(spread), WTFMove(style), WTFMove(color)));
917     }
918     return WTFMove(list);
919 }
920
921 Ref<CSSValue> ComputedStyleExtractor::valueForFilter(const RenderStyle& style, const FilterOperations& filterOperations, AdjustPixelValuesForComputedStyle adjust)
922 {
923     auto& cssValuePool = CSSValuePool::singleton();
924     if (filterOperations.operations().isEmpty())
925         return cssValuePool.createIdentifierValue(CSSValueNone);
926
927     auto list = CSSValueList::createSpaceSeparated();
928
929     RefPtr<WebKitCSSFilterValue> filterValue;
930
931     Vector<RefPtr<FilterOperation>>::const_iterator end = filterOperations.operations().end();
932     for (Vector<RefPtr<FilterOperation>>::const_iterator it = filterOperations.operations().begin(); it != end; ++it) {
933         FilterOperation& filterOperation = **it;
934         switch (filterOperation.type()) {
935         case FilterOperation::REFERENCE: {
936             ReferenceFilterOperation& referenceOperation = downcast<ReferenceFilterOperation>(filterOperation);
937             filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::ReferenceFilterOperation);
938             filterValue->append(cssValuePool.createValue(referenceOperation.url(), CSSPrimitiveValue::CSS_URI));
939             break;
940         }
941         case FilterOperation::GRAYSCALE: {
942             BasicColorMatrixFilterOperation& colorMatrixOperation = downcast<BasicColorMatrixFilterOperation>(filterOperation);
943             filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::GrayscaleFilterOperation);
944             filterValue->append(cssValuePool.createValue(colorMatrixOperation.amount(), CSSPrimitiveValue::CSS_NUMBER));
945             break;
946         }
947         case FilterOperation::SEPIA: {
948             BasicColorMatrixFilterOperation& colorMatrixOperation = downcast<BasicColorMatrixFilterOperation>(filterOperation);
949             filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::SepiaFilterOperation);
950             filterValue->append(cssValuePool.createValue(colorMatrixOperation.amount(), CSSPrimitiveValue::CSS_NUMBER));
951             break;
952         }
953         case FilterOperation::SATURATE: {
954             BasicColorMatrixFilterOperation& colorMatrixOperation = downcast<BasicColorMatrixFilterOperation>(filterOperation);
955             filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::SaturateFilterOperation);
956             filterValue->append(cssValuePool.createValue(colorMatrixOperation.amount(), CSSPrimitiveValue::CSS_NUMBER));
957             break;
958         }
959         case FilterOperation::HUE_ROTATE: {
960             BasicColorMatrixFilterOperation& colorMatrixOperation = downcast<BasicColorMatrixFilterOperation>(filterOperation);
961             filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::HueRotateFilterOperation);
962             filterValue->append(cssValuePool.createValue(colorMatrixOperation.amount(), CSSPrimitiveValue::CSS_DEG));
963             break;
964         }
965         case FilterOperation::INVERT: {
966             BasicComponentTransferFilterOperation& componentTransferOperation = downcast<BasicComponentTransferFilterOperation>(filterOperation);
967             filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::InvertFilterOperation);
968             filterValue->append(cssValuePool.createValue(componentTransferOperation.amount(), CSSPrimitiveValue::CSS_NUMBER));
969             break;
970         }
971         case FilterOperation::OPACITY: {
972             BasicComponentTransferFilterOperation& componentTransferOperation = downcast<BasicComponentTransferFilterOperation>(filterOperation);
973             filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::OpacityFilterOperation);
974             filterValue->append(cssValuePool.createValue(componentTransferOperation.amount(), CSSPrimitiveValue::CSS_NUMBER));
975             break;
976         }
977         case FilterOperation::BRIGHTNESS: {
978             BasicComponentTransferFilterOperation& brightnessOperation = downcast<BasicComponentTransferFilterOperation>(filterOperation);
979             filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::BrightnessFilterOperation);
980             filterValue->append(cssValuePool.createValue(brightnessOperation.amount(), CSSPrimitiveValue::CSS_NUMBER));
981             break;
982         }
983         case FilterOperation::CONTRAST: {
984             BasicComponentTransferFilterOperation& contrastOperation = downcast<BasicComponentTransferFilterOperation>(filterOperation);
985             filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::ContrastFilterOperation);
986             filterValue->append(cssValuePool.createValue(contrastOperation.amount(), CSSPrimitiveValue::CSS_NUMBER));
987             break;
988         }
989         case FilterOperation::BLUR: {
990             BlurFilterOperation& blurOperation = downcast<BlurFilterOperation>(filterOperation);
991             filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::BlurFilterOperation);
992             filterValue->append(adjustLengthForZoom(blurOperation.stdDeviation(), style, adjust));
993             break;
994         }
995         case FilterOperation::DROP_SHADOW: {
996             DropShadowFilterOperation& dropShadowOperation = downcast<DropShadowFilterOperation>(filterOperation);
997             filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::DropShadowFilterOperation);
998             // We want our computed style to look like that of a text shadow (has neither spread nor inset style).
999             ShadowData shadowData = ShadowData(dropShadowOperation.location(), dropShadowOperation.stdDeviation(), 0, Normal, false, dropShadowOperation.color());
1000             filterValue->append(valueForShadow(&shadowData, CSSPropertyTextShadow, style, adjust));
1001             break;
1002         }
1003         default:
1004             filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::UnknownFilterOperation);
1005             break;
1006         }
1007         list.get().append(filterValue.releaseNonNull());
1008     }
1009
1010     return WTFMove(list);
1011 }
1012
1013 #if ENABLE(CSS_GRID_LAYOUT)
1014 static Ref<CSSValue> specifiedValueForGridTrackBreadth(const GridLength& trackBreadth, const RenderStyle& style)
1015 {
1016     if (!trackBreadth.isLength())
1017         return CSSValuePool::singleton().createValue(trackBreadth.flex(), CSSPrimitiveValue::CSS_FR);
1018
1019     const Length& trackBreadthLength = trackBreadth.length();
1020     if (trackBreadthLength.isAuto())
1021         return CSSValuePool::singleton().createIdentifierValue(CSSValueAuto);
1022     return zoomAdjustedPixelValueForLength(trackBreadthLength, style);
1023 }
1024
1025 static Ref<CSSValue> specifiedValueForGridTrackSize(const GridTrackSize& trackSize, const RenderStyle& style)
1026 {
1027     switch (trackSize.type()) {
1028     case LengthTrackSizing:
1029         return specifiedValueForGridTrackBreadth(trackSize.length(), style);
1030     default:
1031         ASSERT(trackSize.type() == MinMaxTrackSizing);
1032         auto minMaxTrackBreadths = CSSValueList::createCommaSeparated();
1033         minMaxTrackBreadths->append(specifiedValueForGridTrackBreadth(trackSize.minTrackBreadth(), style));
1034         minMaxTrackBreadths->append(specifiedValueForGridTrackBreadth(trackSize.maxTrackBreadth(), style));
1035         return CSSFunctionValue::create("minmax(", WTFMove(minMaxTrackBreadths));
1036     }
1037 }
1038
1039 class OrderedNamedLinesCollector {
1040     WTF_MAKE_NONCOPYABLE(OrderedNamedLinesCollector);
1041 public:
1042     OrderedNamedLinesCollector(const RenderStyle& style, bool isRowAxis, unsigned repetitions)
1043         : m_orderedNamedGridLines(isRowAxis ? style.orderedNamedGridColumnLines() : style.orderedNamedGridRowLines())
1044         , m_orderedNamedAutoRepeatGridLines(isRowAxis ? style.autoRepeatOrderedNamedGridColumnLines() : style.autoRepeatOrderedNamedGridRowLines())
1045         , m_insertionPoint(isRowAxis ? style.gridAutoRepeatColumnsInsertionPoint() : style.gridAutoRepeatRowsInsertionPoint())
1046         , m_repetitions(repetitions)
1047     {
1048     }
1049
1050     bool isEmpty() const { return m_orderedNamedGridLines.isEmpty() && m_orderedNamedAutoRepeatGridLines.isEmpty(); }
1051     void collectLineNamesForIndex(CSSGridLineNamesValue&, unsigned index) const;
1052
1053 private:
1054
1055     enum NamedLinesType { NamedLines, AutoRepeatNamedLines };
1056     void appendLines(CSSGridLineNamesValue&, unsigned index, NamedLinesType) const;
1057
1058     const OrderedNamedGridLinesMap& m_orderedNamedGridLines;
1059     const OrderedNamedGridLinesMap& m_orderedNamedAutoRepeatGridLines;
1060     unsigned m_insertionPoint;
1061     unsigned m_repetitions;
1062 };
1063
1064 void OrderedNamedLinesCollector::appendLines(CSSGridLineNamesValue& lineNamesValue, unsigned index, NamedLinesType type) const
1065 {
1066     auto iter = type == NamedLines ? m_orderedNamedGridLines.find(index) : m_orderedNamedAutoRepeatGridLines.find(index);
1067     auto endIter = type == NamedLines ? m_orderedNamedGridLines.end() : m_orderedNamedAutoRepeatGridLines.end();
1068     if (iter == endIter)
1069         return;
1070
1071     auto& cssValuePool = CSSValuePool::singleton();
1072     for (auto lineName : iter->value)
1073         lineNamesValue.append(cssValuePool.createValue(lineName, CSSPrimitiveValue::CSS_STRING));
1074 }
1075
1076 void OrderedNamedLinesCollector::collectLineNamesForIndex(CSSGridLineNamesValue& lineNamesValue, unsigned i) const
1077 {
1078     ASSERT(!isEmpty());
1079     if (m_orderedNamedAutoRepeatGridLines.isEmpty() || i < m_insertionPoint) {
1080         appendLines(lineNamesValue, i, NamedLines);
1081         return;
1082     }
1083
1084     ASSERT(m_repetitions);
1085     if (i > m_insertionPoint + m_repetitions) {
1086         appendLines(lineNamesValue, i - (m_repetitions - 1), NamedLines);
1087         return;
1088     }
1089
1090     if (i == m_insertionPoint) {
1091         appendLines(lineNamesValue, i, NamedLines);
1092         appendLines(lineNamesValue, 0, AutoRepeatNamedLines);
1093         return;
1094     }
1095
1096     if (i == m_insertionPoint + m_repetitions) {
1097         appendLines(lineNamesValue, 1, AutoRepeatNamedLines);
1098         appendLines(lineNamesValue, m_insertionPoint + 1, NamedLines);
1099         return;
1100     }
1101
1102     appendLines(lineNamesValue, 1, AutoRepeatNamedLines);
1103     appendLines(lineNamesValue, 0, AutoRepeatNamedLines);
1104 }
1105
1106 static void addValuesForNamedGridLinesAtIndex(OrderedNamedLinesCollector& collector, unsigned i, CSSValueList& list)
1107 {
1108     if (collector.isEmpty())
1109         return;
1110
1111     auto lineNames = CSSGridLineNamesValue::create();
1112     collector.collectLineNamesForIndex(lineNames.get(), i);
1113     if (lineNames->length())
1114         list.append(WTFMove(lineNames));
1115 }
1116
1117 static Ref<CSSValue> valueForGridTrackList(GridTrackSizingDirection direction, RenderObject* renderer, const RenderStyle& style)
1118 {
1119     bool isRowAxis = direction == ForColumns;
1120     bool isRenderGrid = is<RenderGrid>(renderer);
1121     auto& trackSizes = isRowAxis ? style.gridColumns() : style.gridRows();
1122     auto& autoRepeatTrackSizes = isRowAxis ? style.gridAutoRepeatColumns() : style.gridAutoRepeatRows();
1123
1124     // Handle the 'none' case.
1125     bool trackListIsEmpty = trackSizes.isEmpty() && autoRepeatTrackSizes.isEmpty();
1126     if (isRenderGrid && trackListIsEmpty) {
1127         // For grids we should consider every listed track, whether implicitly or explicitly created. If we don't have
1128         // any explicit track and there are no children then there are no implicit tracks. We cannot simply check the
1129         // number of rows/columns in our internal grid representation because it's always at least 1x1 (see r143331).
1130         trackListIsEmpty = !downcast<RenderBlock>(*renderer).firstChild();
1131     }
1132
1133     if (trackListIsEmpty)
1134         return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
1135
1136     unsigned repetitions = isRenderGrid ? downcast<RenderGrid>(renderer)->autoRepeatCountForDirection(direction) : 0;
1137     OrderedNamedLinesCollector collector(style, isRowAxis, repetitions);
1138     auto list = CSSValueList::createSpaceSeparated();
1139     unsigned insertionIndex;
1140     if (isRenderGrid) {
1141         auto& grid = downcast<RenderGrid>(*renderer);
1142         const auto& trackPositions = direction == ForColumns ? grid.columnPositions() : grid.rowPositions();
1143         // There are at least #tracks + 1 grid lines (trackPositions). Apart from that, the grid container can generate implicit grid tracks,
1144         // so we'll have more trackPositions than trackSizes as the latter only contain the explicit grid.
1145         ASSERT(trackPositions.size() - 1 >= trackSizes.size());
1146
1147         unsigned i = 0;
1148         LayoutUnit gutterSize = grid.guttersSize(direction, 2);
1149         LayoutUnit offsetBetweenTracks = grid.offsetBetweenTracks(direction);
1150         for (; i < trackPositions.size() - 2; ++i) {
1151             addValuesForNamedGridLinesAtIndex(collector, i, list.get());
1152             list.get().append(zoomAdjustedPixelValue(trackPositions[i + 1] - trackPositions[i] - gutterSize - offsetBetweenTracks, style));
1153         }
1154         // Last track line does not have any gutter or distribution offset.
1155         addValuesForNamedGridLinesAtIndex(collector, i, list.get());
1156         list.get().append(zoomAdjustedPixelValue(trackPositions[i + 1] - trackPositions[i], style));
1157         insertionIndex = trackPositions.size() - 1;
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(PassRefPtr<Node> node, bool allowVisitedStyle, PseudoId pseudoElementSpecifier)
1587     : m_node(node)
1588     , m_pseudoElementSpecifier(pseudoElementSpecifier)
1589     , m_allowVisitedStyle(allowVisitedStyle)
1590 {
1591 }
1592
1593
1594 CSSComputedStyleDeclaration::CSSComputedStyleDeclaration(PassRefPtr<Node> n, bool allowVisitedStyle, const String& pseudoElementName)
1595     : m_node(n)
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 static StyleSelfAlignmentData resolveLegacyJustifyItems(const StyleSelfAlignmentData& data)
2283 {
2284     if (data.positionType() == LegacyPosition)
2285         return { data.position(), OverflowAlignmentDefault };
2286     return data;
2287 }
2288
2289 static StyleSelfAlignmentData resolveJustifyItemsAuto(const StyleSelfAlignmentData& data, Node* parent)
2290 {
2291     if (data.position() != ItemPositionAuto)
2292         return data;
2293
2294     // If the inherited value of justify-items includes the 'legacy' keyword, 'auto' computes to the inherited value.
2295     const auto& inheritedValue = (!parent || !parent->computedStyle()) ? RenderStyle::initialDefaultAlignment() : parent->computedStyle()->justifyItems();
2296     if (inheritedValue.positionType() == LegacyPosition)
2297         return inheritedValue;
2298     if (inheritedValue.position() == ItemPositionAuto)
2299         return resolveJustifyItemsAuto(inheritedValue, parent->parentNode());
2300     return { ItemPositionNormal, OverflowAlignmentDefault };
2301 }
2302
2303 static StyleSelfAlignmentData resolveJustifySelfAuto(const StyleSelfAlignmentData& data, Node* parent)
2304 {
2305     if (data.position() != ItemPositionAuto)
2306         return data;
2307
2308     // The 'auto' keyword computes to the computed value of justify-items on the parent or 'normal' if the box has no parent.
2309     if (!parent || !parent->computedStyle())
2310         return { ItemPositionNormal, OverflowAlignmentDefault };
2311     return resolveLegacyJustifyItems(resolveJustifyItemsAuto(parent->computedStyle()->justifyItems(), parent->parentNode()));
2312 }
2313
2314 static StyleSelfAlignmentData resolveAlignSelfAuto(const StyleSelfAlignmentData& data, Node* parent)
2315 {
2316     if (data.position() != ItemPositionAuto)
2317         return data;
2318
2319     // The 'auto' keyword computes to the computed value of align-items on the parent or 'normal' if the box has no parent.
2320     if (!parent || !parent->computedStyle())
2321         return { ItemPositionNormal, OverflowAlignmentDefault };
2322     return parent->computedStyle()->alignItems();
2323 }
2324
2325 RefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropertyID propertyID, EUpdateLayout updateLayout) const
2326 {
2327     return ComputedStyleExtractor(m_node, m_allowVisitedStyle, m_pseudoElementSpecifier).propertyValue(propertyID, updateLayout);
2328 }
2329
2330 Ref<MutableStyleProperties> CSSComputedStyleDeclaration::copyProperties() const
2331 {
2332     return ComputedStyleExtractor(m_node, m_allowVisitedStyle, m_pseudoElementSpecifier).copyProperties();
2333 }
2334
2335 static inline bool nodeOrItsAncestorNeedsStyleRecalc(const Node& node)
2336 {
2337     if (node.needsStyleRecalc())
2338         return true;
2339
2340     const Node* currentNode = &node;
2341     const Element* ancestor = currentNode->parentOrShadowHostElement();
2342     while (ancestor) {
2343         if (ancestor->needsStyleRecalc())
2344             return true;
2345
2346         if (ancestor->directChildNeedsStyleRecalc() && currentNode->styleIsAffectedByPreviousSibling())
2347             return true;
2348
2349         currentNode = ancestor;
2350         ancestor = currentNode->parentOrShadowHostElement();
2351     }
2352     return false;
2353 }
2354
2355 static inline bool updateStyleIfNeededForNode(const Node& node)
2356 {
2357     Document& document = node.document();
2358     if (!document.hasPendingForcedStyleRecalc() && !(document.childNeedsStyleRecalc() && nodeOrItsAncestorNeedsStyleRecalc(node)))
2359         return false;
2360     document.updateStyleIfNeeded();
2361     return true;
2362 }
2363
2364 static inline const RenderStyle* computeRenderStyleForProperty(Node* styledNode, PseudoId pseudoElementSpecifier, CSSPropertyID propertyID, std::unique_ptr<RenderStyle>& ownedStyle)
2365 {
2366     RenderObject* renderer = styledNode->renderer();
2367
2368     if (renderer && renderer->isComposited() && AnimationController::supportsAcceleratedAnimationOfProperty(propertyID)) {
2369         ownedStyle = renderer->animation().getAnimatedStyleForRenderer(downcast<RenderElement>(*renderer));
2370         if (pseudoElementSpecifier && !styledNode->isPseudoElement()) {
2371             // FIXME: This cached pseudo style will only exist if the animation has been run at least once.
2372             return ownedStyle->getCachedPseudoStyle(pseudoElementSpecifier);
2373         }
2374         return ownedStyle.get();
2375     }
2376
2377     return styledNode->computedStyle(styledNode->isPseudoElement() ? NOPSEUDO : pseudoElementSpecifier);
2378 }
2379
2380 #if ENABLE(CSS_SHAPES)
2381 static Ref<CSSValue> shapePropertyValue(const RenderStyle& style, const ShapeValue* shapeValue)
2382 {
2383     if (!shapeValue)
2384         return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
2385
2386     if (shapeValue->type() == ShapeValue::Type::Box)
2387         return CSSValuePool::singleton().createValue(shapeValue->cssBox());
2388
2389     if (shapeValue->type() == ShapeValue::Type::Image) {
2390         if (shapeValue->image())
2391             return *shapeValue->image()->cssValue();
2392         return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
2393     }
2394
2395     ASSERT(shapeValue->type() == ShapeValue::Type::Shape);
2396
2397     RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2398     list->append(valueForBasicShape(style, *shapeValue->shape()));
2399     if (shapeValue->cssBox() != BoxMissing)
2400         list->append(CSSValuePool::singleton().createValue(shapeValue->cssBox()));
2401     return list.releaseNonNull();
2402 }
2403 #endif
2404
2405 static Ref<CSSValueList> valueForItemPositionWithOverflowAlignment(const StyleSelfAlignmentData& data)
2406 {
2407     auto& cssValuePool = CSSValuePool::singleton();
2408     auto result = CSSValueList::createSpaceSeparated();
2409     if (data.positionType() == LegacyPosition)
2410         result.get().append(cssValuePool.createIdentifierValue(CSSValueLegacy));
2411     result.get().append(cssValuePool.createValue(data.position()));
2412     if (data.position() >= ItemPositionCenter && data.overflow() != OverflowAlignmentDefault)
2413         result.get().append(cssValuePool.createValue(data.overflow()));
2414     ASSERT(result.get().length() <= 2);
2415     return result;
2416 }
2417
2418 static Ref<CSSValueList> valueForContentPositionAndDistributionWithOverflowAlignment(const StyleContentAlignmentData& data)
2419 {
2420     auto& cssValuePool = CSSValuePool::singleton();
2421     auto result = CSSValueList::createSpaceSeparated();
2422     if (data.distribution() != ContentDistributionDefault)
2423         result.get().append(cssValuePool.createValue(data.distribution()));
2424     if (data.distribution() == ContentDistributionDefault || data.position() != ContentPositionNormal)
2425         result.get().append(cssValuePool.createValue(data.position()));
2426     if ((data.position() >= ContentPositionCenter || data.distribution() != ContentDistributionDefault) && data.overflow() != OverflowAlignmentDefault)
2427         result.get().append(cssValuePool.createValue(data.overflow()));
2428     ASSERT(result.get().length() > 0);
2429     ASSERT(result.get().length() <= 3);
2430     return result;
2431 }
2432
2433 inline static bool isFlexOrGrid(ContainerNode* element)
2434 {
2435     return element && element->computedStyle() && element->computedStyle()->isDisplayFlexibleOrGridBox();
2436 }
2437
2438 RefPtr<CSSValue> ComputedStyleExtractor::customPropertyValue(const String& propertyName) const
2439 {
2440     Node* styledNode = this->styledNode();
2441     if (!styledNode)
2442         return nullptr;
2443     
2444     if (updateStyleIfNeededForNode(*styledNode)) {
2445         // The style recalc could have caused the styled node to be discarded or replaced
2446         // if it was a PseudoElement so we need to update it.
2447         styledNode = this->styledNode();
2448     }
2449
2450     std::unique_ptr<RenderStyle> ownedStyle;
2451     auto* style = computeRenderStyleForProperty(styledNode, m_pseudoElementSpecifier, CSSPropertyCustom, ownedStyle);
2452     if (!style || !style->hasCustomProperty(propertyName))
2453         return nullptr;
2454
2455     return style->getCustomPropertyValue(propertyName);
2456 }
2457
2458 String ComputedStyleExtractor::customPropertyText(const String& propertyName) const
2459 {
2460     RefPtr<CSSValue> propertyValue = this->customPropertyValue(propertyName);
2461     return propertyValue ? propertyValue->cssText() : emptyString();
2462 }
2463
2464 RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID, EUpdateLayout updateLayout) const
2465 {
2466     Node* styledNode = this->styledNode();
2467     if (!styledNode)
2468         return nullptr;
2469
2470     std::unique_ptr<RenderStyle> ownedStyle;
2471     const RenderStyle* style = nullptr;
2472     RenderObject* renderer = nullptr;
2473     bool forceFullLayout = false;
2474     if (updateLayout) {
2475         Document& document = styledNode->document();
2476
2477         if (updateStyleIfNeededForNode(*styledNode)) {
2478             // The style recalc could have caused the styled node to be discarded or replaced
2479             // if it was a PseudoElement so we need to update it.
2480             styledNode = this->styledNode();
2481         }
2482
2483         renderer = styledNode->renderer();
2484
2485         if (propertyID == CSSPropertyDisplay && !renderer && is<SVGElement>(*styledNode) && !downcast<SVGElement>(*styledNode).isValid())
2486             return nullptr;
2487
2488         style = computeRenderStyleForProperty(styledNode, m_pseudoElementSpecifier, propertyID, ownedStyle);
2489
2490         // FIXME: Some of these cases could be narrowed down or optimized better.
2491         forceFullLayout = isLayoutDependent(propertyID, style, renderer)
2492             || styledNode->isInShadowTree()
2493             || (document.styleResolverIfExists() && document.styleResolverIfExists()->hasViewportDependentMediaQueries() && document.ownerElement());
2494
2495         if (forceFullLayout) {
2496             document.updateLayoutIgnorePendingStylesheets();
2497             styledNode = this->styledNode();
2498         }
2499     }
2500
2501     if (!updateLayout || forceFullLayout) {
2502         style = computeRenderStyleForProperty(styledNode, m_pseudoElementSpecifier, propertyID, ownedStyle);
2503         renderer = styledNode->renderer();
2504     }
2505
2506     if (!style)
2507         return nullptr;
2508
2509     auto& cssValuePool = CSSValuePool::singleton();
2510     propertyID = CSSProperty::resolveDirectionAwareProperty(propertyID, style->direction(), style->writingMode());
2511
2512     switch (propertyID) {
2513         case CSSPropertyInvalid:
2514             break;
2515
2516         case CSSPropertyBackgroundColor:
2517             return cssValuePool.createColorValue(m_allowVisitedStyle? style->visitedDependentColor(CSSPropertyBackgroundColor).rgb() : style->backgroundColor().rgb());
2518         case CSSPropertyBackgroundImage:
2519         case CSSPropertyWebkitMaskImage: {
2520             const FillLayer* layers = propertyID == CSSPropertyWebkitMaskImage ? style->maskLayers() : style->backgroundLayers();
2521             if (!layers)
2522                 return cssValuePool.createIdentifierValue(CSSValueNone);
2523
2524             if (!layers->next()) {
2525                 if (layers->image())
2526                     return layers->image()->cssValue();
2527
2528                 return cssValuePool.createIdentifierValue(CSSValueNone);
2529             }
2530
2531             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2532             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) {
2533                 if (currLayer->image())
2534                     list->append(*currLayer->image()->cssValue());
2535                 else
2536                     list->append(cssValuePool.createIdentifierValue(CSSValueNone));
2537             }
2538             return list;
2539         }
2540         case CSSPropertyBackgroundSize:
2541         case CSSPropertyWebkitBackgroundSize:
2542         case CSSPropertyWebkitMaskSize: {
2543             const FillLayer* layers = propertyID == CSSPropertyWebkitMaskSize ? style->maskLayers() : style->backgroundLayers();
2544             if (!layers->next())
2545                 return fillSizeToCSSValue(layers->size(), *style);
2546
2547             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2548             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
2549                 list->append(fillSizeToCSSValue(currLayer->size(), *style));
2550
2551             return list;
2552         }
2553         case CSSPropertyBackgroundRepeat:
2554         case CSSPropertyWebkitMaskRepeat: {
2555             const FillLayer* layers = propertyID == CSSPropertyWebkitMaskRepeat ? style->maskLayers() : style->backgroundLayers();
2556             if (!layers->next())
2557                 return fillRepeatToCSSValue(layers->repeatX(), layers->repeatY());
2558
2559             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2560             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
2561                 list->append(fillRepeatToCSSValue(currLayer->repeatX(), currLayer->repeatY()));
2562
2563             return list;
2564         }
2565         case CSSPropertyWebkitMaskSourceType: {
2566             const FillLayer* layers = style->maskLayers();
2567
2568             if (!layers)
2569                 return cssValuePool.createIdentifierValue(CSSValueNone);
2570
2571             if (!layers->next())
2572                 return fillSourceTypeToCSSValue(layers->maskSourceType());
2573
2574             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2575             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
2576                 list->append(fillSourceTypeToCSSValue(currLayer->maskSourceType()));
2577
2578             return list;
2579         }
2580         case CSSPropertyWebkitBackgroundComposite:
2581         case CSSPropertyWebkitMaskComposite: {
2582             const FillLayer* layers = propertyID == CSSPropertyWebkitMaskComposite ? style->maskLayers() : style->backgroundLayers();
2583             if (!layers->next())
2584                 return cssValuePool.createValue(layers->composite());
2585
2586             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2587             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
2588                 list->append(cssValuePool.createValue(currLayer->composite()));
2589
2590             return list;
2591         }
2592         case CSSPropertyBackgroundAttachment: {
2593             const FillLayer* layers = style->backgroundLayers();
2594             if (!layers->next())
2595                 return cssValuePool.createValue(layers->attachment());
2596
2597             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2598             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
2599                 list->append(cssValuePool.createValue(currLayer->attachment()));
2600
2601             return list;
2602         }
2603         case CSSPropertyBackgroundClip:
2604         case CSSPropertyBackgroundOrigin:
2605         case CSSPropertyWebkitBackgroundClip:
2606         case CSSPropertyWebkitBackgroundOrigin:
2607         case CSSPropertyWebkitMaskClip:
2608         case CSSPropertyWebkitMaskOrigin: {
2609             const FillLayer* layers = (propertyID == CSSPropertyWebkitMaskClip || propertyID == CSSPropertyWebkitMaskOrigin) ? style->maskLayers() : style->backgroundLayers();
2610             bool isClip = propertyID == CSSPropertyBackgroundClip || propertyID == CSSPropertyWebkitBackgroundClip || propertyID == CSSPropertyWebkitMaskClip;
2611             if (!layers->next()) {
2612                 EFillBox box = isClip ? layers->clip() : layers->origin();
2613                 return cssValuePool.createValue(box);
2614             }
2615
2616             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2617             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) {
2618                 EFillBox box = isClip ? currLayer->clip() : currLayer->origin();
2619                 list->append(cssValuePool.createValue(box));
2620             }
2621
2622             return list;
2623         }
2624         case CSSPropertyBackgroundPosition:
2625         case CSSPropertyWebkitMaskPosition: {
2626             const FillLayer* layers = propertyID == CSSPropertyWebkitMaskPosition ? style->maskLayers() : style->backgroundLayers();
2627             if (!layers->next())
2628                 return createPositionListForLayer(propertyID, layers, *style);
2629
2630             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2631             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
2632                 list->append(createPositionListForLayer(propertyID, currLayer, *style));
2633             return list;
2634         }
2635         case CSSPropertyBackgroundPositionX:
2636         case CSSPropertyWebkitMaskPositionX: {
2637             const FillLayer* layers = propertyID == CSSPropertyWebkitMaskPositionX ? style->maskLayers() : style->backgroundLayers();
2638             if (!layers->next())
2639                 return cssValuePool.createValue(layers->xPosition());
2640
2641             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2642             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
2643                 list->append(cssValuePool.createValue(currLayer->xPosition()));
2644
2645             return list;
2646         }
2647         case CSSPropertyBackgroundPositionY:
2648         case CSSPropertyWebkitMaskPositionY: {
2649             const FillLayer* layers = propertyID == CSSPropertyWebkitMaskPositionY ? style->maskLayers() : style->backgroundLayers();
2650             if (!layers->next())
2651                 return cssValuePool.createValue(layers->yPosition());
2652
2653             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2654             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
2655                 list->append(cssValuePool.createValue(currLayer->yPosition()));
2656
2657             return list;
2658         }
2659         case CSSPropertyBorderCollapse:
2660             if (style->borderCollapse())
2661                 return cssValuePool.createIdentifierValue(CSSValueCollapse);
2662             return cssValuePool.createIdentifierValue(CSSValueSeparate);
2663         case CSSPropertyBorderSpacing: {
2664             RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2665             list->append(zoomAdjustedPixelValue(style->horizontalBorderSpacing(), *style));
2666             list->append(zoomAdjustedPixelValue(style->verticalBorderSpacing(), *style));
2667             return list;
2668         }
2669         case CSSPropertyWebkitBorderHorizontalSpacing:
2670             return zoomAdjustedPixelValue(style->horizontalBorderSpacing(), *style);
2671         case CSSPropertyWebkitBorderVerticalSpacing:
2672             return zoomAdjustedPixelValue(style->verticalBorderSpacing(), *style);
2673         case CSSPropertyBorderImageSource:
2674             if (style->borderImageSource())
2675                 return style->borderImageSource()->cssValue();
2676             return cssValuePool.createIdentifierValue(CSSValueNone);
2677         case CSSPropertyBorderTopColor:
2678             return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyBorderTopColor).rgb()) : currentColorOrValidColor(style, style->borderTopColor());
2679         case CSSPropertyBorderRightColor:
2680             return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyBorderRightColor).rgb()) : currentColorOrValidColor(style, style->borderRightColor());
2681         case CSSPropertyBorderBottomColor:
2682             return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyBorderBottomColor).rgb()) : currentColorOrValidColor(style, style->borderBottomColor());
2683         case CSSPropertyBorderLeftColor:
2684             return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyBorderLeftColor).rgb()) : currentColorOrValidColor(style, style->borderLeftColor());
2685         case CSSPropertyBorderTopStyle:
2686             return cssValuePool.createValue(style->borderTopStyle());
2687         case CSSPropertyBorderRightStyle:
2688             return cssValuePool.createValue(style->borderRightStyle());
2689         case CSSPropertyBorderBottomStyle:
2690             return cssValuePool.createValue(style->borderBottomStyle());
2691         case CSSPropertyBorderLeftStyle:
2692             return cssValuePool.createValue(style->borderLeftStyle());
2693         case CSSPropertyBorderTopWidth:
2694             return zoomAdjustedPixelValue(style->borderTopWidth(), *style);
2695         case CSSPropertyBorderRightWidth:
2696             return zoomAdjustedPixelValue(style->borderRightWidth(), *style);
2697         case CSSPropertyBorderBottomWidth:
2698             return zoomAdjustedPixelValue(style->borderBottomWidth(), *style);
2699         case CSSPropertyBorderLeftWidth:
2700             return zoomAdjustedPixelValue(style->borderLeftWidth(), *style);
2701         case CSSPropertyBottom:
2702             return positionOffsetValue(*style, CSSPropertyBottom);
2703         case CSSPropertyWebkitBoxAlign:
2704             return cssValuePool.createValue(style->boxAlign());
2705 #if ENABLE(CSS_BOX_DECORATION_BREAK)
2706         case CSSPropertyWebkitBoxDecorationBreak:
2707             if (style->boxDecorationBreak() == DSLICE)
2708                 return cssValuePool.createIdentifierValue(CSSValueSlice);
2709         return cssValuePool.createIdentifierValue(CSSValueClone);
2710 #endif
2711         case CSSPropertyWebkitBoxDirection:
2712             return cssValuePool.createValue(style->boxDirection());
2713         case CSSPropertyWebkitBoxFlex:
2714             return cssValuePool.createValue(style->boxFlex(), CSSPrimitiveValue::CSS_NUMBER);
2715         case CSSPropertyWebkitBoxFlexGroup:
2716             return cssValuePool.createValue(style->boxFlexGroup(), CSSPrimitiveValue::CSS_NUMBER);
2717         case CSSPropertyWebkitBoxLines:
2718             return cssValuePool.createValue(style->boxLines());
2719         case CSSPropertyWebkitBoxOrdinalGroup:
2720             return cssValuePool.createValue(style->boxOrdinalGroup(), CSSPrimitiveValue::CSS_NUMBER);
2721         case CSSPropertyWebkitBoxOrient:
2722             return cssValuePool.createValue(style->boxOrient());
2723         case CSSPropertyWebkitBoxPack:
2724             return cssValuePool.createValue(style->boxPack());
2725         case CSSPropertyWebkitBoxReflect:
2726             return valueForReflection(style->boxReflect(), *style);
2727         case CSSPropertyBoxShadow:
2728         case CSSPropertyWebkitBoxShadow:
2729             return valueForShadow(style->boxShadow(), propertyID, *style);
2730         case CSSPropertyCaptionSide:
2731             return cssValuePool.createValue(style->captionSide());
2732         case CSSPropertyClear:
2733             return cssValuePool.createValue(style->clear());
2734         case CSSPropertyColor:
2735             return cssValuePool.createColorValue(m_allowVisitedStyle ? style->visitedDependentColor(CSSPropertyColor).rgb() : style->color().rgb());
2736         case CSSPropertyWebkitPrintColorAdjust:
2737             return cssValuePool.createValue(style->printColorAdjust());
2738         case CSSPropertyWebkitColumnAxis:
2739             return cssValuePool.createValue(style->columnAxis());
2740         case CSSPropertyColumnCount:
2741             if (style->hasAutoColumnCount())
2742                 return cssValuePool.createIdentifierValue(CSSValueAuto);
2743             return cssValuePool.createValue(style->columnCount(), CSSPrimitiveValue::CSS_NUMBER);
2744         case CSSPropertyColumnFill:
2745             return cssValuePool.createValue(style->columnFill());
2746         case CSSPropertyColumnGap:
2747             if (style->hasNormalColumnGap())
2748                 return cssValuePool.createIdentifierValue(CSSValueNormal);
2749             return zoomAdjustedPixelValue(style->columnGap(), *style);
2750         case CSSPropertyColumnProgression:
2751             return cssValuePool.createValue(style->columnProgression());
2752         case CSSPropertyColumnRuleColor:
2753             return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyOutlineColor).rgb()) : currentColorOrValidColor(style, style->columnRuleColor());
2754         case CSSPropertyColumnRuleStyle:
2755             return cssValuePool.createValue(style->columnRuleStyle());
2756         case CSSPropertyColumnRuleWidth:
2757             return zoomAdjustedPixelValue(style->columnRuleWidth(), *style);
2758         case CSSPropertyColumnSpan:
2759             return cssValuePool.createIdentifierValue(style->columnSpan() ? CSSValueAll : CSSValueNone);
2760         case CSSPropertyWebkitColumnBreakAfter:
2761             return cssValuePool.createValue(convertToColumnBreak(style->breakAfter()));
2762         case CSSPropertyWebkitColumnBreakBefore:
2763             return cssValuePool.createValue(convertToColumnBreak(style->breakBefore()));
2764         case CSSPropertyWebkitColumnBreakInside:
2765             return cssValuePool.createValue(convertToColumnBreak(style->breakInside()));
2766         case CSSPropertyColumnWidth:
2767             if (style->hasAutoColumnWidth())
2768                 return cssValuePool.createIdentifierValue(CSSValueAuto);
2769             return zoomAdjustedPixelValue(style->columnWidth(), *style);
2770         case CSSPropertyTabSize:
2771             return cssValuePool.createValue(style->tabSize(), CSSPrimitiveValue::CSS_NUMBER);
2772 #if ENABLE(CSS_REGIONS)
2773         case CSSPropertyWebkitRegionBreakAfter:
2774             return cssValuePool.createValue(convertToRegionBreak(style->breakAfter()));
2775         case CSSPropertyWebkitRegionBreakBefore:
2776             return cssValuePool.createValue(convertToRegionBreak(style->breakBefore()));
2777         case CSSPropertyWebkitRegionBreakInside:
2778             return cssValuePool.createValue(convertToRegionBreak(style->breakInside()));
2779 #endif
2780         case CSSPropertyCursor: {
2781             RefPtr<CSSValueList> list;
2782             CursorList* cursors = style->cursors();
2783             if (cursors && cursors->size() > 0) {
2784                 list = CSSValueList::createCommaSeparated();
2785                 for (unsigned i = 0; i < cursors->size(); ++i)
2786                     if (StyleImage* image = cursors->at(i).image())
2787                         list->append(*image->cssValue());
2788             }
2789             auto value = cssValuePool.createValue(style->cursor());
2790             if (list) {
2791                 list->append(WTFMove(value));
2792                 return list;
2793             }
2794             return WTFMove(value);
2795         }
2796 #if ENABLE(CURSOR_VISIBILITY)
2797         case CSSPropertyWebkitCursorVisibility:
2798             return cssValuePool.createValue(style->cursorVisibility());
2799 #endif
2800         case CSSPropertyDirection:
2801             return cssValuePool.createValue(style->direction());
2802         case CSSPropertyDisplay:
2803             return cssValuePool.createValue(style->display());
2804         case CSSPropertyEmptyCells:
2805             return cssValuePool.createValue(style->emptyCells());
2806         case CSSPropertyAlignContent:
2807             return valueForContentPositionAndDistributionWithOverflowAlignment(style->alignContent());
2808         case CSSPropertyAlignItems:
2809             return valueForItemPositionWithOverflowAlignment(style->alignItems());
2810         case CSSPropertyAlignSelf:
2811             return valueForItemPositionWithOverflowAlignment(resolveAlignSelfAuto(style->alignSelf(), styledNode->parentNode()));
2812         case CSSPropertyFlex:
2813             return getCSSPropertyValuesForShorthandProperties(flexShorthand());
2814         case CSSPropertyFlexBasis:
2815             return cssValuePool.createValue(style->flexBasis());
2816         case CSSPropertyFlexDirection:
2817             return cssValuePool.createValue(style->flexDirection());
2818         case CSSPropertyFlexFlow:
2819             return getCSSPropertyValuesForShorthandProperties(flexFlowShorthand());
2820         case CSSPropertyFlexGrow:
2821             return cssValuePool.createValue(style->flexGrow());
2822         case CSSPropertyFlexShrink:
2823             return cssValuePool.createValue(style->flexShrink());
2824         case CSSPropertyFlexWrap:
2825             return cssValuePool.createValue(style->flexWrap());
2826         case CSSPropertyJustifyContent:
2827             return valueForContentPositionAndDistributionWithOverflowAlignment(style->justifyContent());
2828         case CSSPropertyJustifyItems:
2829             return valueForItemPositionWithOverflowAlignment(resolveJustifyItemsAuto(style->justifyItems(), styledNode->parentNode()));
2830         case CSSPropertyJustifySelf:
2831             return valueForItemPositionWithOverflowAlignment(resolveJustifySelfAuto(style->justifySelf(), styledNode->parentNode()));
2832         case CSSPropertyOrder:
2833             return cssValuePool.createValue(style->order(), CSSPrimitiveValue::CSS_NUMBER);
2834         case CSSPropertyFloat:
2835             if (style->display() != NONE && style->hasOutOfFlowPosition())
2836                 return cssValuePool.createIdentifierValue(CSSValueNone);
2837             return cssValuePool.createValue(style->floating());
2838         case CSSPropertyFont: {
2839             RefPtr<CSSFontValue> computedFont = CSSFontValue::create();
2840             computedFont->style = fontStyleFromStyle(style);
2841             if (style->fontDescription().variantCaps() == FontVariantCaps::Small)
2842                 computedFont->variant = CSSValuePool::singleton().createIdentifierValue(CSSValueSmallCaps);
2843             else
2844                 computedFont->variant = CSSValuePool::singleton().createIdentifierValue(CSSValueNormal);
2845             computedFont->weight = fontWeightFromStyle(style);
2846             computedFont->size = fontSizeFromStyle(*style);
2847             computedFont->lineHeight = lineHeightFromStyle(*style);
2848             computedFont->family = fontFamilyFromStyle(style);
2849             return computedFont;
2850         }
2851         case CSSPropertyFontFamily: {
2852             RefPtr<CSSValueList> fontFamilyList = fontFamilyFromStyle(style);
2853             // If there's only a single family, return that as a CSSPrimitiveValue.
2854             // NOTE: Gecko always returns this as a comma-separated CSSPrimitiveValue string.
2855             if (fontFamilyList->length() == 1)
2856                 return fontFamilyList->item(0);
2857             return fontFamilyList;
2858         }
2859         case CSSPropertyFontSize:
2860             return fontSizeFromStyle(*style);
2861         case CSSPropertyFontStyle:
2862             return fontStyleFromStyle(style);
2863         case CSSPropertyFontVariant:
2864             return fontVariantFromStyle(style);
2865         case CSSPropertyFontWeight:
2866             return fontWeightFromStyle(style);
2867         case CSSPropertyFontSynthesis:
2868             return fontSynthesisFromStyle(*style);
2869         case CSSPropertyFontFeatureSettings: {
2870             const FontFeatureSettings& featureSettings = style->fontDescription().featureSettings();
2871             if (!featureSettings.size())
2872                 return cssValuePool.createIdentifierValue(CSSValueNormal);
2873             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2874             for (auto& feature : featureSettings)
2875                 list->append(CSSFontFeatureValue::create(FontFeatureTag(feature.tag()), feature.value()));
2876             return list;
2877         }
2878 #if ENABLE(CSS_GRID_LAYOUT)
2879         case CSSPropertyGridAutoFlow: {
2880             RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2881             ASSERT(style->isGridAutoFlowDirectionRow() || style->isGridAutoFlowDirectionColumn());
2882             if (style->isGridAutoFlowDirectionRow())
2883                 list->append(cssValuePool.createIdentifierValue(CSSValueRow));
2884             else
2885                 list->append(cssValuePool.createIdentifierValue(CSSValueColumn));
2886
2887             if (style->isGridAutoFlowAlgorithmDense())
2888                 list->append(cssValuePool.createIdentifierValue(CSSValueDense));
2889
2890             return list;
2891         }
2892
2893         // Specs mention that getComputedStyle() should return the used value of the property instead of the computed
2894         // one for grid-definition-{rows|columns} but not for the grid-auto-{rows|columns} as things like
2895         // grid-auto-columns: 2fr; cannot be resolved to a value in pixels as the '2fr' means very different things
2896         // depending on the size of the explicit grid or the number of implicit tracks added to the grid. See
2897         // http://lists.w3.org/Archives/Public/www-style/2013Nov/0014.html
2898         case CSSPropertyGridAutoColumns:
2899             return specifiedValueForGridTrackSize(style->gridAutoColumns(), *style);
2900         case CSSPropertyGridAutoRows:
2901             return specifiedValueForGridTrackSize(style->gridAutoRows(), *style);
2902
2903         case CSSPropertyGridTemplateColumns:
2904             return valueForGridTrackList(ForColumns, renderer, *style);
2905         case CSSPropertyGridTemplateRows:
2906             return valueForGridTrackList(ForRows, renderer, *style);
2907
2908         case CSSPropertyGridColumnStart:
2909             return valueForGridPosition(style->gridItemColumnStart());
2910         case CSSPropertyGridColumnEnd:
2911             return valueForGridPosition(style->gridItemColumnEnd());
2912         case CSSPropertyGridRowStart:
2913             return valueForGridPosition(style->gridItemRowStart());
2914         case CSSPropertyGridRowEnd:
2915             return valueForGridPosition(style->gridItemRowEnd());
2916         case CSSPropertyGridArea:
2917             return getCSSPropertyValuesForGridShorthand(gridAreaShorthand());
2918         case CSSPropertyGridTemplate:
2919             return getCSSPropertyValuesForGridShorthand(gridTemplateShorthand());
2920         case CSSPropertyGrid:
2921             return getCSSPropertyValuesForGridShorthand(gridShorthand());
2922         case CSSPropertyGridColumn:
2923             return getCSSPropertyValuesForGridShorthand(gridColumnShorthand());
2924         case CSSPropertyGridRow:
2925             return getCSSPropertyValuesForGridShorthand(gridRowShorthand());
2926
2927         case CSSPropertyGridTemplateAreas:
2928             if (!style->namedGridAreaRowCount()) {
2929                 ASSERT(!style->namedGridAreaColumnCount());
2930                 return cssValuePool.createIdentifierValue(CSSValueNone);
2931             }
2932
2933             return CSSGridTemplateAreasValue::create(style->namedGridArea(), style->namedGridAreaRowCount(), style->namedGridAreaColumnCount());
2934         case CSSPropertyGridColumnGap:
2935             return zoomAdjustedPixelValueForLength(style->gridColumnGap(), *style);
2936         case CSSPropertyGridRowGap:
2937             return zoomAdjustedPixelValueForLength(style->gridRowGap(), *style);
2938         case CSSPropertyGridGap:
2939             return getCSSPropertyValuesForGridShorthand(gridGapShorthand());
2940 #endif /* ENABLE(CSS_GRID_LAYOUT) */
2941         case CSSPropertyHeight:
2942             if (renderer && !renderer->isRenderSVGModelObject()) {
2943                 // According to http://www.w3.org/TR/CSS2/visudet.html#the-height-property,
2944                 // the "height" property does not apply for non-replaced inline elements.
2945                 if (!renderer->isReplaced() && renderer->isInline())
2946                     return cssValuePool.createIdentifierValue(CSSValueAuto);
2947                 return zoomAdjustedPixelValue(sizingBox(*renderer).height(), *style);
2948             }
2949             return zoomAdjustedPixelValueForLength(style->height(), *style);
2950         case CSSPropertyWebkitHyphens:
2951             return cssValuePool.createValue(style->hyphens());
2952         case CSSPropertyWebkitHyphenateCharacter:
2953             if (style->hyphenationString().isNull())
2954                 return cssValuePool.createIdentifierValue(CSSValueAuto);
2955             return cssValuePool.createValue(style->hyphenationString(), CSSPrimitiveValue::CSS_STRING);
2956         case CSSPropertyWebkitHyphenateLimitAfter:
2957             if (style->hyphenationLimitAfter() < 0)
2958                 return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
2959             return CSSPrimitiveValue::create(style->hyphenationLimitAfter(), CSSPrimitiveValue::CSS_NUMBER);
2960         case CSSPropertyWebkitHyphenateLimitBefore:
2961             if (style->hyphenationLimitBefore() < 0)
2962                 return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
2963             return CSSPrimitiveValue::create(style->hyphenationLimitBefore(), CSSPrimitiveValue::CSS_NUMBER);
2964         case CSSPropertyWebkitHyphenateLimitLines:
2965             if (style->hyphenationLimitLines() < 0)
2966                 return CSSPrimitiveValue::createIdentifier(CSSValueNoLimit);
2967             return CSSPrimitiveValue::create(style->hyphenationLimitLines(), CSSPrimitiveValue::CSS_NUMBER);
2968         case CSSPropertyWebkitBorderFit:
2969             if (style->borderFit() == BorderFitBorder)
2970                 return cssValuePool.createIdentifierValue(CSSValueBorder);
2971             return cssValuePool.createIdentifierValue(CSSValueLines);
2972 #if ENABLE(CSS_IMAGE_ORIENTATION)
2973         case CSSPropertyImageOrientation:
2974             return cssValuePool.createValue(style->imageOrientation());
2975 #endif
2976         case CSSPropertyImageRendering:
2977             return CSSPrimitiveValue::create(style->imageRendering());
2978 #if ENABLE(CSS_IMAGE_RESOLUTION)
2979         case CSSPropertyImageResolution:
2980             return cssValuePool.createValue(style->imageResolution(), CSSPrimitiveValue::CSS_DPPX);
2981 #endif
2982         case CSSPropertyLeft:
2983             return positionOffsetValue(*style, CSSPropertyLeft);
2984         case CSSPropertyLetterSpacing:
2985             if (!style->letterSpacing())
2986                 return cssValuePool.createIdentifierValue(CSSValueNormal);
2987             return zoomAdjustedPixelValue(style->letterSpacing(), *style);
2988         case CSSPropertyWebkitLineClamp:
2989             if (style->lineClamp().isNone())
2990                 return cssValuePool.createIdentifierValue(CSSValueNone);
2991             return cssValuePool.createValue(style->lineClamp().value(), style->lineClamp().isPercentage() ? CSSPrimitiveValue::CSS_PERCENTAGE : CSSPrimitiveValue::CSS_NUMBER);
2992         case CSSPropertyLineHeight:
2993             return lineHeightFromStyle(*style);
2994         case CSSPropertyListStyleImage:
2995             if (style->listStyleImage())
2996                 return style->listStyleImage()->cssValue();
2997             return cssValuePool.createIdentifierValue(CSSValueNone);
2998         case CSSPropertyListStylePosition:
2999             return cssValuePool.createValue(style->listStylePosition());
3000         case CSSPropertyListStyleType:
3001             return cssValuePool.createValue(style->listStyleType());
3002         case CSSPropertyWebkitLocale:
3003             if (style->locale().isNull())
3004                 return cssValuePool.createIdentifierValue(CSSValueAuto);
3005             return cssValuePool.createValue(style->locale(), CSSPrimitiveValue::CSS_STRING);
3006         case CSSPropertyMarginTop:
3007             return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::marginTop, &RenderBoxModelObject::marginTop>(*style, renderer);
3008         case CSSPropertyMarginRight: {
3009             Length marginRight = style->marginRight();
3010             if (marginRight.isFixed() || !is<RenderBox>(renderer))
3011                 return zoomAdjustedPixelValueForLength(marginRight, *style);
3012             float value;
3013             if (marginRight.isPercentOrCalculated()) {
3014                 // RenderBox gives a marginRight() that is the distance between the right-edge of the child box
3015                 // and the right-edge of the containing box, when display == BLOCK. Let's calculate the absolute
3016                 // value of the specified margin-right % instead of relying on RenderBox's marginRight() value.
3017                 value = minimumValueForLength(marginRight, downcast<RenderBox>(*renderer).containingBlockLogicalWidthForContent());
3018             } else
3019                 value = downcast<RenderBox>(*renderer).marginRight();
3020             return zoomAdjustedPixelValue(value, *style);
3021         }
3022         case CSSPropertyMarginBottom:
3023             return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::marginBottom, &RenderBoxModelObject::marginBottom>(*style, renderer);
3024         case CSSPropertyMarginLeft:
3025             return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::marginLeft, &RenderBoxModelObject::marginLeft>(*style, renderer);
3026         case CSSPropertyWebkitMarqueeDirection:
3027             return cssValuePool.createValue(style->marqueeDirection());
3028         case CSSPropertyWebkitMarqueeIncrement:
3029             return cssValuePool.createValue(style->marqueeIncrement());
3030         case CSSPropertyWebkitMarqueeRepetition:
3031             if (style->marqueeLoopCount() < 0)
3032                 return cssValuePool.createIdentifierValue(CSSValueInfinite);
3033             return cssValuePool.createValue(style->marqueeLoopCount(), CSSPrimitiveValue::CSS_NUMBER);
3034         case CSSPropertyWebkitMarqueeStyle:
3035             return cssValuePool.createValue(style->marqueeBehavior());
3036         case CSSPropertyWebkitUserModify:
3037             return cssValuePool.createValue(style->userModify());
3038         case CSSPropertyMaxHeight: {
3039             const Length& maxHeight = style->maxHeight();
3040             if (maxHeight.isUndefined())
3041                 return cssValuePool.createIdentifierValue(CSSValueNone);
3042             return zoomAdjustedPixelValueForLength(maxHeight, *style);
3043         }
3044         case CSSPropertyMaxWidth: {
3045             const Length& maxWidth = style->maxWidth();
3046             if (maxWidth.isUndefined())
3047                 return cssValuePool.createIdentifierValue(CSSValueNone);
3048             return zoomAdjustedPixelValueForLength(maxWidth, *style);
3049         }
3050         case CSSPropertyMinHeight:
3051             if (style->minHeight().isAuto()) {
3052                 if (isFlexOrGrid(styledNode->parentNode()))
3053                     return cssValuePool.createIdentifierValue(CSSValueAuto);
3054                 return zoomAdjustedPixelValue(0, *style);
3055             }
3056             return zoomAdjustedPixelValueForLength(style->minHeight(), *style);
3057         case CSSPropertyMinWidth:
3058             if (style->minWidth().isAuto()) {
3059                 if (isFlexOrGrid(styledNode->parentNode()))
3060                     return cssValuePool.createIdentifierValue(CSSValueAuto);
3061                 return zoomAdjustedPixelValue(0, *style);
3062             }
3063             return zoomAdjustedPixelValueForLength(style->minWidth(), *style);
3064         case CSSPropertyObjectFit:
3065             return cssValuePool.createValue(style->objectFit());
3066         case CSSPropertyObjectPosition: {
3067             RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
3068             list->append(zoomAdjustedPixelValueForLength(style->objectPosition().x(), *style));
3069             list->append(zoomAdjustedPixelValueForLength(style->objectPosition().y(), *style));
3070             return list;
3071         }
3072         case CSSPropertyOpacity:
3073             return cssValuePool.createValue(style->opacity(), CSSPrimitiveValue::CSS_NUMBER);
3074         case CSSPropertyOrphans:
3075             if (style->hasAutoOrphans())
3076                 return cssValuePool.createIdentifierValue(CSSValueAuto);
3077             return cssValuePool.createValue(style->orphans(), CSSPrimitiveValue::CSS_NUMBER);
3078         case CSSPropertyOutlineColor:
3079             return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyOutlineColor).rgb()) : currentColorOrValidColor(style, style->outlineColor());
3080         case CSSPropertyOutlineOffset:
3081             return zoomAdjustedPixelValue(style->outlineOffset(), *style);
3082         case CSSPropertyOutlineStyle:
3083             if (style->outlineStyleIsAuto())
3084                 return cssValuePool.createIdentifierValue(CSSValueAuto);
3085             return cssValuePool.createValue(style->outlineStyle());
3086         case CSSPropertyOutlineWidth:
3087             return zoomAdjustedPixelValue(style->outlineWidth(), *style);
3088         case CSSPropertyOverflow:
3089             return cssValuePool.createValue(std::max(style->overflowX(), style->overflowY()));
3090         case CSSPropertyOverflowWrap:
3091             return cssValuePool.createValue(style->overflowWrap());
3092         case CSSPropertyOverflowX:
3093             return cssValuePool.createValue(style->overflowX());
3094         case CSSPropertyOverflowY:
3095             return cssValuePool.createValue(style->overflowY());
3096         case CSSPropertyPaddingTop:
3097             return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::paddingTop, &RenderBoxModelObject::computedCSSPaddingTop>(*style, renderer);
3098         case CSSPropertyPaddingRight:
3099             return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::paddingRight, &RenderBoxModelObject::computedCSSPaddingRight>(*style, renderer);
3100         case CSSPropertyPaddingBottom:
3101             return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::paddingBottom, &RenderBoxModelObject::computedCSSPaddingBottom>(*style, renderer);
3102         case CSSPropertyPaddingLeft:
3103             return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::paddingLeft, &RenderBoxModelObject::computedCSSPaddingLeft>(*style, renderer);
3104         case CSSPropertyPageBreakAfter:
3105             return cssValuePool.createValue(convertToPageBreak(style->breakAfter()));
3106         case CSSPropertyPageBreakBefore:
3107             return cssValuePool.createValue(convertToPageBreak(style->breakBefore()));
3108         case CSSPropertyPageBreakInside:
3109             return cssValuePool.createValue(convertToPageBreak(style->breakInside()));
3110         case CSSPropertyBreakAfter:
3111             return cssValuePool.createValue(style->breakAfter());
3112         case CSSPropertyBreakBefore:
3113             return cssValuePool.createValue(style->breakBefore());
3114         case CSSPropertyBreakInside:
3115             return cssValuePool.createValue(style->breakInside());
3116         case CSSPropertyHangingPunctuation:
3117             return hangingPunctuationToCSSValue(style->hangingPunctuation());
3118         case CSSPropertyPosition:
3119             return cssValuePool.createValue(style->position());
3120         case CSSPropertyRight:
3121             return positionOffsetValue(*style, CSSPropertyRight);
3122         case CSSPropertyWebkitRubyPosition:
3123             return cssValuePool.createValue(style->rubyPosition());
3124         case CSSPropertyTableLayout:
3125             return cssValuePool.createValue(style->tableLayout());
3126         case CSSPropertyTextAlign:
3127             return cssValuePool.createValue(style->textAlign());
3128         case CSSPropertyTextDecoration:
3129             return renderTextDecorationFlagsToCSSValue(style->textDecoration());
3130 #if ENABLE(CSS3_TEXT)
3131         case CSSPropertyWebkitTextAlignLast:
3132             return cssValuePool.createValue(style->textAlignLast());
3133         case CSSPropertyWebkitTextJustify:
3134             return cssValuePool.createValue(style->textJustify());
3135 #endif // CSS3_TEXT
3136         case CSSPropertyWebkitTextDecoration:
3137             return getCSSPropertyValuesForShorthandProperties(webkitTextDecorationShorthand());
3138         case CSSPropertyWebkitTextDecorationLine:
3139             return renderTextDecorationFlagsToCSSValue(style->textDecoration());
3140         case CSSPropertyWebkitTextDecorationStyle:
3141             return renderTextDecorationStyleFlagsToCSSValue(style->textDecorationStyle());
3142         case CSSPropertyWebkitTextDecorationColor:
3143             return currentColorOrValidColor(style, style->textDecorationColor());
3144         case CSSPropertyWebkitTextDecorationSkip:
3145             return renderTextDecorationSkipFlagsToCSSValue(style->textDecorationSkip());
3146         case CSSPropertyWebkitTextUnderlinePosition:
3147             return cssValuePool.createValue(style->textUnderlinePosition());
3148         case CSSPropertyWebkitTextDecorationsInEffect:
3149             return renderTextDecorationFlagsToCSSValue(style->textDecorationsInEffect());
3150         case CSSPropertyWebkitTextFillColor:
3151             return currentColorOrValidColor(style, style->textFillColor());
3152         case CSSPropertyWebkitTextEmphasisColor:
3153             return currentColorOrValidColor(style, style->textEmphasisColor());
3154         case CSSPropertyWebkitTextEmphasisPosition:
3155             return renderEmphasisPositionFlagsToCSSValue(style->textEmphasisPosition());
3156         case CSSPropertyWebkitTextEmphasisStyle:
3157             switch (style->textEmphasisMark()) {
3158             case TextEmphasisMarkNone:
3159                 return cssValuePool.createIdentifierValue(CSSValueNone);
3160             case TextEmphasisMarkCustom:
3161                 return cssValuePool.createValue(style->textEmphasisCustomMark(), CSSPrimitiveValue::CSS_STRING);
3162             case TextEmphasisMarkAuto:
3163                 ASSERT_NOT_REACHED();
3164 #if ASSERT_DISABLED
3165                 FALLTHROUGH;
3166 #endif
3167             case TextEmphasisMarkDot:
3168             case TextEmphasisMarkCircle:
3169             case TextEmphasisMarkDoubleCircle:
3170             case TextEmphasisMarkTriangle:
3171             case TextEmphasisMarkSesame: {
3172                 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
3173                 list->append(cssValuePool.createValue(style->textEmphasisFill()));
3174                 list->append(cssValuePool.createValue(style->textEmphasisMark()));
3175                 return list;
3176             }
3177             }
3178         case CSSPropertyTextIndent: {
3179             // If CSS3_TEXT is disabled or text-indent has only one value(<length> | <percentage>),
3180             // getPropertyCSSValue() returns CSSValue.
3181             RefPtr<CSSValue> textIndent = zoomAdjustedPixelValueForLength(style->textIndent(), *style);
3182 #if ENABLE(CSS3_TEXT)
3183             // If CSS3_TEXT is enabled and text-indent has -webkit-each-line or -webkit-hanging,
3184             // getPropertyCSSValue() returns CSSValueList.
3185             if (style->textIndentLine() == TextIndentEachLine || style->textIndentType() == TextIndentHanging) {
3186                 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
3187                 list->append(textIndent.releaseNonNull());
3188                 if (style->textIndentLine() == TextIndentEachLine)
3189                     list->append(cssValuePool.createIdentifierValue(CSSValueWebkitEachLine));
3190                 if (style->textIndentType() == TextIndentHanging)
3191                     list->append(cssValuePool.createIdentifierValue(CSSValueWebkitHanging));
3192                 return list;
3193             }
3194 #endif
3195             return textIndent;
3196         }
3197         case CSSPropertyTextShadow:
3198             return valueForShadow(style->textShadow(), propertyID, *style);
3199         case CSSPropertyTextRendering:
3200             return cssValuePool.createValue(style->fontDescription().textRenderingMode());
3201         case CSSPropertyTextOverflow:
3202             if (style->textOverflow())
3203                 return cssValuePool.createIdentifierValue(CSSValueEllipsis);
3204             return cssValuePool.createIdentifierValue(CSSValueClip);
3205         case CSSPropertyWebkitTextSecurity:
3206             return cssValuePool.createValue(style->textSecurity());
3207 #if ENABLE(IOS_TEXT_AUTOSIZING)
3208         case CSSPropertyWebkitTextSizeAdjust:
3209             if (style->textSizeAdjust().isAuto())
3210                 return cssValuePool.createIdentifierValue(CSSValueAuto);
3211             if (style->textSizeAdjust().isNone())
3212                 return cssValuePool.createIdentifierValue(CSSValueNone);
3213             return CSSPrimitiveValue::create(style->textSizeAdjust().percentage(), CSSPrimitiveValue::CSS_PERCENTAGE);
3214 #endif
3215         case CSSPropertyWebkitTextStrokeColor:
3216             return currentColorOrValidColor(style, style->textStrokeColor());
3217         case CSSPropertyWebkitTextStrokeWidth:
3218             return zoomAdjustedPixelValue(style->textStrokeWidth(), *style);
3219         case CSSPropertyTextTransform:
3220             return cssValuePool.createValue(style->textTransform());
3221         case CSSPropertyTop:
3222             return positionOffsetValue(*style, CSSPropertyTop);
3223         case CSSPropertyUnicodeBidi:
3224             return cssValuePool.createValue(style->unicodeBidi());
3225         case CSSPropertyVerticalAlign:
3226             switch (style->verticalAlign()) {
3227                 case BASELINE:
3228                     return cssValuePool.createIdentifierValue(CSSValueBaseline);
3229                 case MIDDLE:
3230                     return cssValuePool.createIdentifierValue(CSSValueMiddle);
3231                 case SUB:
3232                     return cssValuePool.createIdentifierValue(CSSValueSub);
3233                 case SUPER:
3234                     return cssValuePool.createIdentifierValue(CSSValueSuper);
3235                 case TEXT_TOP:
3236                     return cssValuePool.createIdentifierValue(CSSValueTextTop);
3237                 case TEXT_BOTTOM:
3238                     return cssValuePool.createIdentifierValue(CSSValueTextBottom);
3239                 case TOP:
3240                     return cssValuePool.createIdentifierValue(CSSValueTop);
3241                 case BOTTOM:
3242                     return cssValuePool.createIdentifierValue(CSSValueBottom);
3243                 case BASELINE_MIDDLE:
3244                     return cssValuePool.createIdentifierValue(CSSValueWebkitBaselineMiddle);
3245                 case LENGTH:
3246                     return cssValuePool.createValue(style->verticalAlignLength());
3247             }
3248             ASSERT_NOT_REACHED();
3249             return nullptr;
3250         case CSSPropertyVisibility:
3251             return cssValuePool.createValue(style->visibility());
3252         case CSSPropertyWhiteSpace:
3253             return cssValuePool.createValue(style->whiteSpace());
3254         case CSSPropertyWidows:
3255             if (style->hasAutoWidows())
3256                 return cssValuePool.createIdentifierValue(CSSValueAuto);
3257             return cssValuePool.createValue(style->widows(), CSSPrimitiveValue::CSS_NUMBER);
3258         case CSSPropertyWidth:
3259             if (renderer && !renderer->isRenderSVGModelObject()) {
3260                 // According to http://www.w3.org/TR/CSS2/visudet.html#the-width-property,
3261                 // the "width" property does not apply for non-replaced inline elements.
3262                 if (!renderer->isReplaced() && renderer->isInline())
3263                     return cssValuePool.createIdentifierValue(CSSValueAuto);
3264                 return zoomAdjustedPixelValue(sizingBox(*renderer).width(), *style);
3265             }
3266             return zoomAdjustedPixelValueForLength(style->width(), *style);
3267         case CSSPropertyWillChange:
3268             return getWillChangePropertyValue(style->willChange());
3269             break;
3270         case CSSPropertyWordBreak:
3271             return cssValuePool.createValue(style->wordBreak());
3272         case CSSPropertyWordSpacing:
3273             return zoomAdjustedPixelValue(style->fontCascade().wordSpacing(), *style);
3274         case CSSPropertyWordWrap:
3275             return cssValuePool.createValue(style->overflowWrap());
3276         case CSSPropertyWebkitLineBreak:
3277             return cssValuePool.createValue(style->lineBreak());
3278         case CSSPropertyWebkitNbspMode:
3279             return cssValuePool.createValue(style->nbspMode());
3280         case CSSPropertyResize:
3281             return cssValuePool.createValue(style->resize());
3282         case CSSPropertyWebkitFontKerning:
3283             return cssValuePool.createValue(style->fontDescription().kerning());
3284         case CSSPropertyWebkitFontSmoothing:
3285             return cssValuePool.createValue(style->fontDescription().fontSmoothing());
3286         case CSSPropertyFontVariantLigatures:
3287             return fontVariantLigaturesPropertyValue(style->fontDescription().variantCommonLigatures(), style->fontDescription().variantDiscretionaryLigatures(), style->fontDescription().variantHistoricalLigatures(), style->fontDescription().variantContextualAlternates());
3288         case CSSPropertyFontVariantPosition:
3289             return fontVariantPositionPropertyValue(style->fontDescription().variantPosition());
3290         case CSSPropertyFontVariantCaps:
3291             return fontVariantCapsPropertyValue(style->fontDescription().variantCaps());
3292         case CSSPropertyFontVariantNumeric:
3293             return fontVariantNumericPropertyValue(style->fontDescription().variantNumericFigure(), style->fontDescription().variantNumericSpacing(), style->fontDescription().variantNumericFraction(), style->fontDescription().variantNumericOrdinal(), style->fontDescription().variantNumericSlashedZero());
3294         case CSSPropertyFontVariantAlternates:
3295             return fontVariantAlternatesPropertyValue(style->fontDescription().variantAlternates());
3296         case CSSPropertyFontVariantEastAsian:
3297             return fontVariantEastAsianPropertyValue(style->fontDescription().variantEastAsianVariant(), style->fontDescription().variantEastAsianWidth(), style->fontDescription().variantEastAsianRuby());
3298         case CSSPropertyZIndex:
3299             if (style->hasAutoZIndex())
3300                 return cssValuePool.createIdentifierValue(CSSValueAuto);
3301             return cssValuePool.createValue(style->zIndex(), CSSPrimitiveValue::CSS_NUMBER);
3302         case CSSPropertyZoom:
3303             return cssValuePool.createValue(style->zoom(), CSSPrimitiveValue::CSS_NUMBER);
3304         case CSSPropertyBoxSizing:
3305             if (style->boxSizing() == CONTENT_BOX)
3306                 return cssValuePool.createIdentifierValue(CSSValueContentBox);
3307             return cssValuePool.createIdentifierValue(CSSValueBorderBox);
3308 #if ENABLE(DASHBOARD_SUPPORT)
3309         case CSSPropertyWebkitDashboardRegion:
3310         {
3311             const Vector<StyleDashboardRegion>& regions = style->dashboardRegions();
3312             unsigned count = regions.size();
3313             if (count == 1 && regions[0].type == StyleDashboardRegion::None)
3314                 return cssValuePool.createIdentifierValue(CSSValueNone);
3315
3316             RefPtr<DashboardRegion> firstRegion;
3317             DashboardRegion* previousRegion = nullptr;
3318             for (unsigned i = 0; i < count; i++) {
3319                 auto region = DashboardRegion::create();
3320                 StyleDashboardRegion styleRegion = regions[i];
3321
3322                 region->m_label = styleRegion.label;
3323                 LengthBox offset = styleRegion.offset;
3324                 region->setTop(zoomAdjustedPixelValue(offset.top().value(), *style));
3325                 region->setRight(zoomAdjustedPixelValue(offset.right().value(), *style));
3326                 region->setBottom(zoomAdjustedPixelValue(offset.bottom().value(), *style));
3327                 region->setLeft(zoomAdjustedPixelValue(offset.left().value(), *style));
3328                 region->m_isRectangle = (styleRegion.type == StyleDashboardRegion::Rectangle);
3329                 region->m_isCircle = (styleRegion.type == StyleDashboardRegion::Circle);
3330
3331                 if (previousRegion)
3332                     previousRegion->m_next = region.copyRef();
3333                 else
3334                     firstRegion = region.copyRef();
3335                 previousRegion = region.ptr();
3336             }
3337             return cssValuePool.createValue(WTFMove(firstRegion));
3338         }
3339 #endif
3340         case CSSPropertyAnimationDelay:
3341         case CSSPropertyWebkitAnimationDelay:
3342             return getDelayValue(style->animations());
3343         case CSSPropertyAnimationDirection:
3344         case CSSPropertyWebkitAnimationDirection: {
3345             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
3346             const AnimationList* t = style->animations();
3347             if (t) {
3348                 for (size_t i = 0; i < t->size(); ++i) {
3349                     switch (t->animation(i).direction()) {
3350                     case Animation::AnimationDirectionNormal:
3351                         list->append(cssValuePool.createIdentifierValue(CSSValueNormal));
3352                         break;
3353                     case Animation::AnimationDirectionAlternate:
3354                         list->append(cssValuePool.createIdentifierValue(CSSValueAlternate));
3355                         break;
3356                     case Animation::AnimationDirectionReverse:
3357                         list->append(cssValuePool.createIdentifierValue(CSSValueReverse));
3358                         break;
3359                     case Animation::AnimationDirectionAlternateReverse:
3360                         list->append(cssValuePool.createIdentifierValue(CSSValueAlternateReverse));
3361                         break;
3362                     }
3363                 }
3364             } else
3365                 list->append(cssValuePool.createIdentifierValue(CSSValueNormal));
3366             return list;
3367         }
3368         case CSSPropertyAnimationDuration:
3369         case CSSPropertyWebkitAnimationDuration:
3370             return getDurationValue(style->animations());
3371         case CSSPropertyAnimationFillMode:
3372         case CSSPropertyWebkitAnimationFillMode: {
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         case CSSPropertyWebkitAnimationIterationCount: {
3398             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
3399             const AnimationList* t = style->animations();
3400             if (t) {
3401                 for (size_t i = 0; i < t->size(); ++i) {
3402                     double iterationCount = t->animation(i).iterationCount();
3403                     if (iterationCount == Animation::IterationCountInfinite)
3404                         list->append(cssValuePool.createIdentifierValue(CSSValueInfinite));
3405                     else
3406                         list->append(cssValuePool.createValue(iterationCount, CSSPrimitiveValue::CSS_NUMBER));
3407                 }
3408             } else
3409                 list->append(cssValuePool.createValue(Animation::initialIterationCount(), CSSPrimitiveValue::CSS_NUMBER));
3410             return list;
3411         }
3412         case CSSPropertyAnimationName:
3413         case CSSPropertyWebkitAnimationName: {
3414             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
3415             const AnimationList* t = style->animations();
3416             if (t) {
3417                 for (size_t i = 0; i < t->size(); ++i)
3418                     list->append(cssValuePool.createValue(t->animation(i).name(), CSSPrimitiveValue::CSS_STRING));
3419             } else
3420                 list->append(cssValuePool.createIdentifierValue(CSSValueNone));
3421             return list;
3422         }
3423         case CSSPropertyAnimationPlayState:
3424         case CSSPropertyWebkitAnimationPlayState: {
3425             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
3426             const AnimationList* t = style->animations();
3427             if (t) {
3428                 for (size_t i = 0; i < t->size(); ++i) {
3429                     int prop = t->animation(i).playState();
3430                     if (prop == AnimPlayStatePlaying)
3431                         list->append(cssValuePool.createIdentifierValue(CSSValueRunning));
3432                     else
3433                         list->append(cssValuePool.createIdentifierValue(CSSValuePaused));
3434                 }
3435             } else
3436                 list->append(cssValuePool.createIdentifierValue(CSSValueRunning));
3437             return list;
3438         }
3439         case CSSPropertyAnimationTimingFunction:
3440         case CSSPropertyWebkitAnimationTimingFunction:
3441             return getTimingFunctionValue(style->animations());
3442 #if ENABLE(CSS_ANIMATIONS_LEVEL_2)
3443         case CSSPropertyWebkitAnimationTrigger:
3444             return getAnimationTriggerValue(style->animations(), *style);
3445 #endif
3446         case CSSPropertyWebkitAppearance:
3447             return cssValuePool.createValue(style->appearance());
3448         case CSSPropertyWebkitAspectRatio:
3449             if (style->aspectRatioType() == AspectRatioAuto)
3450                 return cssValuePool.createIdentifierValue(CSSValueAuto);
3451             if (style->aspectRatioType() == AspectRatioFromDimensions)
3452                 return cssValuePool.createIdentifierValue(CSSValueFromDimensions);
3453             if (style->aspectRatioType() == AspectRatioFromIntrinsic)
3454                 return cssValuePool.createIdentifierValue(CSSValueFromIntrinsic);
3455             return CSSAspectRatioValue::create(style->aspectRatioNumerator(), style->aspectRatioDenominator());
3456         case CSSPropertyWebkitBackfaceVisibility:
3457             return cssValuePool.createIdentifierValue((style->backfaceVisibility() == BackfaceVisibilityHidden) ? CSSValueHidden : CSSValueVisible);
3458         case CSSPropertyWebkitBorderImage:
3459             return valueForNinePieceImage(style->borderImage());
3460         case CSSPropertyBorderImageOutset:
3461             return valueForNinePieceImageQuad(style->borderImage().outset());
3462         case CSSPropertyBorderImageRepeat:
3463             return valueForNinePieceImageRepeat(style->borderImage());
3464         case CSSPropertyBorderImageSlice:
3465             return valueForNinePieceImageSlice(style->borderImage());
3466         case CSSPropertyBorderImageWidth:
3467             return valueForNinePieceImageQuad(style->borderImage().borderSlices());
3468         case CSSPropertyWebkitMaskBoxImage:
3469             return valueForNinePieceImage(style->maskBoxImage());
3470         case CSSPropertyWebkitMaskBoxImageOutset:
3471             return valueForNinePieceImageQuad(style->maskBoxImage().outset());
3472         case CSSPropertyWebkitMaskBoxImageRepeat:
3473             return valueForNinePieceImageRepeat(style->maskBoxImage());
3474         case CSSPropertyWebkitMaskBoxImageSlice:
3475             return valueForNinePieceImageSlice(style->maskBoxImage());
3476         case CSSPropertyWebkitMaskBoxImageWidth:
3477             return valueForNinePieceImageQuad(style->maskBoxImage().borderSlices());
3478         case CSSPropertyWebkitMaskBoxImageSource:
3479             if (style->maskBoxImageSource())
3480                 return style->maskBoxImageSource()->cssValue();
3481             return cssValuePool.createIdentifierValue(CSSValueNone);
3482         case CSSPropertyWebkitFontSizeDelta:
3483             // Not a real style property -- used by the editing engine -- so has no computed value.
3484             break;
3485         case CSSPropertyWebkitInitialLetter: {
3486             Ref<CSSPrimitiveValue> drop = !style->initialLetterDrop() ? cssValuePool.createIdentifierValue(CSSValueNormal) : cssValuePool.createValue(style->initialLetterDrop(), CSSPrimitiveValue::CSS_NUMBER);
3487             Ref<CSSPrimitiveValue> size = !style->initialLetterHeight() ? cssValuePool.createIdentifierValue(CSSValueNormal) : cssValuePool.createValue(style->initialLetterHeight(), CSSPrimitiveValue::CSS_NUMBER);
3488             return cssValuePool.createValue(Pair::create(WTFMove(drop), WTFMove(size)));
3489         }
3490         case CSSPropertyWebkitMarginBottomCollapse:
3491         case CSSPropertyWebkitMarginAfterCollapse:
3492             return cssValuePool.createValue(style->marginAfterCollapse());
3493         case CSSPropertyWebkitMarginTopCollapse:
3494         case CSSPropertyWebkitMarginBeforeCollapse:
3495             return cssValuePool.createValue(style->marginBeforeCollapse());
3496 #if ENABLE(ACCELERATED_OVERFLOW_SCROLLING)
3497         case CSSPropertyWebkitOverflowScrolling:
3498             if (!style->useTouchOverflowScrolling())
3499                 return cssValuePool.createIdentifierValue(CSSValueAuto);
3500             return cssValuePool.createIdentifierValue(CSSValueTouch);
3501 #endif
3502         case CSSPropertyPerspective:
3503             if (!style->hasPerspective())
3504                 return cssValuePool.createIdentifierValue(CSSValueNone);
3505             return zoomAdjustedPixelValue(style->perspective(), *style);
3506         case CSSPropertyPerspectiveOrigin: {
3507             RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
3508             if (renderer) {
3509                 LayoutRect box;
3510                 if (is<RenderBox>(*renderer))
3511                     box = downcast<RenderBox>(*renderer).borderBoxRect();
3512
3513                 list->append(zoomAdjustedPixelValue(minimumValueForLength(style->perspectiveOriginX(), box.width()), *style));
3514                 list->append(zoomAdjustedPixelValue(minimumValueForLength(style->perspectiveOriginY(), box.height()), *style));
3515             }
3516             else {
3517                 list->append(zoomAdjustedPixelValueForLength(style->perspectiveOriginX(), *style));
3518                 list->append(zoomAdjustedPixelValueForLength(style->perspectiveOriginY(), *style));
3519
3520             }
3521             return list;
3522         }
3523         case CSSPropertyWebkitRtlOrdering:
3524             return cssValuePool.createIdentifierValue(style->rtlOrdering() ? CSSValueVisual : CSSValueLogical);
3525 #if ENABLE(TOUCH_EVENTS)
3526         case CSSPropertyWebkitTapHighlightColor:
3527             return currentColorOrValidColor(style, style->tapHighlightColor());
3528         case CSSPropertyTouchAction:
3529             return cssValuePool.createValue(style->touchAction());
3530 #endif
3531 #if PLATFORM(IOS)
3532         case CSSPropertyWebkitTouchCallout:
3533             return cssValuePool.createIdentifierValue(style->touchCalloutEnabled() ? CSSValueDefault : CSSValueNone);
3534 #endif
3535         case CSSPropertyWebkitUserDrag:
3536             return cssValuePool.createValue(style->userDrag());
3537         case CSSPropertyWebkitUserSelect:
3538             return cssValuePool.createValue(style->userSelect());
3539         case CSSPropertyBorderBottomLeftRadius:
3540             return getBorderRadiusCornerValue(style->borderBottomLeftRadius(), *style);
3541         case CSSPropertyBorderBottomRightRadius:
3542             return getBorderRadiusCornerValue(style->borderBottomRightRadius(), *style);
3543         case CSSPropertyBorderTopLeftRadius:
3544             return getBorderRadiusCornerValue(style->borderTopLeftRadius(), *style);
3545         case CSSPropertyBorderTopRightRadius:
3546             return getBorderRadiusCornerValue(style->borderTopRightRadius(), *style);
3547         case CSSPropertyClip: {
3548             if (!style->hasClip())
3549                 return cssValuePool.createIdentifierValue(CSSValueAuto);
3550             auto rect = Rect::create();
3551             rect->setTop(autoOrZoomAdjustedValue(style->clip().top(), *style));
3552             rect->setRight(autoOrZoomAdjustedValue(style->clip().right(), *style));
3553             rect->setBottom(autoOrZoomAdjustedValue(style->clip().bottom(), *style));
3554             rect->setLeft(autoOrZoomAdjustedValue(style->clip().left(), *style));
3555             return cssValuePool.createValue(WTFMove(rect));
3556         }
3557         case CSSPropertySpeak:
3558             return cssValuePool.createValue(style->speak());
3559         case CSSPropertyTransform:
3560             return computedTransform(renderer, *style);
3561         case CSSPropertyTransformOrigin: {
3562             RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
3563             if (renderer) {
3564                 LayoutRect box;
3565                 if (is<RenderBox>(*renderer))
3566                     box = downcast<RenderBox>(*renderer).borderBoxRect();
3567
3568                 list->append(zoomAdjustedPixelValue(minimumValueForLength(style->transformOriginX(), box.width()), *style));
3569                 list->append(zoomAdjustedPixelValue(minimumValueForLength(style->transformOriginY(), box.height()), *style));
3570                 if (style->transformOriginZ() != 0)
3571                     list->append(zoomAdjustedPixelValue(style->transformOriginZ(), *style));
3572             } else {
3573                 list->append(zoomAdjustedPixelValueForLength(style->transformOriginX(), *style));
3574                 list->append(zoomAdjustedPixelValueForLength(style->transformOriginY(), *style));
3575                 if (style->transformOriginZ() != 0)
3576                     list->append(zoomAdjustedPixelValue(style->transformOriginZ(), *style));
3577             }
3578             return list;
3579         }
3580         case CSSPropertyTransformStyle:
3581         case CSSPropertyWebkitTransformStyle:
3582             return cssValuePool.createIdentifierValue((style->transformStyle3D() == TransformStyle3DPreserve3D) ? CSSValuePreserve3d : CSSValueFlat);
3583         case CSSPropertyTransitionDelay:
3584         case CSSPropertyWebkitTransitionDelay:
3585             return getDelayValue(style->transitions());
3586         case CSSPropertyTransitionDuration:
3587         case CSSPropertyWebkitTransitionDuration:
3588             return getDurationValue(style->transitions());
3589         case CSSPropertyTransitionProperty:
3590         case CSSPropertyWebkitTransitionProperty:
3591             return getTransitionPropertyValue(style->transitions());
3592         case CSSPropertyTransitionTimingFunction:
3593         case CSSPropertyWebkitTransitionTimingFunction:
3594             return getTimingFunctionValue(style->transitions());
3595         case CSSPropertyTransition:
3596         case CSSPropertyWebkitTransition: {
3597             const AnimationList* animList = style->transitions();
3598             if (animList) {
3599                 RefPtr<CSSValueList> transitionsList = CSSValueList::createCommaSeparated();
3600                 for (size_t i = 0; i < animList->size(); ++i) {
3601                     RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
3602                     const Animation& animation = animList->animation(i);
3603                     list->append(createTransitionPropertyValue(animation));
3604                     list->append(cssValuePool.createValue(animation.duration(), CSSPrimitiveValue::CSS_S));
3605                     list->append(createTimingFunctionValue(animation.timingFunction().get()));
3606                     list->append(cssValuePool.createValue(animation.delay(), CSSPrimitiveValue::CSS_S));
3607                     transitionsList->append(list.releaseNonNull());
3608                 }
3609                 return transitionsList;
3610             }
3611
3612             RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
3613             // transition-property default value.
3614             list->append(cssValuePool.createIdentifierValue(CSSValueAll));
3615             list->append(cssValuePool.createValue(Animation::initialDuration(), CSSPrimitiveValue::CSS_S));
3616             list->append(createTimingFunctionValue(Animation::initialTimingFunction().get()));
3617             list->append(cssValuePool.createValue(Animation::initialDelay(), CSSPrimitiveValue::CSS_S));
3618             return list;
3619         }
3620         case CSSPropertyPointerEvents:
3621             return cssValuePool.createValue(style->pointerEvents());
3622         case CSSPropertyWebkitLineGrid:
3623             if (style->lineGrid().isNull())
3624                 return cssValuePool.createIdentifierValue(CSSValueNone);
3625             return cssValuePool.createValue(style->lineGrid(), CSSPrimitiveValue::CSS_STRING);
3626         case CSSPropertyWebkitLineSnap:
3627             return CSSPrimitiveValue::create(style->lineSnap());
3628         case CSSPropertyWebkitLineAlign:
3629             return CSSPrimitiveValue::create(style->lineAlign());
3630         case CSSPropertyWebkitWritingMode:
3631             return cssValuePool.createValue(style->writingMode());
3632         case CSSPropertyWebkitTextCombine:
3633             return cssValuePool.createValue(style->textCombine());
3634         case CSSPropertyWebkitTextOrientation:
3635             return CSSPrimitiveValue::create(style->textOrientation());
3636         case CSSPropertyWebkitLineBoxContain:
3637             return createLineBoxContainValue(style->lineBoxContain());
3638         case CSSPropertyAlt:
3639             return altTextToCSSValue(style);
3640         case CSSPropertyContent:
3641             return contentToCSSValue(style);
3642         case CSSPropertyCounterIncrement:
3643             return counterToCSSValue(style, propertyID);
3644         case CSSPropertyCounterReset:
3645             return counterToCSSValue(style, propertyID);
3646         case CSSPropertyWebkitClipPath: {
3647             ClipPathOperation* operation = style->clipPath();
3648             if (!operation)
3649                 return cssValuePool.createIdentifierValue(CSSValueNone);
3650             if (is<ReferenceClipPathOperation>(*operation)) {
3651                 const auto& referenceOperation = downcast<ReferenceClipPathOperation>(*operation);
3652                 return CSSPrimitiveValue::create(referenceOperation.url(), CSSPrimitiveValue::CSS_URI);
3653             }
3654             RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();