Replace WTF::move with WTFMove
[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().computedPixelSize(), *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> fillRepeatToCSSValue(EFillRepeat xRepeat, EFillRepeat yRepeat)
1699 {
1700     // For backwards compatibility, if both values are equal, just return one of them. And
1701     // if the two values are equivalent to repeat-x or repeat-y, just return the shorthand.
1702     auto& cssValuePool = CSSValuePool::singleton();
1703     if (xRepeat == yRepeat)
1704         return cssValuePool.createValue(xRepeat);
1705     if (xRepeat == RepeatFill && yRepeat == NoRepeatFill)
1706         return cssValuePool.createIdentifierValue(CSSValueRepeatX);
1707     if (xRepeat == NoRepeatFill && yRepeat == RepeatFill)
1708         return cssValuePool.createIdentifierValue(CSSValueRepeatY);
1709
1710     auto list = CSSValueList::createSpaceSeparated();
1711     list.get().append(cssValuePool.createValue(xRepeat));
1712     list.get().append(cssValuePool.createValue(yRepeat));
1713     return WTFMove(list);
1714 }
1715
1716 static Ref<CSSValue> fillSourceTypeToCSSValue(EMaskSourceType type)
1717 {
1718     switch (type) {
1719     case MaskAlpha:
1720         return CSSValuePool::singleton().createValue(CSSValueAlpha);
1721     default:
1722         ASSERT(type == MaskLuminance);
1723         return CSSValuePool::singleton().createValue(CSSValueLuminance);
1724     }
1725 }
1726
1727 static Ref<CSSValue> fillSizeToCSSValue(const FillSize& fillSize, const RenderStyle& style)
1728 {
1729     if (fillSize.type == Contain)
1730         return CSSValuePool::singleton().createIdentifierValue(CSSValueContain);
1731
1732     if (fillSize.type == Cover)
1733         return CSSValuePool::singleton().createIdentifierValue(CSSValueCover);
1734
1735     if (fillSize.size.height().isAuto())
1736         return zoomAdjustedPixelValueForLength(fillSize.size.width(), style);
1737
1738     auto list = CSSValueList::createSpaceSeparated();
1739     list.get().append(zoomAdjustedPixelValueForLength(fillSize.size.width(), style));
1740     list.get().append(zoomAdjustedPixelValueForLength(fillSize.size.height(), style));
1741     return WTFMove(list);
1742 }
1743
1744 static Ref<CSSValue> altTextToCSSValue(const RenderStyle* style)
1745 {
1746     return CSSValuePool::singleton().createValue(style->contentAltText(), CSSPrimitiveValue::CSS_STRING);
1747 }
1748     
1749 static Ref<CSSValueList> contentToCSSValue(const RenderStyle* style)
1750 {
1751     auto& cssValuePool = CSSValuePool::singleton();
1752     auto list = CSSValueList::createSpaceSeparated();
1753     for (const ContentData* contentData = style->contentData(); contentData; contentData = contentData->next()) {
1754         if (is<CounterContentData>(*contentData))
1755             list.get().append(cssValuePool.createValue(downcast<CounterContentData>(*contentData).counter().identifier(), CSSPrimitiveValue::CSS_COUNTER_NAME));
1756         else if (is<ImageContentData>(*contentData))
1757             list.get().append(*downcast<ImageContentData>(*contentData).image().cssValue());
1758         else if (is<TextContentData>(*contentData))
1759             list.get().append(cssValuePool.createValue(downcast<TextContentData>(*contentData).text(), CSSPrimitiveValue::CSS_STRING));
1760     }
1761     if (style->hasFlowFrom())
1762         list.get().append(cssValuePool.createValue(style->regionThread(), CSSPrimitiveValue::CSS_STRING));
1763     return list;
1764 }
1765
1766 static RefPtr<CSSValue> counterToCSSValue(const RenderStyle* style, CSSPropertyID propertyID)
1767 {
1768     const CounterDirectiveMap* map = style->counterDirectives();
1769     if (!map)
1770         return nullptr;
1771
1772     auto& cssValuePool = CSSValuePool::singleton();
1773     RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
1774     for (CounterDirectiveMap::const_iterator it = map->begin(); it != map->end(); ++it) {
1775         list->append(cssValuePool.createValue(it->key, CSSPrimitiveValue::CSS_STRING));
1776         short number = propertyID == CSSPropertyCounterIncrement ? it->value.incrementValue() : it->value.resetValue();
1777         list->append(cssValuePool.createValue((double)number, CSSPrimitiveValue::CSS_NUMBER));
1778     }
1779     return list.release();
1780 }
1781
1782 static void logUnimplementedPropertyID(CSSPropertyID propertyID)
1783 {
1784     static NeverDestroyed<HashSet<CSSPropertyID>> propertyIDSet;
1785     if (!propertyIDSet.get().add(propertyID).isNewEntry)
1786         return;
1787
1788     LOG_ERROR("WebKit does not yet implement getComputedStyle for '%s'.", getPropertyName(propertyID));
1789 }
1790
1791 static Ref<CSSValueList> fontFamilyFromStyle(RenderStyle* style)
1792 {
1793     auto list = CSSValueList::createCommaSeparated();
1794     for (unsigned i = 0; i < style->fontCascade().familyCount(); ++i)
1795         list.get().append(valueForFamily(style->fontCascade().familyAt(i)));
1796     return list;
1797 }
1798
1799 static Ref<CSSPrimitiveValue> lineHeightFromStyle(RenderStyle& style)
1800 {
1801     Length length = style.lineHeight();
1802     if (length.isNegative()) // If true, line-height not set; use the font's line spacing.
1803         return zoomAdjustedPixelValue(style.fontMetrics().floatLineSpacing(), style);
1804     if (length.isPercent()) {
1805         // This is imperfect, because it doesn't include the zoom factor and the real computation
1806         // for how high to be in pixels does include things like minimum font size and the zoom factor.
1807         // On the other hand, since font-size doesn't include the zoom factor, we really can't do
1808         // that here either.
1809         return zoomAdjustedPixelValue(static_cast<int>(length.percent() * style.fontDescription().specifiedSize()) / 100, style);
1810     }
1811     return zoomAdjustedPixelValue(floatValueForLength(length, 0), style);
1812 }
1813
1814 static Ref<CSSPrimitiveValue> fontSizeFromStyle(RenderStyle& style)
1815 {
1816     return zoomAdjustedPixelValue(style.fontDescription().computedPixelSize(), style);
1817 }
1818
1819 static Ref<CSSPrimitiveValue> fontStyleFromStyle(RenderStyle* style)
1820 {
1821     if (style->fontDescription().italic())
1822         return CSSValuePool::singleton().createIdentifierValue(CSSValueItalic);
1823     return CSSValuePool::singleton().createIdentifierValue(CSSValueNormal);
1824 }
1825
1826 static Ref<CSSValue> fontVariantFromStyle(RenderStyle* style)
1827 {
1828     if (style->fontDescription().variantSettings().isAllNormal())
1829         return CSSValuePool::singleton().createIdentifierValue(CSSValueNormal);
1830
1831     auto list = CSSValueList::createSpaceSeparated();
1832
1833     switch (style->fontDescription().variantCommonLigatures()) {
1834     case FontVariantLigatures::Normal:
1835         break;
1836     case FontVariantLigatures::Yes:
1837         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueCommonLigatures));
1838         break;
1839     case FontVariantLigatures::No:
1840         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueNoCommonLigatures));
1841         break;
1842     }
1843
1844     switch (style->fontDescription().variantDiscretionaryLigatures()) {
1845     case FontVariantLigatures::Normal:
1846         break;
1847     case FontVariantLigatures::Yes:
1848         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueDiscretionaryLigatures));
1849         break;
1850     case FontVariantLigatures::No:
1851         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueNoDiscretionaryLigatures));
1852         break;
1853     }
1854
1855     switch (style->fontDescription().variantHistoricalLigatures()) {
1856     case FontVariantLigatures::Normal:
1857         break;
1858     case FontVariantLigatures::Yes:
1859         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueHistoricalLigatures));
1860         break;
1861     case FontVariantLigatures::No:
1862         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueNoHistoricalLigatures));
1863         break;
1864     }
1865
1866     switch (style->fontDescription().variantContextualAlternates()) {
1867     case FontVariantLigatures::Normal:
1868         break;
1869     case FontVariantLigatures::Yes:
1870         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueContextual));
1871         break;
1872     case FontVariantLigatures::No:
1873         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueNoContextual));
1874         break;
1875     }
1876
1877     switch (style->fontDescription().variantPosition()) {
1878     case FontVariantPosition::Normal:
1879         break;
1880     case FontVariantPosition::Subscript:
1881         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueSub));
1882         break;
1883     case FontVariantPosition::Superscript:
1884         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueSuper));
1885         break;
1886     }
1887
1888     switch (style->fontDescription().variantCaps()) {
1889     case FontVariantCaps::Normal:
1890         break;
1891     case FontVariantCaps::Small:
1892         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueSmallCaps));
1893         break;
1894     case FontVariantCaps::AllSmall:
1895         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueAllSmallCaps));
1896         break;
1897     case FontVariantCaps::Petite:
1898         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValuePetiteCaps));
1899         break;
1900     case FontVariantCaps::AllPetite:
1901         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueAllPetiteCaps));
1902         break;
1903     case FontVariantCaps::Unicase:
1904         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueUnicase));
1905         break;
1906     case FontVariantCaps::Titling:
1907         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueTitlingCaps));
1908         break;
1909     }
1910
1911     switch (style->fontDescription().variantNumericFigure()) {
1912     case FontVariantNumericFigure::Normal:
1913         break;
1914     case FontVariantNumericFigure::LiningNumbers:
1915         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueLiningNums));
1916         break;
1917     case FontVariantNumericFigure::OldStyleNumbers:
1918         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueOldstyleNums));
1919         break;
1920     }
1921
1922     switch (style->fontDescription().variantNumericSpacing()) {
1923     case FontVariantNumericSpacing::Normal:
1924         break;
1925     case FontVariantNumericSpacing::ProportionalNumbers:
1926         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueProportionalNums));
1927         break;
1928     case FontVariantNumericSpacing::TabularNumbers:
1929         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueTabularNums));
1930         break;
1931     }
1932
1933     switch (style->fontDescription().variantNumericFraction()) {
1934     case FontVariantNumericFraction::Normal:
1935         break;
1936     case FontVariantNumericFraction::DiagonalFractions:
1937         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueDiagonalFractions));
1938         break;
1939     case FontVariantNumericFraction::StackedFractions:
1940         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueStackedFractions));
1941         break;
1942     }
1943
1944     switch (style->fontDescription().variantNumericOrdinal()) {
1945     case FontVariantNumericOrdinal::Normal:
1946         break;
1947     case FontVariantNumericOrdinal::Yes:
1948         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueOrdinal));
1949         break;
1950     }
1951
1952     switch (style->fontDescription().variantNumericSlashedZero()) {
1953     case FontVariantNumericSlashedZero::Normal:
1954         break;
1955     case FontVariantNumericSlashedZero::Yes:
1956         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueSlashedZero));
1957         break;
1958     }
1959
1960     switch (style->fontDescription().variantAlternates()) {
1961     case FontVariantAlternates::Normal:
1962         break;
1963     case FontVariantAlternates::HistoricalForms:
1964         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueHistoricalForms));
1965         break;
1966     }
1967
1968     switch (style->fontDescription().variantEastAsianVariant()) {
1969     case FontVariantEastAsianVariant::Normal:
1970         break;
1971     case FontVariantEastAsianVariant::Jis78:
1972         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueJis78));
1973         break;
1974     case FontVariantEastAsianVariant::Jis83:
1975         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueJis83));
1976         break;
1977     case FontVariantEastAsianVariant::Jis90:
1978         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueJis90));
1979         break;
1980     case FontVariantEastAsianVariant::Jis04:
1981         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueJis04));
1982         break;
1983     case FontVariantEastAsianVariant::Simplified:
1984         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueSimplified));
1985         break;
1986     case FontVariantEastAsianVariant::Traditional:
1987         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueTraditional));
1988         break;
1989     }
1990
1991     switch (style->fontDescription().variantEastAsianWidth()) {
1992     case FontVariantEastAsianWidth::Normal:
1993         break;
1994     case FontVariantEastAsianWidth::Full:
1995         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueFullWidth));
1996         break;
1997     case FontVariantEastAsianWidth::Proportional:
1998         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueProportionalWidth));
1999         break;
2000     }
2001
2002     switch (style->fontDescription().variantEastAsianRuby()) {
2003     case FontVariantEastAsianRuby::Normal:
2004         break;
2005     case FontVariantEastAsianRuby::Yes:
2006         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueRuby));
2007         break;
2008     }
2009
2010     return WTFMove(list);
2011 }
2012
2013 static Ref<CSSPrimitiveValue> fontWeightFromStyle(RenderStyle* style)
2014 {
2015     switch (style->fontDescription().weight()) {
2016     case FontWeight100:
2017         return CSSValuePool::singleton().createIdentifierValue(CSSValue100);
2018     case FontWeight200:
2019         return CSSValuePool::singleton().createIdentifierValue(CSSValue200);
2020     case FontWeight300:
2021         return CSSValuePool::singleton().createIdentifierValue(CSSValue300);
2022     case FontWeightNormal:
2023         return CSSValuePool::singleton().createIdentifierValue(CSSValueNormal);
2024     case FontWeight500:
2025         return CSSValuePool::singleton().createIdentifierValue(CSSValue500);
2026     case FontWeight600:
2027         return CSSValuePool::singleton().createIdentifierValue(CSSValue600);
2028     case FontWeightBold:
2029         return CSSValuePool::singleton().createIdentifierValue(CSSValueBold);
2030     case FontWeight800:
2031         return CSSValuePool::singleton().createIdentifierValue(CSSValue800);
2032     case FontWeight900:
2033         return CSSValuePool::singleton().createIdentifierValue(CSSValue900);
2034     }
2035     ASSERT_NOT_REACHED();
2036     return CSSValuePool::singleton().createIdentifierValue(CSSValueNormal);
2037 }
2038
2039 static Ref<CSSValue> fontSynthesisFromStyle(RenderStyle& style)
2040 {
2041     if (style.fontDescription().fontSynthesis() == FontSynthesisNone)
2042         return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
2043
2044     auto list = CSSValueList::createSpaceSeparated();
2045     if (style.fontDescription().fontSynthesis() & FontSynthesisStyle)
2046         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueStyle));
2047     if (style.fontDescription().fontSynthesis() & FontSynthesisWeight)
2048         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueWeight));
2049     return Ref<CSSValue>(list.get());
2050 }
2051
2052 typedef const Length& (RenderStyle::*RenderStyleLengthGetter)() const;
2053 typedef LayoutUnit (RenderBoxModelObject::*RenderBoxComputedCSSValueGetter)() const;
2054
2055 template<RenderStyleLengthGetter lengthGetter, RenderBoxComputedCSSValueGetter computedCSSValueGetter>
2056 inline RefPtr<CSSValue> zoomAdjustedPaddingOrMarginPixelValue(RenderStyle& style, RenderObject* renderer)
2057 {
2058     Length unzoomzedLength = (style.*lengthGetter)();
2059     if (!is<RenderBox>(renderer) || unzoomzedLength.isFixed())
2060         return zoomAdjustedPixelValueForLength(unzoomzedLength, style);
2061     return zoomAdjustedPixelValue((downcast<RenderBox>(*renderer).*computedCSSValueGetter)(), style);
2062 }
2063
2064 template<RenderStyleLengthGetter lengthGetter>
2065 inline bool paddingOrMarginIsRendererDependent(RenderStyle* style, RenderObject* renderer)
2066 {
2067     if (!renderer || !renderer->isBox())
2068         return false;
2069     return !(style && (style->*lengthGetter)().isFixed());
2070 }
2071
2072 static bool isLayoutDependent(CSSPropertyID propertyID, RenderStyle* style, RenderObject* renderer)
2073 {
2074     switch (propertyID) {
2075     case CSSPropertyWidth:
2076     case CSSPropertyHeight:
2077     case CSSPropertyPerspectiveOrigin:
2078     case CSSPropertyTransformOrigin:
2079     case CSSPropertyTransform:
2080     case CSSPropertyFilter:
2081 #if ENABLE(FILTERS_LEVEL_2)
2082     case CSSPropertyWebkitBackdropFilter:
2083 #endif
2084         return true;
2085     case CSSPropertyMargin: {
2086         if (!renderer || !renderer->isBox())
2087             return false;
2088         return !(style && style->marginTop().isFixed() && style->marginRight().isFixed()
2089             && style->marginBottom().isFixed() && style->marginLeft().isFixed());
2090     }
2091     case CSSPropertyMarginTop:
2092         return paddingOrMarginIsRendererDependent<&RenderStyle::marginTop>(style, renderer);
2093     case CSSPropertyMarginRight:
2094         return paddingOrMarginIsRendererDependent<&RenderStyle::marginRight>(style, renderer);
2095     case CSSPropertyMarginBottom:
2096         return paddingOrMarginIsRendererDependent<&RenderStyle::marginBottom>(style, renderer);
2097     case CSSPropertyMarginLeft:
2098         return paddingOrMarginIsRendererDependent<&RenderStyle::marginLeft>(style, renderer);
2099     case CSSPropertyPadding: {
2100         if (!renderer || !renderer->isBox())
2101             return false;
2102         return !(style && style->paddingTop().isFixed() && style->paddingRight().isFixed()
2103             && style->paddingBottom().isFixed() && style->paddingLeft().isFixed());
2104     }
2105     case CSSPropertyPaddingTop:
2106         return paddingOrMarginIsRendererDependent<&RenderStyle::paddingTop>(style, renderer);
2107     case CSSPropertyPaddingRight:
2108         return paddingOrMarginIsRendererDependent<&RenderStyle::paddingRight>(style, renderer);
2109     case CSSPropertyPaddingBottom:
2110         return paddingOrMarginIsRendererDependent<&RenderStyle::paddingBottom>(style, renderer);
2111     case CSSPropertyPaddingLeft:
2112         return paddingOrMarginIsRendererDependent<&RenderStyle::paddingLeft>(style, renderer); 
2113 #if ENABLE(CSS_GRID_LAYOUT)
2114     case CSSPropertyWebkitGridTemplateColumns:
2115     case CSSPropertyWebkitGridTemplateRows:
2116     case CSSPropertyWebkitGridTemplate:
2117     case CSSPropertyWebkitGrid:
2118         return renderer && renderer->isRenderGrid();
2119 #endif
2120     default:
2121         return false;
2122     }
2123 }
2124
2125 Node* ComputedStyleExtractor::styledNode() const
2126 {
2127     if (!m_node)
2128         return nullptr;
2129     if (!is<Element>(*m_node))
2130         return m_node.get();
2131     Element& element = downcast<Element>(*m_node);
2132     PseudoElement* pseudoElement;
2133     if (m_pseudoElementSpecifier == BEFORE && (pseudoElement = element.beforePseudoElement()))
2134         return pseudoElement;
2135     if (m_pseudoElementSpecifier == AFTER && (pseudoElement = element.afterPseudoElement()))
2136         return pseudoElement;
2137     return &element;
2138 }
2139
2140 static ItemPosition resolveContainerAlignmentAuto(ItemPosition position, RenderObject* element)
2141 {
2142     if (position != ItemPositionAuto || !element)
2143         return position;
2144
2145     return element->style().isDisplayFlexibleOrGridBox() ? ItemPositionStretch : ItemPositionStart;
2146 }
2147
2148 static ItemPosition resolveSelfAlignmentAuto(ItemPosition position, OverflowAlignment& overflow, RenderObject* element)
2149 {
2150     if (position != ItemPositionAuto || !element || element->isOutOfFlowPositioned())
2151         return position;
2152
2153     RenderBlock* parent = element->containingBlock();
2154     if (!parent)
2155         return ItemPositionStart;
2156
2157     overflow = parent->style().alignItemsOverflowAlignment();
2158     return resolveContainerAlignmentAuto(parent->style().alignItemsPosition(), parent);
2159 }
2160
2161 static void resolveContentAlignmentAuto(ContentPosition& position, ContentDistributionType& distribution, RenderObject* element)
2162 {
2163     if (position != ContentPositionAuto || distribution != ContentDistributionDefault || !element)
2164         return;
2165
2166     // Even that both align-content and justify-content 'auto' values are resolved to 'stretch'
2167     // in case of flexbox containers, 'stretch' value in justify-content will behave like 'flex-start'. 
2168     if (element->style().isDisplayFlexibleBox())
2169         distribution = ContentDistributionStretch;
2170     else
2171         position = ContentPositionStart;
2172 }
2173
2174 RefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropertyID propertyID, EUpdateLayout updateLayout) const
2175 {
2176     return ComputedStyleExtractor(m_node, m_allowVisitedStyle, m_pseudoElementSpecifier).propertyValue(propertyID, updateLayout);
2177 }
2178
2179 Ref<MutableStyleProperties> CSSComputedStyleDeclaration::copyProperties() const
2180 {
2181     return ComputedStyleExtractor(m_node, m_allowVisitedStyle, m_pseudoElementSpecifier).copyProperties();
2182 }
2183
2184 static inline bool nodeOrItsAncestorNeedsStyleRecalc(const Node& node)
2185 {
2186     if (node.needsStyleRecalc())
2187         return true;
2188
2189     const Node* currentNode = &node;
2190     const Element* ancestor = currentNode->parentOrShadowHostElement();
2191     while (ancestor) {
2192         if (ancestor->needsStyleRecalc())
2193             return true;
2194
2195         if (ancestor->directChildNeedsStyleRecalc() && currentNode->styleIsAffectedByPreviousSibling())
2196             return true;
2197
2198         currentNode = ancestor;
2199         ancestor = currentNode->parentOrShadowHostElement();
2200     }
2201     return false;
2202 }
2203
2204 static inline bool updateStyleIfNeededForNode(const Node& node)
2205 {
2206     Document& document = node.document();
2207     if (!document.hasPendingForcedStyleRecalc() && !(document.childNeedsStyleRecalc() && nodeOrItsAncestorNeedsStyleRecalc(node)))
2208         return false;
2209     document.updateStyleIfNeeded();
2210     return true;
2211 }
2212
2213 static inline RefPtr<RenderStyle> computeRenderStyleForProperty(Node* styledNode, PseudoId pseudoElementSpecifier, CSSPropertyID propertyID)
2214 {
2215     RenderObject* renderer = styledNode->renderer();
2216
2217     if (renderer && renderer->isComposited() && AnimationController::supportsAcceleratedAnimationOfProperty(propertyID)) {
2218         RefPtr<RenderStyle> style = renderer->animation().getAnimatedStyleForRenderer(downcast<RenderElement>(*renderer));
2219         if (pseudoElementSpecifier && !styledNode->isPseudoElement()) {
2220             // FIXME: This cached pseudo style will only exist if the animation has been run at least once.
2221             return style->getCachedPseudoStyle(pseudoElementSpecifier);
2222         }
2223         return style;
2224     }
2225
2226     return styledNode->computedStyle(styledNode->isPseudoElement() ? NOPSEUDO : pseudoElementSpecifier);
2227 }
2228
2229 #if ENABLE(CSS_SHAPES)
2230 static Ref<CSSValue> shapePropertyValue(const RenderStyle& style, const ShapeValue* shapeValue)
2231 {
2232     if (!shapeValue)
2233         return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
2234
2235     if (shapeValue->type() == ShapeValue::Type::Box)
2236         return CSSValuePool::singleton().createValue(shapeValue->cssBox());
2237
2238     if (shapeValue->type() == ShapeValue::Type::Image) {
2239         if (shapeValue->image())
2240             return *shapeValue->image()->cssValue();
2241         return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
2242     }
2243
2244     ASSERT(shapeValue->type() == ShapeValue::Type::Shape);
2245
2246     RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2247     list->append(valueForBasicShape(style, *shapeValue->shape()));
2248     if (shapeValue->cssBox() != BoxMissing)
2249         list->append(CSSValuePool::singleton().createValue(shapeValue->cssBox()));
2250     return list.releaseNonNull();
2251 }
2252 #endif
2253
2254 static RefPtr<CSSValueList> valueForItemPositionWithOverflowAlignment(ItemPosition itemPosition, OverflowAlignment overflowAlignment, ItemPositionType positionType)
2255 {
2256     auto& cssValuePool = CSSValuePool::singleton();
2257     RefPtr<CSSValueList> result = CSSValueList::createSpaceSeparated();
2258     if (positionType == LegacyPosition)
2259         result->append(CSSPrimitiveValue::createIdentifier(CSSValueLegacy));
2260     result->append(cssValuePool.createValue(itemPosition));
2261     if (overflowAlignment != OverflowAlignmentDefault)
2262         result->append(cssValuePool.createValue(overflowAlignment));
2263     ASSERT(result->length() <= 2);
2264     return result;
2265 }
2266
2267 static RefPtr<CSSValueList> valueForContentPositionAndDistributionWithOverflowAlignment(ContentPosition position, ContentDistributionType distribution, OverflowAlignment overflowAlignment)
2268 {
2269     RefPtr<CSSValueList> result = CSSValueList::createSpaceSeparated();
2270     if (distribution != ContentDistributionDefault)
2271         result->append(CSSPrimitiveValue::create(distribution));
2272     if (distribution == ContentDistributionDefault || position != ContentPositionAuto)
2273         result->append(CSSPrimitiveValue::create(position));
2274     if ((position >= ContentPositionCenter || distribution != ContentDistributionDefault) && overflowAlignment != OverflowAlignmentDefault)
2275         result->append(CSSPrimitiveValue::create(overflowAlignment));
2276     ASSERT(result->length() > 0);
2277     ASSERT(result->length() <= 3);
2278     return result;
2279 }
2280
2281 inline static bool isFlexOrGrid(ContainerNode* element)
2282 {
2283     return element && element->computedStyle() && element->computedStyle()->isDisplayFlexibleOrGridBox();
2284 }
2285
2286 RefPtr<CSSValue> ComputedStyleExtractor::customPropertyValue(const String& propertyName) const
2287 {
2288     Node* styledNode = this->styledNode();
2289     if (!styledNode)
2290         return nullptr;
2291     
2292     if (updateStyleIfNeededForNode(*styledNode)) {
2293         // The style recalc could have caused the styled node to be discarded or replaced
2294         // if it was a PseudoElement so we need to update it.
2295         styledNode = this->styledNode();
2296     }
2297
2298     RefPtr<RenderStyle> style = computeRenderStyleForProperty(styledNode, m_pseudoElementSpecifier, CSSPropertyCustom);
2299     if (!style || !style->hasCustomProperty(propertyName))
2300         return nullptr;
2301
2302     return style->getCustomPropertyValue(propertyName);
2303 }
2304
2305 String ComputedStyleExtractor::customPropertyText(const String& propertyName) const
2306 {
2307     RefPtr<CSSValue> propertyValue = this->customPropertyValue(propertyName);
2308     return propertyValue ? propertyValue->cssText() : emptyString();
2309 }
2310
2311 RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID, EUpdateLayout updateLayout) const
2312 {
2313     Node* styledNode = this->styledNode();
2314     if (!styledNode)
2315         return nullptr;
2316
2317     RefPtr<RenderStyle> style;
2318     RenderObject* renderer = nullptr;
2319     bool forceFullLayout = false;
2320     if (updateLayout) {
2321         Document& document = styledNode->document();
2322
2323         if (updateStyleIfNeededForNode(*styledNode)) {
2324             // The style recalc could have caused the styled node to be discarded or replaced
2325             // if it was a PseudoElement so we need to update it.
2326             styledNode = this->styledNode();
2327         }
2328
2329         renderer = styledNode->renderer();
2330
2331         if (propertyID == CSSPropertyDisplay && !renderer && is<SVGElement>(*styledNode) && !downcast<SVGElement>(*styledNode).isValid())
2332             return nullptr;
2333
2334         style = computeRenderStyleForProperty(styledNode, m_pseudoElementSpecifier, propertyID);
2335
2336         // FIXME: Some of these cases could be narrowed down or optimized better.
2337         forceFullLayout = isLayoutDependent(propertyID, style.get(), renderer)
2338             || styledNode->isInShadowTree()
2339             || (document.styleResolverIfExists() && document.styleResolverIfExists()->hasViewportDependentMediaQueries() && document.ownerElement());
2340
2341         if (forceFullLayout) {
2342             document.updateLayoutIgnorePendingStylesheets();
2343             styledNode = this->styledNode();
2344         }
2345     }
2346
2347     if (!updateLayout || forceFullLayout) {
2348         style = computeRenderStyleForProperty(styledNode, m_pseudoElementSpecifier, propertyID);
2349         renderer = styledNode->renderer();
2350     }
2351
2352     if (!style)
2353         return nullptr;
2354
2355     auto& cssValuePool = CSSValuePool::singleton();
2356     propertyID = CSSProperty::resolveDirectionAwareProperty(propertyID, style->direction(), style->writingMode());
2357
2358     switch (propertyID) {
2359         case CSSPropertyInvalid:
2360             break;
2361
2362         case CSSPropertyBackgroundColor:
2363             return cssValuePool.createColorValue(m_allowVisitedStyle? style->visitedDependentColor(CSSPropertyBackgroundColor).rgb() : style->backgroundColor().rgb());
2364         case CSSPropertyBackgroundImage:
2365         case CSSPropertyWebkitMaskImage: {
2366             const FillLayer* layers = propertyID == CSSPropertyWebkitMaskImage ? style->maskLayers() : style->backgroundLayers();
2367             if (!layers)
2368                 return cssValuePool.createIdentifierValue(CSSValueNone);
2369
2370             if (!layers->next()) {
2371                 if (layers->image())
2372                     return layers->image()->cssValue();
2373
2374                 return cssValuePool.createIdentifierValue(CSSValueNone);
2375             }
2376
2377             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2378             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) {
2379                 if (currLayer->image())
2380                     list->append(*currLayer->image()->cssValue());
2381                 else
2382                     list->append(cssValuePool.createIdentifierValue(CSSValueNone));
2383             }
2384             return list;
2385         }
2386         case CSSPropertyBackgroundSize:
2387         case CSSPropertyWebkitBackgroundSize:
2388         case CSSPropertyWebkitMaskSize: {
2389             const FillLayer* layers = propertyID == CSSPropertyWebkitMaskSize ? style->maskLayers() : style->backgroundLayers();
2390             if (!layers->next())
2391                 return fillSizeToCSSValue(layers->size(), *style);
2392
2393             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2394             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
2395                 list->append(fillSizeToCSSValue(currLayer->size(), *style));
2396
2397             return list;
2398         }
2399         case CSSPropertyBackgroundRepeat:
2400         case CSSPropertyWebkitMaskRepeat: {
2401             const FillLayer* layers = propertyID == CSSPropertyWebkitMaskRepeat ? style->maskLayers() : style->backgroundLayers();
2402             if (!layers->next())
2403                 return fillRepeatToCSSValue(layers->repeatX(), layers->repeatY());
2404
2405             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2406             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
2407                 list->append(fillRepeatToCSSValue(currLayer->repeatX(), currLayer->repeatY()));
2408
2409             return list;
2410         }
2411         case CSSPropertyWebkitMaskSourceType: {
2412             const FillLayer* layers = style->maskLayers();
2413
2414             if (!layers)
2415                 return cssValuePool.createIdentifierValue(CSSValueNone);
2416
2417             if (!layers->next())
2418                 return fillSourceTypeToCSSValue(layers->maskSourceType());
2419
2420             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2421             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
2422                 list->append(fillSourceTypeToCSSValue(currLayer->maskSourceType()));
2423
2424             return list;
2425         }
2426         case CSSPropertyWebkitBackgroundComposite:
2427         case CSSPropertyWebkitMaskComposite: {
2428             const FillLayer* layers = propertyID == CSSPropertyWebkitMaskComposite ? style->maskLayers() : style->backgroundLayers();
2429             if (!layers->next())
2430                 return cssValuePool.createValue(layers->composite());
2431
2432             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2433             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
2434                 list->append(cssValuePool.createValue(currLayer->composite()));
2435
2436             return list;
2437         }
2438         case CSSPropertyBackgroundAttachment: {
2439             const FillLayer* layers = style->backgroundLayers();
2440             if (!layers->next())
2441                 return cssValuePool.createValue(layers->attachment());
2442
2443             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2444             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
2445                 list->append(cssValuePool.createValue(currLayer->attachment()));
2446
2447             return list;
2448         }
2449         case CSSPropertyBackgroundClip:
2450         case CSSPropertyBackgroundOrigin:
2451         case CSSPropertyWebkitBackgroundClip:
2452         case CSSPropertyWebkitBackgroundOrigin:
2453         case CSSPropertyWebkitMaskClip:
2454         case CSSPropertyWebkitMaskOrigin: {
2455             const FillLayer* layers = (propertyID == CSSPropertyWebkitMaskClip || propertyID == CSSPropertyWebkitMaskOrigin) ? style->maskLayers() : style->backgroundLayers();
2456             bool isClip = propertyID == CSSPropertyBackgroundClip || propertyID == CSSPropertyWebkitBackgroundClip || propertyID == CSSPropertyWebkitMaskClip;
2457             if (!layers->next()) {
2458                 EFillBox box = isClip ? layers->clip() : layers->origin();
2459                 return cssValuePool.createValue(box);
2460             }
2461
2462             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2463             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) {
2464                 EFillBox box = isClip ? currLayer->clip() : currLayer->origin();
2465                 list->append(cssValuePool.createValue(box));
2466             }
2467
2468             return list;
2469         }
2470         case CSSPropertyBackgroundPosition:
2471         case CSSPropertyWebkitMaskPosition: {
2472             const FillLayer* layers = propertyID == CSSPropertyWebkitMaskPosition ? style->maskLayers() : style->backgroundLayers();
2473             if (!layers->next())
2474                 return createPositionListForLayer(propertyID, layers, *style);
2475
2476             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2477             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
2478                 list->append(createPositionListForLayer(propertyID, currLayer, *style));
2479             return list;
2480         }
2481         case CSSPropertyBackgroundPositionX:
2482         case CSSPropertyWebkitMaskPositionX: {
2483             const FillLayer* layers = propertyID == CSSPropertyWebkitMaskPositionX ? style->maskLayers() : style->backgroundLayers();
2484             if (!layers->next())
2485                 return cssValuePool.createValue(layers->xPosition());
2486
2487             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2488             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
2489                 list->append(cssValuePool.createValue(currLayer->xPosition()));
2490
2491             return list;
2492         }
2493         case CSSPropertyBackgroundPositionY:
2494         case CSSPropertyWebkitMaskPositionY: {
2495             const FillLayer* layers = propertyID == CSSPropertyWebkitMaskPositionY ? style->maskLayers() : style->backgroundLayers();
2496             if (!layers->next())
2497                 return cssValuePool.createValue(layers->yPosition());
2498
2499             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2500             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
2501                 list->append(cssValuePool.createValue(currLayer->yPosition()));
2502
2503             return list;
2504         }
2505         case CSSPropertyBorderCollapse:
2506             if (style->borderCollapse())
2507                 return cssValuePool.createIdentifierValue(CSSValueCollapse);
2508             return cssValuePool.createIdentifierValue(CSSValueSeparate);
2509         case CSSPropertyBorderSpacing: {
2510             RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2511             list->append(zoomAdjustedPixelValue(style->horizontalBorderSpacing(), *style));
2512             list->append(zoomAdjustedPixelValue(style->verticalBorderSpacing(), *style));
2513             return list;
2514         }
2515         case CSSPropertyWebkitBorderHorizontalSpacing:
2516             return zoomAdjustedPixelValue(style->horizontalBorderSpacing(), *style);
2517         case CSSPropertyWebkitBorderVerticalSpacing:
2518             return zoomAdjustedPixelValue(style->verticalBorderSpacing(), *style);
2519         case CSSPropertyBorderImageSource:
2520             if (style->borderImageSource())
2521                 return style->borderImageSource()->cssValue();
2522             return cssValuePool.createIdentifierValue(CSSValueNone);
2523         case CSSPropertyBorderTopColor:
2524             return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyBorderTopColor).rgb()) : currentColorOrValidColor(style.get(), style->borderTopColor());
2525         case CSSPropertyBorderRightColor:
2526             return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyBorderRightColor).rgb()) : currentColorOrValidColor(style.get(), style->borderRightColor());
2527         case CSSPropertyBorderBottomColor:
2528             return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyBorderBottomColor).rgb()) : currentColorOrValidColor(style.get(), style->borderBottomColor());
2529         case CSSPropertyBorderLeftColor:
2530             return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyBorderLeftColor).rgb()) : currentColorOrValidColor(style.get(), style->borderLeftColor());
2531         case CSSPropertyBorderTopStyle:
2532             return cssValuePool.createValue(style->borderTopStyle());
2533         case CSSPropertyBorderRightStyle:
2534             return cssValuePool.createValue(style->borderRightStyle());
2535         case CSSPropertyBorderBottomStyle:
2536             return cssValuePool.createValue(style->borderBottomStyle());
2537         case CSSPropertyBorderLeftStyle:
2538             return cssValuePool.createValue(style->borderLeftStyle());
2539         case CSSPropertyBorderTopWidth:
2540             return zoomAdjustedPixelValue(style->borderTopWidth(), *style);
2541         case CSSPropertyBorderRightWidth:
2542             return zoomAdjustedPixelValue(style->borderRightWidth(), *style);
2543         case CSSPropertyBorderBottomWidth:
2544             return zoomAdjustedPixelValue(style->borderBottomWidth(), *style);
2545         case CSSPropertyBorderLeftWidth:
2546             return zoomAdjustedPixelValue(style->borderLeftWidth(), *style);
2547         case CSSPropertyBottom:
2548             return positionOffsetValue(*style, CSSPropertyBottom);
2549         case CSSPropertyWebkitBoxAlign:
2550             return cssValuePool.createValue(style->boxAlign());
2551 #if ENABLE(CSS_BOX_DECORATION_BREAK)
2552         case CSSPropertyWebkitBoxDecorationBreak:
2553             if (style->boxDecorationBreak() == DSLICE)
2554                 return cssValuePool.createIdentifierValue(CSSValueSlice);
2555         return cssValuePool.createIdentifierValue(CSSValueClone);
2556 #endif
2557         case CSSPropertyWebkitBoxDirection:
2558             return cssValuePool.createValue(style->boxDirection());
2559         case CSSPropertyWebkitBoxFlex:
2560             return cssValuePool.createValue(style->boxFlex(), CSSPrimitiveValue::CSS_NUMBER);
2561         case CSSPropertyWebkitBoxFlexGroup:
2562             return cssValuePool.createValue(style->boxFlexGroup(), CSSPrimitiveValue::CSS_NUMBER);
2563         case CSSPropertyWebkitBoxLines:
2564             return cssValuePool.createValue(style->boxLines());
2565         case CSSPropertyWebkitBoxOrdinalGroup:
2566             return cssValuePool.createValue(style->boxOrdinalGroup(), CSSPrimitiveValue::CSS_NUMBER);
2567         case CSSPropertyWebkitBoxOrient:
2568             return cssValuePool.createValue(style->boxOrient());
2569         case CSSPropertyWebkitBoxPack:
2570             return cssValuePool.createValue(style->boxPack());
2571         case CSSPropertyWebkitBoxReflect:
2572             return valueForReflection(style->boxReflect(), *style);
2573         case CSSPropertyBoxShadow:
2574         case CSSPropertyWebkitBoxShadow:
2575             return valueForShadow(style->boxShadow(), propertyID, *style);
2576         case CSSPropertyCaptionSide:
2577             return cssValuePool.createValue(style->captionSide());
2578         case CSSPropertyClear:
2579             return cssValuePool.createValue(style->clear());
2580         case CSSPropertyColor:
2581             return cssValuePool.createColorValue(m_allowVisitedStyle ? style->visitedDependentColor(CSSPropertyColor).rgb() : style->color().rgb());
2582         case CSSPropertyWebkitPrintColorAdjust:
2583             return cssValuePool.createValue(style->printColorAdjust());
2584         case CSSPropertyWebkitColumnAxis:
2585             return cssValuePool.createValue(style->columnAxis());
2586         case CSSPropertyColumnCount:
2587             if (style->hasAutoColumnCount())
2588                 return cssValuePool.createIdentifierValue(CSSValueAuto);
2589             return cssValuePool.createValue(style->columnCount(), CSSPrimitiveValue::CSS_NUMBER);
2590         case CSSPropertyColumnFill:
2591             return cssValuePool.createValue(style->columnFill());
2592         case CSSPropertyColumnGap:
2593             if (style->hasNormalColumnGap())
2594                 return cssValuePool.createIdentifierValue(CSSValueNormal);
2595             return zoomAdjustedPixelValue(style->columnGap(), *style);
2596         case CSSPropertyColumnProgression:
2597             return cssValuePool.createValue(style->columnProgression());
2598         case CSSPropertyColumnRuleColor:
2599             return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyOutlineColor).rgb()) : currentColorOrValidColor(style.get(), style->columnRuleColor());
2600         case CSSPropertyColumnRuleStyle:
2601             return cssValuePool.createValue(style->columnRuleStyle());
2602         case CSSPropertyColumnRuleWidth:
2603             return zoomAdjustedPixelValue(style->columnRuleWidth(), *style);
2604         case CSSPropertyColumnSpan:
2605             return cssValuePool.createIdentifierValue(style->columnSpan() ? CSSValueAll : CSSValueNone);
2606         case CSSPropertyWebkitColumnBreakAfter:
2607             return cssValuePool.createValue(style->columnBreakAfter());
2608         case CSSPropertyWebkitColumnBreakBefore:
2609             return cssValuePool.createValue(style->columnBreakBefore());
2610         case CSSPropertyWebkitColumnBreakInside:
2611             return cssValuePool.createValue(style->columnBreakInside());
2612         case CSSPropertyColumnWidth:
2613             if (style->hasAutoColumnWidth())
2614                 return cssValuePool.createIdentifierValue(CSSValueAuto);
2615             return zoomAdjustedPixelValue(style->columnWidth(), *style);
2616         case CSSPropertyTabSize:
2617             return cssValuePool.createValue(style->tabSize(), CSSPrimitiveValue::CSS_NUMBER);
2618 #if ENABLE(CSS_REGIONS)
2619         case CSSPropertyWebkitRegionBreakAfter:
2620             return cssValuePool.createValue(style->regionBreakAfter());
2621         case CSSPropertyWebkitRegionBreakBefore:
2622             return cssValuePool.createValue(style->regionBreakBefore());
2623         case CSSPropertyWebkitRegionBreakInside:
2624             return cssValuePool.createValue(style->regionBreakInside());
2625 #endif
2626         case CSSPropertyCursor: {
2627             RefPtr<CSSValueList> list;
2628             CursorList* cursors = style->cursors();
2629             if (cursors && cursors->size() > 0) {
2630                 list = CSSValueList::createCommaSeparated();
2631                 for (unsigned i = 0; i < cursors->size(); ++i)
2632                     if (StyleImage* image = cursors->at(i).image())
2633                         list->append(*image->cssValue());
2634             }
2635             auto value = cssValuePool.createValue(style->cursor());
2636             if (list) {
2637                 list->append(WTFMove(value));
2638                 return list;
2639             }
2640             return WTFMove(value);
2641         }
2642 #if ENABLE(CURSOR_VISIBILITY)
2643         case CSSPropertyWebkitCursorVisibility:
2644             return cssValuePool.createValue(style->cursorVisibility());
2645 #endif
2646         case CSSPropertyDirection:
2647             return cssValuePool.createValue(style->direction());
2648         case CSSPropertyDisplay:
2649             return cssValuePool.createValue(style->display());
2650         case CSSPropertyEmptyCells:
2651             return cssValuePool.createValue(style->emptyCells());
2652         case CSSPropertyAlignContent: {
2653             ContentPosition position = style->alignContentPosition();
2654             ContentDistributionType distribution = style->alignContentDistribution();
2655             resolveContentAlignmentAuto(position, distribution, renderer);
2656             return valueForContentPositionAndDistributionWithOverflowAlignment(position, distribution, style->alignContentOverflowAlignment());
2657         }
2658         case CSSPropertyAlignItems:
2659             return valueForItemPositionWithOverflowAlignment(resolveContainerAlignmentAuto(style->alignItemsPosition(), renderer), style->alignItemsOverflowAlignment(), NonLegacyPosition);
2660         case CSSPropertyAlignSelf: {
2661             OverflowAlignment overflow = style->alignSelfOverflowAlignment();
2662             ItemPosition alignSelf = resolveSelfAlignmentAuto(style->alignSelfPosition(), overflow, renderer);
2663             return valueForItemPositionWithOverflowAlignment(alignSelf, overflow, NonLegacyPosition);
2664         }
2665         case CSSPropertyFlex:
2666             return getCSSPropertyValuesForShorthandProperties(flexShorthand());
2667         case CSSPropertyFlexBasis:
2668             return cssValuePool.createValue(style->flexBasis());
2669         case CSSPropertyFlexDirection:
2670             return cssValuePool.createValue(style->flexDirection());
2671         case CSSPropertyFlexFlow:
2672             return getCSSPropertyValuesForShorthandProperties(flexFlowShorthand());
2673         case CSSPropertyFlexGrow:
2674             return cssValuePool.createValue(style->flexGrow());
2675         case CSSPropertyFlexShrink:
2676             return cssValuePool.createValue(style->flexShrink());
2677         case CSSPropertyFlexWrap:
2678             return cssValuePool.createValue(style->flexWrap());
2679         case CSSPropertyJustifyContent: {
2680             ContentPosition position = style->justifyContentPosition();
2681             ContentDistributionType distribution = style->justifyContentDistribution();
2682             resolveContentAlignmentAuto(position, distribution, renderer);
2683             return valueForContentPositionAndDistributionWithOverflowAlignment(position, distribution, style->justifyContentOverflowAlignment());
2684         }
2685         case CSSPropertyJustifyItems:
2686             return valueForItemPositionWithOverflowAlignment(resolveContainerAlignmentAuto(style->justifyItemsPosition(), renderer), style->justifyItemsOverflowAlignment(), style->justifyItemsPositionType());
2687         case CSSPropertyJustifySelf: {
2688             OverflowAlignment overflow = style->justifySelfOverflowAlignment();
2689             ItemPosition justifySelf = resolveSelfAlignmentAuto(style->justifySelfPosition(), overflow, renderer);
2690             return valueForItemPositionWithOverflowAlignment(justifySelf, overflow, NonLegacyPosition);
2691         }
2692         case CSSPropertyOrder:
2693             return cssValuePool.createValue(style->order(), CSSPrimitiveValue::CSS_NUMBER);
2694         case CSSPropertyFloat:
2695             if (style->display() != NONE && style->hasOutOfFlowPosition())
2696                 return cssValuePool.createIdentifierValue(CSSValueNone);
2697             return cssValuePool.createValue(style->floating());
2698         case CSSPropertyFont: {
2699             RefPtr<CSSFontValue> computedFont = CSSFontValue::create();
2700             computedFont->style = fontStyleFromStyle(style.get());
2701             if (style->fontDescription().variantCaps() == FontVariantCaps::Small)
2702                 computedFont->variant = CSSValuePool::singleton().createIdentifierValue(CSSValueSmallCaps);
2703             else
2704                 computedFont->variant = CSSValuePool::singleton().createIdentifierValue(CSSValueNormal);
2705             computedFont->weight = fontWeightFromStyle(style.get());
2706             computedFont->size = fontSizeFromStyle(*style);
2707             computedFont->lineHeight = lineHeightFromStyle(*style);
2708             computedFont->family = fontFamilyFromStyle(style.get());
2709             return computedFont;
2710         }
2711         case CSSPropertyFontFamily: {
2712             RefPtr<CSSValueList> fontFamilyList = fontFamilyFromStyle(style.get());
2713             // If there's only a single family, return that as a CSSPrimitiveValue.
2714             // NOTE: Gecko always returns this as a comma-separated CSSPrimitiveValue string.
2715             if (fontFamilyList->length() == 1)
2716                 return fontFamilyList->item(0);
2717             return fontFamilyList;
2718         }
2719         case CSSPropertyFontSize:
2720             return fontSizeFromStyle(*style);
2721         case CSSPropertyFontStyle:
2722             return fontStyleFromStyle(style.get());
2723         case CSSPropertyFontVariant:
2724             return fontVariantFromStyle(style.get());
2725         case CSSPropertyFontWeight:
2726             return fontWeightFromStyle(style.get());
2727         case CSSPropertyFontSynthesis:
2728             return fontSynthesisFromStyle(*style);
2729         case CSSPropertyFontFeatureSettings: {
2730             const FontFeatureSettings& featureSettings = style->fontDescription().featureSettings();
2731             if (!featureSettings.size())
2732                 return cssValuePool.createIdentifierValue(CSSValueNormal);
2733             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2734             for (auto& feature : featureSettings)
2735                 list->append(CSSFontFeatureValue::create(FontFeatureTag(feature.tag()), feature.value()));
2736             return list;
2737         }
2738 #if ENABLE(CSS_GRID_LAYOUT)
2739         case CSSPropertyWebkitGridAutoFlow: {
2740             RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2741             ASSERT(style->isGridAutoFlowDirectionRow() || style->isGridAutoFlowDirectionColumn());
2742             if (style->isGridAutoFlowDirectionRow())
2743                 list->append(cssValuePool.createIdentifierValue(CSSValueRow));
2744             else
2745                 list->append(cssValuePool.createIdentifierValue(CSSValueColumn));
2746
2747             if (style->isGridAutoFlowAlgorithmDense())
2748                 list->append(cssValuePool.createIdentifierValue(CSSValueDense));
2749
2750             return list;
2751         }
2752
2753         // Specs mention that getComputedStyle() should return the used value of the property instead of the computed
2754         // one for grid-definition-{rows|columns} but not for the grid-auto-{rows|columns} as things like
2755         // grid-auto-columns: 2fr; cannot be resolved to a value in pixels as the '2fr' means very different things
2756         // depending on the size of the explicit grid or the number of implicit tracks added to the grid. See
2757         // http://lists.w3.org/Archives/Public/www-style/2013Nov/0014.html
2758         case CSSPropertyWebkitGridAutoColumns:
2759             return specifiedValueForGridTrackSize(style->gridAutoColumns(), *style);
2760         case CSSPropertyWebkitGridAutoRows:
2761             return specifiedValueForGridTrackSize(style->gridAutoRows(), *style);
2762
2763         case CSSPropertyWebkitGridTemplateColumns:
2764             return valueForGridTrackList(ForColumns, renderer, *style);
2765         case CSSPropertyWebkitGridTemplateRows:
2766             return valueForGridTrackList(ForRows, renderer, *style);
2767
2768         case CSSPropertyWebkitGridColumnStart:
2769             return valueForGridPosition(style->gridItemColumnStart());
2770         case CSSPropertyWebkitGridColumnEnd:
2771             return valueForGridPosition(style->gridItemColumnEnd());
2772         case CSSPropertyWebkitGridRowStart:
2773             return valueForGridPosition(style->gridItemRowStart());
2774         case CSSPropertyWebkitGridRowEnd:
2775             return valueForGridPosition(style->gridItemRowEnd());
2776         case CSSPropertyWebkitGridArea:
2777             return getCSSPropertyValuesForGridShorthand(webkitGridAreaShorthand());
2778         case CSSPropertyWebkitGridTemplate:
2779             return getCSSPropertyValuesForGridShorthand(webkitGridTemplateShorthand());
2780         case CSSPropertyWebkitGrid:
2781             return getCSSPropertyValuesForGridShorthand(webkitGridShorthand());
2782         case CSSPropertyWebkitGridColumn:
2783             return getCSSPropertyValuesForGridShorthand(webkitGridColumnShorthand());
2784         case CSSPropertyWebkitGridRow:
2785             return getCSSPropertyValuesForGridShorthand(webkitGridRowShorthand());
2786
2787         case CSSPropertyWebkitGridTemplateAreas:
2788             if (!style->namedGridAreaRowCount()) {
2789                 ASSERT(!style->namedGridAreaColumnCount());
2790                 return cssValuePool.createIdentifierValue(CSSValueNone);
2791             }
2792
2793             return CSSGridTemplateAreasValue::create(style->namedGridArea(), style->namedGridAreaRowCount(), style->namedGridAreaColumnCount());
2794         case CSSPropertyWebkitGridColumnGap:
2795             return zoomAdjustedPixelValueForLength(style->gridColumnGap(), *style);
2796         case CSSPropertyWebkitGridRowGap:
2797             return zoomAdjustedPixelValueForLength(style->gridRowGap(), *style);
2798         case CSSPropertyWebkitGridGap:
2799             return getCSSPropertyValuesForGridShorthand(webkitGridGapShorthand());
2800 #endif /* ENABLE(CSS_GRID_LAYOUT) */
2801         case CSSPropertyHeight:
2802             if (renderer && !renderer->isRenderSVGModelObject()) {
2803                 // According to http://www.w3.org/TR/CSS2/visudet.html#the-height-property,
2804                 // the "height" property does not apply for non-replaced inline elements.
2805                 if (!renderer->isReplaced() && renderer->isInline())
2806                     return cssValuePool.createIdentifierValue(CSSValueAuto);
2807                 return zoomAdjustedPixelValue(sizingBox(*renderer).height(), *style);
2808             }
2809             return zoomAdjustedPixelValueForLength(style->height(), *style);
2810         case CSSPropertyWebkitHyphens:
2811             return cssValuePool.createValue(style->hyphens());
2812         case CSSPropertyWebkitHyphenateCharacter:
2813             if (style->hyphenationString().isNull())
2814                 return cssValuePool.createIdentifierValue(CSSValueAuto);
2815             return cssValuePool.createValue(style->hyphenationString(), CSSPrimitiveValue::CSS_STRING);
2816         case CSSPropertyWebkitHyphenateLimitAfter:
2817             if (style->hyphenationLimitAfter() < 0)
2818                 return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
2819             return CSSPrimitiveValue::create(style->hyphenationLimitAfter(), CSSPrimitiveValue::CSS_NUMBER);
2820         case CSSPropertyWebkitHyphenateLimitBefore:
2821             if (style->hyphenationLimitBefore() < 0)
2822                 return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
2823             return CSSPrimitiveValue::create(style->hyphenationLimitBefore(), CSSPrimitiveValue::CSS_NUMBER);
2824         case CSSPropertyWebkitHyphenateLimitLines:
2825             if (style->hyphenationLimitLines() < 0)
2826                 return CSSPrimitiveValue::createIdentifier(CSSValueNoLimit);
2827             return CSSPrimitiveValue::create(style->hyphenationLimitLines(), CSSPrimitiveValue::CSS_NUMBER);
2828         case CSSPropertyWebkitBorderFit:
2829             if (style->borderFit() == BorderFitBorder)
2830                 return cssValuePool.createIdentifierValue(CSSValueBorder);
2831             return cssValuePool.createIdentifierValue(CSSValueLines);
2832 #if ENABLE(CSS_IMAGE_ORIENTATION)
2833         case CSSPropertyImageOrientation:
2834             return cssValuePool.createValue(style->imageOrientation());
2835 #endif
2836         case CSSPropertyImageRendering:
2837             return CSSPrimitiveValue::create(style->imageRendering());
2838 #if ENABLE(CSS_IMAGE_RESOLUTION)
2839         case CSSPropertyImageResolution:
2840             return cssValuePool.createValue(style->imageResolution(), CSSPrimitiveValue::CSS_DPPX);
2841 #endif
2842         case CSSPropertyLeft:
2843             return positionOffsetValue(*style, CSSPropertyLeft);
2844         case CSSPropertyLetterSpacing:
2845             if (!style->letterSpacing())
2846                 return cssValuePool.createIdentifierValue(CSSValueNormal);
2847             return zoomAdjustedPixelValue(style->letterSpacing(), *style);
2848         case CSSPropertyWebkitLineClamp:
2849             if (style->lineClamp().isNone())
2850                 return cssValuePool.createIdentifierValue(CSSValueNone);
2851             return cssValuePool.createValue(style->lineClamp().value(), style->lineClamp().isPercentage() ? CSSPrimitiveValue::CSS_PERCENTAGE : CSSPrimitiveValue::CSS_NUMBER);
2852         case CSSPropertyLineHeight:
2853             return lineHeightFromStyle(*style);
2854         case CSSPropertyListStyleImage:
2855             if (style->listStyleImage())
2856                 return style->listStyleImage()->cssValue();
2857             return cssValuePool.createIdentifierValue(CSSValueNone);
2858         case CSSPropertyListStylePosition:
2859             return cssValuePool.createValue(style->listStylePosition());
2860         case CSSPropertyListStyleType:
2861             return cssValuePool.createValue(style->listStyleType());
2862         case CSSPropertyWebkitLocale:
2863             if (style->locale().isNull())
2864                 return cssValuePool.createIdentifierValue(CSSValueAuto);
2865             return cssValuePool.createValue(style->locale(), CSSPrimitiveValue::CSS_STRING);
2866         case CSSPropertyMarginTop:
2867             return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::marginTop, &RenderBoxModelObject::marginTop>(*style, renderer);
2868         case CSSPropertyMarginRight: {
2869             Length marginRight = style->marginRight();
2870             if (marginRight.isFixed() || !is<RenderBox>(renderer))
2871                 return zoomAdjustedPixelValueForLength(marginRight, *style);
2872             float value;
2873             if (marginRight.isPercentOrCalculated()) {
2874                 // RenderBox gives a marginRight() that is the distance between the right-edge of the child box
2875                 // and the right-edge of the containing box, when display == BLOCK. Let's calculate the absolute
2876                 // value of the specified margin-right % instead of relying on RenderBox's marginRight() value.
2877                 value = minimumValueForLength(marginRight, downcast<RenderBox>(*renderer).containingBlockLogicalWidthForContent());
2878             } else
2879                 value = downcast<RenderBox>(*renderer).marginRight();
2880             return zoomAdjustedPixelValue(value, *style);
2881         }
2882         case CSSPropertyMarginBottom:
2883             return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::marginBottom, &RenderBoxModelObject::marginBottom>(*style, renderer);
2884         case CSSPropertyMarginLeft:
2885             return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::marginLeft, &RenderBoxModelObject::marginLeft>(*style, renderer);
2886         case CSSPropertyWebkitMarqueeDirection:
2887             return cssValuePool.createValue(style->marqueeDirection());
2888         case CSSPropertyWebkitMarqueeIncrement:
2889             return cssValuePool.createValue(style->marqueeIncrement());
2890         case CSSPropertyWebkitMarqueeRepetition:
2891             if (style->marqueeLoopCount() < 0)
2892                 return cssValuePool.createIdentifierValue(CSSValueInfinite);
2893             return cssValuePool.createValue(style->marqueeLoopCount(), CSSPrimitiveValue::CSS_NUMBER);
2894         case CSSPropertyWebkitMarqueeStyle:
2895             return cssValuePool.createValue(style->marqueeBehavior());
2896         case CSSPropertyWebkitUserModify:
2897             return cssValuePool.createValue(style->userModify());
2898         case CSSPropertyMaxHeight: {
2899             const Length& maxHeight = style->maxHeight();
2900             if (maxHeight.isUndefined())
2901                 return cssValuePool.createIdentifierValue(CSSValueNone);
2902             return zoomAdjustedPixelValueForLength(maxHeight, *style);
2903         }
2904         case CSSPropertyMaxWidth: {
2905             const Length& maxWidth = style->maxWidth();
2906             if (maxWidth.isUndefined())
2907                 return cssValuePool.createIdentifierValue(CSSValueNone);
2908             return zoomAdjustedPixelValueForLength(maxWidth, *style);
2909         }
2910         case CSSPropertyMinHeight:
2911             if (style->minHeight().isAuto()) {
2912                 if (isFlexOrGrid(styledNode->parentNode()))
2913                     return cssValuePool.createIdentifierValue(CSSValueAuto);
2914                 return zoomAdjustedPixelValue(0, *style);
2915             }
2916             return zoomAdjustedPixelValueForLength(style->minHeight(), *style);
2917         case CSSPropertyMinWidth:
2918             if (style->minWidth().isAuto()) {
2919                 if (isFlexOrGrid(styledNode->parentNode()))
2920                     return cssValuePool.createIdentifierValue(CSSValueAuto);
2921                 return zoomAdjustedPixelValue(0, *style);
2922             }
2923             return zoomAdjustedPixelValueForLength(style->minWidth(), *style);
2924         case CSSPropertyObjectFit:
2925             return cssValuePool.createValue(style->objectFit());
2926         case CSSPropertyOpacity:
2927             return cssValuePool.createValue(style->opacity(), CSSPrimitiveValue::CSS_NUMBER);
2928         case CSSPropertyOrphans:
2929             if (style->hasAutoOrphans())
2930                 return cssValuePool.createIdentifierValue(CSSValueAuto);
2931             return cssValuePool.createValue(style->orphans(), CSSPrimitiveValue::CSS_NUMBER);
2932         case CSSPropertyOutlineColor:
2933             return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyOutlineColor).rgb()) : currentColorOrValidColor(style.get(), style->outlineColor());
2934         case CSSPropertyOutlineOffset:
2935             return zoomAdjustedPixelValue(style->outlineOffset(), *style);
2936         case CSSPropertyOutlineStyle:
2937             if (style->outlineStyleIsAuto())
2938                 return cssValuePool.createIdentifierValue(CSSValueAuto);
2939             return cssValuePool.createValue(style->outlineStyle());
2940         case CSSPropertyOutlineWidth:
2941             return zoomAdjustedPixelValue(style->outlineWidth(), *style);
2942         case CSSPropertyOverflow:
2943             return cssValuePool.createValue(std::max(style->overflowX(), style->overflowY()));
2944         case CSSPropertyOverflowWrap:
2945             return cssValuePool.createValue(style->overflowWrap());
2946         case CSSPropertyOverflowX:
2947             return cssValuePool.createValue(style->overflowX());
2948         case CSSPropertyOverflowY:
2949             return cssValuePool.createValue(style->overflowY());
2950         case CSSPropertyPaddingTop:
2951             return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::paddingTop, &RenderBoxModelObject::computedCSSPaddingTop>(*style, renderer);
2952         case CSSPropertyPaddingRight:
2953             return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::paddingRight, &RenderBoxModelObject::computedCSSPaddingRight>(*style, renderer);
2954         case CSSPropertyPaddingBottom:
2955             return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::paddingBottom, &RenderBoxModelObject::computedCSSPaddingBottom>(*style, renderer);
2956         case CSSPropertyPaddingLeft:
2957             return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::paddingLeft, &RenderBoxModelObject::computedCSSPaddingLeft>(*style, renderer);
2958         case CSSPropertyPageBreakAfter:
2959             return cssValuePool.createValue(style->pageBreakAfter());
2960         case CSSPropertyPageBreakBefore:
2961             return cssValuePool.createValue(style->pageBreakBefore());
2962         case CSSPropertyPageBreakInside: {
2963             EPageBreak pageBreak = style->pageBreakInside();
2964             ASSERT(pageBreak != PBALWAYS);
2965             if (pageBreak == PBALWAYS)
2966                 return nullptr;
2967             return cssValuePool.createValue(style->pageBreakInside());
2968         }
2969         case CSSPropertyPosition:
2970             return cssValuePool.createValue(style->position());
2971         case CSSPropertyRight:
2972             return positionOffsetValue(*style, CSSPropertyRight);
2973         case CSSPropertyWebkitRubyPosition:
2974             return cssValuePool.createValue(style->rubyPosition());
2975         case CSSPropertyTableLayout:
2976             return cssValuePool.createValue(style->tableLayout());
2977         case CSSPropertyTextAlign:
2978             return cssValuePool.createValue(style->textAlign());
2979         case CSSPropertyTextDecoration:
2980             return renderTextDecorationFlagsToCSSValue(style->textDecoration());
2981 #if ENABLE(CSS3_TEXT)
2982         case CSSPropertyWebkitTextAlignLast:
2983             return cssValuePool.createValue(style->textAlignLast());
2984         case CSSPropertyWebkitTextJustify:
2985             return cssValuePool.createValue(style->textJustify());
2986 #endif // CSS3_TEXT
2987         case CSSPropertyWebkitTextDecoration:
2988             return getCSSPropertyValuesForShorthandProperties(webkitTextDecorationShorthand());
2989         case CSSPropertyWebkitTextDecorationLine:
2990             return renderTextDecorationFlagsToCSSValue(style->textDecoration());
2991         case CSSPropertyWebkitTextDecorationStyle:
2992             return renderTextDecorationStyleFlagsToCSSValue(style->textDecorationStyle());
2993         case CSSPropertyWebkitTextDecorationColor:
2994             return currentColorOrValidColor(style.get(), style->textDecorationColor());
2995         case CSSPropertyWebkitTextDecorationSkip:
2996             return renderTextDecorationSkipFlagsToCSSValue(style->textDecorationSkip());
2997         case CSSPropertyWebkitTextUnderlinePosition:
2998             return cssValuePool.createValue(style->textUnderlinePosition());
2999         case CSSPropertyWebkitTextDecorationsInEffect:
3000             return renderTextDecorationFlagsToCSSValue(style->textDecorationsInEffect());
3001         case CSSPropertyWebkitTextFillColor:
3002             return currentColorOrValidColor(style.get(), style->textFillColor());
3003         case CSSPropertyWebkitTextEmphasisColor:
3004             return currentColorOrValidColor(style.get(), style->textEmphasisColor());
3005         case CSSPropertyWebkitTextEmphasisPosition:
3006             return renderEmphasisPositionFlagsToCSSValue(style->textEmphasisPosition());
3007         case CSSPropertyWebkitTextEmphasisStyle:
3008             switch (style->textEmphasisMark()) {
3009             case TextEmphasisMarkNone:
3010                 return cssValuePool.createIdentifierValue(CSSValueNone);
3011             case TextEmphasisMarkCustom:
3012                 return cssValuePool.createValue(style->textEmphasisCustomMark(), CSSPrimitiveValue::CSS_STRING);
3013             case TextEmphasisMarkAuto:
3014                 ASSERT_NOT_REACHED();
3015 #if ASSERT_DISABLED
3016                 FALLTHROUGH;
3017 #endif
3018             case TextEmphasisMarkDot:
3019             case TextEmphasisMarkCircle:
3020             case TextEmphasisMarkDoubleCircle:
3021             case TextEmphasisMarkTriangle:
3022             case TextEmphasisMarkSesame: {
3023                 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
3024                 list->append(cssValuePool.createValue(style->textEmphasisFill()));
3025                 list->append(cssValuePool.createValue(style->textEmphasisMark()));
3026                 return list;
3027             }
3028             }
3029         case CSSPropertyTextIndent: {
3030             // If CSS3_TEXT is disabled or text-indent has only one value(<length> | <percentage>),
3031             // getPropertyCSSValue() returns CSSValue.
3032             RefPtr<CSSValue> textIndent = zoomAdjustedPixelValueForLength(style->textIndent(), *style);
3033 #if ENABLE(CSS3_TEXT)
3034             // If CSS3_TEXT is enabled and text-indent has -webkit-each-line or -webkit-hanging,
3035             // getPropertyCSSValue() returns CSSValueList.
3036             if (style->textIndentLine() == TextIndentEachLine || style->textIndentType() == TextIndentHanging) {
3037                 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
3038                 list->append(textIndent.releaseNonNull());
3039                 if (style->textIndentLine() == TextIndentEachLine)
3040                     list->append(cssValuePool.createIdentifierValue(CSSValueWebkitEachLine));
3041                 if (style->textIndentType() == TextIndentHanging)
3042                     list->append(cssValuePool.createIdentifierValue(CSSValueWebkitHanging));
3043                 return list;
3044             }
3045 #endif
3046             return textIndent;
3047         }
3048         case CSSPropertyTextShadow:
3049             return valueForShadow(style->textShadow(), propertyID, *style);
3050         case CSSPropertyTextRendering:
3051             return cssValuePool.createValue(style->fontDescription().textRenderingMode());
3052         case CSSPropertyTextOverflow:
3053             if (style->textOverflow())
3054                 return cssValuePool.createIdentifierValue(CSSValueEllipsis);
3055             return cssValuePool.createIdentifierValue(CSSValueClip);
3056         case CSSPropertyWebkitTextSecurity:
3057             return cssValuePool.createValue(style->textSecurity());
3058 #if ENABLE(IOS_TEXT_AUTOSIZING)
3059         case CSSPropertyWebkitTextSizeAdjust:
3060             if (style->textSizeAdjust().isAuto())
3061                 return cssValuePool.createIdentifierValue(CSSValueAuto);
3062             if (style->textSizeAdjust().isNone())
3063                 return cssValuePool.createIdentifierValue(CSSValueNone);
3064             return CSSPrimitiveValue::create(style->textSizeAdjust().percentage(), CSSPrimitiveValue::CSS_PERCENTAGE);
3065 #endif
3066         case CSSPropertyWebkitTextStrokeColor:
3067             return currentColorOrValidColor(style.get(), style->textStrokeColor());
3068         case CSSPropertyWebkitTextStrokeWidth:
3069             return zoomAdjustedPixelValue(style->textStrokeWidth(), *style);
3070         case CSSPropertyTextTransform:
3071             return cssValuePool.createValue(style->textTransform());
3072         case CSSPropertyTop:
3073             return positionOffsetValue(*style, CSSPropertyTop);
3074         case CSSPropertyUnicodeBidi:
3075             return cssValuePool.createValue(style->unicodeBidi());
3076         case CSSPropertyVerticalAlign:
3077             switch (style->verticalAlign()) {
3078                 case BASELINE:
3079                     return cssValuePool.createIdentifierValue(CSSValueBaseline);
3080                 case MIDDLE:
3081                     return cssValuePool.createIdentifierValue(CSSValueMiddle);
3082                 case SUB:
3083                     return cssValuePool.createIdentifierValue(CSSValueSub);
3084                 case SUPER:
3085                     return cssValuePool.createIdentifierValue(CSSValueSuper);
3086                 case TEXT_TOP:
3087                     return cssValuePool.createIdentifierValue(CSSValueTextTop);
3088                 case TEXT_BOTTOM:
3089                     return cssValuePool.createIdentifierValue(CSSValueTextBottom);
3090                 case TOP:
3091                     return cssValuePool.createIdentifierValue(CSSValueTop);
3092                 case BOTTOM:
3093                     return cssValuePool.createIdentifierValue(CSSValueBottom);
3094                 case BASELINE_MIDDLE:
3095                     return cssValuePool.createIdentifierValue(CSSValueWebkitBaselineMiddle);
3096                 case LENGTH:
3097                     return cssValuePool.createValue(style->verticalAlignLength());
3098             }
3099             ASSERT_NOT_REACHED();
3100             return nullptr;
3101         case CSSPropertyVisibility:
3102             return cssValuePool.createValue(style->visibility());
3103         case CSSPropertyWhiteSpace:
3104             return cssValuePool.createValue(style->whiteSpace());
3105         case CSSPropertyWidows:
3106             if (style->hasAutoWidows())
3107                 return cssValuePool.createIdentifierValue(CSSValueAuto);
3108             return cssValuePool.createValue(style->widows(), CSSPrimitiveValue::CSS_NUMBER);
3109         case CSSPropertyWidth:
3110             if (renderer && !renderer->isRenderSVGModelObject()) {
3111                 // According to http://www.w3.org/TR/CSS2/visudet.html#the-width-property,
3112                 // the "width" property does not apply for non-replaced inline elements.
3113                 if (!renderer->isReplaced() && renderer->isInline())
3114                     return cssValuePool.createIdentifierValue(CSSValueAuto);
3115                 return zoomAdjustedPixelValue(sizingBox(*renderer).width(), *style);
3116             }
3117             return zoomAdjustedPixelValueForLength(style->width(), *style);
3118         case CSSPropertyWillChange:
3119             return getWillChangePropertyValue(style->willChange());
3120             break;
3121         case CSSPropertyWordBreak:
3122             return cssValuePool.createValue(style->wordBreak());
3123         case CSSPropertyWordSpacing:
3124             return zoomAdjustedPixelValue(style->fontCascade().wordSpacing(), *style);
3125         case CSSPropertyWordWrap:
3126             return cssValuePool.createValue(style->overflowWrap());
3127         case CSSPropertyWebkitLineBreak:
3128             return cssValuePool.createValue(style->lineBreak());
3129         case CSSPropertyWebkitNbspMode:
3130             return cssValuePool.createValue(style->nbspMode());
3131         case CSSPropertyResize:
3132             return cssValuePool.createValue(style->resize());
3133         case CSSPropertyWebkitFontKerning:
3134             return cssValuePool.createValue(style->fontDescription().kerning());
3135         case CSSPropertyWebkitFontSmoothing:
3136             return cssValuePool.createValue(style->fontDescription().fontSmoothing());
3137         case CSSPropertyFontVariantLigatures:
3138             return fontVariantLigaturesPropertyValue(style->fontDescription().variantCommonLigatures(), style->fontDescription().variantDiscretionaryLigatures(), style->fontDescription().variantHistoricalLigatures(), style->fontDescription().variantContextualAlternates());
3139         case CSSPropertyFontVariantPosition:
3140             return fontVariantPositionPropertyValue(style->fontDescription().variantPosition());
3141         case CSSPropertyFontVariantCaps:
3142             return fontVariantCapsPropertyValue(style->fontDescription().variantCaps());
3143         case CSSPropertyFontVariantNumeric:
3144             return fontVariantNumericPropertyValue(style->fontDescription().variantNumericFigure(), style->fontDescription().variantNumericSpacing(), style->fontDescription().variantNumericFraction(), style->fontDescription().variantNumericOrdinal(), style->fontDescription().variantNumericSlashedZero());
3145         case CSSPropertyFontVariantAlternates:
3146             return fontVariantAlternatesPropertyValue(style->fontDescription().variantAlternates());
3147         case CSSPropertyFontVariantEastAsian:
3148             return fontVariantEastAsianPropertyValue(style->fontDescription().variantEastAsianVariant(), style->fontDescription().variantEastAsianWidth(), style->fontDescription().variantEastAsianRuby());
3149         case CSSPropertyZIndex:
3150             if (style->hasAutoZIndex())
3151                 return cssValuePool.createIdentifierValue(CSSValueAuto);
3152             return cssValuePool.createValue(style->zIndex(), CSSPrimitiveValue::CSS_NUMBER);
3153         case CSSPropertyZoom:
3154             return cssValuePool.createValue(style->zoom(), CSSPrimitiveValue::CSS_NUMBER);
3155         case CSSPropertyBoxSizing:
3156             if (style->boxSizing() == CONTENT_BOX)
3157                 return cssValuePool.createIdentifierValue(CSSValueContentBox);
3158             return cssValuePool.createIdentifierValue(CSSValueBorderBox);
3159 #if ENABLE(DASHBOARD_SUPPORT)
3160         case CSSPropertyWebkitDashboardRegion:
3161         {
3162             const Vector<StyleDashboardRegion>& regions = style->dashboardRegions();
3163             unsigned count = regions.size();
3164             if (count == 1 && regions[0].type == StyleDashboardRegion::None)
3165                 return cssValuePool.createIdentifierValue(CSSValueNone);
3166
3167             RefPtr<DashboardRegion> firstRegion;
3168             DashboardRegion* previousRegion = nullptr;
3169             for (unsigned i = 0; i < count; i++) {
3170                 auto region = DashboardRegion::create();
3171                 StyleDashboardRegion styleRegion = regions[i];
3172
3173                 region->m_label = styleRegion.label;
3174                 LengthBox offset = styleRegion.offset;
3175                 region->setTop(zoomAdjustedPixelValue(offset.top().value(), *style));
3176                 region->setRight(zoomAdjustedPixelValue(offset.right().value(), *style));
3177                 region->setBottom(zoomAdjustedPixelValue(offset.bottom().value(), *style));
3178                 region->setLeft(zoomAdjustedPixelValue(offset.left().value(), *style));
3179                 region->m_isRectangle = (styleRegion.type == StyleDashboardRegion::Rectangle);
3180                 region->m_isCircle = (styleRegion.type == StyleDashboardRegion::Circle);
3181
3182                 if (previousRegion)
3183                     previousRegion->m_next = region.copyRef();
3184                 else
3185                     firstRegion = region.copyRef();
3186                 previousRegion = region.ptr();
3187             }
3188             return cssValuePool.createValue(WTFMove(firstRegion));
3189         }
3190 #endif
3191         case CSSPropertyAnimationDelay:
3192         case CSSPropertyWebkitAnimationDelay:
3193             return getDelayValue(style->animations());
3194         case CSSPropertyAnimationDirection:
3195         case CSSPropertyWebkitAnimationDirection: {
3196             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
3197             const AnimationList* t = style->animations();
3198             if (t) {
3199                 for (size_t i = 0; i < t->size(); ++i) {
3200                     switch (t->animation(i).direction()) {
3201                     case Animation::AnimationDirectionNormal:
3202                         list->append(cssValuePool.createIdentifierValue(CSSValueNormal));
3203