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