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