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