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