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