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