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