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