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