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