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