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