Clean up CSS code
[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.release(), offset.release(), 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         RefPtr<CSSPrimitiveValue> x = adjustLengthForZoom(currShadowData->x(), style, adjust);
911         RefPtr<CSSPrimitiveValue> y = adjustLengthForZoom(currShadowData->y(), style, adjust);
912         RefPtr<CSSPrimitiveValue> blur = adjustLengthForZoom(currShadowData->radius(), style, adjust);
913         RefPtr<CSSPrimitiveValue> spread = propertyID == CSSPropertyTextShadow ? PassRefPtr<CSSPrimitiveValue>() : adjustLengthForZoom(currShadowData->spread(), style, adjust);
914         RefPtr<CSSPrimitiveValue> style = propertyID == CSSPropertyTextShadow || currShadowData->style() == Normal ? PassRefPtr<CSSPrimitiveValue>() : cssValuePool.createIdentifierValue(CSSValueInset);
915         RefPtr<CSSPrimitiveValue> color = cssValuePool.createColorValue(currShadowData->color().rgb());
916         list.get().prepend(CSSShadowValue::create(x.release(), y.release(), blur.release(), spread.release(), style.release(), color.release()));
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         RefPtr<CSSValueList> minMaxTrackBreadths = CSSValueList::createCommaSeparated();
1033         minMaxTrackBreadths->append(specifiedValueForGridTrackBreadth(trackSize.minTrackBreadth(), style));
1034         minMaxTrackBreadths->append(specifiedValueForGridTrackBreadth(trackSize.maxTrackBreadth(), style));
1035         return CSSFunctionValue::create("minmax(", 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         const CubicBezierTimingFunction* bezierTimingFunction = static_cast<const CubicBezierTimingFunction*>(timingFunction);
1502         if (bezierTimingFunction->timingFunctionPreset() != CubicBezierTimingFunction::Custom) {
1503             CSSValueID valueId = CSSValueInvalid;
1504             switch (bezierTimingFunction->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(bezierTimingFunction->timingFunctionPreset() == CubicBezierTimingFunction::EaseInOut);
1516                 valueId = CSSValueEaseInOut;
1517                 break;
1518             }
1519             return CSSValuePool::singleton().createIdentifierValue(valueId);
1520         }
1521         return CSSCubicBezierTimingFunctionValue::create(bezierTimingFunction->x1(), bezierTimingFunction->y1(), bezierTimingFunction->x2(), bezierTimingFunction->y2());
1522     }
1523     case TimingFunction::StepsFunction: {
1524         const StepsTimingFunction* stepsTimingFunction = static_cast<const StepsTimingFunction*>(timingFunction);
1525         return CSSStepsTimingFunctionValue::create(stepsTimingFunction->numberOfSteps(), stepsTimingFunction->stepAtStart());
1526     }
1527     default:
1528         ASSERT(timingFunction->type() == TimingFunction::LinearFunction);
1529         return CSSValuePool::singleton().createIdentifierValue(CSSValueLinear);
1530     }
1531 }
1532
1533 static Ref<CSSValueList> getTimingFunctionValue(const AnimationList* animList)
1534 {
1535     auto list = CSSValueList::createCommaSeparated();
1536     if (animList) {
1537         for (size_t i = 0; i < animList->size(); ++i)
1538             list.get().append(createTimingFunctionValue(animList->animation(i).timingFunction().get()));
1539     } else
1540         // Note that initialAnimationTimingFunction() is used for both transitions and animations
1541         list.get().append(createTimingFunctionValue(Animation::initialTimingFunction().get()));
1542     return list;
1543 }
1544
1545 #if ENABLE(CSS_ANIMATIONS_LEVEL_2)
1546 static Ref<CSSValue> createAnimationTriggerValue(const AnimationTrigger* trigger, const RenderStyle& style)
1547 {
1548     switch (trigger->type()) {
1549     case AnimationTrigger::AnimationTriggerType::ScrollAnimationTriggerType: {
1550         auto& scrollAnimationTrigger = downcast<ScrollAnimationTrigger>(*trigger);
1551         if (scrollAnimationTrigger.endValue().isAuto())
1552             return CSSAnimationTriggerScrollValue::create(zoomAdjustedPixelValueForLength(scrollAnimationTrigger.startValue(), style));
1553         return CSSAnimationTriggerScrollValue::create(zoomAdjustedPixelValueForLength(scrollAnimationTrigger.startValue(), style),
1554                                                       zoomAdjustedPixelValueForLength(scrollAnimationTrigger.endValue(), style));
1555     }
1556     default:
1557         ASSERT(trigger->type() == AnimationTrigger::AnimationTriggerType::AutoAnimationTriggerType);
1558         return CSSValuePool::singleton().createIdentifierValue(CSSValueAuto);
1559     }
1560 }
1561
1562 static Ref<CSSValueList> getAnimationTriggerValue(const AnimationList* animList, const RenderStyle& style)
1563 {
1564     auto list = CSSValueList::createCommaSeparated();
1565     if (animList) {
1566         for (size_t i = 0; i < animList->size(); ++i)
1567             list.get().append(createAnimationTriggerValue(animList->animation(i).trigger().get(), style));
1568     } else
1569         list.get().append(createAnimationTriggerValue(Animation::initialTrigger().get(), style));
1570
1571     return list;
1572 }
1573 #endif
1574
1575 static Ref<CSSValue> createLineBoxContainValue(unsigned lineBoxContain)
1576 {
1577     if (!lineBoxContain)
1578         return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
1579     return CSSLineBoxContainValue::create(lineBoxContain);
1580 }
1581
1582 ComputedStyleExtractor::ComputedStyleExtractor(PassRefPtr<Node> node, bool allowVisitedStyle, PseudoId pseudoElementSpecifier)
1583     : m_node(node)
1584     , m_pseudoElementSpecifier(pseudoElementSpecifier)
1585     , m_allowVisitedStyle(allowVisitedStyle)
1586 {
1587 }
1588
1589
1590 CSSComputedStyleDeclaration::CSSComputedStyleDeclaration(PassRefPtr<Node> n, bool allowVisitedStyle, const String& pseudoElementName)
1591     : m_node(n)
1592     , m_allowVisitedStyle(allowVisitedStyle)
1593     , m_refCount(1)
1594 {
1595     unsigned nameWithoutColonsStart = pseudoElementName[0] == ':' ? (pseudoElementName[1] == ':' ? 2 : 1) : 0;
1596     m_pseudoElementSpecifier = CSSSelector::pseudoId(CSSSelector::parsePseudoElementType(
1597     (pseudoElementName.substringSharingImpl(nameWithoutColonsStart))));
1598 }
1599
1600 CSSComputedStyleDeclaration::~CSSComputedStyleDeclaration()
1601 {
1602 }
1603
1604 void CSSComputedStyleDeclaration::ref()
1605 {
1606     ++m_refCount;
1607 }
1608
1609 void CSSComputedStyleDeclaration::deref()
1610 {
1611     ASSERT(m_refCount);
1612     if (!--m_refCount)
1613         delete this;
1614 }
1615
1616 String CSSComputedStyleDeclaration::cssText() const
1617 {
1618     StringBuilder result;
1619
1620     for (unsigned i = 0; i < numComputedProperties; i++) {
1621         if (i)
1622             result.append(' ');
1623         result.append(getPropertyName(computedProperties[i]));
1624         result.appendLiteral(": ");
1625         result.append(getPropertyValue(computedProperties[i]));
1626         result.append(';');
1627     }
1628
1629     return result.toString();
1630 }
1631
1632 void CSSComputedStyleDeclaration::setCssText(const String&, ExceptionCode& ec)
1633 {
1634     ec = NO_MODIFICATION_ALLOWED_ERR;
1635 }
1636
1637 RefPtr<CSSPrimitiveValue> ComputedStyleExtractor::getFontSizeCSSValuePreferringKeyword() const
1638 {
1639     if (!m_node)
1640         return nullptr;
1641
1642     m_node->document().updateLayoutIgnorePendingStylesheets();
1643
1644     auto* style = m_node->computedStyle(m_pseudoElementSpecifier);
1645     if (!style)
1646         return nullptr;
1647
1648     if (CSSValueID sizeIdentifier = style->fontDescription().keywordSizeAsIdentifier())
1649         return CSSValuePool::singleton().createIdentifierValue(sizeIdentifier);
1650
1651     return zoomAdjustedPixelValue(style->fontDescription().computedSize(), *style);
1652 }
1653
1654 bool ComputedStyleExtractor::useFixedFontDefaultSize() const
1655 {
1656     if (!m_node)
1657         return false;
1658
1659     auto* style = m_node->computedStyle(m_pseudoElementSpecifier);
1660     if (!style)
1661         return false;
1662
1663     return style->fontDescription().useFixedDefaultSize();
1664 }
1665
1666
1667 static CSSValueID identifierForFamily(const AtomicString& family)
1668 {
1669     if (family == cursiveFamily)
1670         return CSSValueCursive;
1671     if (family == fantasyFamily)
1672         return CSSValueFantasy;
1673     if (family == monospaceFamily)
1674         return CSSValueMonospace;
1675     if (family == pictographFamily)
1676         return CSSValueWebkitPictograph;
1677     if (family == sansSerifFamily)
1678         return CSSValueSansSerif;
1679     if (family == serifFamily)
1680         return CSSValueSerif;
1681     return CSSValueInvalid;
1682 }
1683
1684 static Ref<CSSPrimitiveValue> valueForFamily(const AtomicString& family)
1685 {
1686     if (CSSValueID familyIdentifier = identifierForFamily(family))
1687         return CSSValuePool::singleton().createIdentifierValue(familyIdentifier);
1688     return CSSValuePool::singleton().createFontFamilyValue(family);
1689 }
1690
1691 static Ref<CSSValue> renderTextDecorationFlagsToCSSValue(int textDecoration)
1692 {
1693     auto& cssValuePool = CSSValuePool::singleton();
1694     // Blink value is ignored.
1695     RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
1696     if (textDecoration & TextDecorationUnderline)
1697         list->append(cssValuePool.createIdentifierValue(CSSValueUnderline));
1698     if (textDecoration & TextDecorationOverline)
1699         list->append(cssValuePool.createIdentifierValue(CSSValueOverline));
1700     if (textDecoration & TextDecorationLineThrough)
1701         list->append(cssValuePool.createIdentifierValue(CSSValueLineThrough));
1702 #if ENABLE(LETTERPRESS)
1703     if (textDecoration & TextDecorationLetterpress)
1704         list->append(cssValuePool.createIdentifierValue(CSSValueWebkitLetterpress));
1705 #endif
1706
1707     if (!list->length())
1708         return cssValuePool.createIdentifierValue(CSSValueNone);
1709     return list.releaseNonNull();
1710 }
1711
1712 static Ref<CSSValue> renderTextDecorationStyleFlagsToCSSValue(TextDecorationStyle textDecorationStyle)
1713 {
1714     switch (textDecorationStyle) {
1715     case TextDecorationStyleSolid:
1716         return CSSValuePool::singleton().createIdentifierValue(CSSValueSolid);
1717     case TextDecorationStyleDouble:
1718         return CSSValuePool::singleton().createIdentifierValue(CSSValueDouble);
1719     case TextDecorationStyleDotted:
1720         return CSSValuePool::singleton().createIdentifierValue(CSSValueDotted);
1721     case TextDecorationStyleDashed:
1722         return CSSValuePool::singleton().createIdentifierValue(CSSValueDashed);
1723     case TextDecorationStyleWavy:
1724         return CSSValuePool::singleton().createIdentifierValue(CSSValueWavy);
1725     }
1726
1727     ASSERT_NOT_REACHED();
1728     return CSSValuePool::singleton().createExplicitInitialValue();
1729 }
1730
1731 static Ref<CSSValue> renderTextDecorationSkipFlagsToCSSValue(TextDecorationSkip textDecorationSkip)
1732 {
1733     switch (textDecorationSkip) {
1734     case TextDecorationSkipAuto:
1735         return CSSValuePool::singleton().createIdentifierValue(CSSValueAuto);
1736     case TextDecorationSkipNone:
1737         return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
1738     case TextDecorationSkipInk:
1739         return CSSValuePool::singleton().createIdentifierValue(CSSValueInk);
1740     case TextDecorationSkipObjects:
1741         return CSSValuePool::singleton().createIdentifierValue(CSSValueObjects);
1742     }
1743
1744     ASSERT_NOT_REACHED();
1745     return CSSValuePool::singleton().createExplicitInitialValue();
1746 }
1747
1748 static Ref<CSSValue> renderEmphasisPositionFlagsToCSSValue(TextEmphasisPosition textEmphasisPosition)
1749 {
1750     ASSERT(!((textEmphasisPosition & TextEmphasisPositionOver) && (textEmphasisPosition & TextEmphasisPositionUnder)));
1751     ASSERT(!((textEmphasisPosition & TextEmphasisPositionLeft) && (textEmphasisPosition & TextEmphasisPositionRight)));
1752     auto& cssValuePool = CSSValuePool::singleton();
1753     RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
1754     if (textEmphasisPosition & TextEmphasisPositionOver)
1755         list->append(cssValuePool.createIdentifierValue(CSSValueOver));
1756     if (textEmphasisPosition & TextEmphasisPositionUnder)
1757         list->append(cssValuePool.createIdentifierValue(CSSValueUnder));
1758     if (textEmphasisPosition & TextEmphasisPositionLeft)
1759         list->append(cssValuePool.createIdentifierValue(CSSValueLeft));
1760     if (textEmphasisPosition & TextEmphasisPositionRight)
1761         list->append(cssValuePool.createIdentifierValue(CSSValueRight));
1762
1763     if (!list->length())
1764         return cssValuePool.createIdentifierValue(CSSValueNone);
1765     return list.releaseNonNull();
1766 }
1767
1768 static Ref<CSSValue> hangingPunctuationToCSSValue(HangingPunctuation hangingPunctuation)
1769 {
1770     auto& cssValuePool = CSSValuePool::singleton();
1771     RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
1772     if (hangingPunctuation & FirstHangingPunctuation)
1773         list->append(cssValuePool.createIdentifierValue(CSSValueFirst));
1774     if (hangingPunctuation & AllowEndHangingPunctuation)
1775         list->append(cssValuePool.createIdentifierValue(CSSValueAllowEnd));
1776     if (hangingPunctuation & ForceEndHangingPunctuation)
1777         list->append(cssValuePool.createIdentifierValue(CSSValueForceEnd));
1778     if (hangingPunctuation & LastHangingPunctuation)
1779         list->append(cssValuePool.createIdentifierValue(CSSValueLast));
1780     if (!list->length())
1781         return cssValuePool.createIdentifierValue(CSSValueNone);
1782     return list.releaseNonNull();
1783 }
1784     
1785 static Ref<CSSValue> fillRepeatToCSSValue(EFillRepeat xRepeat, EFillRepeat yRepeat)
1786 {
1787     // For backwards compatibility, if both values are equal, just return one of them. And
1788     // if the two values are equivalent to repeat-x or repeat-y, just return the shorthand.
1789     auto& cssValuePool = CSSValuePool::singleton();
1790     if (xRepeat == yRepeat)
1791         return cssValuePool.createValue(xRepeat);
1792     if (xRepeat == RepeatFill && yRepeat == NoRepeatFill)
1793         return cssValuePool.createIdentifierValue(CSSValueRepeatX);
1794     if (xRepeat == NoRepeatFill && yRepeat == RepeatFill)
1795         return cssValuePool.createIdentifierValue(CSSValueRepeatY);
1796
1797     auto list = CSSValueList::createSpaceSeparated();
1798     list.get().append(cssValuePool.createValue(xRepeat));
1799     list.get().append(cssValuePool.createValue(yRepeat));
1800     return WTFMove(list);
1801 }
1802
1803 static Ref<CSSValue> fillSourceTypeToCSSValue(EMaskSourceType type)
1804 {
1805     switch (type) {
1806     case MaskAlpha:
1807         return CSSValuePool::singleton().createValue(CSSValueAlpha);
1808     default:
1809         ASSERT(type == MaskLuminance);
1810         return CSSValuePool::singleton().createValue(CSSValueLuminance);
1811     }
1812 }
1813
1814 static Ref<CSSValue> fillSizeToCSSValue(const FillSize& fillSize, const RenderStyle& style)
1815 {
1816     if (fillSize.type == Contain)
1817         return CSSValuePool::singleton().createIdentifierValue(CSSValueContain);
1818
1819     if (fillSize.type == Cover)
1820         return CSSValuePool::singleton().createIdentifierValue(CSSValueCover);
1821
1822     if (fillSize.size.height().isAuto())
1823         return zoomAdjustedPixelValueForLength(fillSize.size.width(), style);
1824
1825     auto list = CSSValueList::createSpaceSeparated();
1826     list.get().append(zoomAdjustedPixelValueForLength(fillSize.size.width(), style));
1827     list.get().append(zoomAdjustedPixelValueForLength(fillSize.size.height(), style));
1828     return WTFMove(list);
1829 }
1830
1831 static Ref<CSSValue> altTextToCSSValue(const RenderStyle* style)
1832 {
1833     return CSSValuePool::singleton().createValue(style->contentAltText(), CSSPrimitiveValue::CSS_STRING);
1834 }
1835     
1836 static Ref<CSSValueList> contentToCSSValue(const RenderStyle* style)
1837 {
1838     auto& cssValuePool = CSSValuePool::singleton();
1839     auto list = CSSValueList::createSpaceSeparated();
1840     for (const ContentData* contentData = style->contentData(); contentData; contentData = contentData->next()) {
1841         if (is<CounterContentData>(*contentData))
1842             list.get().append(cssValuePool.createValue(downcast<CounterContentData>(*contentData).counter().identifier(), CSSPrimitiveValue::CSS_COUNTER_NAME));
1843         else if (is<ImageContentData>(*contentData))
1844             list.get().append(*downcast<ImageContentData>(*contentData).image().cssValue());
1845         else if (is<TextContentData>(*contentData))
1846             list.get().append(cssValuePool.createValue(downcast<TextContentData>(*contentData).text(), CSSPrimitiveValue::CSS_STRING));
1847     }
1848     if (style->hasFlowFrom())
1849         list.get().append(cssValuePool.createValue(style->regionThread(), CSSPrimitiveValue::CSS_STRING));
1850     return list;
1851 }
1852
1853 static RefPtr<CSSValue> counterToCSSValue(const RenderStyle* style, CSSPropertyID propertyID)
1854 {
1855     const CounterDirectiveMap* map = style->counterDirectives();
1856     if (!map)
1857         return nullptr;
1858
1859     auto& cssValuePool = CSSValuePool::singleton();
1860     auto list = CSSValueList::createSpaceSeparated();
1861     for (CounterDirectiveMap::const_iterator it = map->begin(); it != map->end(); ++it) {
1862         list->append(cssValuePool.createValue(it->key, CSSPrimitiveValue::CSS_STRING));
1863         short number = propertyID == CSSPropertyCounterIncrement ? it->value.incrementValue() : it->value.resetValue();
1864         list->append(cssValuePool.createValue((double)number, CSSPrimitiveValue::CSS_NUMBER));
1865     }
1866     return WTFMove(list);
1867 }
1868
1869 static void logUnimplementedPropertyID(CSSPropertyID propertyID)
1870 {
1871     static NeverDestroyed<HashSet<CSSPropertyID>> propertyIDSet;
1872     if (!propertyIDSet.get().add(propertyID).isNewEntry)
1873         return;
1874
1875     LOG_ERROR("WebKit does not yet implement getComputedStyle for '%s'.", getPropertyName(propertyID));
1876 }
1877
1878 static Ref<CSSValueList> fontFamilyFromStyle(const RenderStyle* style)
1879 {
1880     auto list = CSSValueList::createCommaSeparated();
1881     for (unsigned i = 0; i < style->fontCascade().familyCount(); ++i)
1882         list.get().append(valueForFamily(style->fontCascade().familyAt(i)));
1883     return list;
1884 }
1885
1886 static Ref<CSSPrimitiveValue> lineHeightFromStyle(const RenderStyle& style)
1887 {
1888     Length length = style.lineHeight();
1889     if (length.isNegative()) // If true, line-height not set; use the font's line spacing.
1890         return zoomAdjustedPixelValue(style.fontMetrics().floatLineSpacing(), style);
1891     if (length.isPercent()) {
1892         // This is imperfect, because it doesn't include the zoom factor and the real computation
1893         // for how high to be in pixels does include things like minimum font size and the zoom factor.
1894         // On the other hand, since font-size doesn't include the zoom factor, we really can't do
1895         // that here either.
1896         return zoomAdjustedPixelValue(static_cast<int>(length.percent() * style.fontDescription().specifiedSize()) / 100, style);
1897     }
1898     return zoomAdjustedPixelValue(floatValueForLength(length, 0), style);
1899 }
1900
1901 static Ref<CSSPrimitiveValue> fontSizeFromStyle(const RenderStyle& style)
1902 {
1903     return zoomAdjustedPixelValue(style.fontDescription().computedSize(), style);
1904 }
1905
1906 static Ref<CSSPrimitiveValue> fontStyleFromStyle(const RenderStyle* style)
1907 {
1908     if (style->fontDescription().italic())
1909         return CSSValuePool::singleton().createIdentifierValue(CSSValueItalic);
1910     return CSSValuePool::singleton().createIdentifierValue(CSSValueNormal);
1911 }
1912
1913 static Ref<CSSValue> fontVariantFromStyle(const RenderStyle* style)
1914 {
1915     if (style->fontDescription().variantSettings().isAllNormal())
1916         return CSSValuePool::singleton().createIdentifierValue(CSSValueNormal);
1917
1918     auto list = CSSValueList::createSpaceSeparated();
1919
1920     switch (style->fontDescription().variantCommonLigatures()) {
1921     case FontVariantLigatures::Normal:
1922         break;
1923     case FontVariantLigatures::Yes:
1924         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueCommonLigatures));
1925         break;
1926     case FontVariantLigatures::No:
1927         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueNoCommonLigatures));
1928         break;
1929     }
1930
1931     switch (style->fontDescription().variantDiscretionaryLigatures()) {
1932     case FontVariantLigatures::Normal:
1933         break;
1934     case FontVariantLigatures::Yes:
1935         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueDiscretionaryLigatures));
1936         break;
1937     case FontVariantLigatures::No:
1938         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueNoDiscretionaryLigatures));
1939         break;
1940     }
1941
1942     switch (style->fontDescription().variantHistoricalLigatures()) {
1943     case FontVariantLigatures::Normal:
1944         break;
1945     case FontVariantLigatures::Yes:
1946         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueHistoricalLigatures));
1947         break;
1948     case FontVariantLigatures::No:
1949         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueNoHistoricalLigatures));
1950         break;
1951     }
1952
1953     switch (style->fontDescription().variantContextualAlternates()) {
1954     case FontVariantLigatures::Normal:
1955         break;
1956     case FontVariantLigatures::Yes:
1957         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueContextual));
1958         break;
1959     case FontVariantLigatures::No:
1960         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueNoContextual));
1961         break;
1962     }
1963
1964     switch (style->fontDescription().variantPosition()) {
1965     case FontVariantPosition::Normal:
1966         break;
1967     case FontVariantPosition::Subscript:
1968         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueSub));
1969         break;
1970     case FontVariantPosition::Superscript:
1971         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueSuper));
1972         break;
1973     }
1974
1975     switch (style->fontDescription().variantCaps()) {
1976     case FontVariantCaps::Normal:
1977         break;
1978     case FontVariantCaps::Small:
1979         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueSmallCaps));
1980         break;
1981     case FontVariantCaps::AllSmall:
1982         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueAllSmallCaps));
1983         break;
1984     case FontVariantCaps::Petite:
1985         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValuePetiteCaps));
1986         break;
1987     case FontVariantCaps::AllPetite:
1988         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueAllPetiteCaps));
1989         break;
1990     case FontVariantCaps::Unicase:
1991         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueUnicase));
1992         break;
1993     case FontVariantCaps::Titling:
1994         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueTitlingCaps));
1995         break;
1996     }
1997
1998     switch (style->fontDescription().variantNumericFigure()) {
1999     case FontVariantNumericFigure::Normal:
2000         break;
2001     case FontVariantNumericFigure::LiningNumbers:
2002         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueLiningNums));
2003         break;
2004     case FontVariantNumericFigure::OldStyleNumbers:
2005         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueOldstyleNums));
2006         break;
2007     }
2008
2009     switch (style->fontDescription().variantNumericSpacing()) {
2010     case FontVariantNumericSpacing::Normal:
2011         break;
2012     case FontVariantNumericSpacing::ProportionalNumbers:
2013         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueProportionalNums));
2014         break;
2015     case FontVariantNumericSpacing::TabularNumbers:
2016         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueTabularNums));
2017         break;
2018     }
2019
2020     switch (style->fontDescription().variantNumericFraction()) {
2021     case FontVariantNumericFraction::Normal:
2022         break;
2023     case FontVariantNumericFraction::DiagonalFractions:
2024         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueDiagonalFractions));
2025         break;
2026     case FontVariantNumericFraction::StackedFractions:
2027         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueStackedFractions));
2028         break;
2029     }
2030
2031     switch (style->fontDescription().variantNumericOrdinal()) {
2032     case FontVariantNumericOrdinal::Normal:
2033         break;
2034     case FontVariantNumericOrdinal::Yes:
2035         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueOrdinal));
2036         break;
2037     }
2038
2039     switch (style->fontDescription().variantNumericSlashedZero()) {
2040     case FontVariantNumericSlashedZero::Normal:
2041         break;
2042     case FontVariantNumericSlashedZero::Yes:
2043         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueSlashedZero));
2044         break;
2045     }
2046
2047     switch (style->fontDescription().variantAlternates()) {
2048     case FontVariantAlternates::Normal:
2049         break;
2050     case FontVariantAlternates::HistoricalForms:
2051         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueHistoricalForms));
2052         break;
2053     }
2054
2055     switch (style->fontDescription().variantEastAsianVariant()) {
2056     case FontVariantEastAsianVariant::Normal:
2057         break;
2058     case FontVariantEastAsianVariant::Jis78:
2059         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueJis78));
2060         break;
2061     case FontVariantEastAsianVariant::Jis83:
2062         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueJis83));
2063         break;
2064     case FontVariantEastAsianVariant::Jis90:
2065         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueJis90));
2066         break;
2067     case FontVariantEastAsianVariant::Jis04:
2068         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueJis04));
2069         break;
2070     case FontVariantEastAsianVariant::Simplified:
2071         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueSimplified));
2072         break;
2073     case FontVariantEastAsianVariant::Traditional:
2074         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueTraditional));
2075         break;
2076     }
2077
2078     switch (style->fontDescription().variantEastAsianWidth()) {
2079     case FontVariantEastAsianWidth::Normal:
2080         break;
2081     case FontVariantEastAsianWidth::Full:
2082         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueFullWidth));
2083         break;
2084     case FontVariantEastAsianWidth::Proportional:
2085         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueProportionalWidth));
2086         break;
2087     }
2088
2089     switch (style->fontDescription().variantEastAsianRuby()) {
2090     case FontVariantEastAsianRuby::Normal:
2091         break;
2092     case FontVariantEastAsianRuby::Yes:
2093         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueRuby));
2094         break;
2095     }
2096
2097     return WTFMove(list);
2098 }
2099
2100 static Ref<CSSPrimitiveValue> fontWeightFromStyle(const RenderStyle* style)
2101 {
2102     switch (style->fontDescription().weight()) {
2103     case FontWeight100:
2104         return CSSValuePool::singleton().createIdentifierValue(CSSValue100);
2105     case FontWeight200:
2106         return CSSValuePool::singleton().createIdentifierValue(CSSValue200);
2107     case FontWeight300:
2108         return CSSValuePool::singleton().createIdentifierValue(CSSValue300);
2109     case FontWeightNormal:
2110         return CSSValuePool::singleton().createIdentifierValue(CSSValueNormal);
2111     case FontWeight500:
2112         return CSSValuePool::singleton().createIdentifierValue(CSSValue500);
2113     case FontWeight600:
2114         return CSSValuePool::singleton().createIdentifierValue(CSSValue600);
2115     case FontWeightBold:
2116         return CSSValuePool::singleton().createIdentifierValue(CSSValueBold);
2117     case FontWeight800:
2118         return CSSValuePool::singleton().createIdentifierValue(CSSValue800);
2119     case FontWeight900:
2120         return CSSValuePool::singleton().createIdentifierValue(CSSValue900);
2121     }
2122     ASSERT_NOT_REACHED();
2123     return CSSValuePool::singleton().createIdentifierValue(CSSValueNormal);
2124 }
2125
2126 static Ref<CSSValue> fontSynthesisFromStyle(const RenderStyle& style)
2127 {
2128     if (style.fontDescription().fontSynthesis() == FontSynthesisNone)
2129         return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
2130
2131     auto list = CSSValueList::createSpaceSeparated();
2132     if (style.fontDescription().fontSynthesis() & FontSynthesisStyle)
2133         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueStyle));
2134     if (style.fontDescription().fontSynthesis() & FontSynthesisWeight)
2135         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueWeight));
2136     return Ref<CSSValue>(list.get());
2137 }
2138
2139 typedef const Length& (RenderStyle::*RenderStyleLengthGetter)() const;
2140 typedef LayoutUnit (RenderBoxModelObject::*RenderBoxComputedCSSValueGetter)() const;
2141
2142 template<RenderStyleLengthGetter lengthGetter, RenderBoxComputedCSSValueGetter computedCSSValueGetter>
2143 inline RefPtr<CSSValue> zoomAdjustedPaddingOrMarginPixelValue(const RenderStyle& style, RenderObject* renderer)
2144 {
2145     Length unzoomzedLength = (style.*lengthGetter)();
2146     if (!is<RenderBox>(renderer) || unzoomzedLength.isFixed())
2147         return zoomAdjustedPixelValueForLength(unzoomzedLength, style);
2148     return zoomAdjustedPixelValue((downcast<RenderBox>(*renderer).*computedCSSValueGetter)(), style);
2149 }
2150
2151 template<RenderStyleLengthGetter lengthGetter>
2152 inline bool paddingOrMarginIsRendererDependent(const RenderStyle* style, RenderObject* renderer)
2153 {
2154     if (!renderer || !renderer->isBox())
2155         return false;
2156     return !(style && (style->*lengthGetter)().isFixed());
2157 }
2158
2159 static CSSValueID convertToPageBreak(BreakBetween value)
2160 {
2161     if (value == PageBreakBetween || value == LeftPageBreakBetween || value == RightPageBreakBetween
2162         || value == RectoPageBreakBetween || value == VersoPageBreakBetween)
2163         return CSSValueAlways; // CSS 2.1 allows us to map these to always.
2164     if (value == AvoidBreakBetween || value == AvoidPageBreakBetween)
2165         return CSSValueAvoid;
2166     return CSSValueAuto;
2167 }
2168
2169 static CSSValueID convertToColumnBreak(BreakBetween value)
2170 {
2171     if (value == ColumnBreakBetween)
2172         return CSSValueAlways;
2173     if (value == AvoidBreakBetween || value == AvoidColumnBreakBetween)
2174         return CSSValueAvoid;
2175     return CSSValueAuto;
2176 }
2177
2178 static CSSValueID convertToPageBreak(BreakInside value)
2179 {
2180     if (value == AvoidBreakInside || value == AvoidPageBreakInside)
2181         return CSSValueAvoid;
2182     return CSSValueAuto;
2183 }
2184
2185 static CSSValueID convertToColumnBreak(BreakInside value)
2186 {
2187     if (value == AvoidBreakInside || value == AvoidColumnBreakInside)
2188         return CSSValueAvoid;
2189     return CSSValueAuto;
2190 }
2191
2192 #if ENABLE(CSS_REGIONS)
2193 static CSSValueID convertToRegionBreak(BreakBetween value)
2194 {
2195     if (value == RegionBreakBetween)
2196         return CSSValueAlways;
2197     if (value == AvoidBreakBetween || value == AvoidRegionBreakBetween)
2198         return CSSValueAvoid;
2199     return CSSValueAuto;
2200 }
2201     
2202 static CSSValueID convertToRegionBreak(BreakInside value)
2203 {
2204     if (value == AvoidBreakInside || value == AvoidRegionBreakInside)
2205         return CSSValueAvoid;
2206     return CSSValueAuto;
2207 }
2208 #endif
2209     
2210 static bool isLayoutDependent(CSSPropertyID propertyID, const RenderStyle* style, RenderObject* renderer)
2211 {
2212     switch (propertyID) {
2213     case CSSPropertyWidth:
2214     case CSSPropertyHeight:
2215     case CSSPropertyPerspectiveOrigin:
2216     case CSSPropertyTransformOrigin:
2217     case CSSPropertyTransform:
2218     case CSSPropertyFilter:
2219 #if ENABLE(FILTERS_LEVEL_2)
2220     case CSSPropertyWebkitBackdropFilter:
2221 #endif
2222         return true;
2223     case CSSPropertyMargin: {
2224         if (!renderer || !renderer->isBox())
2225             return false;
2226         return !(style && style->marginTop().isFixed() && style->marginRight().isFixed()
2227             && style->marginBottom().isFixed() && style->marginLeft().isFixed());
2228     }
2229     case CSSPropertyMarginTop:
2230         return paddingOrMarginIsRendererDependent<&RenderStyle::marginTop>(style, renderer);
2231     case CSSPropertyMarginRight:
2232         return paddingOrMarginIsRendererDependent<&RenderStyle::marginRight>(style, renderer);
2233     case CSSPropertyMarginBottom:
2234         return paddingOrMarginIsRendererDependent<&RenderStyle::marginBottom>(style, renderer);
2235     case CSSPropertyMarginLeft:
2236         return paddingOrMarginIsRendererDependent<&RenderStyle::marginLeft>(style, renderer);
2237     case CSSPropertyPadding: {
2238         if (!renderer || !renderer->isBox())
2239             return false;
2240         return !(style && style->paddingTop().isFixed() && style->paddingRight().isFixed()
2241             && style->paddingBottom().isFixed() && style->paddingLeft().isFixed());
2242     }
2243     case CSSPropertyPaddingTop:
2244         return paddingOrMarginIsRendererDependent<&RenderStyle::paddingTop>(style, renderer);
2245     case CSSPropertyPaddingRight:
2246         return paddingOrMarginIsRendererDependent<&RenderStyle::paddingRight>(style, renderer);
2247     case CSSPropertyPaddingBottom:
2248         return paddingOrMarginIsRendererDependent<&RenderStyle::paddingBottom>(style, renderer);
2249     case CSSPropertyPaddingLeft:
2250         return paddingOrMarginIsRendererDependent<&RenderStyle::paddingLeft>(style, renderer); 
2251 #if ENABLE(CSS_GRID_LAYOUT)
2252     case CSSPropertyGridTemplateColumns:
2253     case CSSPropertyGridTemplateRows:
2254     case CSSPropertyGridTemplate:
2255     case CSSPropertyGrid:
2256         return renderer && renderer->isRenderGrid();
2257 #endif
2258     default:
2259         return false;
2260     }
2261 }
2262
2263 Node* ComputedStyleExtractor::styledNode() const
2264 {
2265     if (!m_node)
2266         return nullptr;
2267     if (!is<Element>(*m_node))
2268         return m_node.get();
2269     Element& element = downcast<Element>(*m_node);
2270     PseudoElement* pseudoElement;
2271     if (m_pseudoElementSpecifier == BEFORE && (pseudoElement = element.beforePseudoElement()))
2272         return pseudoElement;
2273     if (m_pseudoElementSpecifier == AFTER && (pseudoElement = element.afterPseudoElement()))
2274         return pseudoElement;
2275     return &element;
2276 }
2277
2278 static ItemPosition resolveContainerAlignmentAuto(ItemPosition position, RenderObject* element)
2279 {
2280     if (position != ItemPositionAuto || !element)
2281         return position;
2282
2283     return element->style().isDisplayFlexibleOrGridBox() ? ItemPositionStretch : ItemPositionStart;
2284 }
2285
2286 static ItemPosition resolveSelfAlignmentAuto(ItemPosition position, OverflowAlignment& overflow, RenderObject* element)
2287 {
2288     if (position != ItemPositionAuto || !element || element->isOutOfFlowPositioned())
2289         return position;
2290
2291     RenderBlock* parent = element->containingBlock();
2292     if (!parent)
2293         return ItemPositionStart;
2294
2295     overflow = parent->style().alignItemsOverflowAlignment();
2296     return resolveContainerAlignmentAuto(parent->style().alignItemsPosition(), parent);
2297 }
2298
2299 RefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropertyID propertyID, EUpdateLayout updateLayout) const
2300 {
2301     return ComputedStyleExtractor(m_node, m_allowVisitedStyle, m_pseudoElementSpecifier).propertyValue(propertyID, updateLayout);
2302 }
2303
2304 Ref<MutableStyleProperties> CSSComputedStyleDeclaration::copyProperties() const
2305 {
2306     return ComputedStyleExtractor(m_node, m_allowVisitedStyle, m_pseudoElementSpecifier).copyProperties();
2307 }
2308
2309 static inline bool nodeOrItsAncestorNeedsStyleRecalc(const Node& node)
2310 {
2311     if (node.needsStyleRecalc())
2312         return true;
2313
2314     const Node* currentNode = &node;
2315     const Element* ancestor = currentNode->parentOrShadowHostElement();
2316     while (ancestor) {
2317         if (ancestor->needsStyleRecalc())
2318             return true;
2319
2320         if (ancestor->directChildNeedsStyleRecalc() && currentNode->styleIsAffectedByPreviousSibling())
2321             return true;
2322
2323         currentNode = ancestor;
2324         ancestor = currentNode->parentOrShadowHostElement();
2325     }
2326     return false;
2327 }
2328
2329 static inline bool updateStyleIfNeededForNode(const Node& node)
2330 {
2331     Document& document = node.document();
2332     if (!document.hasPendingForcedStyleRecalc() && !(document.childNeedsStyleRecalc() && nodeOrItsAncestorNeedsStyleRecalc(node)))
2333         return false;
2334     document.updateStyleIfNeeded();
2335     return true;
2336 }
2337
2338 static inline const RenderStyle* computeRenderStyleForProperty(Node* styledNode, PseudoId pseudoElementSpecifier, CSSPropertyID propertyID, std::unique_ptr<RenderStyle>& ownedStyle)
2339 {
2340     RenderObject* renderer = styledNode->renderer();
2341
2342     if (renderer && renderer->isComposited() && AnimationController::supportsAcceleratedAnimationOfProperty(propertyID)) {
2343         ownedStyle = renderer->animation().getAnimatedStyleForRenderer(downcast<RenderElement>(*renderer));
2344         if (pseudoElementSpecifier && !styledNode->isPseudoElement()) {
2345             // FIXME: This cached pseudo style will only exist if the animation has been run at least once.
2346             return ownedStyle->getCachedPseudoStyle(pseudoElementSpecifier);
2347         }
2348         return ownedStyle.get();
2349     }
2350
2351     return styledNode->computedStyle(styledNode->isPseudoElement() ? NOPSEUDO : pseudoElementSpecifier);
2352 }
2353
2354 #if ENABLE(CSS_SHAPES)
2355 static Ref<CSSValue> shapePropertyValue(const RenderStyle& style, const ShapeValue* shapeValue)
2356 {
2357     if (!shapeValue)
2358         return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
2359
2360     if (shapeValue->type() == ShapeValue::Type::Box)
2361         return CSSValuePool::singleton().createValue(shapeValue->cssBox());
2362
2363     if (shapeValue->type() == ShapeValue::Type::Image) {
2364         if (shapeValue->image())
2365             return *shapeValue->image()->cssValue();
2366         return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
2367     }
2368
2369     ASSERT(shapeValue->type() == ShapeValue::Type::Shape);
2370
2371     RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2372     list->append(valueForBasicShape(style, *shapeValue->shape()));
2373     if (shapeValue->cssBox() != BoxMissing)
2374         list->append(CSSValuePool::singleton().createValue(shapeValue->cssBox()));
2375     return list.releaseNonNull();
2376 }
2377 #endif
2378
2379 static RefPtr<CSSValueList> valueForItemPositionWithOverflowAlignment(ItemPosition itemPosition, OverflowAlignment overflowAlignment, ItemPositionType positionType)
2380 {
2381     auto& cssValuePool = CSSValuePool::singleton();
2382     RefPtr<CSSValueList> result = CSSValueList::createSpaceSeparated();
2383     if (positionType == LegacyPosition)
2384         result->append(CSSPrimitiveValue::createIdentifier(CSSValueLegacy));
2385     result->append(cssValuePool.createValue(itemPosition));
2386     if (overflowAlignment != OverflowAlignmentDefault)
2387         result->append(cssValuePool.createValue(overflowAlignment));
2388     ASSERT(result->length() <= 2);
2389     return result;
2390 }
2391
2392 static RefPtr<CSSValueList> valueForContentPositionAndDistributionWithOverflowAlignment(const StyleContentAlignmentData& data)
2393 {
2394     RefPtr<CSSValueList> result = CSSValueList::createSpaceSeparated();
2395     if (data.distribution() != ContentDistributionDefault)
2396         result->append(CSSPrimitiveValue::create(data.distribution()));
2397     if (data.distribution() == ContentDistributionDefault || data.position() != ContentPositionNormal)
2398         result->append(CSSPrimitiveValue::create(data.position()));
2399     if ((data.position() >= ContentPositionCenter || data.distribution() != ContentDistributionDefault) && data.overflow() != OverflowAlignmentDefault)
2400         result->append(CSSPrimitiveValue::create(data.overflow()));
2401     ASSERT(result->length() > 0);
2402     ASSERT(result->length() <= 3);
2403     return result;
2404 }
2405
2406 inline static bool isFlexOrGrid(ContainerNode* element)
2407 {
2408     return element && element->computedStyle() && element->computedStyle()->isDisplayFlexibleOrGridBox();
2409 }
2410
2411 RefPtr<CSSValue> ComputedStyleExtractor::customPropertyValue(const String& propertyName) const
2412 {
2413     Node* styledNode = this->styledNode();
2414     if (!styledNode)
2415         return nullptr;
2416     
2417     if (updateStyleIfNeededForNode(*styledNode)) {
2418         // The style recalc could have caused the styled node to be discarded or replaced
2419         // if it was a PseudoElement so we need to update it.
2420         styledNode = this->styledNode();
2421     }
2422
2423     std::unique_ptr<RenderStyle> ownedStyle;
2424     auto* style = computeRenderStyleForProperty(styledNode, m_pseudoElementSpecifier, CSSPropertyCustom, ownedStyle);
2425     if (!style || !style->hasCustomProperty(propertyName))
2426         return nullptr;
2427
2428     return style->getCustomPropertyValue(propertyName);
2429 }
2430
2431 String ComputedStyleExtractor::customPropertyText(const String& propertyName) const
2432 {
2433     RefPtr<CSSValue> propertyValue = this->customPropertyValue(propertyName);
2434     return propertyValue ? propertyValue->cssText() : emptyString();
2435 }
2436
2437 RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID, EUpdateLayout updateLayout) const
2438 {
2439     Node* styledNode = this->styledNode();
2440     if (!styledNode)
2441         return nullptr;
2442
2443     std::unique_ptr<RenderStyle> ownedStyle;
2444     const RenderStyle* style = nullptr;
2445     RenderObject* renderer = nullptr;
2446     bool forceFullLayout = false;
2447     if (updateLayout) {
2448         Document& document = styledNode->document();
2449
2450         if (updateStyleIfNeededForNode(*styledNode)) {
2451             // The style recalc could have caused the styled node to be discarded or replaced
2452             // if it was a PseudoElement so we need to update it.
2453             styledNode = this->styledNode();
2454         }
2455
2456         renderer = styledNode->renderer();
2457
2458         if (propertyID == CSSPropertyDisplay && !renderer && is<SVGElement>(*styledNode) && !downcast<SVGElement>(*styledNode).isValid())
2459             return nullptr;
2460
2461         style = computeRenderStyleForProperty(styledNode, m_pseudoElementSpecifier, propertyID, ownedStyle);
2462
2463         // FIXME: Some of these cases could be narrowed down or optimized better.
2464         forceFullLayout = isLayoutDependent(propertyID, style, renderer)
2465             || styledNode->isInShadowTree()
2466             || (document.styleResolverIfExists() && document.styleResolverIfExists()->hasViewportDependentMediaQueries() && document.ownerElement());
2467
2468         if (forceFullLayout) {
2469             document.updateLayoutIgnorePendingStylesheets();
2470             styledNode = this->styledNode();
2471         }
2472     }
2473
2474     if (!updateLayout || forceFullLayout) {
2475         style = computeRenderStyleForProperty(styledNode, m_pseudoElementSpecifier, propertyID, ownedStyle);
2476         renderer = styledNode->renderer();
2477     }
2478
2479     if (!style)
2480         return nullptr;
2481
2482     auto& cssValuePool = CSSValuePool::singleton();
2483     propertyID = CSSProperty::resolveDirectionAwareProperty(propertyID, style->direction(), style->writingMode());
2484
2485     switch (propertyID) {
2486         case CSSPropertyInvalid:
2487             break;
2488
2489         case CSSPropertyBackgroundColor:
2490             return cssValuePool.createColorValue(m_allowVisitedStyle? style->visitedDependentColor(CSSPropertyBackgroundColor).rgb() : style->backgroundColor().rgb());
2491         case CSSPropertyBackgroundImage:
2492         case CSSPropertyWebkitMaskImage: {
2493             const FillLayer* layers = propertyID == CSSPropertyWebkitMaskImage ? style->maskLayers() : style->backgroundLayers();
2494             if (!layers)
2495                 return cssValuePool.createIdentifierValue(CSSValueNone);
2496
2497             if (!layers->next()) {
2498                 if (layers->image())
2499                     return layers->image()->cssValue();
2500
2501                 return cssValuePool.createIdentifierValue(CSSValueNone);
2502             }
2503
2504             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2505             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) {
2506                 if (currLayer->image())
2507                     list->append(*currLayer->image()->cssValue());
2508                 else
2509                     list->append(cssValuePool.createIdentifierValue(CSSValueNone));
2510             }
2511             return list;
2512         }
2513         case CSSPropertyBackgroundSize:
2514         case CSSPropertyWebkitBackgroundSize:
2515         case CSSPropertyWebkitMaskSize: {
2516             const FillLayer* layers = propertyID == CSSPropertyWebkitMaskSize ? style->maskLayers() : style->backgroundLayers();
2517             if (!layers->next())
2518                 return fillSizeToCSSValue(layers->size(), *style);
2519
2520             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2521             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
2522                 list->append(fillSizeToCSSValue(currLayer->size(), *style));
2523
2524             return list;
2525         }
2526         case CSSPropertyBackgroundRepeat:
2527         case CSSPropertyWebkitMaskRepeat: {
2528             const FillLayer* layers = propertyID == CSSPropertyWebkitMaskRepeat ? style->maskLayers() : style->backgroundLayers();
2529             if (!layers->next())
2530                 return fillRepeatToCSSValue(layers->repeatX(), layers->repeatY());
2531
2532             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2533             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
2534                 list->append(fillRepeatToCSSValue(currLayer->repeatX(), currLayer->repeatY()));
2535
2536             return list;
2537         }
2538         case CSSPropertyWebkitMaskSourceType: {
2539             const FillLayer* layers = style->maskLayers();
2540
2541             if (!layers)
2542                 return cssValuePool.createIdentifierValue(CSSValueNone);
2543
2544             if (!layers->next())
2545                 return fillSourceTypeToCSSValue(layers->maskSourceType());
2546
2547             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2548             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
2549                 list->append(fillSourceTypeToCSSValue(currLayer->maskSourceType()));
2550
2551             return list;
2552         }
2553         case CSSPropertyWebkitBackgroundComposite:
2554         case CSSPropertyWebkitMaskComposite: {
2555             const FillLayer* layers = propertyID == CSSPropertyWebkitMaskComposite ? style->maskLayers() : style->backgroundLayers();
2556             if (!layers->next())
2557                 return cssValuePool.createValue(layers->composite());
2558
2559             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2560             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
2561                 list->append(cssValuePool.createValue(currLayer->composite()));
2562
2563             return list;
2564         }
2565         case CSSPropertyBackgroundAttachment: {
2566             const FillLayer* layers = style->backgroundLayers();
2567             if (!layers->next())
2568                 return cssValuePool.createValue(layers->attachment());
2569
2570             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2571             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
2572                 list->append(cssValuePool.createValue(currLayer->attachment()));
2573
2574             return list;
2575         }
2576         case CSSPropertyBackgroundClip:
2577         case CSSPropertyBackgroundOrigin:
2578         case CSSPropertyWebkitBackgroundClip:
2579         case CSSPropertyWebkitBackgroundOrigin:
2580         case CSSPropertyWebkitMaskClip:
2581         case CSSPropertyWebkitMaskOrigin: {
2582             const FillLayer* layers = (propertyID == CSSPropertyWebkitMaskClip || propertyID == CSSPropertyWebkitMaskOrigin) ? style->maskLayers() : style->backgroundLayers();
2583             bool isClip = propertyID == CSSPropertyBackgroundClip || propertyID == CSSPropertyWebkitBackgroundClip || propertyID == CSSPropertyWebkitMaskClip;
2584             if (!layers->next()) {
2585                 EFillBox box = isClip ? layers->clip() : layers->origin();
2586                 return cssValuePool.createValue(box);
2587             }
2588
2589             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2590             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) {
2591                 EFillBox box = isClip ? currLayer->clip() : currLayer->origin();
2592                 list->append(cssValuePool.createValue(box));
2593             }
2594
2595             return list;
2596         }
2597         case CSSPropertyBackgroundPosition:
2598         case CSSPropertyWebkitMaskPosition: {
2599             const FillLayer* layers = propertyID == CSSPropertyWebkitMaskPosition ? style->maskLayers() : style->backgroundLayers();
2600             if (!layers->next())
2601                 return createPositionListForLayer(propertyID, layers, *style);
2602
2603             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2604             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
2605                 list->append(createPositionListForLayer(propertyID, currLayer, *style));
2606             return list;
2607         }
2608         case CSSPropertyBackgroundPositionX:
2609         case CSSPropertyWebkitMaskPositionX: {
2610             const FillLayer* layers = propertyID == CSSPropertyWebkitMaskPositionX ? style->maskLayers() : style->backgroundLayers();
2611             if (!layers->next())
2612                 return cssValuePool.createValue(layers->xPosition());
2613
2614             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2615             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
2616                 list->append(cssValuePool.createValue(currLayer->xPosition()));
2617
2618             return list;
2619         }
2620         case CSSPropertyBackgroundPositionY:
2621         case CSSPropertyWebkitMaskPositionY: {
2622             const FillLayer* layers = propertyID == CSSPropertyWebkitMaskPositionY ? style->maskLayers() : style->backgroundLayers();
2623             if (!layers->next())
2624                 return cssValuePool.createValue(layers->yPosition());
2625
2626             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2627             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
2628                 list->append(cssValuePool.createValue(currLayer->yPosition()));
2629
2630             return list;
2631         }
2632         case CSSPropertyBorderCollapse:
2633             if (style->borderCollapse())
2634                 return cssValuePool.createIdentifierValue(CSSValueCollapse);
2635             return cssValuePool.createIdentifierValue(CSSValueSeparate);
2636         case CSSPropertyBorderSpacing: {
2637             RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2638             list->append(zoomAdjustedPixelValue(style->horizontalBorderSpacing(), *style));
2639             list->append(zoomAdjustedPixelValue(style->verticalBorderSpacing(), *style));
2640             return list;
2641         }
2642         case CSSPropertyWebkitBorderHorizontalSpacing:
2643             return zoomAdjustedPixelValue(style->horizontalBorderSpacing(), *style);
2644         case CSSPropertyWebkitBorderVerticalSpacing:
2645             return zoomAdjustedPixelValue(style->verticalBorderSpacing(), *style);
2646         case CSSPropertyBorderImageSource:
2647             if (style->borderImageSource())
2648                 return style->borderImageSource()->cssValue();
2649             return cssValuePool.createIdentifierValue(CSSValueNone);
2650         case CSSPropertyBorderTopColor:
2651             return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyBorderTopColor).rgb()) : currentColorOrValidColor(style, style->borderTopColor());
2652         case CSSPropertyBorderRightColor:
2653             return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyBorderRightColor).rgb()) : currentColorOrValidColor(style, style->borderRightColor());
2654         case CSSPropertyBorderBottomColor:
2655             return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyBorderBottomColor).rgb()) : currentColorOrValidColor(style, style->borderBottomColor());
2656         case CSSPropertyBorderLeftColor:
2657             return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyBorderLeftColor).rgb()) : currentColorOrValidColor(style, style->borderLeftColor());
2658         case CSSPropertyBorderTopStyle:
2659             return cssValuePool.createValue(style->borderTopStyle());
2660         case CSSPropertyBorderRightStyle:
2661             return cssValuePool.createValue(style->borderRightStyle());
2662         case CSSPropertyBorderBottomStyle:
2663             return cssValuePool.createValue(style->borderBottomStyle());
2664         case CSSPropertyBorderLeftStyle:
2665             return cssValuePool.createValue(style->borderLeftStyle());
2666         case CSSPropertyBorderTopWidth:
2667             return zoomAdjustedPixelValue(style->borderTopWidth(), *style);
2668         case CSSPropertyBorderRightWidth:
2669             return zoomAdjustedPixelValue(style->borderRightWidth(), *style);
2670         case CSSPropertyBorderBottomWidth:
2671             return zoomAdjustedPixelValue(style->borderBottomWidth(), *style);
2672         case CSSPropertyBorderLeftWidth:
2673             return zoomAdjustedPixelValue(style->borderLeftWidth(), *style);
2674         case CSSPropertyBottom:
2675             return positionOffsetValue(*style, CSSPropertyBottom);
2676         case CSSPropertyWebkitBoxAlign:
2677             return cssValuePool.createValue(style->boxAlign());
2678 #if ENABLE(CSS_BOX_DECORATION_BREAK)
2679         case CSSPropertyWebkitBoxDecorationBreak:
2680             if (style->boxDecorationBreak() == DSLICE)
2681                 return cssValuePool.createIdentifierValue(CSSValueSlice);
2682         return cssValuePool.createIdentifierValue(CSSValueClone);
2683 #endif
2684         case CSSPropertyWebkitBoxDirection:
2685             return cssValuePool.createValue(style->boxDirection());
2686         case CSSPropertyWebkitBoxFlex:
2687             return cssValuePool.createValue(style->boxFlex(), CSSPrimitiveValue::CSS_NUMBER);
2688         case CSSPropertyWebkitBoxFlexGroup:
2689             return cssValuePool.createValue(style->boxFlexGroup(), CSSPrimitiveValue::CSS_NUMBER);
2690         case CSSPropertyWebkitBoxLines:
2691             return cssValuePool.createValue(style->boxLines());
2692         case CSSPropertyWebkitBoxOrdinalGroup:
2693             return cssValuePool.createValue(style->boxOrdinalGroup(), CSSPrimitiveValue::CSS_NUMBER);
2694         case CSSPropertyWebkitBoxOrient:
2695             return cssValuePool.createValue(style->boxOrient());
2696         case CSSPropertyWebkitBoxPack:
2697             return cssValuePool.createValue(style->boxPack());
2698         case CSSPropertyWebkitBoxReflect:
2699             return valueForReflection(style->boxReflect(), *style);
2700         case CSSPropertyBoxShadow:
2701         case CSSPropertyWebkitBoxShadow:
2702             return valueForShadow(style->boxShadow(), propertyID, *style);
2703         case CSSPropertyCaptionSide:
2704             return cssValuePool.createValue(style->captionSide());
2705         case CSSPropertyClear:
2706             return cssValuePool.createValue(style->clear());
2707         case CSSPropertyColor:
2708             return cssValuePool.createColorValue(m_allowVisitedStyle ? style->visitedDependentColor(CSSPropertyColor).rgb() : style->color().rgb());
2709         case CSSPropertyWebkitPrintColorAdjust:
2710             return cssValuePool.createValue(style->printColorAdjust());
2711         case CSSPropertyWebkitColumnAxis:
2712             return cssValuePool.createValue(style->columnAxis());
2713         case CSSPropertyColumnCount:
2714             if (style->hasAutoColumnCount())
2715                 return cssValuePool.createIdentifierValue(CSSValueAuto);
2716             return cssValuePool.createValue(style->columnCount(), CSSPrimitiveValue::CSS_NUMBER);
2717         case CSSPropertyColumnFill:
2718             return cssValuePool.createValue(style->columnFill());
2719         case CSSPropertyColumnGap:
2720             if (style->hasNormalColumnGap())
2721                 return cssValuePool.createIdentifierValue(CSSValueNormal);
2722             return zoomAdjustedPixelValue(style->columnGap(), *style);
2723         case CSSPropertyColumnProgression:
2724             return cssValuePool.createValue(style->columnProgression());
2725         case CSSPropertyColumnRuleColor:
2726             return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyOutlineColor).rgb()) : currentColorOrValidColor(style, style->columnRuleColor());
2727         case CSSPropertyColumnRuleStyle:
2728             return cssValuePool.createValue(style->columnRuleStyle());
2729         case CSSPropertyColumnRuleWidth:
2730             return zoomAdjustedPixelValue(style->columnRuleWidth(), *style);
2731         case CSSPropertyColumnSpan:
2732             return cssValuePool.createIdentifierValue(style->columnSpan() ? CSSValueAll : CSSValueNone);
2733         case CSSPropertyWebkitColumnBreakAfter:
2734             return cssValuePool.createValue(convertToColumnBreak(style->breakAfter()));
2735         case CSSPropertyWebkitColumnBreakBefore:
2736             return cssValuePool.createValue(convertToColumnBreak(style->breakBefore()));
2737         case CSSPropertyWebkitColumnBreakInside:
2738             return cssValuePool.createValue(convertToColumnBreak(style->breakInside()));
2739         case CSSPropertyColumnWidth:
2740             if (style->hasAutoColumnWidth())
2741                 return cssValuePool.createIdentifierValue(CSSValueAuto);
2742             return zoomAdjustedPixelValue(style->columnWidth(), *style);
2743         case CSSPropertyTabSize:
2744             return cssValuePool.createValue(style->tabSize(), CSSPrimitiveValue::CSS_NUMBER);
2745 #if ENABLE(CSS_REGIONS)
2746         case CSSPropertyWebkitRegionBreakAfter:
2747             return cssValuePool.createValue(convertToRegionBreak(style->breakAfter()));
2748         case CSSPropertyWebkitRegionBreakBefore:
2749             return cssValuePool.createValue(convertToRegionBreak(style->breakBefore()));
2750         case CSSPropertyWebkitRegionBreakInside:
2751             return cssValuePool.createValue(convertToRegionBreak(style->breakInside()));
2752 #endif
2753         case CSSPropertyCursor: {
2754             RefPtr<CSSValueList> list;
2755             CursorList* cursors = style->cursors();
2756             if (cursors && cursors->size() > 0) {
2757                 list = CSSValueList::createCommaSeparated();
2758                 for (unsigned i = 0; i < cursors->size(); ++i)
2759                     if (StyleImage* image = cursors->at(i).image())
2760                         list->append(*image->cssValue());
2761             }
2762             auto value = cssValuePool.createValue(style->cursor());
2763             if (list) {
2764                 list->append(WTFMove(value));
2765                 return list;
2766             }
2767             return WTFMove(value);
2768         }
2769 #if ENABLE(CURSOR_VISIBILITY)
2770         case CSSPropertyWebkitCursorVisibility:
2771             return cssValuePool.createValue(style->cursorVisibility());
2772 #endif
2773         case CSSPropertyDirection:
2774             return cssValuePool.createValue(style->direction());
2775         case CSSPropertyDisplay:
2776             return cssValuePool.createValue(style->display());
2777         case CSSPropertyEmptyCells:
2778             return cssValuePool.createValue(style->emptyCells());
2779         case CSSPropertyAlignContent:
2780             return valueForContentPositionAndDistributionWithOverflowAlignment(style->alignContent());
2781         case CSSPropertyAlignItems:
2782             return valueForItemPositionWithOverflowAlignment(resolveContainerAlignmentAuto(style->alignItemsPosition(), renderer), style->alignItemsOverflowAlignment(), NonLegacyPosition);
2783         case CSSPropertyAlignSelf: {
2784             OverflowAlignment overflow = style->alignSelfOverflowAlignment();
2785             ItemPosition alignSelf = resolveSelfAlignmentAuto(style->alignSelfPosition(), overflow, renderer);
2786             return valueForItemPositionWithOverflowAlignment(alignSelf, overflow, NonLegacyPosition);
2787         }
2788         case CSSPropertyFlex:
2789             return getCSSPropertyValuesForShorthandProperties(flexShorthand());
2790         case CSSPropertyFlexBasis:
2791             return cssValuePool.createValue(style->flexBasis());
2792         case CSSPropertyFlexDirection:
2793             return cssValuePool.createValue(style->flexDirection());
2794         case CSSPropertyFlexFlow:
2795             return getCSSPropertyValuesForShorthandProperties(flexFlowShorthand());
2796         case CSSPropertyFlexGrow:
2797             return cssValuePool.createValue(style->flexGrow());
2798         case CSSPropertyFlexShrink:
2799             return cssValuePool.createValue(style->flexShrink());
2800         case CSSPropertyFlexWrap:
2801             return cssValuePool.createValue(style->flexWrap());
2802         case CSSPropertyJustifyContent:
2803             return valueForContentPositionAndDistributionWithOverflowAlignment(style->justifyContent());
2804         case CSSPropertyJustifyItems:
2805             return valueForItemPositionWithOverflowAlignment(resolveContainerAlignmentAuto(style->justifyItemsPosition(), renderer), style->justifyItemsOverflowAlignment(), style->justifyItemsPositionType());
2806         case CSSPropertyJustifySelf: {
2807             OverflowAlignment overflow = style->justifySelfOverflowAlignment();
2808             ItemPosition justifySelf = resolveSelfAlignmentAuto(style->justifySelfPosition(), overflow, renderer);
2809             return valueForItemPositionWithOverflowAlignment(justifySelf, overflow, NonLegacyPosition);
2810         }
2811         case CSSPropertyOrder:
2812             return cssValuePool.createValue(style->order(), CSSPrimitiveValue::CSS_NUMBER);
2813         case CSSPropertyFloat:
2814             if (style->display() != NONE && style->hasOutOfFlowPosition())
2815                 return cssValuePool.createIdentifierValue(CSSValueNone);
2816             return cssValuePool.createValue(style->floating());
2817         case CSSPropertyFont: {
2818             RefPtr<CSSFontValue> computedFont = CSSFontValue::create();
2819             computedFont->style = fontStyleFromStyle(style);
2820             if (style->fontDescription().variantCaps() == FontVariantCaps::Small)
2821                 computedFont->variant = CSSValuePool::singleton().createIdentifierValue(CSSValueSmallCaps);
2822             else
2823                 computedFont->variant = CSSValuePool::singleton().createIdentifierValue(CSSValueNormal);
2824             computedFont->weight = fontWeightFromStyle(style);
2825             computedFont->size = fontSizeFromStyle(*style);
2826             computedFont->lineHeight = lineHeightFromStyle(*style);
2827             computedFont->family = fontFamilyFromStyle(style);
2828             return computedFont;
2829         }
2830         case CSSPropertyFontFamily: {
2831             RefPtr<CSSValueList> fontFamilyList = fontFamilyFromStyle(style);
2832             // If there's only a single family, return that as a CSSPrimitiveValue.
2833             // NOTE: Gecko always returns this as a comma-separated CSSPrimitiveValue string.
2834             if (fontFamilyList->length() == 1)
2835                 return fontFamilyList->item(0);
2836             return fontFamilyList;
2837         }
2838         case CSSPropertyFontSize:
2839             return fontSizeFromStyle(*style);
2840         case CSSPropertyFontStyle:
2841             return fontStyleFromStyle(style);
2842         case CSSPropertyFontVariant:
2843             return fontVariantFromStyle(style);
2844         case CSSPropertyFontWeight:
2845             return fontWeightFromStyle(style);
2846         case CSSPropertyFontSynthesis:
2847             return fontSynthesisFromStyle(*style);
2848         case CSSPropertyFontFeatureSettings: {
2849             const FontFeatureSettings& featureSettings = style->fontDescription().featureSettings();
2850             if (!featureSettings.size())
2851                 return cssValuePool.createIdentifierValue(CSSValueNormal);
2852             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2853             for (auto& feature : featureSettings)
2854                 list->append(CSSFontFeatureValue::create(FontFeatureTag(feature.tag()), feature.value()));
2855             return list;
2856         }
2857 #if ENABLE(CSS_GRID_LAYOUT)
2858         case CSSPropertyGridAutoFlow: {
2859             RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2860             ASSERT(style->isGridAutoFlowDirectionRow() || style->isGridAutoFlowDirectionColumn());
2861             if (style->isGridAutoFlowDirectionRow())
2862                 list->append(cssValuePool.createIdentifierValue(CSSValueRow));
2863             else
2864                 list->append(cssValuePool.createIdentifierValue(CSSValueColumn));
2865
2866             if (style->isGridAutoFlowAlgorithmDense())
2867                 list->append(cssValuePool.createIdentifierValue(CSSValueDense));
2868
2869             return list;
2870         }
2871
2872         // Specs mention that getComputedStyle() should return the used value of the property instead of the computed
2873         // one for grid-definition-{rows|columns} but not for the grid-auto-{rows|columns} as things like
2874         // grid-auto-columns: 2fr; cannot be resolved to a value in pixels as the '2fr' means very different things
2875         // depending on the size of the explicit grid or the number of implicit tracks added to the grid. See
2876         // http://lists.w3.org/Archives/Public/www-style/2013Nov/0014.html
2877         case CSSPropertyGridAutoColumns:
2878             return specifiedValueForGridTrackSize(style->gridAutoColumns(), *style);
2879         case CSSPropertyGridAutoRows:
2880             return specifiedValueForGridTrackSize(style->gridAutoRows(), *style);
2881
2882         case CSSPropertyGridTemplateColumns:
2883             return valueForGridTrackList(ForColumns, renderer, *style);
2884         case CSSPropertyGridTemplateRows:
2885             return valueForGridTrackList(ForRows, renderer, *style);
2886
2887         case CSSPropertyGridColumnStart:
2888             return valueForGridPosition(style->gridItemColumnStart());
2889         case CSSPropertyGridColumnEnd:
2890             return valueForGridPosition(style->gridItemColumnEnd());
2891         case CSSPropertyGridRowStart:
2892             return valueForGridPosition(style->gridItemRowStart());
2893         case CSSPropertyGridRowEnd:
2894             return valueForGridPosition(style->gridItemRowEnd());
2895         case CSSPropertyGridArea:
2896             return getCSSPropertyValuesForGridShorthand(gridAreaShorthand());
2897         case CSSPropertyGridTemplate:
2898             return getCSSPropertyValuesForGridShorthand(gridTemplateShorthand());
2899         case CSSPropertyGrid:
2900             return getCSSPropertyValuesForGridShorthand(gridShorthand());
2901         case CSSPropertyGridColumn:
2902             return getCSSPropertyValuesForGridShorthand(gridColumnShorthand());
2903         case CSSPropertyGridRow:
2904             return getCSSPropertyValuesForGridShorthand(gridRowShorthand());
2905
2906         case CSSPropertyGridTemplateAreas:
2907             if (!style->namedGridAreaRowCount()) {
2908                 ASSERT(!style->namedGridAreaColumnCount());
2909                 return cssValuePool.createIdentifierValue(CSSValueNone);
2910             }
2911
2912             return CSSGridTemplateAreasValue::create(style->namedGridArea(), style->namedGridAreaRowCount(), style->namedGridAreaColumnCount());
2913         case CSSPropertyGridColumnGap:
2914             return zoomAdjustedPixelValueForLength(style->gridColumnGap(), *style);
2915         case CSSPropertyGridRowGap:
2916             return zoomAdjustedPixelValueForLength(style->gridRowGap(), *style);
2917         case CSSPropertyGridGap:
2918             return getCSSPropertyValuesForGridShorthand(gridGapShorthand());
2919 #endif /* ENABLE(CSS_GRID_LAYOUT) */
2920         case CSSPropertyHeight:
2921             if (renderer && !renderer->isRenderSVGModelObject()) {
2922                 // According to http://www.w3.org/TR/CSS2/visudet.html#the-height-property,
2923                 // the "height" property does not apply for non-replaced inline elements.
2924                 if (!renderer->isReplaced() && renderer->isInline())
2925                     return cssValuePool.createIdentifierValue(CSSValueAuto);
2926                 return zoomAdjustedPixelValue(sizingBox(*renderer).height(), *style);
2927             }
2928             return zoomAdjustedPixelValueForLength(style->height(), *style);
2929         case CSSPropertyWebkitHyphens:
2930             return cssValuePool.createValue(style->hyphens());
2931         case CSSPropertyWebkitHyphenateCharacter:
2932             if (style->hyphenationString().isNull())
2933                 return cssValuePool.createIdentifierValue(CSSValueAuto);
2934             return cssValuePool.createValue(style->hyphenationString(), CSSPrimitiveValue::CSS_STRING);
2935         case CSSPropertyWebkitHyphenateLimitAfter:
2936             if (style->hyphenationLimitAfter() < 0)
2937                 return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
2938             return CSSPrimitiveValue::create(style->hyphenationLimitAfter(), CSSPrimitiveValue::CSS_NUMBER);
2939         case CSSPropertyWebkitHyphenateLimitBefore:
2940             if (style->hyphenationLimitBefore() < 0)
2941                 return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
2942             return CSSPrimitiveValue::create(style->hyphenationLimitBefore(), CSSPrimitiveValue::CSS_NUMBER);
2943         case CSSPropertyWebkitHyphenateLimitLines:
2944             if (style->hyphenationLimitLines() < 0)
2945                 return CSSPrimitiveValue::createIdentifier(CSSValueNoLimit);
2946             return CSSPrimitiveValue::create(style->hyphenationLimitLines(), CSSPrimitiveValue::CSS_NUMBER);
2947         case CSSPropertyWebkitBorderFit:
2948             if (style->borderFit() == BorderFitBorder)
2949                 return cssValuePool.createIdentifierValue(CSSValueBorder);
2950             return cssValuePool.createIdentifierValue(CSSValueLines);
2951 #if ENABLE(CSS_IMAGE_ORIENTATION)
2952         case CSSPropertyImageOrientation:
2953             return cssValuePool.createValue(style->imageOrientation());
2954 #endif
2955         case CSSPropertyImageRendering:
2956             return CSSPrimitiveValue::create(style->imageRendering());
2957 #if ENABLE(CSS_IMAGE_RESOLUTION)
2958         case CSSPropertyImageResolution:
2959             return cssValuePool.createValue(style->imageResolution(), CSSPrimitiveValue::CSS_DPPX);
2960 #endif
2961         case CSSPropertyLeft:
2962             return positionOffsetValue(*style, CSSPropertyLeft);
2963         case CSSPropertyLetterSpacing:
2964             if (!style->letterSpacing())
2965                 return cssValuePool.createIdentifierValue(CSSValueNormal);
2966             return zoomAdjustedPixelValue(style->letterSpacing(), *style);
2967         case CSSPropertyWebkitLineClamp:
2968             if (style->lineClamp().isNone())
2969                 return cssValuePool.createIdentifierValue(CSSValueNone);
2970             return cssValuePool.createValue(style->lineClamp().value(), style->lineClamp().isPercentage() ? CSSPrimitiveValue::CSS_PERCENTAGE : CSSPrimitiveValue::CSS_NUMBER);
2971         case CSSPropertyLineHeight:
2972             return lineHeightFromStyle(*style);
2973         case CSSPropertyListStyleImage:
2974             if (style->listStyleImage())
2975                 return style->listStyleImage()->cssValue();
2976             return cssValuePool.createIdentifierValue(CSSValueNone);
2977         case CSSPropertyListStylePosition:
2978             return cssValuePool.createValue(style->listStylePosition());
2979         case CSSPropertyListStyleType:
2980             return cssValuePool.createValue(style->listStyleType());
2981         case CSSPropertyWebkitLocale:
2982             if (style->locale().isNull())
2983                 return cssValuePool.createIdentifierValue(CSSValueAuto);
2984             return cssValuePool.createValue(style->locale(), CSSPrimitiveValue::CSS_STRING);
2985         case CSSPropertyMarginTop:
2986             return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::marginTop, &RenderBoxModelObject::marginTop>(*style, renderer);
2987         case CSSPropertyMarginRight: {
2988             Length marginRight = style->marginRight();
2989             if (marginRight.isFixed() || !is<RenderBox>(renderer))
2990                 return zoomAdjustedPixelValueForLength(marginRight, *style);
2991             float value;
2992             if (marginRight.isPercentOrCalculated()) {
2993                 // RenderBox gives a marginRight() that is the distance between the right-edge of the child box
2994                 // and the right-edge of the containing box, when display == BLOCK. Let's calculate the absolute
2995                 // value of the specified margin-right % instead of relying on RenderBox's marginRight() value.
2996                 value = minimumValueForLength(marginRight, downcast<RenderBox>(*renderer).containingBlockLogicalWidthForContent());
2997             } else
2998                 value = downcast<RenderBox>(*renderer).marginRight();
2999             return zoomAdjustedPixelValue(value, *style);
3000         }
3001         case CSSPropertyMarginBottom:
3002             return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::marginBottom, &RenderBoxModelObject::marginBottom>(*style, renderer);
3003         case CSSPropertyMarginLeft:
3004             return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::marginLeft, &RenderBoxModelObject::marginLeft>(*style, renderer);
3005         case CSSPropertyWebkitMarqueeDirection:
3006             return cssValuePool.createValue(style->marqueeDirection());
3007         case CSSPropertyWebkitMarqueeIncrement:
3008             return cssValuePool.createValue(style->marqueeIncrement());
3009         case CSSPropertyWebkitMarqueeRepetition:
3010             if (style->marqueeLoopCount() < 0)
3011                 return cssValuePool.createIdentifierValue(CSSValueInfinite);
3012             return cssValuePool.createValue(style->marqueeLoopCount(), CSSPrimitiveValue::CSS_NUMBER);
3013         case CSSPropertyWebkitMarqueeStyle:
3014             return cssValuePool.createValue(style->marqueeBehavior());
3015         case CSSPropertyWebkitUserModify:
3016             return cssValuePool.createValue(style->userModify());
3017         case CSSPropertyMaxHeight: {
3018             const Length& maxHeight = style->maxHeight();
3019             if (maxHeight.isUndefined())
3020                 return cssValuePool.createIdentifierValue(CSSValueNone);
3021             return zoomAdjustedPixelValueForLength(maxHeight, *style);
3022         }
3023         case CSSPropertyMaxWidth: {
3024             const Length& maxWidth = style->maxWidth();
3025             if (maxWidth.isUndefined())
3026                 return cssValuePool.createIdentifierValue(CSSValueNone);
3027             return zoomAdjustedPixelValueForLength(maxWidth, *style);
3028         }
3029         case CSSPropertyMinHeight:
3030             if (style->minHeight().isAuto()) {
3031                 if (isFlexOrGrid(styledNode->parentNode()))
3032                     return cssValuePool.createIdentifierValue(CSSValueAuto);
3033                 return zoomAdjustedPixelValue(0, *style);
3034             }
3035             return zoomAdjustedPixelValueForLength(style->minHeight(), *style);
3036         case CSSPropertyMinWidth:
3037             if (style->minWidth().isAuto()) {
3038                 if (isFlexOrGrid(styledNode->parentNode()))
3039                     return cssValuePool.createIdentifierValue(CSSValueAuto);
3040                 return zoomAdjustedPixelValue(0, *style);
3041             }
3042             return zoomAdjustedPixelValueForLength(style->minWidth(), *style);
3043         case CSSPropertyObjectFit:
3044             return cssValuePool.createValue(style->objectFit());
3045         case CSSPropertyObjectPosition: {
3046             RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
3047             list->append(zoomAdjustedPixelValueForLength(style->objectPosition().x(), *style));
3048             list->append(zoomAdjustedPixelValueForLength(style->objectPosition().y(), *style));
3049             return list;
3050         }
3051         case CSSPropertyOpacity:
3052             return cssValuePool.createValue(style->opacity(), CSSPrimitiveValue::CSS_NUMBER);
3053         case CSSPropertyOrphans:
3054             if (style->hasAutoOrphans())
3055                 return cssValuePool.createIdentifierValue(CSSValueAuto);
3056             return cssValuePool.createValue(style->orphans(), CSSPrimitiveValue::CSS_NUMBER);
3057         case CSSPropertyOutlineColor:
3058             return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyOutlineColor).rgb()) : currentColorOrValidColor(style, style->outlineColor());
3059         case CSSPropertyOutlineOffset:
3060             return zoomAdjustedPixelValue(style->outlineOffset(), *style);
3061         case CSSPropertyOutlineStyle:
3062             if (style->outlineStyleIsAuto())
3063                 return cssValuePool.createIdentifierValue(CSSValueAuto);
3064             return cssValuePool.createValue(style->outlineStyle());
3065         case CSSPropertyOutlineWidth:
3066             return zoomAdjustedPixelValue(style->outlineWidth(), *style);
3067         case CSSPropertyOverflow:
3068             return cssValuePool.createValue(std::max(style->overflowX(), style->overflowY()));
3069         case CSSPropertyOverflowWrap:
3070             return cssValuePool.createValue(style->overflowWrap());
3071         case CSSPropertyOverflowX:
3072             return cssValuePool.createValue(style->overflowX());
3073         case CSSPropertyOverflowY:
3074             return cssValuePool.createValue(style->overflowY());
3075         case CSSPropertyPaddingTop:
3076             return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::paddingTop, &RenderBoxModelObject::computedCSSPaddingTop>(*style, renderer);
3077         case CSSPropertyPaddingRight:
3078             return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::paddingRight, &RenderBoxModelObject::computedCSSPaddingRight>(*style, renderer);
3079         case CSSPropertyPaddingBottom:
3080             return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::paddingBottom, &RenderBoxModelObject::computedCSSPaddingBottom>(*style, renderer);
3081         case CSSPropertyPaddingLeft:
3082             return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::paddingLeft, &RenderBoxModelObject::computedCSSPaddingLeft>(*style, renderer);
3083         case CSSPropertyPageBreakAfter:
3084             return cssValuePool.createValue(convertToPageBreak(style->breakAfter()));
3085         case CSSPropertyPageBreakBefore:
3086             return cssValuePool.createValue(convertToPageBreak(style->breakBefore()));
3087         case CSSPropertyPageBreakInside:
3088             return cssValuePool.createValue(convertToPageBreak(style->breakInside()));
3089         case CSSPropertyBreakAfter:
3090             return cssValuePool.createValue(style->breakAfter());
3091         case CSSPropertyBreakBefore:
3092             return cssValuePool.createValue(style->breakBefore());
3093         case CSSPropertyBreakInside:
3094             return cssValuePool.createValue(style->breakInside());
3095         case CSSPropertyHangingPunctuation:
3096             return hangingPunctuationToCSSValue(style->hangingPunctuation());
3097         case CSSPropertyPosition:
3098             return cssValuePool.createValue(style->position());
3099         case CSSPropertyRight:
3100             return positionOffsetValue(*style, CSSPropertyRight);
3101         case CSSPropertyWebkitRubyPosition:
3102             return cssValuePool.createValue(style->rubyPosition());
3103         case CSSPropertyTableLayout:
3104             return cssValuePool.createValue(style->tableLayout());
3105         case CSSPropertyTextAlign:
3106             return cssValuePool.createValue(style->textAlign());
3107         case CSSPropertyTextDecoration:
3108             return renderTextDecorationFlagsToCSSValue(style->textDecoration());
3109 #if ENABLE(CSS3_TEXT)
3110         case CSSPropertyWebkitTextAlignLast:
3111             return cssValuePool.createValue(style->textAlignLast());
3112         case CSSPropertyWebkitTextJustify:
3113             return cssValuePool.createValue(style->textJustify());
3114 #endif // CSS3_TEXT
3115         case CSSPropertyWebkitTextDecoration:
3116             return getCSSPropertyValuesForShorthandProperties(webkitTextDecorationShorthand());
3117         case CSSPropertyWebkitTextDecorationLine:
3118             return renderTextDecorationFlagsToCSSValue(style->textDecoration());
3119         case CSSPropertyWebkitTextDecorationStyle:
3120             return renderTextDecorationStyleFlagsToCSSValue(style->textDecorationStyle());
3121         case CSSPropertyWebkitTextDecorationColor:
3122             return currentColorOrValidColor(style, style->textDecorationColor());
3123         case CSSPropertyWebkitTextDecorationSkip:
3124             return renderTextDecorationSkipFlagsToCSSValue(style->textDecorationSkip());
3125         case CSSPropertyWebkitTextUnderlinePosition:
3126             return cssValuePool.createValue(style->textUnderlinePosition());
3127         case CSSPropertyWebkitTextDecorationsInEffect:
3128             return renderTextDecorationFlagsToCSSValue(style->textDecorationsInEffect());
3129         case CSSPropertyWebkitTextFillColor:
3130             return currentColorOrValidColor(style, style->textFillColor());
3131         case CSSPropertyWebkitTextEmphasisColor:
3132             return currentColorOrValidColor(style, style->textEmphasisColor());
3133         case CSSPropertyWebkitTextEmphasisPosition:
3134             return renderEmphasisPositionFlagsToCSSValue(style->textEmphasisPosition());
3135         case CSSPropertyWebkitTextEmphasisStyle:
3136             switch (style->textEmphasisMark()) {
3137             case TextEmphasisMarkNone:
3138                 return cssValuePool.createIdentifierValue(CSSValueNone);
3139             case TextEmphasisMarkCustom:
3140                 return cssValuePool.createValue(style->textEmphasisCustomMark(), CSSPrimitiveValue::CSS_STRING);
3141             case TextEmphasisMarkAuto:
3142                 ASSERT_NOT_REACHED();
3143 #if ASSERT_DISABLED
3144                 FALLTHROUGH;
3145 #endif
3146             case TextEmphasisMarkDot:
3147             case TextEmphasisMarkCircle:
3148             case TextEmphasisMarkDoubleCircle:
3149             case TextEmphasisMarkTriangle:
3150             case TextEmphasisMarkSesame: {
3151                 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
3152                 list->append(cssValuePool.createValue(style->textEmphasisFill()));
3153                 list->append(cssValuePool.createValue(style->textEmphasisMark()));
3154                 return list;
3155             }
3156             }
3157         case CSSPropertyTextIndent: {
3158             // If CSS3_TEXT is disabled or text-indent has only one value(<length> | <percentage>),
3159             // getPropertyCSSValue() returns CSSValue.
3160             RefPtr<CSSValue> textIndent = zoomAdjustedPixelValueForLength(style->textIndent(), *style);
3161 #if ENABLE(CSS3_TEXT)
3162             // If CSS3_TEXT is enabled and text-indent has -webkit-each-line or -webkit-hanging,
3163             // getPropertyCSSValue() returns CSSValueList.
3164             if (style->textIndentLine() == TextIndentEachLine || style->textIndentType() == TextIndentHanging) {
3165                 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
3166                 list->append(textIndent.releaseNonNull());
3167                 if (style->textIndentLine() == TextIndentEachLine)
3168                     list->append(cssValuePool.createIdentifierValue(CSSValueWebkitEachLine));
3169                 if (style->textIndentType() == TextIndentHanging)
3170                     list->append(cssValuePool.createIdentifierValue(CSSValueWebkitHanging));
3171                 return list;
3172             }
3173 #endif
3174             return textIndent;
3175         }
3176         case CSSPropertyTextShadow:
3177             return valueForShadow(style->textShadow(), propertyID, *style);
3178         case CSSPropertyTextRendering:
3179             return cssValuePool.createValue(style->fontDescription().textRenderingMode());
3180         case CSSPropertyTextOverflow:
3181             if (style->textOverflow())
3182                 return cssValuePool.createIdentifierValue(CSSValueEllipsis);
3183             return cssValuePool.createIdentifierValue(CSSValueClip);
3184         case CSSPropertyWebkitTextSecurity:
3185             return cssValuePool.createValue(style->textSecurity());
3186 #if ENABLE(IOS_TEXT_AUTOSIZING)
3187         case CSSPropertyWebkitTextSizeAdjust:
3188             if (style->textSizeAdjust().isAuto())
3189                 return cssValuePool.createIdentifierValue(CSSValueAuto);
3190             if (style->textSizeAdjust().isNone())
3191                 return cssValuePool.createIdentifierValue(CSSValueNone);
3192             return CSSPrimitiveValue::create(style->textSizeAdjust().percentage(), CSSPrimitiveValue::CSS_PERCENTAGE);
3193 #endif
3194         case CSSPropertyWebkitTextStrokeColor:
3195             return currentColorOrValidColor(style, style->textStrokeColor());
3196         case CSSPropertyWebkitTextStrokeWidth:
3197             return zoomAdjustedPixelValue(style->textStrokeWidth(), *style);
3198         case CSSPropertyTextTransform:
3199             return cssValuePool.createValue(style->textTransform());
3200         case CSSPropertyTop:
3201             return positionOffsetValue(*style, CSSPropertyTop);
3202         case CSSPropertyUnicodeBidi:
3203             return cssValuePool.createValue(style->unicodeBidi());
3204         case CSSPropertyVerticalAlign:
3205             switch (style->verticalAlign()) {
3206                 case BASELINE:
3207                     return cssValuePool.createIdentifierValue(CSSValueBaseline);
3208                 case MIDDLE:
3209                     return cssValuePool.createIdentifierValue(CSSValueMiddle);
3210                 case SUB:
3211                     return cssValuePool.createIdentifierValue(CSSValueSub);
3212                 case SUPER:
3213                     return cssValuePool.createIdentifierValue(CSSValueSuper);
3214                 case TEXT_TOP:
3215                     return cssValuePool.createIdentifierValue(CSSValueTextTop);
3216                 case TEXT_BOTTOM:
3217                     return cssValuePool.createIdentifierValue(CSSValueTextBottom);
3218                 case TOP:
3219                     return cssValuePool.createIdentifierValue(CSSValueTop);
3220                 case BOTTOM:
3221                     return cssValuePool.createIdentifierValue(CSSValueBottom);
3222                 case BASELINE_MIDDLE:
3223                     return cssValuePool.createIdentifierValue(CSSValueWebkitBaselineMiddle);
3224                 case LENGTH:
3225                     return cssValuePool.createValue(style->verticalAlignLength());
3226             }
3227             ASSERT_NOT_REACHED();
3228             return nullptr;
3229         case CSSPropertyVisibility:
3230             return cssValuePool.createValue(style->visibility());
3231         case CSSPropertyWhiteSpace:
3232             return cssValuePool.createValue(style->whiteSpace());
3233         case CSSPropertyWidows:
3234             if (style->hasAutoWidows())
3235                 return cssValuePool.createIdentifierValue(CSSValueAuto);
3236             return cssValuePool.createValue(style->widows(), CSSPrimitiveValue::CSS_NUMBER);
3237         case CSSPropertyWidth:
3238             if (renderer && !renderer->isRenderSVGModelObject()) {
3239                 // According to http://www.w3.org/TR/CSS2/visudet.html#the-width-property,
3240                 // the "width" property does not apply for non-replaced inline elements.
3241                 if (!renderer->isReplaced() && renderer->isInline())
3242                     return cssValuePool.createIdentifierValue(CSSValueAuto);
3243                 return zoomAdjustedPixelValue(sizingBox(*renderer).width(), *style);
3244             }
3245             return zoomAdjustedPixelValueForLength(style->width(), *style);
3246         case CSSPropertyWillChange:
3247             return getWillChangePropertyValue(style->willChange());
3248             break;
3249         case CSSPropertyWordBreak:
3250             return cssValuePool.createValue(style->wordBreak());
3251         case CSSPropertyWordSpacing:
3252             return zoomAdjustedPixelValue(style->fontCascade().wordSpacing(), *style);
3253         case CSSPropertyWordWrap:
3254             return cssValuePool.createValue(style->overflowWrap());
3255         case CSSPropertyWebkitLineBreak:
3256             return cssValuePool.createValue(style->lineBreak());
3257         case CSSPropertyWebkitNbspMode:
3258             return cssValuePool.createValue(style->nbspMode());
3259         case CSSPropertyResize:
3260             return cssValuePool.createValue(style->resize());
3261         case CSSPropertyWebkitFontKerning:
3262             return cssValuePool.createValue(style->fontDescription().kerning());
3263         case CSSPropertyWebkitFontSmoothing:
3264             return cssValuePool.createValue(style->fontDescription().fontSmoothing());
3265         case CSSPropertyFontVariantLigatures:
3266             return fontVariantLigaturesPropertyValue(style->fontDescription().variantCommonLigatures(), style->fontDescription().variantDiscretionaryLigatures(), style->fontDescription().variantHistoricalLigatures(), style->fontDescription().variantContextualAlternates());
3267         case CSSPropertyFontVariantPosition:
3268             return fontVariantPositionPropertyValue(style->fontDescription().variantPosition());
3269         case CSSPropertyFontVariantCaps:
3270             return fontVariantCapsPropertyValue(style->fontDescription().variantCaps());
3271         case CSSPropertyFontVariantNumeric:
3272             return fontVariantNumericPropertyValue(style->fontDescription().variantNumericFigure(), style->fontDescription().variantNumericSpacing(), style->fontDescription().variantNumericFraction(), style->fontDescription().variantNumericOrdinal(), style->fontDescription().variantNumericSlashedZero());
3273         case CSSPropertyFontVariantAlternates:
3274             return fontVariantAlternatesPropertyValue(style->fontDescription().variantAlternates());
3275         case CSSPropertyFontVariantEastAsian:
3276             return fontVariantEastAsianPropertyValue(style->fontDescription().variantEastAsianVariant(), style->fontDescription().variantEastAsianWidth(), style->fontDescription().variantEastAsianRuby());
3277         case CSSPropertyZIndex:
3278             if (style->hasAutoZIndex())
3279                 return cssValuePool.createIdentifierValue(CSSValueAuto);
3280             return cssValuePool.createValue(style->zIndex(), CSSPrimitiveValue::CSS_NUMBER);
3281         case CSSPropertyZoom:
3282             return cssValuePool.createValue(style->zoom(), CSSPrimitiveValue::CSS_NUMBER);
3283         case CSSPropertyBoxSizing:
3284             if (style->boxSizing() == CONTENT_BOX)
3285                 return cssValuePool.createIdentifierValue(CSSValueContentBox);
3286             return cssValuePool.createIdentifierValue(CSSValueBorderBox);
3287 #if ENABLE(DASHBOARD_SUPPORT)
3288         case CSSPropertyWebkitDashboardRegion:
3289         {
3290             const Vector<StyleDashboardRegion>& regions = style->dashboardRegions();
3291             unsigned count = regions.size();
3292             if (count == 1 && regions[0].type == StyleDashboardRegion::None)
3293                 return cssValuePool.createIdentifierValue(CSSValueNone);
3294
3295             RefPtr<DashboardRegion> firstRegion;
3296             DashboardRegion* previousRegion = nullptr;
3297             for (unsigned i = 0; i < count; i++) {
3298                 auto region = DashboardRegion::create();
3299                 StyleDashboardRegion styleRegion = regions[i];
3300
3301                 region->m_label = styleRegion.label;
3302                 LengthBox offset = styleRegion.offset;
3303                 region->setTop(zoomAdjustedPixelValue(offset.top().value(), *style));
3304                 region->setRight(zoomAdjustedPixelValue(offset.right().value(), *style));
3305                 region->setBottom(zoomAdjustedPixelValue(offset.bottom().value(), *style));
3306                 region->setLeft(zoomAdjustedPixelValue(offset.left().value(), *style));
3307                 region->m_isRectangle = (styleRegion.type == StyleDashboardRegion::Rectangle);
3308                 region->m_isCircle = (styleRegion.type == StyleDashboardRegion::Circle);
3309
3310                 if (previousRegion)
3311                     previousRegion->m_next = region.copyRef();
3312                 else
3313                     firstRegion = region.copyRef();
3314                 previousRegion = region.ptr();
3315             }
3316             return cssValuePool.createValue(WTFMove(firstRegion));
3317         }
3318 #endif
3319         case CSSPropertyAnimationDelay:
3320         case CSSPropertyWebkitAnimationDelay:
3321             return getDelayValue(style->animations());
3322         case CSSPropertyAnimationDirection:
3323         case CSSPropertyWebkitAnimationDirection: {
3324             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
3325             const AnimationList* t = style->animations();
3326             if (t) {
3327                 for (size_t i = 0; i < t->size(); ++i) {
3328                     switch (t->animation(i).direction()) {
3329                     case Animation::AnimationDirectionNormal:
3330                         list->append(cssValuePool.createIdentifierValue(CSSValueNormal));
3331                         break;
3332                     case Animation::AnimationDirectionAlternate:
3333                         list->append(cssValuePool.createIdentifierValue(CSSValueAlternate));
3334                         break;
3335                     case Animation::AnimationDirectionReverse:
3336                         list->append(cssValuePool.createIdentifierValue(CSSValueReverse));
3337                         break;
3338                     case Animation::AnimationDirectionAlternateReverse:
3339                         list->append(cssValuePool.createIdentifierValue(CSSValueAlternateReverse));
3340                         break;
3341                     }
3342                 }
3343             } else
3344                 list->append(cssValuePool.createIdentifierValue(CSSValueNormal));
3345             return list;
3346         }
3347         case CSSPropertyAnimationDuration:
3348         case CSSPropertyWebkitAnimationDuration:
3349             return getDurationValue(style->animations());
3350         case CSSPropertyAnimationFillMode:
3351         case CSSPropertyWebkitAnimationFillMode: {
3352             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
3353             const AnimationList* t = style->animations();
3354             if (t) {
3355                 for (size_t i = 0; i < t->size(); ++i) {
3356                     switch (t->animation(i).fillMode()) {
3357                     case AnimationFillModeNone:
3358                         list->append(cssValuePool.createIdentifierValue(CSSValueNone));
3359                         break;
3360                     case AnimationFillModeForwards:
3361                         list->append(cssValuePool.createIdentifierValue(CSSValueForwards));
3362                         break;
3363                     case AnimationFillModeBackwards:
3364                         list->append(cssValuePool.createIdentifierValue(CSSValueBackwards));
3365                         break;
3366                     case AnimationFillModeBoth:
3367                         list->append(cssValuePool.createIdentifierValue(CSSValueBoth));
3368                         break;
3369                     }
3370                 }
3371             } else
3372                 list->append(cssValuePool.createIdentifierValue(CSSValueNone));
3373             return list;
3374         }
3375         case CSSPropertyAnimationIterationCount:
3376         case CSSPropertyWebkitAnimationIterationCount: {
3377             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
3378             const AnimationList* t = style->animations();
3379             if (t) {
3380                 for (size_t i = 0; i < t->size(); ++i) {
3381                     double iterationCount = t->animation(i).iterationCount();
3382                     if (iterationCount == Animation::IterationCountInfinite)
3383                         list->append(cssValuePool.createIdentifierValue(CSSValueInfinite));
3384                     else
3385                         list->append(cssValuePool.createValue(iterationCount, CSSPrimitiveValue::CSS_NUMBER));
3386                 }
3387             } else
3388                 list->append(cssValuePool.createValue(Animation::initialIterationCount(), CSSPrimitiveValue::CSS_NUMBER));
3389             return list;
3390         }
3391         case CSSPropertyAnimationName:
3392         case CSSPropertyWebkitAnimationName: {
3393             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
3394             const AnimationList* t = style->animations();
3395             if (t) {
3396                 for (size_t i = 0; i < t->size(); ++i)
3397                     list->append(cssValuePool.createValue(t->animation(i).name(), CSSPrimitiveValue::CSS_STRING));
3398             } else
3399                 list->append(cssValuePool.createIdentifierValue(CSSValueNone));
3400             return list;
3401         }
3402         case CSSPropertyAnimationPlayState:
3403         case CSSPropertyWebkitAnimationPlayState: {
3404             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
3405             const AnimationList* t = style->animations();
3406             if (t) {
3407                 for (size_t i = 0; i < t->size(); ++i) {
3408                     int prop = t->animation(i).playState();
3409                     if (prop == AnimPlayStatePlaying)
3410                         list->append(cssValuePool.createIdentifierValue(CSSValueRunning));
3411                     else
3412                         list->append(cssValuePool.createIdentifierValue(CSSValuePaused));
3413                 }
3414             } else
3415                 list->append(cssValuePool.createIdentifierValue(CSSValueRunning));
3416             return list;
3417         }
3418         case CSSPropertyAnimationTimingFunction:
3419         case CSSPropertyWebkitAnimationTimingFunction:
3420             return getTimingFunctionValue(style->animations());
3421 #if ENABLE(CSS_ANIMATIONS_LEVEL_2)
3422         case CSSPropertyWebkitAnimationTrigger:
3423             return getAnimationTriggerValue(style->animations(), *style);
3424 #endif
3425         case CSSPropertyWebkitAppearance:
3426             return cssValuePool.createValue(style->appearance());
3427         case CSSPropertyWebkitAspectRatio:
3428             if (style->aspectRatioType() == AspectRatioAuto)
3429                 return cssValuePool.createIdentifierValue(CSSValueAuto);
3430             if (style->aspectRatioType() == AspectRatioFromDimensions)
3431                 return cssValuePool.createIdentifierValue(CSSValueFromDimensions);
3432             if (style->aspectRatioType() == AspectRatioFromIntrinsic)
3433                 return cssValuePool.createIdentifierValue(CSSValueFromIntrinsic);
3434             return CSSAspectRatioValue::create(style->aspectRatioNumerator(), style->aspectRatioDenominator());
3435         case CSSPropertyWebkitBackfaceVisibility:
3436             return cssValuePool.createIdentifierValue((style->backfaceVisibility() == BackfaceVisibilityHidden) ? CSSValueHidden : CSSValueVisible);
3437         case CSSPropertyWebkitBorderImage:
3438             return valueForNinePieceImage(style->borderImage());
3439         case CSSPropertyBorderImageOutset:
3440             return valueForNinePieceImageQuad(style->borderImage().outset());
3441         case CSSPropertyBorderImageRepeat:
3442             return valueForNinePieceImageRepeat(style->borderImage());
3443         case CSSPropertyBorderImageSlice:
3444             return valueForNinePieceImageSlice(style->borderImage());
3445         case CSSPropertyBorderImageWidth:
3446             return valueForNinePieceImageQuad(style->borderImage().borderSlices());
3447         case CSSPropertyWebkitMaskBoxImage:
3448             return valueForNinePieceImage(style->maskBoxImage());
3449         case CSSPropertyWebkitMaskBoxImageOutset:
3450             return valueForNinePieceImageQuad(style->maskBoxImage().outset());
3451         case CSSPropertyWebkitMaskBoxImageRepeat:
3452             return valueForNinePieceImageRepeat(style->maskBoxImage());
3453         case CSSPropertyWebkitMaskBoxImageSlice:
3454             return valueForNinePieceImageSlice(style->maskBoxImage());
3455         case CSSPropertyWebkitMaskBoxImageWidth:
3456             return valueForNinePieceImageQuad(style->maskBoxImage().borderSlices());
3457         case CSSPropertyWebkitMaskBoxImageSource:
3458             if (style->maskBoxImageSource())
3459                 return style->maskBoxImageSource()->cssValue();
3460             return cssValuePool.createIdentifierValue(CSSValueNone);
3461         case CSSPropertyWebkitFontSizeDelta:
3462             // Not a real style property -- used by the editing engine -- so has no computed value.
3463             break;
3464         case CSSPropertyWebkitInitialLetter: {
3465             Ref<CSSPrimitiveValue> drop = !style->initialLetterDrop() ? cssValuePool.createIdentifierValue(CSSValueNormal) : cssValuePool.createValue(style->initialLetterDrop(), CSSPrimitiveValue::CSS_NUMBER);
3466             Ref<CSSPrimitiveValue> size = !style->initialLetterHeight() ? cssValuePool.createIdentifierValue(CSSValueNormal) : cssValuePool.createValue(style->initialLetterHeight(), CSSPrimitiveValue::CSS_NUMBER);
3467             return cssValuePool.createValue(Pair::create(WTFMove(drop), WTFMove(size)));
3468         }
3469         case CSSPropertyWebkitMarginBottomCollapse:
3470         case CSSPropertyWebkitMarginAfterCollapse:
3471             return cssValuePool.createValue(style->marginAfterCollapse());
3472         case CSSPropertyWebkitMarginTopCollapse:
3473         case CSSPropertyWebkitMarginBeforeCollapse:
3474             return cssValuePool.createValue(style->marginBeforeCollapse());
3475 #if ENABLE(ACCELERATED_OVERFLOW_SCROLLING)
3476         case CSSPropertyWebkitOverflowScrolling:
3477             if (!style->useTouchOverflowScrolling())
3478                 return cssValuePool.createIdentifierValue(CSSValueAuto);
3479             return cssValuePool.createIdentifierValue(CSSValueTouch);
3480 #endif
3481         case CSSPropertyPerspective:
3482             if (!style->hasPerspective())
3483                 return cssValuePool.createIdentifierValue(CSSValueNone);
3484             return zoomAdjustedPixelValue(style->perspective(), *style);
3485         case CSSPropertyPerspectiveOrigin: {
3486             RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
3487             if (renderer) {
3488                 LayoutRect box;
3489                 if (is<RenderBox>(*renderer))
3490                     box = downcast<RenderBox>(*renderer).borderBoxRect();
3491
3492                 list->append(zoomAdjustedPixelValue(minimumValueForLength(style->perspectiveOriginX(), box.width()), *style));
3493                 list->append(zoomAdjustedPixelValue(minimumValueForLength(style->perspectiveOriginY(), box.height()), *style));
3494             }
3495             else {
3496                 list->append(zoomAdjustedPixelValueForLength(style->perspectiveOriginX(), *style));
3497                 list->append(zoomAdjustedPixelValueForLength(style->perspectiveOriginY(), *style));
3498
3499             }
3500             return list;
3501         }
3502         case CSSPropertyWebkitRtlOrdering:
3503             return cssValuePool.createIdentifierValue(style->rtlOrdering() ? CSSValueVisual : CSSValueLogical);
3504 #if ENABLE(TOUCH_EVENTS)
3505         case CSSPropertyWebkitTapHighlightColor:
3506             return currentColorOrValidColor(style, style->tapHighlightColor());
3507         case CSSPropertyTouchAction:
3508             return cssValuePool.createValue(style->touchAction());
3509 #endif
3510 #if PLATFORM(IOS)
3511         case CSSPropertyWebkitTouchCallout:
3512             return cssValuePool.createIdentifierValue(style->touchCalloutEnabled() ? CSSValueDefault : CSSValueNone);
3513 #endif
3514         case CSSPropertyWebkitUserDrag:
3515             return cssValuePool.createValue(style->userDrag());
3516         case CSSPropertyWebkitUserSelect:
3517             return cssValuePool.createValue(style->userSelect());
3518         case CSSPropertyBorderBottomLeftRadius:
3519             return getBorderRadiusCornerValue(style->borderBottomLeftRadius(), *style);
3520         case CSSPropertyBorderBottomRightRadius:
3521             return getBorderRadiusCornerValue(style->borderBottomRightRadius(), *style);
3522         case CSSPropertyBorderTopLeftRadius:
3523             return getBorderRadiusCornerValue(style->borderTopLeftRadius(), *style);
3524         case CSSPropertyBorderTopRightRadius:
3525             return getBorderRadiusCornerValue(style->borderTopRightRadius(), *style);
3526         case CSSPropertyClip: {
3527             if (!style->hasClip())
3528                 return cssValuePool.createIdentifierValue(CSSValueAuto);
3529             auto rect = Rect::create();
3530             rect->setTop(autoOrZoomAdjustedValue(style->clip().top(), *style));
3531             rect->setRight(autoOrZoomAdjustedValue(style->clip().right(), *style));
3532             rect->setBottom(autoOrZoomAdjustedValue(style->clip().bottom(), *style));
3533             rect->setLeft(autoOrZoomAdjustedValue(style->clip().left(), *style));
3534             return cssValuePool.createValue(WTFMove(rect));
3535         }
3536         case CSSPropertySpeak:
3537             return cssValuePool.createValue(style->speak());
3538         case CSSPropertyTransform:
3539             return computedTransform(renderer, *style);
3540         case CSSPropertyTransformOrigin: {
3541             RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
3542             if (renderer) {
3543                 LayoutRect box;
3544                 if (is<RenderBox>(*renderer))
3545                     box = downcast<RenderBox>(*renderer).borderBoxRect();
3546
3547                 list->append(zoomAdjustedPixelValue(minimumValueForLength(style->transformOriginX(), box.width()), *style));
3548                 list->append(zoomAdjustedPixelValue(minimumValueForLength(style->transformOriginY(), box.height()), *style));
3549                 if (style->transformOriginZ() != 0)
3550                     list->append(zoomAdjustedPixelValue(style->transformOriginZ(), *style));
3551             } else {
3552                 list->append(zoomAdjustedPixelValueForLength(style->transformOriginX(), *style));
3553                 list->append(zoomAdjustedPixelValueForLength(style->transformOriginY(), *style));
3554                 if (style->transformOriginZ() != 0)
3555                     list->append(zoomAdjustedPixelValue(style->transformOriginZ(), *style));
3556             }
3557             return list;
3558         }
3559         case CSSPropertyTransformStyle:
3560         case CSSPropertyWebkitTransformStyle:
3561             return cssValuePool.createIdentifierValue((style->transformStyle3D() == TransformStyle3DPreserve3D) ? CSSValuePreserve3d : CSSValueFlat);
3562         case CSSPropertyTransitionDelay:
3563         case CSSPropertyWebkitTransitionDelay:
3564             return getDelayValue(style->transitions());
3565         case CSSPropertyTransitionDuration:
3566         case CSSPropertyWebkitTransitionDuration:
3567             return getDurationValue(style->transitions());
3568         case CSSPropertyTransitionProperty:
3569         case CSSPropertyWebkitTransitionProperty:
3570             return getTransitionPropertyValue(style->transitions());
3571         case CSSPropertyTransitionTimingFunction:
3572         case CSSPropertyWebkitTransitionTimingFunction:
3573             return getTimingFunctionValue(style->transitions());
3574         case CSSPropertyTransition:
3575         case CSSPropertyWebkitTransition: {
3576             const AnimationList* animList = style->transitions();
3577             if (animList) {
3578                 RefPtr<CSSValueList> transitionsList = CSSValueList::createCommaSeparated();
3579                 for (size_t i = 0; i < animList->size(); ++i) {
3580                     RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
3581                     const Animation& animation = animList->animation(i);
3582                     list->append(createTransitionPropertyValue(animation));
3583                     list->append(cssValuePool.createValue(animation.duration(), CSSPrimitiveValue::CSS_S));
3584                     list->append(createTimingFunctionValue(animation.timingFunction().get()));
3585                     list->append(cssValuePool.createValue(animation.delay(), CSSPrimitiveValue::CSS_S));
3586                     transitionsList->append(list.releaseNonNull());
3587                 }
3588                 return transitionsList;
3589             }
3590
3591             RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
3592             // transition-property default value.
3593             list->append(cssValuePool.createIdentifierValue(CSSValueAll));
3594             list->append(cssValuePool.createValue(Animation::initialDuration(), CSSPrimitiveValue::CSS_S));
3595             list->append(createTimingFunctionValue(Animation::initialTimingFunction().get()));
3596             list->append(cssValuePool.createValue(Animation::initialDelay(), CSSPrimitiveValue::CSS_S));
3597             return list;
3598         }
3599         case CSSPropertyPointerEvents:
3600             return cssValuePool.createValue(style->pointerEvents());
3601         case CSSPropertyWebkitLineGrid:
3602             if (style->lineGrid().isNull())
3603                 return cssValuePool.createIdentifierValue(CSSValueNone);
3604             return cssValuePool.createValue(style->lineGrid(), CSSPrimitiveValue::CSS_STRING);
3605         case CSSPropertyWebkitLineSnap:
3606             return CSSPrimitiveValue::create(style->lineSnap());
3607         case CSSPropertyWebkitLineAlign:
3608             return CSSPrimitiveValue::create(style->lineAlign());
3609         case CSSPropertyWebkitWritingMode:
3610             return cssValuePool.createValue(style->writingMode());
3611         case CSSPropertyWebkitTextCombine:
3612             return cssValuePool.createValue(style->textCombine());
3613         case CSSPropertyWebkitTextOrientation:
3614             return CSSPrimitiveValue::create(style->textOrientation());
3615         case CSSPropertyWebkitLineBoxContain:
3616             return createLineBoxContainValue(style->lineBoxContain());
3617         case CSSPropertyAlt:
3618             return altTextToCSSValue(style);
3619         case CSSPropertyContent:
3620             return contentToCSSValue(style);
3621         case CSSPropertyCounterIncrement:
3622             return counterToCSSValue(style, propertyID);
3623         case CSSPropertyCounterReset:
3624             return counterToCSSValue(style, propertyID);
3625         case CSSPropertyWebkitClipPath: {
3626             ClipPathOperation* operation = style->clipPath();
3627             if (!operation)
3628                 return cssValuePool.createIdentifierValue(CSSValueNone);
3629             if (is<ReferenceClipPathOperation>(*operation)) {
3630                 const auto& referenceOperation = downcast<ReferenceClipPathOperation>(*operation);
3631                 return CSSPrimitiveValue::create(referenceOperation.url(), CSSPrimitiveValue::CSS_URI);
3632             }
3633             RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
3634             if (is<ShapeClipPathOperation>(*operation)) {
3635                 const auto& shapeOperation = downcast<ShapeClipPathOperation>(*operation);
3636                 list->append(valueForBasicShape(*style, shapeOperation.basicShape()));
3637                 if (shapeOperation.referenceBox() != BoxMissing)
3638                     list->append(cssValuePool.createValue(shapeOperation.referenceBox()));
3639             }
3640             if (is<BoxClipPathOperation>(*operation)) {
3641                 const auto& boxOperation = downcast<BoxClipPathOperation>(*operation);
3642                 list->append(cssValuePool.createValue(boxOperation.referenceBox()));
3643             }
3644             return list;
3645         }
3646 #if ENABLE(CSS_REGIONS)
3647         case CSSPropertyWebkitFlowInto:
3648             if (!style->hasFlowInto())
3649                 return cssValuePool.createIdentifierValue(CSSValueNone);
3650             return cssValuePool.createValue(style->flowThread(), CSSPrimitiveValue::CSS_STRING);
<