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