Make more of the CSS animation system internals element based
[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() const
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
2386 RenderElement* ComputedStyleExtractor::styledRenderer() const
2387 {
2388     auto* element = styledElement();
2389     if (!element)
2390         return nullptr;
2391     if (m_pseudoElementSpecifier != NOPSEUDO && element == m_element.get())
2392         return nullptr;
2393     return element->renderer();
2394 }
2395
2396 static bool isImplicitlyInheritedGridOrFlexProperty(CSSPropertyID propertyID)
2397 {
2398     // It would be nice if grid and flex worked within normal CSS mechanisms and not invented their own inheritance system.
2399     switch (propertyID) {
2400     case CSSPropertyAlignSelf:
2401     case CSSPropertyJustifySelf:
2402     case CSSPropertyJustifyItems:
2403     // FIXME: In StyleResolver::adjustRenderStyle z-index is adjusted based on the parent display property for grid/flex.
2404     case CSSPropertyZIndex:
2405         return true;
2406     default:
2407         return false;
2408     }
2409 }
2410
2411 // In CSS 2.1 the returned object should actually contain the "used values"
2412 // rather then the "computed values" (despite the name saying otherwise).
2413 //
2414 // See;
2415 // http://www.w3.org/TR/CSS21/cascade.html#used-value
2416 // http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSStyleDeclaration
2417 // https://developer.mozilla.org/en-US/docs/Web/API/Window/getComputedStyle#Notes
2418 RefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropertyID propertyID, EUpdateLayout updateLayout) const
2419 {
2420     return ComputedStyleExtractor(m_element.ptr(), m_allowVisitedStyle, m_pseudoElementSpecifier).propertyValue(propertyID, updateLayout);
2421 }
2422
2423 Ref<MutableStyleProperties> CSSComputedStyleDeclaration::copyProperties() const
2424 {
2425     return ComputedStyleExtractor(m_element.ptr(), m_allowVisitedStyle, m_pseudoElementSpecifier).copyProperties();
2426 }
2427
2428 static inline bool hasValidStyleForProperty(Element& element, CSSPropertyID propertyID)
2429 {
2430     if (element.styleValidity() != Style::Validity::Valid)
2431         return false;
2432     if (element.document().hasPendingForcedStyleRecalc())
2433         return false;
2434     if (!element.document().childNeedsStyleRecalc())
2435         return true;
2436
2437     bool isInherited = CSSProperty::isInheritedProperty(propertyID) || isImplicitlyInheritedGridOrFlexProperty(propertyID);
2438     bool maybeExplicitlyInherited = !isInherited;
2439
2440     const auto* currentElement = &element;
2441     for (auto& ancestor : composedTreeAncestors(element)) {
2442         if (ancestor.styleValidity() >= Style::Validity::SubtreeInvalid)
2443             return false;
2444
2445         if (maybeExplicitlyInherited) {
2446             auto* style = currentElement->renderStyle();
2447             maybeExplicitlyInherited = !style || style->hasExplicitlyInheritedProperties();
2448         }
2449
2450         if ((isInherited || maybeExplicitlyInherited) && ancestor.styleValidity() == Style::Validity::ElementInvalid)
2451             return false;
2452
2453         if (ancestor.directChildNeedsStyleRecalc() && currentElement->styleIsAffectedByPreviousSibling())
2454             return false;
2455
2456         currentElement = &ancestor;
2457     }
2458
2459     return true;
2460 }
2461
2462 static bool updateStyleIfNeededForProperty(Element& element, CSSPropertyID propertyID)
2463 {
2464     auto& document = element.document();
2465
2466     document.styleScope().flushPendingUpdate();
2467
2468     if (hasValidStyleForProperty(element, propertyID))
2469         return false;
2470
2471     document.updateStyleIfNeeded();
2472     return true;
2473 }
2474
2475 static inline const RenderStyle* computeRenderStyleForProperty(Element& element, PseudoId pseudoElementSpecifier, CSSPropertyID propertyID, std::unique_ptr<RenderStyle>& ownedStyle)
2476 {
2477     auto* renderer = element.renderer();
2478
2479     if (renderer && renderer->isComposited() && CSSAnimationController::supportsAcceleratedAnimationOfProperty(propertyID)) {
2480         ownedStyle = renderer->animation().animatedStyleForRenderer(*renderer);
2481         if (pseudoElementSpecifier && !element.isPseudoElement()) {
2482             // FIXME: This cached pseudo style will only exist if the animation has been run at least once.
2483             return ownedStyle->getCachedPseudoStyle(pseudoElementSpecifier);
2484         }
2485         return ownedStyle.get();
2486     }
2487
2488     return element.computedStyle(element.isPseudoElement() ? NOPSEUDO : pseudoElementSpecifier);
2489 }
2490
2491 static Ref<CSSValue> shapePropertyValue(const RenderStyle& style, const ShapeValue* shapeValue)
2492 {
2493     if (!shapeValue)
2494         return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
2495
2496     if (shapeValue->type() == ShapeValue::Type::Box)
2497         return CSSValuePool::singleton().createValue(shapeValue->cssBox());
2498
2499     if (shapeValue->type() == ShapeValue::Type::Image) {
2500         if (shapeValue->image())
2501             return shapeValue->image()->cssValue();
2502         return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
2503     }
2504
2505     ASSERT(shapeValue->type() == ShapeValue::Type::Shape);
2506
2507     auto list = CSSValueList::createSpaceSeparated();
2508     list->append(valueForBasicShape(style, *shapeValue->shape()));
2509     if (shapeValue->cssBox() != BoxMissing)
2510         list->append(CSSValuePool::singleton().createValue(shapeValue->cssBox()));
2511     return WTFMove(list);
2512 }
2513
2514 static Ref<CSSValueList> valueForItemPositionWithOverflowAlignment(const StyleSelfAlignmentData& data)
2515 {
2516     auto& cssValuePool = CSSValuePool::singleton();
2517     auto result = CSSValueList::createSpaceSeparated();
2518     if (data.positionType() == LegacyPosition)
2519         result->append(cssValuePool.createIdentifierValue(CSSValueLegacy));
2520     if (data.position() == ItemPositionBaseline)
2521         result->append(cssValuePool.createIdentifierValue(CSSValueBaseline));
2522     else if (data.position() == ItemPositionLastBaseline) {
2523         result->append(cssValuePool.createIdentifierValue(CSSValueLast));
2524         result->append(cssValuePool.createIdentifierValue(CSSValueBaseline));
2525     } else
2526         result->append(cssValuePool.createValue(data.position()));
2527     if (data.position() >= ItemPositionCenter && data.overflow() != OverflowAlignmentDefault)
2528         result->append(cssValuePool.createValue(data.overflow()));
2529     ASSERT(result->length() <= 2);
2530     return result;
2531 }
2532
2533 static Ref<CSSValueList> valueForContentPositionAndDistributionWithOverflowAlignment(const StyleContentAlignmentData& data, CSSValueID normalBehaviorValueID)
2534 {
2535     auto& cssValuePool = CSSValuePool::singleton();
2536     auto result = CSSValueList::createSpaceSeparated();
2537     // Handle content-distribution values
2538     if (data.distribution() != ContentDistributionDefault)
2539         result->append(cssValuePool.createValue(data.distribution()));
2540
2541     bool gridEnabled = false;
2542     gridEnabled = RuntimeEnabledFeatures::sharedFeatures().isCSSGridLayoutEnabled();
2543
2544     // Handle content-position values (either as fallback or actual value)
2545     switch (data.position()) {
2546     case ContentPositionNormal:
2547         // Handle 'normal' value, not valid as content-distribution fallback.
2548         if (data.distribution() == ContentDistributionDefault)
2549             result->append(cssValuePool.createIdentifierValue(gridEnabled ? CSSValueNormal : normalBehaviorValueID));
2550         break;
2551     case ContentPositionLastBaseline:
2552         result->append(cssValuePool.createIdentifierValue(CSSValueLast));
2553         result->append(cssValuePool.createIdentifierValue(CSSValueBaseline));
2554         break;
2555     default:
2556         result->append(cssValuePool.createValue(data.position()));
2557     }
2558
2559     // Handle overflow-alignment (only allowed for content-position values)
2560     if ((data.position() >= ContentPositionCenter || data.distribution() != ContentDistributionDefault) && data.overflow() != OverflowAlignmentDefault)
2561         result->append(cssValuePool.createValue(data.overflow()));
2562     ASSERT(result->length() > 0);
2563     ASSERT(result->length() <= 3);
2564     return result;
2565 }
2566
2567 static Ref<CSSValue> paintOrder(PaintOrder paintOrder)
2568 {
2569     if (paintOrder == PaintOrder::Normal)
2570         return CSSPrimitiveValue::createIdentifier(CSSValueNormal);
2571     
2572     auto paintOrderList = CSSValueList::createSpaceSeparated();
2573     switch (paintOrder) {
2574     case PaintOrder::Normal:
2575         ASSERT_NOT_REACHED();
2576         break;
2577     case PaintOrder::Fill:
2578         paintOrderList->append(CSSPrimitiveValue::createIdentifier(CSSValueFill));
2579         break;
2580     case PaintOrder::FillMarkers:
2581         paintOrderList->append(CSSPrimitiveValue::createIdentifier(CSSValueFill));
2582         paintOrderList->append(CSSPrimitiveValue::createIdentifier(CSSValueMarkers));
2583         break;
2584     case PaintOrder::Stroke:
2585         paintOrderList->append(CSSPrimitiveValue::createIdentifier(CSSValueStroke));
2586         break;
2587     case PaintOrder::StrokeMarkers:
2588         paintOrderList->append(CSSPrimitiveValue::createIdentifier(CSSValueStroke));
2589         paintOrderList->append(CSSPrimitiveValue::createIdentifier(CSSValueMarkers));
2590         break;
2591     case PaintOrder::Markers:
2592         paintOrderList->append(CSSPrimitiveValue::createIdentifier(CSSValueMarkers));
2593         break;
2594     case PaintOrder::MarkersStroke:
2595         paintOrderList->append(CSSPrimitiveValue::createIdentifier(CSSValueMarkers));
2596         paintOrderList->append(CSSPrimitiveValue::createIdentifier(CSSValueStroke));
2597         break;
2598     }
2599     return WTFMove(paintOrderList);
2600 }
2601
2602 inline static bool isFlexOrGrid(ContainerNode* element)
2603 {
2604     return element && element->computedStyle() && element->computedStyle()->isDisplayFlexibleOrGridBox();
2605 }
2606
2607 RefPtr<CSSValue> ComputedStyleExtractor::customPropertyValue(const String& propertyName)
2608 {
2609     Element* styledElement = this->styledElement();
2610     if (!styledElement)
2611         return nullptr;
2612     
2613     if (updateStyleIfNeededForProperty(*styledElement, CSSPropertyCustom)) {
2614         // Style update may change styledElement() to PseudoElement or back.
2615         styledElement = this->styledElement();
2616     }
2617
2618     std::unique_ptr<RenderStyle> ownedStyle;
2619     auto* style = computeRenderStyleForProperty(*styledElement, m_pseudoElementSpecifier, CSSPropertyCustom, ownedStyle);
2620     if (!style)
2621         return nullptr;
2622
2623     return style->customProperties().get(propertyName);
2624 }
2625
2626 String ComputedStyleExtractor::customPropertyText(const String& propertyName)
2627 {
2628     RefPtr<CSSValue> propertyValue = customPropertyValue(propertyName);
2629     return propertyValue ? propertyValue->cssText() : emptyString();
2630 }
2631
2632 static Ref<CSSFontValue> fontShorthandValueForSelectionProperties(const FontDescription& fontDescription)
2633 {
2634     auto computedFont = CSSFontValue::create();
2635
2636     auto variantCaps = fontDescription.variantCaps();
2637     if (variantCaps == FontVariantCaps::Small)
2638         computedFont->variant = CSSValuePool::singleton().createIdentifierValue(CSSValueSmallCaps);
2639     else if (variantCaps == FontVariantCaps::Normal)
2640         computedFont->variant = CSSValuePool::singleton().createIdentifierValue(CSSValueNormal);
2641     else
2642         return CSSFontValue::create();
2643
2644     auto weight = fontDescription.weight();
2645     if (auto value = fontWeightKeyword(weight))
2646         computedFont->weight = CSSValuePool::singleton().createIdentifierValue(value.value());
2647     else if (isCSS21Weight(weight))
2648         computedFont->weight = CSSValuePool::singleton().createValue(static_cast<float>(weight), CSSPrimitiveValue::CSS_NUMBER);
2649     else
2650         return CSSFontValue::create();
2651
2652     if (auto keyword = fontStretchKeyword(fontDescription.stretch()))
2653         computedFont->stretch = CSSValuePool::singleton().createIdentifierValue(keyword.value());
2654     else
2655         return CSSFontValue::create();
2656
2657     if (auto italic = fontStyleKeyword(fontDescription.italic(), fontDescription.fontStyleAxis()))
2658         computedFont->style = CSSFontStyleValue::create(CSSValuePool::singleton().createIdentifierValue(italic.value()));
2659     else
2660         return CSSFontValue::create();
2661
2662     return computedFont;
2663 }
2664
2665 RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID, EUpdateLayout updateLayout)
2666 {
2667     auto* styledElement = this->styledElement();
2668     if (!styledElement)
2669         return nullptr;
2670
2671     std::unique_ptr<RenderStyle> ownedStyle;
2672     const RenderStyle* style = nullptr;
2673     RenderElement* renderer = nullptr;
2674     bool forceFullLayout = false;
2675     if (updateLayout) {
2676         Document& document = m_element->document();
2677
2678         if (updateStyleIfNeededForProperty(*styledElement, propertyID)) {
2679             // Style update may change styledElement() to PseudoElement or back.
2680             styledElement = this->styledElement();
2681         }
2682         renderer = styledRenderer();
2683
2684         if (propertyID == CSSPropertyDisplay && !renderer && is<SVGElement>(*styledElement) && !downcast<SVGElement>(*styledElement).isValid())
2685             return nullptr;
2686
2687         style = computeRenderStyleForProperty(*styledElement, m_pseudoElementSpecifier, propertyID, ownedStyle);
2688
2689         // FIXME: Some of these cases could be narrowed down or optimized better.
2690         forceFullLayout = isLayoutDependent(propertyID, style, renderer)
2691             || styledElement->isInShadowTree()
2692             || (document.styleScope().resolverIfExists() && document.styleScope().resolverIfExists()->hasViewportDependentMediaQueries() && document.ownerElement());
2693
2694         if (forceFullLayout) {
2695             document.updateLayoutIgnorePendingStylesheets();
2696             styledElement = this->styledElement();
2697         }
2698     }
2699
2700     if (!updateLayout || forceFullLayout) {
2701         style = computeRenderStyleForProperty(*styledElement, m_pseudoElementSpecifier, propertyID, ownedStyle);
2702         renderer = styledRenderer();
2703     }
2704
2705     if (!style)
2706         return nullptr;
2707
2708     auto& cssValuePool = CSSValuePool::singleton();
2709     propertyID = CSSProperty::resolveDirectionAwareProperty(propertyID, style->direction(), style->writingMode());
2710
2711     switch (propertyID) {
2712         case CSSPropertyInvalid:
2713             break;
2714
2715         case CSSPropertyBackgroundColor:
2716             return cssValuePool.createColorValue(m_allowVisitedStyle? style->visitedDependentColor(CSSPropertyBackgroundColor) : style->backgroundColor());
2717         case CSSPropertyBackgroundImage:
2718         case CSSPropertyWebkitMaskImage: {
2719             auto& layers = propertyID == CSSPropertyWebkitMaskImage ? style->maskLayers() : style->backgroundLayers();
2720             if (!layers.next()) {
2721                 if (layers.image())
2722                     return layers.image()->cssValue();
2723                 return cssValuePool.createIdentifierValue(CSSValueNone);
2724             }
2725             auto list = CSSValueList::createCommaSeparated();
2726             for (auto* currLayer = &layers; currLayer; currLayer = currLayer->next()) {
2727                 if (currLayer->image())
2728                     list->append(currLayer->image()->cssValue());
2729                 else
2730                     list->append(cssValuePool.createIdentifierValue(CSSValueNone));
2731             }
2732             return WTFMove(list);
2733         }
2734         case CSSPropertyBackgroundSize:
2735         case CSSPropertyWebkitBackgroundSize:
2736         case CSSPropertyWebkitMaskSize: {
2737             auto& layers = propertyID == CSSPropertyWebkitMaskSize ? style->maskLayers() : style->backgroundLayers();
2738             if (!layers.next())
2739                 return fillSizeToCSSValue(layers.size(), *style);
2740             auto list = CSSValueList::createCommaSeparated();
2741             for (auto* currLayer = &layers; currLayer; currLayer = currLayer->next())
2742                 list->append(fillSizeToCSSValue(currLayer->size(), *style));
2743             return WTFMove(list);
2744         }
2745         case CSSPropertyBackgroundRepeat:
2746         case CSSPropertyWebkitMaskRepeat: {
2747             auto& layers = propertyID == CSSPropertyWebkitMaskRepeat ? style->maskLayers() : style->backgroundLayers();
2748             if (!layers.next())
2749                 return fillRepeatToCSSValue(layers.repeatX(), layers.repeatY());
2750             auto list = CSSValueList::createCommaSeparated();
2751             for (auto* currLayer = &layers; currLayer; currLayer = currLayer->next())
2752                 list->append(fillRepeatToCSSValue(currLayer->repeatX(), currLayer->repeatY()));
2753             return WTFMove(list);
2754         }
2755         case CSSPropertyWebkitMaskSourceType: {
2756             auto& layers = style->maskLayers();
2757             if (!layers.next())
2758                 return fillSourceTypeToCSSValue(layers.maskSourceType());
2759             auto list = CSSValueList::createCommaSeparated();
2760             for (auto* currLayer = &layers; currLayer; currLayer = currLayer->next())
2761                 list->append(fillSourceTypeToCSSValue(currLayer->maskSourceType()));
2762             return WTFMove(list);
2763         }
2764         case CSSPropertyWebkitBackgroundComposite:
2765         case CSSPropertyWebkitMaskComposite: {
2766             auto& layers = propertyID == CSSPropertyWebkitMaskComposite ? style->maskLayers() : style->backgroundLayers();
2767             if (!layers.next())
2768                 return cssValuePool.createValue(layers.composite());
2769             auto list = CSSValueList::createCommaSeparated();
2770             for (auto* currLayer = &layers; currLayer; currLayer = currLayer->next())
2771                 list->append(cssValuePool.createValue(currLayer->composite()));
2772             return WTFMove(list);
2773         }
2774         case CSSPropertyBackgroundAttachment: {
2775             auto& layers = style->backgroundLayers();
2776             if (!layers.next())
2777                 return cssValuePool.createValue(layers.attachment());
2778             auto list = CSSValueList::createCommaSeparated();
2779             for (auto* currLayer = &layers; currLayer; currLayer = currLayer->next())
2780                 list->append(cssValuePool.createValue(currLayer->attachment()));
2781             return WTFMove(list);
2782         }
2783         case CSSPropertyBackgroundClip:
2784         case CSSPropertyBackgroundOrigin:
2785         case CSSPropertyWebkitBackgroundClip:
2786         case CSSPropertyWebkitBackgroundOrigin:
2787         case CSSPropertyWebkitMaskClip:
2788         case CSSPropertyWebkitMaskOrigin: {
2789             auto& layers = (propertyID == CSSPropertyWebkitMaskClip || propertyID == CSSPropertyWebkitMaskOrigin) ? style->maskLayers() : style->backgroundLayers();
2790             bool isClip = propertyID == CSSPropertyBackgroundClip || propertyID == CSSPropertyWebkitBackgroundClip || propertyID == CSSPropertyWebkitMaskClip;
2791             if (!layers.next())
2792                 return cssValuePool.createValue(isClip ? layers.clip() : layers.origin());
2793             auto list = CSSValueList::createCommaSeparated();
2794             for (auto* currLayer = &layers; currLayer; currLayer = currLayer->next())
2795                 list->append(cssValuePool.createValue(isClip ? currLayer->clip() : currLayer->origin()));
2796             return WTFMove(list);
2797         }
2798         case CSSPropertyBackgroundPosition:
2799         case CSSPropertyWebkitMaskPosition: {
2800             auto& layers = propertyID == CSSPropertyWebkitMaskPosition ? style->maskLayers() : style->backgroundLayers();
2801             if (!layers.next())
2802                 return createPositionListForLayer(propertyID, layers, *style);
2803
2804             auto list = CSSValueList::createCommaSeparated();
2805             for (auto* currLayer = &layers; currLayer; currLayer = currLayer->next())
2806                 list->append(createPositionListForLayer(propertyID, *currLayer, *style));
2807             return WTFMove(list);
2808         }
2809         case CSSPropertyBackgroundPositionX:
2810         case CSSPropertyWebkitMaskPositionX: {
2811             auto& layers = propertyID == CSSPropertyWebkitMaskPositionX ? style->maskLayers() : style->backgroundLayers();
2812             if (!layers.next())
2813                 return cssValuePool.createValue(layers.xPosition());
2814
2815             auto list = CSSValueList::createCommaSeparated();
2816             for (auto* currLayer = &layers; currLayer; currLayer = currLayer->next())
2817                 list->append(cssValuePool.createValue(currLayer->xPosition()));
2818
2819             return WTFMove(list);
2820         }
2821         case CSSPropertyBackgroundPositionY:
2822         case CSSPropertyWebkitMaskPositionY: {
2823             auto& layers = propertyID == CSSPropertyWebkitMaskPositionY ? style->maskLayers() : style->backgroundLayers();
2824             if (!layers.next())
2825                 return cssValuePool.createValue(layers.yPosition());
2826
2827             auto list = CSSValueList::createCommaSeparated();
2828             for (auto* currLayer = &layers; currLayer; currLayer = currLayer->next())
2829                 list->append(cssValuePool.createValue(currLayer->yPosition()));
2830
2831             return WTFMove(list);
2832         }
2833         case CSSPropertyBorderCollapse:
2834             if (style->borderCollapse())
2835                 return cssValuePool.createIdentifierValue(CSSValueCollapse);
2836             return cssValuePool.createIdentifierValue(CSSValueSeparate);
2837         case CSSPropertyBorderSpacing: {
2838             auto list = CSSValueList::createSpaceSeparated();
2839             list->append(zoomAdjustedPixelValue(style->horizontalBorderSpacing(), *style));
2840             list->append(zoomAdjustedPixelValue(style->verticalBorderSpacing(), *style));
2841             return WTFMove(list);
2842         }
2843         case CSSPropertyWebkitBorderHorizontalSpacing:
2844             return zoomAdjustedPixelValue(style->horizontalBorderSpacing(), *style);
2845         case CSSPropertyWebkitBorderVerticalSpacing:
2846             return zoomAdjustedPixelValue(style->verticalBorderSpacing(), *style);
2847         case CSSPropertyBorderImageSource:
2848             if (style->borderImageSource())
2849                 return style->borderImageSource()->cssValue();
2850             return cssValuePool.createIdentifierValue(CSSValueNone);
2851         case CSSPropertyBorderTopColor:
2852             return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyBorderTopColor)) : currentColorOrValidColor(style, style->borderTopColor());
2853         case CSSPropertyBorderRightColor:
2854             return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyBorderRightColor)) : currentColorOrValidColor(style, style->borderRightColor());
2855         case CSSPropertyBorderBottomColor:
2856             return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyBorderBottomColor)) : currentColorOrValidColor(style, style->borderBottomColor());
2857         case CSSPropertyBorderLeftColor:
2858             return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyBorderLeftColor)) : currentColorOrValidColor(style, style->borderLeftColor());
2859         case CSSPropertyBorderTopStyle:
2860             return cssValuePool.createValue(style->borderTopStyle());
2861         case CSSPropertyBorderRightStyle:
2862             return cssValuePool.createValue(style->borderRightStyle());
2863         case CSSPropertyBorderBottomStyle:
2864             return cssValuePool.createValue(style->borderBottomStyle());
2865         case CSSPropertyBorderLeftStyle:
2866             return cssValuePool.createValue(style->borderLeftStyle());
2867         case CSSPropertyBorderTopWidth:
2868             return zoomAdjustedPixelValue(style->borderTopWidth(), *style);
2869         case CSSPropertyBorderRightWidth:
2870             return zoomAdjustedPixelValue(style->borderRightWidth(), *style);
2871         case CSSPropertyBorderBottomWidth:
2872             return zoomAdjustedPixelValue(style->borderBottomWidth(), *style);
2873         case CSSPropertyBorderLeftWidth:
2874             return zoomAdjustedPixelValue(style->borderLeftWidth(), *style);
2875         case CSSPropertyBottom:
2876             return positionOffsetValue(*style, CSSPropertyBottom, renderer);
2877         case CSSPropertyWebkitBoxAlign:
2878             return cssValuePool.createValue(style->boxAlign());
2879 #if ENABLE(CSS_BOX_DECORATION_BREAK)
2880         case CSSPropertyWebkitBoxDecorationBreak:
2881             if (style->boxDecorationBreak() == DSLICE)
2882                 return cssValuePool.createIdentifierValue(CSSValueSlice);
2883         return cssValuePool.createIdentifierValue(CSSValueClone);
2884 #endif
2885         case CSSPropertyWebkitBoxDirection:
2886             return cssValuePool.createValue(style->boxDirection());
2887         case CSSPropertyWebkitBoxFlex:
2888             return cssValuePool.createValue(style->boxFlex(), CSSPrimitiveValue::CSS_NUMBER);
2889         case CSSPropertyWebkitBoxFlexGroup:
2890             return cssValuePool.createValue(style->boxFlexGroup(), CSSPrimitiveValue::CSS_NUMBER);
2891         case CSSPropertyWebkitBoxLines:
2892             return cssValuePool.createValue(style->boxLines());
2893         case CSSPropertyWebkitBoxOrdinalGroup:
2894             return cssValuePool.createValue(style->boxOrdinalGroup(), CSSPrimitiveValue::CSS_NUMBER);
2895         case CSSPropertyWebkitBoxOrient:
2896             return cssValuePool.createValue(style->boxOrient());
2897         case CSSPropertyWebkitBoxPack:
2898             return cssValuePool.createValue(style->boxPack());
2899         case CSSPropertyWebkitBoxReflect:
2900             return valueForReflection(style->boxReflect(), *style);
2901         case CSSPropertyBoxShadow:
2902         case CSSPropertyWebkitBoxShadow:
2903             return valueForShadow(style->boxShadow(), propertyID, *style);
2904         case CSSPropertyCaptionSide:
2905             return cssValuePool.createValue(style->captionSide());
2906         case CSSPropertyCaretColor:
2907             return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyCaretColor)) : currentColorOrValidColor(style, style->caretColor());
2908         case CSSPropertyClear:
2909             return cssValuePool.createValue(style->clear());
2910         case CSSPropertyColor:
2911             return cssValuePool.createColorValue(m_allowVisitedStyle ? style->visitedDependentColor(CSSPropertyColor) : style->color());
2912         case CSSPropertyWebkitPrintColorAdjust:
2913             return cssValuePool.createValue(style->printColorAdjust());
2914         case CSSPropertyWebkitColumnAxis:
2915             return cssValuePool.createValue(style->columnAxis());
2916         case CSSPropertyColumnCount:
2917             if (style->hasAutoColumnCount())
2918                 return cssValuePool.createIdentifierValue(CSSValueAuto);
2919             return cssValuePool.createValue(style->columnCount(), CSSPrimitiveValue::CSS_NUMBER);
2920         case CSSPropertyColumnFill:
2921             return cssValuePool.createValue(style->columnFill());
2922         case CSSPropertyColumnGap:
2923             if (style->hasNormalColumnGap())
2924                 return cssValuePool.createIdentifierValue(CSSValueNormal);
2925             return zoomAdjustedPixelValue(style->columnGap(), *style);
2926         case CSSPropertyWebkitColumnProgression:
2927             return cssValuePool.createValue(style->columnProgression());
2928         case CSSPropertyColumnRuleColor:
2929             return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyOutlineColor)) : currentColorOrValidColor(style, style->columnRuleColor());
2930         case CSSPropertyColumnRuleStyle:
2931             return cssValuePool.createValue(style->columnRuleStyle());
2932         case CSSPropertyColumnRuleWidth:
2933             return zoomAdjustedPixelValue(style->columnRuleWidth(), *style);
2934         case CSSPropertyColumnSpan:
2935             return cssValuePool.createIdentifierValue(style->columnSpan() ? CSSValueAll : CSSValueNone);
2936         case CSSPropertyWebkitColumnBreakAfter:
2937             return cssValuePool.createValue(convertToColumnBreak(style->breakAfter()));
2938         case CSSPropertyWebkitColumnBreakBefore:
2939             return cssValuePool.createValue(convertToColumnBreak(style->breakBefore()));
2940         case CSSPropertyWebkitColumnBreakInside:
2941             return cssValuePool.createValue(convertToColumnBreak(style->breakInside()));
2942         case CSSPropertyColumnWidth:
2943             if (style->hasAutoColumnWidth())
2944                 return cssValuePool.createIdentifierValue(CSSValueAuto);
2945             return zoomAdjustedPixelValue(style->columnWidth(), *style);
2946         case CSSPropertyTabSize:
2947             return cssValuePool.createValue(style->tabSize(), CSSPrimitiveValue::CSS_NUMBER);
2948 #if ENABLE(CSS_REGIONS)
2949         case CSSPropertyWebkitRegionBreakAfter:
2950             return cssValuePool.createValue(convertToRegionBreak(style->breakAfter()));
2951         case CSSPropertyWebkitRegionBreakBefore:
2952             return cssValuePool.createValue(convertToRegionBreak(style->breakBefore()));
2953         case CSSPropertyWebkitRegionBreakInside:
2954             return cssValuePool.createValue(convertToRegionBreak(style->breakInside()));
2955 #endif
2956         case CSSPropertyCursor: {
2957             RefPtr<CSSValueList> list;
2958             auto* cursors = style->cursors();
2959             if (cursors && cursors->size() > 0) {
2960                 list = CSSValueList::createCommaSeparated();
2961                 for (unsigned i = 0; i < cursors->size(); ++i)
2962                     if (StyleImage* image = cursors->at(i).image())
2963                         list->append(image->cssValue());
2964             }
2965             auto value = cssValuePool.createValue(style->cursor());
2966             if (list) {
2967                 list->append(WTFMove(value));
2968                 return list;
2969             }
2970             return WTFMove(value);
2971         }
2972 #if ENABLE(CURSOR_VISIBILITY)
2973         case CSSPropertyWebkitCursorVisibility:
2974             return cssValuePool.createValue(style->cursorVisibility());
2975 #endif
2976         case CSSPropertyDirection:
2977             return cssValuePool.createValue(style->direction());
2978         case CSSPropertyDisplay:
2979             return cssValuePool.createValue(style->display());
2980         case CSSPropertyEmptyCells:
2981             return cssValuePool.createValue(style->emptyCells());
2982         case CSSPropertyAlignContent:
2983             return valueForContentPositionAndDistributionWithOverflowAlignment(style->alignContent(), CSSValueStretch);
2984         case CSSPropertyAlignItems:
2985             return valueForItemPositionWithOverflowAlignment(style->alignItems());
2986         case CSSPropertyAlignSelf:
2987             return valueForItemPositionWithOverflowAlignment(style->alignSelf());
2988         case CSSPropertyFlex:
2989             return getCSSPropertyValuesForShorthandProperties(flexShorthand());
2990         case CSSPropertyFlexBasis:
2991             return cssValuePool.createValue(style->flexBasis(), *style);
2992         case CSSPropertyFlexDirection:
2993             return cssValuePool.createValue(style->flexDirection());
2994         case CSSPropertyFlexFlow:
2995             return getCSSPropertyValuesForShorthandProperties(flexFlowShorthand());
2996         case CSSPropertyFlexGrow:
2997             return cssValuePool.createValue(style->flexGrow());
2998         case CSSPropertyFlexShrink:
2999             return cssValuePool.createValue(style->flexShrink());
3000         case CSSPropertyFlexWrap:
3001             return cssValuePool.createValue(style->flexWrap());
3002         case CSSPropertyJustifyContent:
3003             return valueForContentPositionAndDistributionWithOverflowAlignment(style->justifyContent(), CSSValueFlexStart);
3004         case CSSPropertyJustifyItems:
3005             return valueForItemPositionWithOverflowAlignment(style->justifyItems().position() == ItemPositionAuto ? RenderStyle::initialDefaultAlignment() : style->justifyItems());
3006         case CSSPropertyJustifySelf:
3007             return valueForItemPositionWithOverflowAlignment(style->justifySelf());
3008         case CSSPropertyPlaceContent:
3009             return getCSSPropertyValuesForShorthandProperties(placeContentShorthand());
3010         case CSSPropertyPlaceItems:
3011             return getCSSPropertyValuesForShorthandProperties(placeItemsShorthand());
3012         case CSSPropertyPlaceSelf:
3013             return getCSSPropertyValuesForShorthandProperties(placeSelfShorthand());
3014         case CSSPropertyOrder:
3015             return cssValuePool.createValue(style->order(), CSSPrimitiveValue::CSS_NUMBER);
3016         case CSSPropertyFloat:
3017             if (style->display() != NONE && style->hasOutOfFlowPosition())
3018                 return cssValuePool.createIdentifierValue(CSSValueNone);
3019             return cssValuePool.createValue(style->floating());
3020         case CSSPropertyFont: {
3021             auto computedFont = fontShorthandValueForSelectionProperties(style->fontDescription());
3022             computedFont->size = fontSizeFromStyle(*style);
3023             computedFont->lineHeight = lineHeightFromStyle(*style);
3024             computedFont->family = fontFamilyListFromStyle(*style);
3025             return WTFMove(computedFont);
3026         }
3027         case CSSPropertyFontFamily:
3028             return fontFamilyFromStyle(*style);
3029         case CSSPropertyFontSize:
3030             return fontSizeFromStyle(*style);
3031         case CSSPropertyFontStyle:
3032             return fontStyleFromStyle(*style);
3033         case CSSPropertyFontStretch:
3034             return fontStretchFromStyle(*style);
3035         case CSSPropertyFontVariant:
3036             return fontVariantFromStyle(*style);
3037         case CSSPropertyFontWeight:
3038             return fontWeightFromStyle(*style);
3039         case CSSPropertyFontSynthesis:
3040             return fontSynthesisFromStyle(*style);
3041         case CSSPropertyFontFeatureSettings: {
3042             const FontFeatureSettings& featureSettings = style->fontDescription().featureSettings();
3043             if (!featureSettings.size())
3044                 return cssValuePool.createIdentifierValue(CSSValueNormal);
3045             auto list = CSSValueList::createCommaSeparated();
3046             for (auto& feature : featureSettings)
3047                 list->append(CSSFontFeatureValue::create(FontTag(feature.tag()), feature.value()));
3048             return WTFMove(list);
3049         }
3050 #if ENABLE(VARIATION_FONTS)
3051         case CSSPropertyFontVariationSettings: {
3052             const FontVariationSettings& variationSettings = style->fontDescription().variationSettings();
3053             if (variationSettings.isEmpty())
3054                 return cssValuePool.createIdentifierValue(CSSValueNormal);
3055             auto list = CSSValueList::createCommaSeparated();
3056             for (auto& feature : variationSettings)
3057                 list->append(CSSFontVariationValue::create(feature.tag(), feature.value()));
3058             return WTFMove(list);
3059         }
3060         case CSSPropertyFontOpticalSizing:
3061             return cssValuePool.createValue(style->fontDescription().opticalSizing());
3062 #endif
3063         case CSSPropertyGridAutoFlow: {
3064             auto list = CSSValueList::createSpaceSeparated();
3065             ASSERT(style->isGridAutoFlowDirectionRow() || style->isGridAutoFlowDirectionColumn());
3066             if (style->isGridAutoFlowDirectionRow())
3067                 list->append(cssValuePool.createIdentifierValue(CSSValueRow));
3068             else
3069                 list->append(cssValuePool.createIdentifierValue(CSSValueColumn));
3070
3071             if (style->isGridAutoFlowAlgorithmDense())
3072                 list->append(cssValuePool.createIdentifierValue(CSSValueDense));
3073
3074             return WTFMove(list);
3075         }
3076
3077         // Specs mention that getComputedStyle() should return the used value of the property instead of the computed
3078         // one for grid-template-{rows|columns} but not for the grid-auto-{rows|columns} as things like
3079         // grid-auto-columns: 2fr; cannot be resolved to a value in pixels as the '2fr' means very different things
3080         // depending on the size of the explicit grid or the number of implicit tracks added to the grid. See
3081         // http://lists.w3.org/Archives/Public/www-style/2013Nov/0014.html
3082         case CSSPropertyGridAutoColumns:
3083             return valueForGridTrackSizeList(ForColumns, *style);
3084         case CSSPropertyGridAutoRows:
3085             return valueForGridTrackSizeList(ForRows, *style);
3086
3087         case CSSPropertyGridTemplateColumns:
3088             return valueForGridTrackList(ForColumns, renderer, *style);
3089         case CSSPropertyGridTemplateRows:
3090             return valueForGridTrackList(ForRows, renderer, *style);
3091
3092         case CSSPropertyGridColumnStart:
3093             return valueForGridPosition(style->gridItemColumnStart());
3094         case CSSPropertyGridColumnEnd:
3095             return valueForGridPosition(style->gridItemColumnEnd());
3096         case CSSPropertyGridRowStart:
3097             return valueForGridPosition(style->gridItemRowStart());
3098         case CSSPropertyGridRowEnd:
3099             return valueForGridPosition(style->gridItemRowEnd());
3100         case CSSPropertyGridArea:
3101             return getCSSPropertyValuesForGridShorthand(gridAreaShorthand());
3102         case CSSPropertyGridTemplate:
3103             return getCSSPropertyValuesForGridShorthand(gridTemplateShorthand());
3104         case CSSPropertyGrid:
3105             return getCSSPropertyValuesForGridShorthand(gridShorthand());
3106         case CSSPropertyGridColumn:
3107             return getCSSPropertyValuesForGridShorthand(gridColumnShorthand());
3108         case CSSPropertyGridRow:
3109             return getCSSPropertyValuesForGridShorthand(gridRowShorthand());
3110         case CSSPropertyGridTemplateAreas:
3111             if (!style->namedGridAreaRowCount()) {
3112                 ASSERT(!style->namedGridAreaColumnCount());
3113                 return cssValuePool.createIdentifierValue(CSSValueNone);
3114             }
3115             return CSSGridTemplateAreasValue::create(style->namedGridArea(), style->namedGridAreaRowCount(), style->namedGridAreaColumnCount());
3116         case CSSPropertyGridColumnGap:
3117             return zoomAdjustedPixelValueForLength(style->gridColumnGap(), *style);
3118         case CSSPropertyGridRowGap:
3119             return zoomAdjustedPixelValueForLength(style->gridRowGap(), *style);
3120         case CSSPropertyGridGap:
3121             return getCSSPropertyValuesForGridShorthand(gridGapShorthand());
3122         case CSSPropertyHeight:
3123             if (renderer && !renderer->isRenderSVGModelObject()) {
3124                 // According to http://www.w3.org/TR/CSS2/visudet.html#the-height-property,
3125                 // the "height" property does not apply for non-replaced inline elements.
3126                 if (isNonReplacedInline(*renderer))
3127                     return cssValuePool.createIdentifierValue(CSSValueAuto);
3128                 return zoomAdjustedPixelValue(sizingBox(*renderer).height(), *style);
3129             }
3130             return zoomAdjustedPixelValueForLength(style->height(), *style);
3131         case CSSPropertyWebkitHyphens:
3132             return cssValuePool.createValue(style->hyphens());
3133         case CSSPropertyWebkitHyphenateCharacter:
3134             if (style->hyphenationString().isNull())
3135                 return cssValuePool.createIdentifierValue(CSSValueAuto);
3136             return cssValuePool.createValue(style->hyphenationString(), CSSPrimitiveValue::CSS_STRING);
3137         case CSSPropertyWebkitHyphenateLimitAfter:
3138             if (style->hyphenationLimitAfter() < 0)
3139                 return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
3140             return CSSPrimitiveValue::create(style->hyphenationLimitAfter(), CSSPrimitiveValue::CSS_NUMBER);
3141         case CSSPropertyWebkitHyphenateLimitBefore:
3142             if (style->hyphenationLimitBefore() < 0)
3143                 return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
3144             return CSSPrimitiveValue::create(style->hyphenationLimitBefore(), CSSPrimitiveValue::CSS_NUMBER);
3145         case CSSPropertyWebkitHyphenateLimitLines:
3146             if (style->hyphenationLimitLines() < 0)
3147                 return CSSPrimitiveValue::createIdentifier(CSSValueNoLimit);
3148             return CSSPrimitiveValue::create(style->hyphenationLimitLines(), CSSPrimitiveValue::CSS_NUMBER);
3149         case CSSPropertyWebkitBorderFit:
3150             if (style->borderFit() == BorderFitBorder)
3151                 return cssValuePool.createIdentifierValue(CSSValueBorder);
3152             return cssValuePool.createIdentifierValue(CSSValueLines);
3153 #if ENABLE(CSS_IMAGE_ORIENTATION)
3154         case CSSPropertyImageOrientation:
3155             return cssValuePool.createValue(style->imageOrientation());
3156 #endif
3157         case CSSPropertyImageRendering:
3158             return CSSPrimitiveValue::create(style->imageRendering());
3159 #if ENABLE(CSS_IMAGE_RESOLUTION)
3160         case CSSPropertyImageResolution:
3161             return cssValuePool.createValue(style->imageResolution(), CSSPrimitiveValue::CSS_DPPX);
3162 #endif
3163         case CSSPropertyLeft:
3164             return positionOffsetValue(*style, CSSPropertyLeft, renderer);
3165         case CSSPropertyLetterSpacing:
3166             if (!style->letterSpacing())
3167                 return cssValuePool.createIdentifierValue(CSSValueNormal);
3168             return zoomAdjustedPixelValue(style->letterSpacing(), *style);
3169         case CSSPropertyWebkitLineClamp:
3170             if (style->lineClamp().isNone())
3171                 return cssValuePool.createIdentifierValue(CSSValueNone);
3172             return cssValuePool.createValue(style->lineClamp().value(), style->lineClamp().isPercentage() ? CSSPrimitiveValue::CSS_PERCENTAGE : CSSPrimitiveValue::CSS_NUMBER);
3173         case CSSPropertyLineHeight:
3174             return lineHeightFromStyle(*style);
3175         case CSSPropertyListStyleImage:
3176             if (style->listStyleImage())
3177                 return style->listStyleImage()->cssValue();
3178             return cssValuePool.createIdentifierValue(CSSValueNone);
3179         case CSSPropertyListStylePosition:
3180             return cssValuePool.createValue(style->listStylePosition());
3181         case CSSPropertyListStyleType:
3182             return cssValuePool.createValue(style->listStyleType());
3183         case CSSPropertyWebkitLocale:
3184             if (style->locale().isNull())
3185                 return cssValuePool.createIdentifierValue(CSSValueAuto);
3186             return cssValuePool.createValue(style->locale(), CSSPrimitiveValue::CSS_STRING);
3187         case CSSPropertyMarginTop:
3188             return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::marginTop, &RenderBoxModelObject::marginTop>(*style, renderer);
3189         case CSSPropertyMarginRight: {
3190             Length marginRight = style->marginRight();
3191             if (marginRight.isFixed() || !is<RenderBox>(renderer))
3192                 return zoomAdjustedPixelValueForLength(marginRight, *style);
3193             float value;
3194             if (marginRight.isPercentOrCalculated()) {
3195                 // RenderBox gives a marginRight() that is the distance between the right-edge of the child box
3196                 // and the right-edge of the containing box, when display == BLOCK. Let's calculate the absolute
3197                 // value of the specified margin-right % instead of relying on RenderBox's marginRight() value.
3198                 value = minimumValueForLength(marginRight, downcast<RenderBox>(*renderer).containingBlockLogicalWidthForContent());
3199             } else
3200                 value = downcast<RenderBox>(*renderer).marginRight();
3201             return zoomAdjustedPixelValue(value, *style);
3202         }
3203         case CSSPropertyMarginBottom:
3204             return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::marginBottom, &RenderBoxModelObject::marginBottom>(*style, renderer);
3205         case CSSPropertyMarginLeft:
3206             return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::marginLeft, &RenderBoxModelObject::marginLeft>(*style, renderer);
3207         case CSSPropertyWebkitMarqueeDirection:
3208             return cssValuePool.createValue(style->marqueeDirection());
3209         case CSSPropertyWebkitMarqueeIncrement:
3210             return cssValuePool.createValue(style->marqueeIncrement());
3211         case CSSPropertyWebkitMarqueeRepetition:
3212             if (style->marqueeLoopCount() < 0)
3213                 return cssValuePool.createIdentifierValue(CSSValueInfinite);
3214             return cssValuePool.createValue(style->marqueeLoopCount(), CSSPrimitiveValue::CSS_NUMBER);
3215         case CSSPropertyWebkitMarqueeStyle:
3216             return cssValuePool.createValue(style->marqueeBehavior());
3217         case CSSPropertyWebkitUserModify:
3218             return cssValuePool.createValue(style->userModify());
3219         case CSSPropertyMaxHeight: {
3220             const Length& maxHeight = style->maxHeight();
3221             if (maxHeight.isUndefined())
3222                 return cssValuePool.createIdentifierValue(CSSValueNone);
3223             return zoomAdjustedPixelValueForLength(maxHeight, *style);
3224         }
3225         case CSSPropertyMaxWidth: {
3226             const Length& maxWidth = style->maxWidth();
3227             if (maxWidth.isUndefined())
3228                 return cssValuePool.createIdentifierValue(CSSValueNone);
3229             return zoomAdjustedPixelValueForLength(maxWidth, *style);
3230         }
3231         case CSSPropertyMinHeight:
3232             if (style->minHeight().isAuto()) {
3233                 if (isFlexOrGrid(styledElement->parentNode()))
3234                     return cssValuePool.createIdentifierValue(CSSValueAuto);
3235                 return zoomAdjustedPixelValue(0, *style);
3236             }
3237             return zoomAdjustedPixelValueForLength(style->minHeight(), *style);
3238         case CSSPropertyMinWidth:
3239             if (style->minWidth().isAuto()) {
3240                 if (isFlexOrGrid(styledElement->parentNode()))
3241                     return cssValuePool.createIdentifierValue(CSSValueAuto);
3242                 return zoomAdjustedPixelValue(0, *style);
3243             }
3244             return zoomAdjustedPixelValueForLength(style->minWidth(), *style);
3245         case CSSPropertyObjectFit:
3246             return cssValuePool.createValue(style->objectFit());
3247         case CSSPropertyObjectPosition: {
3248             auto list = CSSValueList::createSpaceSeparated();
3249             list->append(zoomAdjustedPixelValueForLength(style->objectPosition().x(), *style));
3250             list->append(zoomAdjustedPixelValueForLength(style->objectPosition().y(), *style));
3251             return WTFMove(list);
3252         }
3253         case CSSPropertyOpacity:
3254             return cssValuePool.createValue(style->opacity(), CSSPrimitiveValue::CSS_NUMBER);
3255         case CSSPropertyOrphans:
3256             if (style->hasAutoOrphans())
3257                 return cssValuePool.createIdentifierValue(CSSValueAuto);
3258             return cssValuePool.createValue(style->orphans(), CSSPrimitiveValue::CSS_NUMBER);
3259         case CSSPropertyOutlineColor:
3260             return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyOutlineColor)) : currentColorOrValidColor(style, style->outlineColor());
3261         case CSSPropertyOutlineOffset:
3262             return zoomAdjustedPixelValue(style->outlineOffset(), *style);
3263         case CSSPropertyOutlineStyle:
3264             if (style->outlineStyleIsAuto())
3265                 return cssValuePool.createIdentifierValue(CSSValueAuto);
3266             return cssValuePool.createValue(style->outlineStyle());
3267         case CSSPropertyOutlineWidth:
3268             return zoomAdjustedPixelValue(style->outlineWidth(), *style);
3269         case CSSPropertyOverflow:
3270             return cssValuePool.createValue(std::max(style->overflowX(), style->overflowY()));
3271         case CSSPropertyOverflowWrap:
3272             return cssValuePool.createValue(style->overflowWrap());
3273         case CSSPropertyOverflowX:
3274             return cssValuePool.createValue(style->overflowX());
3275         case CSSPropertyOverflowY:
3276             return cssValuePool.createValue(style->overflowY());
3277         case CSSPropertyPaddingTop:
3278             return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::paddingTop, &RenderBoxModelObject::computedCSSPaddingTop>(*style, renderer);
3279         case CSSPropertyPaddingRight:
3280             return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::paddingRight, &RenderBoxModelObject::computedCSSPaddingRight>(*style, renderer);
3281         case CSSPropertyPaddingBottom:
3282             return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::paddingBottom, &RenderBoxModelObject::computedCSSPaddingBottom>(*style, renderer);
3283         case CSSPropertyPaddingLeft:
3284             return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::paddingLeft, &RenderBoxModelObject::computedCSSPaddingLeft>(*style, renderer);
3285         case CSSPropertyPageBreakAfter:
3286             return cssValuePool.createValue(convertToPageBreak(style->breakAfter()));
3287         case CSSPropertyPageBreakBefore:
3288             return cssValuePool.createValue(convertToPageBreak(style->breakBefore()));
3289         case CSSPropertyPageBreakInside:
3290             return cssValuePool.createValue(convertToPageBreak(style->breakInside()));
3291         case CSSPropertyBreakAfter:
3292             return cssValuePool.createValue(style->breakAfter());
3293         case CSSPropertyBreakBefore:
3294             return cssValuePool.createValue(style->breakBefore());
3295         case CSSPropertyBreakInside:
3296             return cssValuePool.createValue(style->breakInside());
3297         case CSSPropertyHangingPunctuation:
3298             return hangingPunctuationToCSSValue(style->hangingPunctuation());
3299         case CSSPropertyPosition:
3300             return cssValuePool.createValue(style->position());
3301         case CSSPropertyRight:
3302             return positionOffsetValue(*style, CSSPropertyRight, renderer);
3303         case CSSPropertyWebkitRubyPosition:
3304             return cssValuePool.createValue(style->rubyPosition());
3305         case CSSPropertyTableLayout:
3306             return cssValuePool.createValue(style->tableLayout());
3307         case CSSPropertyTextAlign:
3308             return cssValuePool.createValue(style->textAlign());
3309         case CSSPropertyTextDecoration:
3310             return renderTextDecorationFlagsToCSSValue(style->textDecoration());
3311 #if ENABLE(CSS3_TEXT)
3312         case CSSPropertyWebkitTextAlignLast:
3313             return cssValuePool.createValue(style->textAlignLast());
3314         case CSSPropertyWebkitTextJustify:
3315             return cssValuePool.createValue(style->textJustify());
3316 #endif // CSS3_TEXT
3317         case CSSPropertyWebkitTextDecoration:
3318             return getCSSPropertyValuesForShorthandProperties(webkitTextDecorationShorthand());
3319         case CSSPropertyWebkitTextDecorationLine:
3320             return renderTextDecorationFlagsToCSSValue(style->textDecoration());
3321         case CSSPropertyWebkitTextDecorationStyle:
3322             return renderTextDecorationStyleFlagsToCSSValue(style->textDecorationStyle());
3323         case CSSPropertyWebkitTextDecorationColor:
3324             return currentColorOrValidColor(style, style->textDecorationColor());
3325         case CSSPropertyWebkitTextDecorationSkip:
3326             return renderTextDecorationSkipFlagsToCSSValue(style->textDecorationSkip());
3327         case CSSPropertyWebkitTextUnderlinePosition:
3328             return cssValuePool.createValue(style->textUnderlinePosition());
3329         case CSSPropertyWebkitTextDecorationsInEffect:
3330             return renderTextDecorationFlagsToCSSValue(style->textDecorationsInEffect());
3331         case CSSPropertyWebkitTextFillColor:
3332             return currentColorOrValidColor(style, style->textFillColor());
3333         case CSSPropertyWebkitTextEmphasisColor:
3334             return currentColorOrValidColor(style, style->textEmphasisColor());
3335         case CSSPropertyWebkitTextEmphasisPosition:
3336             return renderEmphasisPositionFlagsToCSSValue(style->textEmphasisPosition());
3337         case CSSPropertyWebkitTextEmphasisStyle:
3338             switch (style->textEmphasisMark()) {
3339             case TextEmphasisMarkNone:
3340                 return cssValuePool.createIdentifierValue(CSSValueNone);
3341             case TextEmphasisMarkCustom:
3342                 return cssValuePool.createValue(style->textEmphasisCustomMark(), CSSPrimitiveValue::CSS_STRING);
3343             case TextEmphasisMarkAuto:
3344                 ASSERT_NOT_REACHED();
3345 #if ASSERT_DISABLED
3346                 FALLTHROUGH;
3347 #endif
3348             case TextEmphasisMarkDot:
3349             case TextEmphasisMarkCircle:
3350             case TextEmphasisMarkDoubleCircle:
3351             case TextEmphasisMarkTriangle:
3352             case TextEmphasisMarkSesame:
3353                 auto list = CSSValueList::createSpaceSeparated();
3354                 list->append(cssValuePool.createValue(style->textEmphasisFill()));
3355                 list->append(cssValuePool.createValue(style->textEmphasisMark()));
3356                 return WTFMove(list);
3357             }
3358             RELEASE_ASSERT_NOT_REACHED();
3359         case CSSPropertyTextIndent: {
3360             // If CSS3_TEXT is disabled or text-indent has only one value(<length> | <percentage>),
3361             // getPropertyCSSValue() returns CSSValue.
3362             auto textIndent = zoomAdjustedPixelValueForLength(style->textIndent(), *style);
3363 #if ENABLE(CSS3_TEXT)
3364             // If CSS3_TEXT is enabled and text-indent has -webkit-each-line or -webkit-hanging,
3365             // getPropertyCSSValue() returns CSSValueList.
3366             if (style->textIndentLine() == TextIndentEachLine || style->textIndentType() == TextIndentHanging) {
3367                 auto list = CSSValueList::createSpaceSeparated();
3368                 list->append(WTFMove(textIndent));
3369                 if (style->textIndentLine() == TextIndentEachLine)
3370                     list->append(cssValuePool.createIdentifierValue(CSSValueWebkitEachLine));
3371                 if (style->textIndentType() == TextIndentHanging)
3372                     list->append(cssValuePool.createIdentifierValue(CSSValueWebkitHanging));
3373                 return WTFMove(list);
3374             }
3375 #endif
3376             return WTFMove(textIndent);
3377         }
3378         case CSSPropertyTextShadow:
3379             return valueForShadow(style->textShadow(), propertyID, *style);
3380         case CSSPropertyTextRendering:
3381             return cssValuePool.createValue(style->fontDescription().textRenderingMode());
3382         case CSSPropertyTextOverflow:
3383             if (style->textOverflow())
3384                 return cssValuePool.createIdentifierValue(CSSValueEllipsis);
3385             return cssValuePool.createIdentifierValue(CSSValueClip);
3386         case CSSPropertyWebkitTextSecurity:
3387             return cssValuePool.createValue(style->textSecurity());
3388 #if ENABLE(TEXT_AUTOSIZING)
3389         case CSSPropertyWebkitTextSizeAdjust:
3390             if (style->textSizeAdjust().isAuto())
3391                 return cssValuePool.createIdentifierValue(CSSValueAuto);
3392             if (style->textSizeAdjust().isNone())
3393                 return cssValuePool.createIdentifierValue(CSSValueNone);
3394             return CSSPrimitiveValue::create(style->textSizeAdjust().percentage(), CSSPrimitiveValue::CSS_PERCENTAGE);
3395 #endif
3396         case CSSPropertyWebkitTextStrokeColor:
3397             return currentColorOrValidColor(style, style->textStrokeColor());
3398         case CSSPropertyWebkitTextStrokeWidth:
3399             return zoomAdjustedPixelValue(style->textStrokeWidth(), *style);
3400         case CSSPropertyTextTransform:
3401             return cssValuePool.createValue(style->textTransform());
3402         case CSSPropertyTop:
3403             return positionOffsetValue(*style, CSSPropertyTop, renderer);
3404         case CSSPropertyUnicodeBidi:
3405             return cssValuePool.createValue(style->unicodeBidi());
3406         case CSSPropertyVerticalAlign:
3407             switch (style->verticalAlign()) {
3408                 case BASELINE:
3409                     return cssValuePool.createIdentifierValue(CSSValueBaseline);
3410                 case MIDDLE:
3411                     return cssValuePool.createIdentifierValue(CSSValueMiddle);
3412                 case SUB:
3413                     return cssValuePool.createIdentifierValue(CSSValueSub);
3414                 case SUPER:
3415                     return cssValuePool.createIdentifierValue(CSSValueSuper);
3416                 case TEXT_TOP:
3417                     return cssValuePool.createIdentifierValue(CSSValueTextTop);
3418                 case TEXT_BOTTOM:
3419                     return cssValuePool.createIdentifierValue(CSSValueTextBottom);
3420                 case TOP:
3421                     return cssValuePool.createIdentifierValue(CSSValueTop);
3422                 case BOTTOM:
3423                     return cssValuePool.createIdentifierValue(CSSValueBottom);
3424                 case BASELINE_MIDDLE:
3425                     return cssValuePool.createIdentifierValue(CSSValueWebkitBaselineMiddle);
3426                 case LENGTH:
3427                     return cssValuePool.createValue(style->verticalAlignLength());
3428             }
3429             ASSERT_NOT_REACHED();
3430             return nullptr;
3431         case CSSPropertyVisibility:
3432             return cssValuePool.createValue(style->visibility());
3433         case CSSPropertyWhiteSpace:
3434             return cssValuePool.createValue(style->whiteSpace());
3435         case CSSPropertyWidows:
3436             if (style->hasAutoWidows())
3437                 return cssValuePool.createIdentifierValue(CSSValueAuto);
3438             return cssValuePool.createValue(style->widows(), CSSPrimitiveValue::CSS_NUMBER);
3439         case CSSPropertyWidth:
3440             if (renderer && !renderer->isRenderSVGModelObject()) {
3441                 // According to http://www.w3.org/TR/CSS2/visudet.html#the-width-property,
3442                 // the "width" property does not apply for non-replaced inline elements.
3443                 if (isNonReplacedInline(*renderer))
3444                     return cssValuePool.createIdentifierValue(CSSValueAuto);
3445                 return zoomAdjustedPixelValue(sizingBox(*renderer).width(), *style);
3446             }
3447             return zoomAdjustedPixelValueForLength(style->width(), *style);
3448         case CSSPropertyWillChange:
3449             return willChangePropertyValue(style->willChange());
3450         case CSSPropertyWordBreak:
3451             return cssValuePool.createValue(style->wordBreak());
3452         case CSSPropertyWordSpacing:
3453             return zoomAdjustedPixelValue(style->fontCascade().wordSpacing(), *style);
3454         case CSSPropertyWordWrap:
3455             return cssValuePool.createValue(style->overflowWrap());
3456         case CSSPropertyLineBreak:
3457             return cssValuePool.createValue(style->lineBreak());
3458         case CSSPropertyWebkitNbspMode:
3459             return cssValuePool.createValue(style->nbspMode());
3460         case CSSPropertyResize:
3461             return cssValuePool.createValue(style->resize());
3462         case CSSPropertyWebkitFontKerning:
3463             return cssValuePool.createValue(style->fontDescription().kerning());
3464         case CSSPropertyWebkitFontSmoothing:
3465             return cssValuePool.createValue(style->fontDescription().fontSmoothing());
3466         case CSSPropertyFontVariantLigatures:
3467             return fontVariantLigaturesPropertyValue(style->fontDescription().variantCommonLigatures(), style->fontDescription().variantDiscretionaryLigatures(), style->fontDescription().variantHistoricalLigatures(), style->fontDescription().variantContextualAlternates());
3468         case CSSPropertyFontVariantPosition:
3469             return fontVariantPositionPropertyValue(style->fontDescription().variantPosition());
3470         case CSSPropertyFontVariantCaps:
3471             return fontVariantCapsPropertyValue(style->fontDescription().variantCaps());
3472         case CSSPropertyFontVariantNumeric:
3473             return fontVariantNumericPropertyValue(style->fontDescription().variantNumericFigure(), style->fontDescription().variantNumericSpacing(), style->fontDescription().variantNumericFraction(), style->fontDescription().variantNumericOrdinal(), style->fontDescription().variantNumericSlashedZero());
3474         case CSSPropertyFontVariantAlternates:
3475             return fontVariantAlternatesPropertyValue(style->fontDescription().variantAlternates());
3476         case CSSPropertyFontVariantEastAsian:
3477             return fontVariantEastAsianPropertyValue(style->fontDescription().variantEastAsianVariant(), style->fontDescription().variantEastAsianWidth(), style->fontDescription().variantEastAsianRuby());
3478         case CSSPropertyZIndex:
3479             if (style->hasAutoZIndex())
3480                 return cssValuePool.createIdentifierValue(CSSValueAuto);
3481             return cssValuePool.createValue(style->zIndex(), CSSPrimitiveValue::CSS_NUMBER);
3482         case CSSPropertyZoom:
3483             return cssValuePool.createValue(style->zoom(), CSSPrimitiveValue::CSS_NUMBER);
3484         case CSSPropertyBoxSizing:
3485             if (style->boxSizing() == CONTENT_BOX)
3486                 return cssValuePool.createIdentifierValue(CSSValueContentBox);
3487             return cssValuePool.createIdentifierValue(CSSValueBorderBox);
3488 #if ENABLE(DASHBOARD_SUPPORT)
3489         case CSSPropertyWebkitDashboardRegion:
3490         {
3491             const Vector<StyleDashboardRegion>& regions = style->dashboardRegions();
3492             unsigned count = regions.size();
3493             if (count == 1 && regions[0].type == StyleDashboardRegion::None)
3494                 return cssValuePool.createIdentifierValue(CSSValueNone);
3495
3496             RefPtr<DashboardRegion> firstRegion;
3497             DashboardRegion* previousRegion = nullptr;
3498             for (unsigned i = 0; i < count; i++) {
3499                 auto region = DashboardRegion::create();
3500                 StyleDashboardRegion styleRegion = regions[i];
3501
3502                 region->m_label = styleRegion.label;
3503                 LengthBox offset = styleRegion.offset;
3504                 region->setTop(zoomAdjustedPixelValue(offset.top().value(), *style));
3505                 region->setRight(zoomAdjustedPixelValue(offset.right().value(), *style));
3506                 region->setBottom(zoomAdjustedPixelValue(offset.bottom().value(), *style));
3507                 region->setLeft(zoomAdjustedPixelValue(offset.left().value(), *style));
3508                 region->m_isRectangle = (styleRegion.type == StyleDashboardRegion::Rectangle);
3509                 region->m_isCircle = (styleRegion.type == StyleDashboardRegion::Circle);
3510
3511                 if (previousRegion)
3512                     previousRegion->m_next = region.copyRef();
3513                 else
3514                     firstRegion = region.copyRef();
3515                 previousRegion = region.ptr();
3516             }
3517             return cssValuePool.createValue(WTFMove(firstRegion));
3518         }
3519 #endif
3520         case CSSPropertyAnimationDelay:
3521             return delayValue(style->animations());
3522         case CSSPropertyAnimationDirection: {
3523             auto list = CSSValueList::createCommaSeparated();
3524             const AnimationList* t = style->animations();
3525             if (t) {
3526                 for (size_t i = 0; i < t->size(); ++i) {
3527                     switch (t->animation(i).direction()) {
3528                     case Animation::AnimationDirectionNormal:
3529                         list->append(cssValuePool.createIdentifierValue(CSSValueNormal));
3530                         break;
3531                     case Animation::AnimationDirectionAlternate:
3532                         list->append(cssValuePool.createIdentifierValue(CSSValueAlternate));
3533                         break;
3534                     case Animation::AnimationDirectionReverse:
3535                         list->append(cssValuePool.createIdentifierValue(CSSValueReverse));
3536                         break;
3537                     case Animation::AnimationDirectionAlternateReverse:
3538                         list->append(cssValuePool.createIdentifierValue(CSSValueAlternateReverse));
3539                         break;
3540                     }
3541                 }
3542             } else
3543                 list->append(cssValuePool.createIdentifierValue(CSSValueNormal));
3544             return WTFMove(list);
3545         }
3546         case CSSPropertyAnimationDuration:
3547             return durationValue(style->animations());
3548         case CSSPropertyAnimationFillMode: {
3549             auto list = CSSValueList::createCommaSeparated();
3550             const AnimationList* t = style->animations();
3551             if (t) {
3552                 for (size_t i = 0; i < t->size(); ++i) {
3553                     switch (t->animation(i).fillMode()) {
3554                     case AnimationFillModeNone:
3555                         list->append(cssValuePool.createIdentifierValue(CSSValueNone));
3556                         break;
3557                     case AnimationFillModeForwards:
3558                         list->append(cssValuePool.createIdentifierValue(CSSValueForwards));
3559                         break;
3560                     case AnimationFillModeBackwards:
3561                         list->append(cssValuePool.createIdentifierValue(CSSValueBackwards));
3562                         break;
3563                     case AnimationFillModeBoth:
3564                         list->append(cssValuePool.createIdentifierValue(CSSValueBoth));
3565                         break;
3566                     }
3567                 }
3568             } else
3569                 list->append(cssValuePool.createIdentifierValue(CSSValueNone));
3570             return WTFMove(list);
3571         }
3572         case CSSPropertyAnimationIterationCount: {
3573             auto list = CSSValueList::createCommaSeparated();
3574             const AnimationList* t = style->animations();
3575             if (t) {
3576                 for (size_t i = 0; i < t->size(); ++i) {
3577                     double iterationCount = t->animation(i).iterationCount();
3578                     if (iterationCount == Animation::IterationCountInfinite)
3579                         list->append(cssValuePool.createIdentifierValue(CSSValueInfinite));
3580                     else
3581                         list->append(cssValuePool.createValue(iterationCount, CSSPrimitiveValue::CSS_NUMBER));
3582                 }
3583             } else
3584                 list->append(cssValuePool.createValue(Animation::initialIterationCount(), CSSPrimitiveValue::CSS_NUMBER));
3585             return WTFMove(list);
3586         }
3587         case CSSPropertyAnimationName: {
3588             auto list = CSSValueList::createCommaSeparated();
3589             const AnimationList* t = style->animations();
3590             if (t) {
3591                 for (size_t i = 0; i < t->size(); ++i)
3592                     list->append(cssValuePool.createValue(t->animation(i).name(), CSSPrimitiveValue::CSS_STRING));
3593             } else
3594                 list->append(cssValuePool.createIdentifierValue(CSSValueNone));
3595             return WTFMove(list);
3596         }
3597         case CSSPropertyAnimationPlayState: {
3598             auto list = CSSValueList::createCommaSeparated();
3599             const AnimationList* t = style->animations();
3600             if (t) {
3601                 for (size_t i = 0; i < t->size(); ++i) {
3602                     int prop = t->animation(i).playState();
3603                     if (prop == AnimPlayStatePlaying)
3604                         list->append(cssValuePool.createIdentifierValue(CSSValueRunning));
3605                     else
3606                         list->append(cssValuePool.createIdentifierValue(CSSValuePaused));
3607                 }
3608             } else
3609                 list->append(cssValuePool.createIdentifierValue(CSSValueRunning));
3610             return WTFMove(list);
3611         }
3612         case CSSPropertyAnimationTimingFunction:
3613             return timingFunctionValue(style->animations());
3614 #if ENABLE(CSS_ANIMATIONS_LEVEL_2)
3615         case CSSPropertyWebkitAnimationTrigger:
3616             return animationTriggerValue(style->animations(), *style);
3617 #endif
3618         case CSSPropertyWebkitAppearance:
3619             return cssValuePool.createValue(style->appearance());
3620         case CSSPropertyWebkitAspectRatio:
3621             if (style->aspectRatioType() == AspectRatioAuto)
3622                 return cssValuePool.createIdentifierValue(CSSValueAuto);
3623             if (style->aspectRatioType() == AspectRatioFromDimensions)
3624                 return cssValuePool.createIdentifierValue(CSSValueFromDimensions);
3625             if (style->aspectRatioType() == AspectRatioFromIntrinsic)
3626                 return cssValuePool.createIdentifierValue(CSSValueFromIntrinsic);
3627             return CSSAspectRatioValue::create(style->aspectRatioNumerator(), style->aspectRatioDenominator());
3628         case CSSPropertyWebkitBackfaceVisibility:
3629             return cssValuePool.createIdentifierValue((style->backfaceVisibility() == BackfaceVisibilityHidden) ? CSSValueHidden : CSSValueVisible);
3630         case CSSPropertyWebkitBorderImage:
3631             return valueForNinePieceImage(style->borderImage());
3632         case CSSPropertyBorderImageOutset:
3633             return valueForNinePieceImageQuad(style->borderImage().outset());
3634         case CSSPropertyBorderImageRepeat:
3635             return valueForNinePieceImageRepeat(style->borderImage());
3636         case CSSPropertyBorderImageSlice:
3637             return valueForNinePieceImageSlice(style->borderImage());
3638         case CSSPropertyBorderImageWidth:
3639             return valueForNinePieceImageQuad(style->borderImage().borderSlices());
3640         case CSSPropertyWebkitMaskBoxImage:
3641             return valueForNinePieceImage(style->maskBoxImage());
3642         case CSSPropertyWebkitMaskBoxImageOutset:
3643             return valueForNinePieceImageQuad(style->maskBoxImage().outset());
3644         case CSSPropertyWebkitMaskBoxImageRepeat:
3645             return valueForNinePieceImageRepeat(style->maskBoxImage());
3646         case CSSPropertyWebkitMaskBoxImageSlice:
3647             return valueForNinePieceImageSlice(style->maskBoxImage());
3648         case CSSPropertyWebkitMaskBoxImageWidth:
3649             return valueForNinePieceImageQuad(style->maskBoxImage().borderSlices());
3650         case CSSPropertyWebkitMaskBoxImageSource:
3651             if (style->maskBoxImageSource())
3652                 return style->maskBoxImageSource()->cssValue();
3653             return cssValuePool.createIdentifierValue(CSSValueNone);
3654         case CSSPropertyWebkitFontSizeDelta:
3655             // Not a real style property -- used by the editing engine -- so has no computed value.
3656             break;
3657         case CSSPropertyWebkitInitialLetter: {
3658             auto drop = !style->initialLetterDrop() ? cssValuePool.createIdentifierValue(CSSValueNormal) : cssValuePool.createValue(style->initialLetterDrop(), CSSPrimitiveValue::CSS_NUMBER);
3659             auto size = !style->initialLetterHeight() ? cssValuePool.createIdentifierValue(CSSValueNormal) : cssValuePool.createValue(style->initialLetterHeight(), CSSPrimitiveValue::CSS_NUMBER);
3660             return cssValuePool.createValue(Pair::create(WTFMove(drop), WTFMove(size)));
3661         }
3662         case CSSPropertyWebkitMarginBottomCollapse:
3663         case CSSPropertyWebkitMarginAfterCollapse:
3664             return cssValuePool.createValue(style->marginAfterCollapse());
3665         case CSSPropertyWebkitMarginTopCollapse:
3666         case CSSPropertyWebkitMarginBeforeCollapse:
3667             return cssValuePool.createValue(style->marginBeforeCollapse());
3668 #if ENABLE(ACCELERATED_OVERFLOW_SCROLLING)
3669         case CSSPropertyWebkitOverflowScrolling:
3670             if (!style->useTouchOverflowScrolling())
3671                 return cssValuePool.createIdentifierValue(CSSValueAuto);
3672             return cssValuePool.createIdentifierValue(CSSValueTouch);
3673 #endif
3674         case CSSPropertyPerspective:
3675             if (!style->hasPerspective())
3676                 return cssValuePool.createIdentifierValue(CSSValueNone);
3677             return zoomAdjustedPixelValue(style->perspective(), *style);
3678         case CSSPropertyPerspectiveOrigin: {
3679             auto list = CSSValueList::createSpaceSeparated();
3680             if (renderer) {
3681                 LayoutRect box;
3682                 if (is<RenderBox>(*renderer))
3683                     box = downcast<RenderBox>(*renderer).borderBoxRect();
3684
3685                 list->append(zoomAdjustedPixelValue(minimumValueForLength(style->perspectiveOriginX(), box.width()), *style));
3686                 list->append(zoomAdjustedPixelValue(minimumValueForLength(style->perspectiveOriginY(), box.height()), *style));