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