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