1fd99875d041e743d80e2d2e27d6076d4ff1d344
[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 "CSSParser.h"
43 #include "CSSPrimitiveValue.h"
44 #include "CSSPrimitiveValueMappings.h"
45 #include "CSSPropertyNames.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 "Document.h"
57 #include "ExceptionCode.h"
58 #include "FontTaggedSettings.h"
59 #include "HTMLFrameOwnerElement.h"
60 #include "NodeRenderStyle.h"
61 #include "Pair.h"
62 #include "PseudoElement.h"
63 #include "Rect.h"
64 #include "RenderBlock.h"
65 #include "RenderBox.h"
66 #include "RenderStyle.h"
67 #include "RuntimeEnabledFeatures.h"
68 #include "SVGElement.h"
69 #include "Settings.h"
70 #include "ShapeValue.h"
71 #include "StyleInheritedData.h"
72 #include "StyleProperties.h"
73 #include "StylePropertyShorthand.h"
74 #include "StylePropertyShorthandFunctions.h"
75 #include "StyleResolver.h"
76 #include "StyleScope.h"
77 #include "Text.h"
78 #include "WebKitCSSTransformValue.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->isBackgroundOriginSet()) {
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->isBackgroundOriginSet()) {
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<WebKitCSSTransformValue> matrixTransformValue(const TransformationMatrix& transform, const RenderStyle& style)
822 {
823     RefPtr<WebKitCSSTransformValue> transformValue;
824     auto& cssValuePool = CSSValuePool::singleton();
825     if (transform.isAffine()) {
826         transformValue = WebKitCSSTransformValue::create(WebKitCSSTransformValue::MatrixTransformOperation);
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 = WebKitCSSTransformValue::create(WebKitCSSTransformValue::Matrix3DTransformOperation);
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 = CSSValueList::createCommaSeparated();
1010         fitContentTrackSize->append(zoomAdjustedPixelValueForLength(trackSize.fitContentTrackBreadth().length(), style));
1011         return CSSFunctionValue::create("fit-content(", WTFMove(fitContentTrackSize));
1012     }
1013     default:
1014         ASSERT(trackSize.type() == MinMaxTrackSizing);
1015         auto minMaxTrackBreadths = CSSValueList::createCommaSeparated();
1016         minMaxTrackBreadths->append(specifiedValueForGridTrackBreadth(trackSize.minTrackBreadth(), style));
1017         minMaxTrackBreadths->append(specifiedValueForGridTrackBreadth(trackSize.maxTrackBreadth(), style));
1018         return CSSFunctionValue::create("minmax(", WTFMove(minMaxTrackBreadths));
1019     }
1020 }
1021
1022 class OrderedNamedLinesCollector {
1023     WTF_MAKE_NONCOPYABLE(OrderedNamedLinesCollector);
1024 public:
1025     OrderedNamedLinesCollector(const RenderStyle& style, bool isRowAxis, unsigned autoRepeatTracksCount)
1026         : m_orderedNamedGridLines(isRowAxis ? style.orderedNamedGridColumnLines() : style.orderedNamedGridRowLines())
1027         , m_orderedNamedAutoRepeatGridLines(isRowAxis ? style.autoRepeatOrderedNamedGridColumnLines() : style.autoRepeatOrderedNamedGridRowLines())
1028         , m_insertionPoint(isRowAxis ? style.gridAutoRepeatColumnsInsertionPoint() : style.gridAutoRepeatRowsInsertionPoint())
1029         , m_autoRepeatTotalTracks(autoRepeatTracksCount)
1030         , m_autoRepeatTrackListLength(isRowAxis ? style.gridAutoRepeatColumns().size() : style.gridAutoRepeatRows().size())
1031     {
1032     }
1033
1034     bool isEmpty() const { return m_orderedNamedGridLines.isEmpty() && m_orderedNamedAutoRepeatGridLines.isEmpty(); }
1035     void collectLineNamesForIndex(CSSGridLineNamesValue&, unsigned index) const;
1036
1037 private:
1038
1039     enum NamedLinesType { NamedLines, AutoRepeatNamedLines };
1040     void appendLines(CSSGridLineNamesValue&, unsigned index, NamedLinesType) const;
1041
1042     const OrderedNamedGridLinesMap& m_orderedNamedGridLines;
1043     const OrderedNamedGridLinesMap& m_orderedNamedAutoRepeatGridLines;
1044     unsigned m_insertionPoint;
1045     unsigned m_autoRepeatTotalTracks;
1046     unsigned m_autoRepeatTrackListLength;
1047 };
1048
1049 void OrderedNamedLinesCollector::appendLines(CSSGridLineNamesValue& lineNamesValue, unsigned index, NamedLinesType type) const
1050 {
1051     auto iter = type == NamedLines ? m_orderedNamedGridLines.find(index) : m_orderedNamedAutoRepeatGridLines.find(index);
1052     auto endIter = type == NamedLines ? m_orderedNamedGridLines.end() : m_orderedNamedAutoRepeatGridLines.end();
1053     if (iter == endIter)
1054         return;
1055
1056     auto& cssValuePool = CSSValuePool::singleton();
1057     for (auto lineName : iter->value)
1058         lineNamesValue.append(cssValuePool.createValue(lineName, CSSPrimitiveValue::CSS_STRING));
1059 }
1060
1061 void OrderedNamedLinesCollector::collectLineNamesForIndex(CSSGridLineNamesValue& lineNamesValue, unsigned i) const
1062 {
1063     ASSERT(!isEmpty());
1064     if (m_orderedNamedAutoRepeatGridLines.isEmpty() || i < m_insertionPoint) {
1065         appendLines(lineNamesValue, i, NamedLines);
1066         return;
1067     }
1068
1069     ASSERT(m_autoRepeatTotalTracks);
1070
1071     if (i > m_insertionPoint + m_autoRepeatTotalTracks) {
1072         appendLines(lineNamesValue, i - (m_autoRepeatTotalTracks - 1), NamedLines);
1073         return;
1074     }
1075
1076     if (i == m_insertionPoint) {
1077         appendLines(lineNamesValue, i, NamedLines);
1078         appendLines(lineNamesValue, 0, AutoRepeatNamedLines);
1079         return;
1080     }
1081
1082     if (i == m_insertionPoint + m_autoRepeatTotalTracks) {
1083         appendLines(lineNamesValue, m_autoRepeatTrackListLength, AutoRepeatNamedLines);
1084         appendLines(lineNamesValue, m_insertionPoint + 1, NamedLines);
1085         return;
1086     }
1087
1088     unsigned autoRepeatIndexInFirstRepetition = (i - m_insertionPoint) % m_autoRepeatTrackListLength;
1089     if (!autoRepeatIndexInFirstRepetition && i > m_insertionPoint)
1090         appendLines(lineNamesValue, m_autoRepeatTrackListLength, AutoRepeatNamedLines);
1091     appendLines(lineNamesValue, autoRepeatIndexInFirstRepetition, AutoRepeatNamedLines);
1092 }
1093
1094 static void addValuesForNamedGridLinesAtIndex(OrderedNamedLinesCollector& collector, unsigned i, CSSValueList& list)
1095 {
1096     if (collector.isEmpty())
1097         return;
1098
1099     auto lineNames = CSSGridLineNamesValue::create();
1100     collector.collectLineNamesForIndex(lineNames.get(), i);
1101     if (lineNames->length())
1102         list.append(WTFMove(lineNames));
1103 }
1104
1105 static Ref<CSSValueList> valueForGridTrackSizeList(GridTrackSizingDirection direction, const RenderStyle& style)
1106 {
1107     auto& autoTrackSizes = direction == ForColumns ? style.gridAutoColumns() : style.gridAutoRows();
1108
1109     auto list = CSSValueList::createSpaceSeparated();
1110     for (auto& trackSize : autoTrackSizes)
1111         list->append(specifiedValueForGridTrackSize(trackSize, style));
1112     return list;
1113 }
1114
1115 static Ref<CSSValue> valueForGridTrackList(GridTrackSizingDirection direction, RenderObject* renderer, const RenderStyle& style)
1116 {
1117     bool isRowAxis = direction == ForColumns;
1118     bool isRenderGrid = is<RenderGrid>(renderer);
1119     auto& trackSizes = isRowAxis ? style.gridColumns() : style.gridRows();
1120     auto& autoRepeatTrackSizes = isRowAxis ? style.gridAutoRepeatColumns() : style.gridAutoRepeatRows();
1121
1122     // Handle the 'none' case.
1123     bool trackListIsEmpty = trackSizes.isEmpty() && autoRepeatTrackSizes.isEmpty();
1124     if (isRenderGrid && trackListIsEmpty) {
1125         // For grids we should consider every listed track, whether implicitly or explicitly
1126         // created. Empty grids have a sole grid line per axis.
1127         auto& grid = downcast<RenderGrid>(*renderer);
1128         auto& positions = isRowAxis ? grid.columnPositions() : grid.rowPositions();
1129         trackListIsEmpty = positions.size() == 1;
1130     }
1131
1132     if (trackListIsEmpty)
1133         return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
1134
1135     unsigned autoRepeatTotalTracks = isRenderGrid ? downcast<RenderGrid>(renderer)->autoRepeatCountForDirection(direction) : 0;
1136     OrderedNamedLinesCollector collector(style, isRowAxis, autoRepeatTotalTracks);
1137     auto list = CSSValueList::createSpaceSeparated();
1138     unsigned insertionIndex;
1139     if (isRenderGrid) {
1140         auto computedTrackSizes = downcast<RenderGrid>(*renderer).trackSizesForComputedStyle(direction);
1141         unsigned numTracks = computedTrackSizes.size();
1142
1143         for (unsigned i = 0; i < numTracks; ++i) {
1144             addValuesForNamedGridLinesAtIndex(collector, i, list.get());
1145             list->append(zoomAdjustedPixelValue(computedTrackSizes[i], style));
1146         }
1147         addValuesForNamedGridLinesAtIndex(collector, numTracks + 1, list.get());
1148         insertionIndex = numTracks;
1149     } else {
1150         for (unsigned i = 0; i < trackSizes.size(); ++i) {
1151             addValuesForNamedGridLinesAtIndex(collector, i, list.get());
1152             list.get().append(specifiedValueForGridTrackSize(trackSizes[i], style));
1153         }
1154         insertionIndex = trackSizes.size();
1155     }
1156
1157     // Those are the trailing <ident>* allowed in the syntax.
1158     addValuesForNamedGridLinesAtIndex(collector, insertionIndex, list.get());
1159     return WTFMove(list);
1160 }
1161
1162 static Ref<CSSValue> valueForGridPosition(const GridPosition& position)
1163 {
1164     auto& cssValuePool = CSSValuePool::singleton();
1165     if (position.isAuto())
1166         return cssValuePool.createIdentifierValue(CSSValueAuto);
1167
1168     if (position.isNamedGridArea())
1169         return cssValuePool.createValue(position.namedGridLine(), CSSPrimitiveValue::CSS_STRING);
1170
1171     auto list = CSSValueList::createSpaceSeparated();
1172     if (position.isSpan()) {
1173         list.get().append(cssValuePool.createIdentifierValue(CSSValueSpan));
1174         list.get().append(cssValuePool.createValue(position.spanPosition(), CSSPrimitiveValue::CSS_NUMBER));
1175     } else
1176         list.get().append(cssValuePool.createValue(position.integerPosition(), CSSPrimitiveValue::CSS_NUMBER));
1177
1178     if (!position.namedGridLine().isNull())
1179         list.get().append(cssValuePool.createValue(position.namedGridLine(), CSSPrimitiveValue::CSS_STRING));
1180     return WTFMove(list);
1181 }
1182 #endif
1183
1184 static Ref<CSSValue> createTransitionPropertyValue(const Animation& animation)
1185 {
1186     if (animation.animationMode() == Animation::AnimateNone)
1187         return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
1188     if (animation.animationMode() == Animation::AnimateAll)
1189         return CSSValuePool::singleton().createIdentifierValue(CSSValueAll);
1190     return CSSValuePool::singleton().createValue(getPropertyNameString(animation.property()), CSSPrimitiveValue::CSS_STRING);
1191 }
1192
1193 static Ref<CSSValueList> getTransitionPropertyValue(const AnimationList* animList)
1194 {
1195     auto list = CSSValueList::createCommaSeparated();
1196     if (animList) {
1197         for (size_t i = 0; i < animList->size(); ++i)
1198             list.get().append(createTransitionPropertyValue(animList->animation(i)));
1199     } else
1200         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueAll));
1201     return list;
1202 }
1203
1204 #if ENABLE(CSS_SCROLL_SNAP)
1205 static Ref<CSSValueList> scrollSnapDestination(const RenderStyle& style, const LengthSize& destination)
1206 {
1207     auto list = CSSValueList::createSpaceSeparated();
1208     list.get().append(zoomAdjustedPixelValueForLength(destination.width(), style));
1209     list.get().append(zoomAdjustedPixelValueForLength(destination.height(), style));
1210     return list;
1211 }
1212
1213 static Ref<CSSValue> scrollSnapPoints(const RenderStyle& style, const ScrollSnapPoints* points)
1214 {
1215     if (!points)
1216         return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
1217
1218     if (points->usesElements)
1219         return CSSValuePool::singleton().createIdentifierValue(CSSValueElements);
1220     auto list = CSSValueList::createSpaceSeparated();
1221     for (auto& point : points->offsets)
1222         list.get().append(zoomAdjustedPixelValueForLength(point, style));
1223     if (points->hasRepeat)
1224         list.get().append(CSSValuePool::singleton().createValue(LengthRepeat::create(zoomAdjustedPixelValueForLength(points->repeatOffset, style))));
1225     return WTFMove(list);
1226 }
1227
1228 static Ref<CSSValue> scrollSnapCoordinates(const RenderStyle& style, const Vector<LengthSize>& coordinates)
1229 {
1230     if (coordinates.isEmpty())
1231         return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
1232
1233     auto list = CSSValueList::createCommaSeparated();
1234
1235     for (auto& coordinate : coordinates) {
1236         auto pair = CSSValueList::createSpaceSeparated();
1237         pair.get().append(zoomAdjustedPixelValueForLength(coordinate.width(), style));
1238         pair.get().append(zoomAdjustedPixelValueForLength(coordinate.height(), style));
1239         list.get().append(WTFMove(pair));
1240     }
1241
1242     return WTFMove(list);
1243 }
1244 #endif
1245
1246 static Ref<CSSValue> getWillChangePropertyValue(const WillChangeData* willChangeData)
1247 {
1248     auto& cssValuePool = CSSValuePool::singleton();
1249     if (!willChangeData || !willChangeData->numFeatures())
1250         return cssValuePool.createIdentifierValue(CSSValueAuto);
1251
1252     auto list = CSSValueList::createCommaSeparated();
1253     for (size_t i = 0; i < willChangeData->numFeatures(); ++i) {
1254         WillChangeData::FeaturePropertyPair feature = willChangeData->featureAt(i);
1255         switch (feature.first) {
1256         case WillChangeData::ScrollPosition:
1257             list.get().append(cssValuePool.createIdentifierValue(CSSValueScrollPosition));
1258             break;
1259         case WillChangeData::Contents:
1260             list.get().append(cssValuePool.createIdentifierValue(CSSValueContents));
1261             break;
1262         case WillChangeData::Property:
1263             list.get().append(cssValuePool.createIdentifierValue(feature.second));
1264             break;
1265         case WillChangeData::Invalid:
1266             ASSERT_NOT_REACHED();
1267             break;
1268         }
1269     }
1270
1271     return WTFMove(list);
1272 }
1273
1274 static inline void appendLigaturesValue(CSSValueList& list, FontVariantLigatures value, CSSValueID yesValue, CSSValueID noValue)
1275 {
1276     switch (value) {
1277     case FontVariantLigatures::Normal:
1278         return;
1279     case FontVariantLigatures::No:
1280         list.append(CSSValuePool::singleton().createIdentifierValue(noValue));
1281         return;
1282     case FontVariantLigatures::Yes:
1283         list.append(CSSValuePool::singleton().createIdentifierValue(yesValue));
1284         return;
1285     }
1286     ASSERT_NOT_REACHED();
1287 }
1288
1289 static Ref<CSSValue> fontVariantLigaturesPropertyValue(FontVariantLigatures common, FontVariantLigatures discretionary, FontVariantLigatures historical, FontVariantLigatures contextualAlternates)
1290 {
1291     auto& cssValuePool = CSSValuePool::singleton();
1292     if (common == FontVariantLigatures::No && discretionary == FontVariantLigatures::No && historical == FontVariantLigatures::No && contextualAlternates == FontVariantLigatures::No)
1293         return cssValuePool.createIdentifierValue(CSSValueNone);
1294     if (common == FontVariantLigatures::Normal && discretionary == FontVariantLigatures::Normal && historical == FontVariantLigatures::Normal && contextualAlternates == FontVariantLigatures::Normal)
1295         return cssValuePool.createIdentifierValue(CSSValueNormal);
1296
1297     auto valueList = CSSValueList::createSpaceSeparated();
1298     appendLigaturesValue(valueList, common, CSSValueCommonLigatures, CSSValueNoCommonLigatures);
1299     appendLigaturesValue(valueList, discretionary, CSSValueDiscretionaryLigatures, CSSValueNoDiscretionaryLigatures);
1300     appendLigaturesValue(valueList, historical, CSSValueHistoricalLigatures, CSSValueNoHistoricalLigatures);
1301     appendLigaturesValue(valueList, contextualAlternates, CSSValueContextual, CSSValueNoContextual);
1302     return WTFMove(valueList);
1303 }
1304
1305 static Ref<CSSValue> fontVariantPositionPropertyValue(FontVariantPosition position)
1306 {
1307     auto& cssValuePool = CSSValuePool::singleton();
1308     CSSValueID valueID = CSSValueNormal;
1309     switch (position) {
1310     case FontVariantPosition::Normal:
1311         break;
1312     case FontVariantPosition::Subscript:
1313         valueID = CSSValueSub;
1314         break;
1315     case FontVariantPosition::Superscript:
1316         valueID = CSSValueSuper;
1317         break;
1318     }
1319     return cssValuePool.createIdentifierValue(valueID);
1320 }
1321
1322 static Ref<CSSValue> fontVariantCapsPropertyValue(FontVariantCaps caps)
1323 {
1324     auto& cssValuePool = CSSValuePool::singleton();
1325     CSSValueID valueID = CSSValueNormal;
1326     switch (caps) {
1327     case FontVariantCaps::Normal:
1328         break;
1329     case FontVariantCaps::Small:
1330         valueID = CSSValueSmallCaps;
1331         break;
1332     case FontVariantCaps::AllSmall:
1333         valueID = CSSValueAllSmallCaps;
1334         break;
1335     case FontVariantCaps::Petite:
1336         valueID = CSSValuePetiteCaps;
1337         break;
1338     case FontVariantCaps::AllPetite:
1339         valueID = CSSValueAllPetiteCaps;
1340         break;
1341     case FontVariantCaps::Unicase:
1342         valueID = CSSValueUnicase;
1343         break;
1344     case FontVariantCaps::Titling:
1345         valueID = CSSValueTitlingCaps;
1346         break;
1347     }
1348     return cssValuePool.createIdentifierValue(valueID);
1349 }
1350
1351 static Ref<CSSValue> fontVariantNumericPropertyValue(FontVariantNumericFigure figure, FontVariantNumericSpacing spacing, FontVariantNumericFraction fraction, FontVariantNumericOrdinal ordinal, FontVariantNumericSlashedZero slashedZero)
1352 {
1353     auto& cssValuePool = CSSValuePool::singleton();
1354     if (figure == FontVariantNumericFigure::Normal && spacing == FontVariantNumericSpacing::Normal && fraction == FontVariantNumericFraction::Normal && ordinal == FontVariantNumericOrdinal::Normal && slashedZero == FontVariantNumericSlashedZero::Normal)
1355         return cssValuePool.createIdentifierValue(CSSValueNormal);
1356
1357     auto valueList = CSSValueList::createSpaceSeparated();
1358     switch (figure) {
1359     case FontVariantNumericFigure::Normal:
1360         break;
1361     case FontVariantNumericFigure::LiningNumbers:
1362         valueList->append(cssValuePool.createIdentifierValue(CSSValueLiningNums));
1363         break;
1364     case FontVariantNumericFigure::OldStyleNumbers:
1365         valueList->append(cssValuePool.createIdentifierValue(CSSValueOldstyleNums));
1366         break;
1367     }
1368
1369     switch (spacing) {
1370     case FontVariantNumericSpacing::Normal:
1371         break;
1372     case FontVariantNumericSpacing::ProportionalNumbers:
1373         valueList->append(cssValuePool.createIdentifierValue(CSSValueProportionalNums));
1374         break;
1375     case FontVariantNumericSpacing::TabularNumbers:
1376         valueList->append(cssValuePool.createIdentifierValue(CSSValueTabularNums));
1377         break;
1378     }
1379
1380     switch (fraction) {
1381     case FontVariantNumericFraction::Normal:
1382         break;
1383     case FontVariantNumericFraction::DiagonalFractions:
1384         valueList->append(cssValuePool.createIdentifierValue(CSSValueDiagonalFractions));
1385         break;
1386     case FontVariantNumericFraction::StackedFractions:
1387         valueList->append(cssValuePool.createIdentifierValue(CSSValueStackedFractions));
1388         break;
1389     }
1390
1391     if (ordinal == FontVariantNumericOrdinal::Yes)
1392         valueList->append(cssValuePool.createIdentifierValue(CSSValueOrdinal));
1393     if (slashedZero == FontVariantNumericSlashedZero::Yes)
1394         valueList->append(cssValuePool.createIdentifierValue(CSSValueSlashedZero));
1395
1396     return WTFMove(valueList);
1397 }
1398
1399 static Ref<CSSValue> fontVariantAlternatesPropertyValue(FontVariantAlternates alternates)
1400 {
1401     auto& cssValuePool = CSSValuePool::singleton();
1402     CSSValueID valueID = CSSValueNormal;
1403     switch (alternates) {
1404     case FontVariantAlternates::Normal:
1405         break;
1406     case FontVariantAlternates::HistoricalForms:
1407         valueID = CSSValueHistoricalForms;
1408         break;
1409     }
1410     return cssValuePool.createIdentifierValue(valueID);
1411 }
1412
1413 static Ref<CSSValue> fontVariantEastAsianPropertyValue(FontVariantEastAsianVariant variant, FontVariantEastAsianWidth width, FontVariantEastAsianRuby ruby)
1414 {
1415     auto& cssValuePool = CSSValuePool::singleton();
1416     if (variant == FontVariantEastAsianVariant::Normal && width == FontVariantEastAsianWidth::Normal && ruby == FontVariantEastAsianRuby::Normal)
1417         return cssValuePool.createIdentifierValue(CSSValueNormal);
1418
1419     auto valueList = CSSValueList::createSpaceSeparated();
1420     switch (variant) {
1421     case FontVariantEastAsianVariant::Normal:
1422         break;
1423     case FontVariantEastAsianVariant::Jis78:
1424         valueList->append(cssValuePool.createIdentifierValue(CSSValueJis78));
1425         break;
1426     case FontVariantEastAsianVariant::Jis83:
1427         valueList->append(cssValuePool.createIdentifierValue(CSSValueJis83));
1428         break;
1429     case FontVariantEastAsianVariant::Jis90:
1430         valueList->append(cssValuePool.createIdentifierValue(CSSValueJis90));
1431         break;
1432     case FontVariantEastAsianVariant::Jis04:
1433         valueList->append(cssValuePool.createIdentifierValue(CSSValueJis04));
1434         break;
1435     case FontVariantEastAsianVariant::Simplified:
1436         valueList->append(cssValuePool.createIdentifierValue(CSSValueSimplified));
1437         break;
1438     case FontVariantEastAsianVariant::Traditional:
1439         valueList->append(cssValuePool.createIdentifierValue(CSSValueTraditional));
1440         break;
1441     }
1442
1443     switch (width) {
1444     case FontVariantEastAsianWidth::Normal:
1445         break;
1446     case FontVariantEastAsianWidth::Full:
1447         valueList->append(cssValuePool.createIdentifierValue(CSSValueFullWidth));
1448         break;
1449     case FontVariantEastAsianWidth::Proportional:
1450         valueList->append(cssValuePool.createIdentifierValue(CSSValueProportionalWidth));
1451         break;
1452     }
1453
1454     if (ruby == FontVariantEastAsianRuby::Yes)
1455         valueList->append(cssValuePool.createIdentifierValue(CSSValueRuby));
1456
1457     return WTFMove(valueList);
1458 }
1459
1460 static Ref<CSSValueList> getDelayValue(const AnimationList* animList)
1461 {
1462     auto& cssValuePool = CSSValuePool::singleton();
1463     auto list = CSSValueList::createCommaSeparated();
1464     if (animList) {
1465         for (size_t i = 0; i < animList->size(); ++i)
1466             list.get().append(cssValuePool.createValue(animList->animation(i).delay(), CSSPrimitiveValue::CSS_S));
1467     } else {
1468         // Note that initialAnimationDelay() is used for both transitions and animations
1469         list.get().append(cssValuePool.createValue(Animation::initialDelay(), CSSPrimitiveValue::CSS_S));
1470     }
1471     return list;
1472 }
1473
1474 static Ref<CSSValueList> getDurationValue(const AnimationList* animList)
1475 {
1476     auto& cssValuePool = CSSValuePool::singleton();
1477     auto list = CSSValueList::createCommaSeparated();
1478     if (animList) {
1479         for (size_t i = 0; i < animList->size(); ++i)
1480             list.get().append(cssValuePool.createValue(animList->animation(i).duration(), CSSPrimitiveValue::CSS_S));
1481     } else {
1482         // Note that initialAnimationDuration() is used for both transitions and animations
1483         list.get().append(cssValuePool.createValue(Animation::initialDuration(), CSSPrimitiveValue::CSS_S));
1484     }
1485     return list;
1486 }
1487
1488 static Ref<CSSValue> createTimingFunctionValue(const TimingFunction* timingFunction)
1489 {
1490     switch (timingFunction->type()) {
1491     case TimingFunction::CubicBezierFunction: {
1492         auto& function = *static_cast<const CubicBezierTimingFunction*>(timingFunction);
1493         if (function.timingFunctionPreset() != CubicBezierTimingFunction::Custom) {
1494             CSSValueID valueId = CSSValueInvalid;
1495             switch (function.timingFunctionPreset()) {
1496             case CubicBezierTimingFunction::Ease:
1497                 valueId = CSSValueEase;
1498                 break;
1499             case CubicBezierTimingFunction::EaseIn:
1500                 valueId = CSSValueEaseIn;
1501                 break;
1502             case CubicBezierTimingFunction::EaseOut:
1503                 valueId = CSSValueEaseOut;
1504                 break;
1505             default:
1506                 ASSERT(function.timingFunctionPreset() == CubicBezierTimingFunction::EaseInOut);
1507                 valueId = CSSValueEaseInOut;
1508                 break;
1509             }
1510             return CSSValuePool::singleton().createIdentifierValue(valueId);
1511         }
1512         return CSSCubicBezierTimingFunctionValue::create(function.x1(), function.y1(), function.x2(), function.y2());
1513     }
1514     case TimingFunction::StepsFunction: {
1515         auto& function = *static_cast<const StepsTimingFunction*>(timingFunction);
1516         return CSSStepsTimingFunctionValue::create(function.numberOfSteps(), function.stepAtStart());
1517     }
1518     case TimingFunction::SpringFunction: {
1519         auto& function = *static_cast<const SpringTimingFunction*>(timingFunction);
1520         return CSSSpringTimingFunctionValue::create(function.mass(), function.stiffness(), function.damping(), function.initialVelocity());
1521     }
1522     default:
1523         ASSERT(timingFunction->type() == TimingFunction::LinearFunction);
1524         return CSSValuePool::singleton().createIdentifierValue(CSSValueLinear);
1525     }
1526 }
1527
1528 static Ref<CSSValueList> getTimingFunctionValue(const AnimationList* animList)
1529 {
1530     auto list = CSSValueList::createCommaSeparated();
1531     if (animList) {
1532         for (size_t i = 0; i < animList->size(); ++i)
1533             list.get().append(createTimingFunctionValue(animList->animation(i).timingFunction().get()));
1534     } else
1535         // Note that initialAnimationTimingFunction() is used for both transitions and animations
1536         list.get().append(createTimingFunctionValue(Animation::initialTimingFunction().get()));
1537     return list;
1538 }
1539
1540 #if ENABLE(CSS_ANIMATIONS_LEVEL_2)
1541 static Ref<CSSValue> createAnimationTriggerValue(const AnimationTrigger* trigger, const RenderStyle& style)
1542 {
1543     switch (trigger->type()) {
1544     case AnimationTrigger::AnimationTriggerType::ScrollAnimationTriggerType: {
1545         auto& scrollAnimationTrigger = downcast<ScrollAnimationTrigger>(*trigger);
1546         if (scrollAnimationTrigger.endValue().isAuto())
1547             return CSSAnimationTriggerScrollValue::create(zoomAdjustedPixelValueForLength(scrollAnimationTrigger.startValue(), style));
1548         return CSSAnimationTriggerScrollValue::create(zoomAdjustedPixelValueForLength(scrollAnimationTrigger.startValue(), style),
1549                                                       zoomAdjustedPixelValueForLength(scrollAnimationTrigger.endValue(), style));
1550     }
1551     default:
1552         ASSERT(trigger->type() == AnimationTrigger::AnimationTriggerType::AutoAnimationTriggerType);
1553         return CSSValuePool::singleton().createIdentifierValue(CSSValueAuto);
1554     }
1555 }
1556
1557 static Ref<CSSValueList> getAnimationTriggerValue(const AnimationList* animList, const RenderStyle& style)
1558 {
1559     auto list = CSSValueList::createCommaSeparated();
1560     if (animList) {
1561         for (size_t i = 0; i < animList->size(); ++i)
1562             list.get().append(createAnimationTriggerValue(animList->animation(i).trigger().get(), style));
1563     } else
1564         list.get().append(createAnimationTriggerValue(Animation::initialTrigger().get(), style));
1565
1566     return list;
1567 }
1568 #endif
1569
1570 static Ref<CSSValue> createLineBoxContainValue(unsigned lineBoxContain)
1571 {
1572     if (!lineBoxContain)
1573         return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
1574     return CSSLineBoxContainValue::create(lineBoxContain);
1575 }
1576
1577 static Element* styleElementForNode(Node* node)
1578 {
1579     if (!node)
1580         return nullptr;
1581     if (is<Element>(*node))
1582         return downcast<Element>(node);
1583     return composedTreeAncestors(*node).first();
1584 }
1585
1586 ComputedStyleExtractor::ComputedStyleExtractor(Node* node, bool allowVisitedStyle, PseudoId pseudoElementSpecifier)
1587     : m_element(styleElementForNode(node))
1588     , m_pseudoElementSpecifier(pseudoElementSpecifier)
1589     , m_allowVisitedStyle(allowVisitedStyle)
1590 {
1591 }
1592
1593 ComputedStyleExtractor::ComputedStyleExtractor(Element* element, bool allowVisitedStyle, PseudoId pseudoElementSpecifier)
1594     : m_element(element)
1595     , m_pseudoElementSpecifier(pseudoElementSpecifier)
1596     , m_allowVisitedStyle(allowVisitedStyle)
1597 {
1598 }
1599
1600 CSSComputedStyleDeclaration::CSSComputedStyleDeclaration(Element& element, bool allowVisitedStyle, const String& pseudoElementName)
1601     : m_element(element)
1602     , m_allowVisitedStyle(allowVisitedStyle)
1603     , m_refCount(1)
1604 {
1605     unsigned nameWithoutColonsStart = pseudoElementName[0] == ':' ? (pseudoElementName[1] == ':' ? 2 : 1) : 0;
1606     m_pseudoElementSpecifier = CSSSelector::pseudoId(CSSSelector::parsePseudoElementType(
1607     (pseudoElementName.substringSharingImpl(nameWithoutColonsStart))));
1608 }
1609
1610 CSSComputedStyleDeclaration::~CSSComputedStyleDeclaration()
1611 {
1612 }
1613
1614 void CSSComputedStyleDeclaration::ref()
1615 {
1616     ++m_refCount;
1617 }
1618
1619 void CSSComputedStyleDeclaration::deref()
1620 {
1621     ASSERT(m_refCount);
1622     if (!--m_refCount)
1623         delete this;
1624 }
1625
1626 String CSSComputedStyleDeclaration::cssText() const
1627 {
1628     StringBuilder result;
1629
1630     for (unsigned i = 0; i < numComputedProperties; i++) {
1631         if (i)
1632             result.append(' ');
1633         result.append(getPropertyName(computedProperties[i]));
1634         result.appendLiteral(": ");
1635         result.append(getPropertyValue(computedProperties[i]));
1636         result.append(';');
1637     }
1638
1639     return result.toString();
1640 }
1641
1642 ExceptionOr<void> CSSComputedStyleDeclaration::setCssText(const String&)
1643 {
1644     return Exception { NO_MODIFICATION_ALLOWED_ERR };
1645 }
1646
1647 RefPtr<CSSPrimitiveValue> ComputedStyleExtractor::getFontSizeCSSValuePreferringKeyword()
1648 {
1649     if (!m_element)
1650         return nullptr;
1651
1652     m_element->document().updateLayoutIgnorePendingStylesheets();
1653
1654     auto* style = m_element->computedStyle(m_pseudoElementSpecifier);
1655     if (!style)
1656         return nullptr;
1657
1658     if (CSSValueID sizeIdentifier = style->fontDescription().keywordSizeAsIdentifier())
1659         return CSSValuePool::singleton().createIdentifierValue(sizeIdentifier);
1660
1661     return zoomAdjustedPixelValue(style->fontDescription().computedSize(), *style);
1662 }
1663
1664 bool ComputedStyleExtractor::useFixedFontDefaultSize()
1665 {
1666     if (!m_element)
1667         return false;
1668     auto* style = m_element->computedStyle(m_pseudoElementSpecifier);
1669     if (!style)
1670         return false;
1671
1672     return style->fontDescription().useFixedDefaultSize();
1673 }
1674
1675
1676 static CSSValueID identifierForFamily(const AtomicString& family)
1677 {
1678     if (family == cursiveFamily)
1679         return CSSValueCursive;
1680     if (family == fantasyFamily)
1681         return CSSValueFantasy;
1682     if (family == monospaceFamily)
1683         return CSSValueMonospace;
1684     if (family == pictographFamily)
1685         return CSSValueWebkitPictograph;
1686     if (family == sansSerifFamily)
1687         return CSSValueSansSerif;
1688     if (family == serifFamily)
1689         return CSSValueSerif;
1690     return CSSValueInvalid;
1691 }
1692
1693 static Ref<CSSPrimitiveValue> valueForFamily(const AtomicString& family)
1694 {
1695     if (CSSValueID familyIdentifier = identifierForFamily(family))
1696         return CSSValuePool::singleton().createIdentifierValue(familyIdentifier);
1697     return CSSValuePool::singleton().createFontFamilyValue(family);
1698 }
1699
1700 static Ref<CSSValue> renderTextDecorationFlagsToCSSValue(int textDecoration)
1701 {
1702     auto& cssValuePool = CSSValuePool::singleton();
1703     // Blink value is ignored.
1704     RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
1705     if (textDecoration & TextDecorationUnderline)
1706         list->append(cssValuePool.createIdentifierValue(CSSValueUnderline));
1707     if (textDecoration & TextDecorationOverline)
1708         list->append(cssValuePool.createIdentifierValue(CSSValueOverline));
1709     if (textDecoration & TextDecorationLineThrough)
1710         list->append(cssValuePool.createIdentifierValue(CSSValueLineThrough));
1711 #if ENABLE(LETTERPRESS)
1712     if (textDecoration & TextDecorationLetterpress)
1713         list->append(cssValuePool.createIdentifierValue(CSSValueWebkitLetterpress));
1714 #endif
1715
1716     if (!list->length())
1717         return cssValuePool.createIdentifierValue(CSSValueNone);
1718     return list.releaseNonNull();
1719 }
1720
1721 static Ref<CSSValue> renderTextDecorationStyleFlagsToCSSValue(TextDecorationStyle textDecorationStyle)
1722 {
1723     switch (textDecorationStyle) {
1724     case TextDecorationStyleSolid:
1725         return CSSValuePool::singleton().createIdentifierValue(CSSValueSolid);
1726     case TextDecorationStyleDouble:
1727         return CSSValuePool::singleton().createIdentifierValue(CSSValueDouble);
1728     case TextDecorationStyleDotted:
1729         return CSSValuePool::singleton().createIdentifierValue(CSSValueDotted);
1730     case TextDecorationStyleDashed:
1731         return CSSValuePool::singleton().createIdentifierValue(CSSValueDashed);
1732     case TextDecorationStyleWavy:
1733         return CSSValuePool::singleton().createIdentifierValue(CSSValueWavy);
1734     }
1735
1736     ASSERT_NOT_REACHED();
1737     return CSSValuePool::singleton().createExplicitInitialValue();
1738 }
1739
1740 static Ref<CSSValue> renderTextDecorationSkipFlagsToCSSValue(TextDecorationSkip textDecorationSkip)
1741 {
1742     switch (textDecorationSkip) {
1743     case TextDecorationSkipAuto:
1744         return CSSValuePool::singleton().createIdentifierValue(CSSValueAuto);
1745     case TextDecorationSkipNone:
1746         return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
1747     case TextDecorationSkipInk:
1748         return CSSValuePool::singleton().createIdentifierValue(CSSValueInk);
1749     case TextDecorationSkipObjects:
1750         return CSSValuePool::singleton().createIdentifierValue(CSSValueObjects);
1751     }
1752
1753     ASSERT_NOT_REACHED();
1754     return CSSValuePool::singleton().createExplicitInitialValue();
1755 }
1756
1757 static Ref<CSSValue> renderEmphasisPositionFlagsToCSSValue(TextEmphasisPosition textEmphasisPosition)
1758 {
1759     ASSERT(!((textEmphasisPosition & TextEmphasisPositionOver) && (textEmphasisPosition & TextEmphasisPositionUnder)));
1760     ASSERT(!((textEmphasisPosition & TextEmphasisPositionLeft) && (textEmphasisPosition & TextEmphasisPositionRight)));
1761     auto& cssValuePool = CSSValuePool::singleton();
1762     RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
1763     if (textEmphasisPosition & TextEmphasisPositionOver)
1764         list->append(cssValuePool.createIdentifierValue(CSSValueOver));
1765     if (textEmphasisPosition & TextEmphasisPositionUnder)
1766         list->append(cssValuePool.createIdentifierValue(CSSValueUnder));
1767     if (textEmphasisPosition & TextEmphasisPositionLeft)
1768         list->append(cssValuePool.createIdentifierValue(CSSValueLeft));
1769     if (textEmphasisPosition & TextEmphasisPositionRight)
1770         list->append(cssValuePool.createIdentifierValue(CSSValueRight));
1771
1772     if (!list->length())
1773         return cssValuePool.createIdentifierValue(CSSValueNone);
1774     return list.releaseNonNull();
1775 }
1776
1777 static Ref<CSSValue> hangingPunctuationToCSSValue(HangingPunctuation hangingPunctuation)
1778 {
1779     auto& cssValuePool = CSSValuePool::singleton();
1780     RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
1781     if (hangingPunctuation & FirstHangingPunctuation)
1782         list->append(cssValuePool.createIdentifierValue(CSSValueFirst));
1783     if (hangingPunctuation & AllowEndHangingPunctuation)
1784         list->append(cssValuePool.createIdentifierValue(CSSValueAllowEnd));
1785     if (hangingPunctuation & ForceEndHangingPunctuation)
1786         list->append(cssValuePool.createIdentifierValue(CSSValueForceEnd));
1787     if (hangingPunctuation & LastHangingPunctuation)
1788         list->append(cssValuePool.createIdentifierValue(CSSValueLast));
1789     if (!list->length())
1790         return cssValuePool.createIdentifierValue(CSSValueNone);
1791     return list.releaseNonNull();
1792 }
1793     
1794 static Ref<CSSValue> fillRepeatToCSSValue(EFillRepeat xRepeat, EFillRepeat yRepeat)
1795 {
1796     // For backwards compatibility, if both values are equal, just return one of them. And
1797     // if the two values are equivalent to repeat-x or repeat-y, just return the shorthand.
1798     auto& cssValuePool = CSSValuePool::singleton();
1799     if (xRepeat == yRepeat)
1800         return cssValuePool.createValue(xRepeat);
1801     if (xRepeat == RepeatFill && yRepeat == NoRepeatFill)
1802         return cssValuePool.createIdentifierValue(CSSValueRepeatX);
1803     if (xRepeat == NoRepeatFill && yRepeat == RepeatFill)
1804         return cssValuePool.createIdentifierValue(CSSValueRepeatY);
1805
1806     auto list = CSSValueList::createSpaceSeparated();
1807     list.get().append(cssValuePool.createValue(xRepeat));
1808     list.get().append(cssValuePool.createValue(yRepeat));
1809     return WTFMove(list);
1810 }
1811
1812 static Ref<CSSValue> fillSourceTypeToCSSValue(EMaskSourceType type)
1813 {
1814     switch (type) {
1815     case MaskAlpha:
1816         return CSSValuePool::singleton().createValue(CSSValueAlpha);
1817     default:
1818         ASSERT(type == MaskLuminance);
1819         return CSSValuePool::singleton().createValue(CSSValueLuminance);
1820     }
1821 }
1822
1823 static Ref<CSSValue> fillSizeToCSSValue(const FillSize& fillSize, const RenderStyle& style)
1824 {
1825     if (fillSize.type == Contain)
1826         return CSSValuePool::singleton().createIdentifierValue(CSSValueContain);
1827
1828     if (fillSize.type == Cover)
1829         return CSSValuePool::singleton().createIdentifierValue(CSSValueCover);
1830
1831     if (fillSize.size.height().isAuto())
1832         return zoomAdjustedPixelValueForLength(fillSize.size.width(), style);
1833
1834     auto list = CSSValueList::createSpaceSeparated();
1835     list.get().append(zoomAdjustedPixelValueForLength(fillSize.size.width(), style));
1836     list.get().append(zoomAdjustedPixelValueForLength(fillSize.size.height(), style));
1837     return WTFMove(list);
1838 }
1839
1840 static Ref<CSSValue> altTextToCSSValue(const RenderStyle* style)
1841 {
1842     return CSSValuePool::singleton().createValue(style->contentAltText(), CSSPrimitiveValue::CSS_STRING);
1843 }
1844     
1845 static Ref<CSSValueList> contentToCSSValue(const RenderStyle* style)
1846 {
1847     auto& cssValuePool = CSSValuePool::singleton();
1848     auto list = CSSValueList::createSpaceSeparated();
1849     for (const ContentData* contentData = style->contentData(); contentData; contentData = contentData->next()) {
1850         if (is<CounterContentData>(*contentData))
1851             list.get().append(cssValuePool.createValue(downcast<CounterContentData>(*contentData).counter().identifier(), CSSPrimitiveValue::CSS_COUNTER_NAME));
1852         else if (is<ImageContentData>(*contentData))
1853             list.get().append(downcast<ImageContentData>(*contentData).image().cssValue());
1854         else if (is<TextContentData>(*contentData))
1855             list.get().append(cssValuePool.createValue(downcast<TextContentData>(*contentData).text(), CSSPrimitiveValue::CSS_STRING));
1856     }
1857     if (style->hasFlowFrom())
1858         list.get().append(cssValuePool.createValue(style->regionThread(), CSSPrimitiveValue::CSS_STRING));
1859     return list;
1860 }
1861
1862 static RefPtr<CSSValue> counterToCSSValue(const RenderStyle* style, CSSPropertyID propertyID)
1863 {
1864     const CounterDirectiveMap* map = style->counterDirectives();
1865     if (!map)
1866         return nullptr;
1867
1868     auto& cssValuePool = CSSValuePool::singleton();
1869     auto list = CSSValueList::createSpaceSeparated();
1870     for (CounterDirectiveMap::const_iterator it = map->begin(); it != map->end(); ++it) {
1871         list->append(cssValuePool.createValue(it->key, CSSPrimitiveValue::CSS_STRING));
1872         short number = propertyID == CSSPropertyCounterIncrement ? it->value.incrementValue() : it->value.resetValue();
1873         list->append(cssValuePool.createValue((double)number, CSSPrimitiveValue::CSS_NUMBER));
1874     }
1875     return WTFMove(list);
1876 }
1877
1878 static void logUnimplementedPropertyID(CSSPropertyID propertyID)
1879 {
1880     static NeverDestroyed<HashSet<CSSPropertyID>> propertyIDSet;
1881     if (!propertyIDSet.get().add(propertyID).isNewEntry)
1882         return;
1883
1884     LOG_ERROR("WebKit does not yet implement getComputedStyle for '%s'.", getPropertyName(propertyID));
1885 }
1886
1887 static Ref<CSSValueList> fontFamilyFromStyle(const RenderStyle* style)
1888 {
1889     auto list = CSSValueList::createCommaSeparated();
1890     for (unsigned i = 0; i < style->fontCascade().familyCount(); ++i)
1891         list.get().append(valueForFamily(style->fontCascade().familyAt(i)));
1892     return list;
1893 }
1894
1895 static Ref<CSSPrimitiveValue> lineHeightFromStyle(const RenderStyle& style)
1896 {
1897     Length length = style.lineHeight();
1898     if (length.isNegative()) // If true, line-height not set; use the font's line spacing.
1899         return zoomAdjustedPixelValue(style.fontMetrics().floatLineSpacing(), style);
1900     if (length.isPercent()) {
1901         // This is imperfect, because it doesn't include the zoom factor and the real computation
1902         // for how high to be in pixels does include things like minimum font size and the zoom factor.
1903         // On the other hand, since font-size doesn't include the zoom factor, we really can't do
1904         // that here either.
1905         return zoomAdjustedPixelValue(static_cast<int>(length.percent() * style.fontDescription().specifiedSize()) / 100, style);
1906     }
1907     return zoomAdjustedPixelValue(floatValueForLength(length, 0), style);
1908 }
1909
1910 static Ref<CSSPrimitiveValue> fontSizeFromStyle(const RenderStyle& style)
1911 {
1912     return zoomAdjustedPixelValue(style.fontDescription().computedSize(), style);
1913 }
1914
1915 static Ref<CSSPrimitiveValue> fontStyleFromStyle(const RenderStyle* style)
1916 {
1917     if (style->fontDescription().italic())
1918         return CSSValuePool::singleton().createIdentifierValue(CSSValueItalic);
1919     return CSSValuePool::singleton().createIdentifierValue(CSSValueNormal);
1920 }
1921
1922 static Ref<CSSValue> fontVariantFromStyle(const RenderStyle* style)
1923 {
1924     if (style->fontDescription().variantSettings().isAllNormal())
1925         return CSSValuePool::singleton().createIdentifierValue(CSSValueNormal);
1926
1927     auto list = CSSValueList::createSpaceSeparated();
1928
1929     switch (style->fontDescription().variantCommonLigatures()) {
1930     case FontVariantLigatures::Normal:
1931         break;
1932     case FontVariantLigatures::Yes:
1933         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueCommonLigatures));
1934         break;
1935     case FontVariantLigatures::No:
1936         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueNoCommonLigatures));
1937         break;
1938     }
1939
1940     switch (style->fontDescription().variantDiscretionaryLigatures()) {
1941     case FontVariantLigatures::Normal:
1942         break;
1943     case FontVariantLigatures::Yes:
1944         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueDiscretionaryLigatures));
1945         break;
1946     case FontVariantLigatures::No:
1947         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueNoDiscretionaryLigatures));
1948         break;
1949     }
1950
1951     switch (style->fontDescription().variantHistoricalLigatures()) {
1952     case FontVariantLigatures::Normal:
1953         break;
1954     case FontVariantLigatures::Yes:
1955         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueHistoricalLigatures));
1956         break;
1957     case FontVariantLigatures::No:
1958         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueNoHistoricalLigatures));
1959         break;
1960     }
1961
1962     switch (style->fontDescription().variantContextualAlternates()) {
1963     case FontVariantLigatures::Normal:
1964         break;
1965     case FontVariantLigatures::Yes:
1966         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueContextual));
1967         break;
1968     case FontVariantLigatures::No:
1969         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueNoContextual));
1970         break;
1971     }
1972
1973     switch (style->fontDescription().variantPosition()) {
1974     case FontVariantPosition::Normal:
1975         break;
1976     case FontVariantPosition::Subscript:
1977         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueSub));
1978         break;
1979     case FontVariantPosition::Superscript:
1980         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueSuper));
1981         break;
1982     }
1983
1984     switch (style->fontDescription().variantCaps()) {
1985     case FontVariantCaps::Normal:
1986         break;
1987     case FontVariantCaps::Small:
1988         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueSmallCaps));
1989         break;
1990     case FontVariantCaps::AllSmall:
1991         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueAllSmallCaps));
1992         break;
1993     case FontVariantCaps::Petite:
1994         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValuePetiteCaps));
1995         break;
1996     case FontVariantCaps::AllPetite:
1997         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueAllPetiteCaps));
1998         break;
1999     case FontVariantCaps::Unicase:
2000         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueUnicase));
2001         break;
2002     case FontVariantCaps::Titling:
2003         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueTitlingCaps));
2004         break;
2005     }
2006
2007     switch (style->fontDescription().variantNumericFigure()) {
2008     case FontVariantNumericFigure::Normal:
2009         break;
2010     case FontVariantNumericFigure::LiningNumbers:
2011         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueLiningNums));
2012         break;
2013     case FontVariantNumericFigure::OldStyleNumbers:
2014         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueOldstyleNums));
2015         break;
2016     }
2017
2018     switch (style->fontDescription().variantNumericSpacing()) {
2019     case FontVariantNumericSpacing::Normal:
2020         break;
2021     case FontVariantNumericSpacing::ProportionalNumbers:
2022         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueProportionalNums));
2023         break;
2024     case FontVariantNumericSpacing::TabularNumbers:
2025         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueTabularNums));
2026         break;
2027     }
2028
2029     switch (style->fontDescription().variantNumericFraction()) {
2030     case FontVariantNumericFraction::Normal:
2031         break;
2032     case FontVariantNumericFraction::DiagonalFractions:
2033         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueDiagonalFractions));
2034         break;
2035     case FontVariantNumericFraction::StackedFractions:
2036         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueStackedFractions));
2037         break;
2038     }
2039
2040     switch (style->fontDescription().variantNumericOrdinal()) {
2041     case FontVariantNumericOrdinal::Normal:
2042         break;
2043     case FontVariantNumericOrdinal::Yes:
2044         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueOrdinal));
2045         break;
2046     }
2047
2048     switch (style->fontDescription().variantNumericSlashedZero()) {
2049     case FontVariantNumericSlashedZero::Normal:
2050         break;
2051     case FontVariantNumericSlashedZero::Yes:
2052         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueSlashedZero));
2053         break;
2054     }
2055
2056     switch (style->fontDescription().variantAlternates()) {
2057     case FontVariantAlternates::Normal:
2058         break;
2059     case FontVariantAlternates::HistoricalForms:
2060         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueHistoricalForms));
2061         break;
2062     }
2063
2064     switch (style->fontDescription().variantEastAsianVariant()) {
2065     case FontVariantEastAsianVariant::Normal:
2066         break;
2067     case FontVariantEastAsianVariant::Jis78:
2068         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueJis78));
2069         break;
2070     case FontVariantEastAsianVariant::Jis83:
2071         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueJis83));
2072         break;
2073     case FontVariantEastAsianVariant::Jis90:
2074         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueJis90));
2075         break;
2076     case FontVariantEastAsianVariant::Jis04:
2077         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueJis04));
2078         break;
2079     case FontVariantEastAsianVariant::Simplified:
2080         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueSimplified));
2081         break;
2082     case FontVariantEastAsianVariant::Traditional:
2083         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueTraditional));
2084         break;
2085     }
2086
2087     switch (style->fontDescription().variantEastAsianWidth()) {
2088     case FontVariantEastAsianWidth::Normal:
2089         break;
2090     case FontVariantEastAsianWidth::Full:
2091         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueFullWidth));
2092         break;
2093     case FontVariantEastAsianWidth::Proportional:
2094         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueProportionalWidth));
2095         break;
2096     }
2097
2098     switch (style->fontDescription().variantEastAsianRuby()) {
2099     case FontVariantEastAsianRuby::Normal:
2100         break;
2101     case FontVariantEastAsianRuby::Yes:
2102         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueRuby));
2103         break;
2104     }
2105
2106     return WTFMove(list);
2107 }
2108
2109 static Ref<CSSPrimitiveValue> fontWeightFromStyle(const RenderStyle* style)
2110 {
2111     switch (style->fontDescription().weight()) {
2112     case FontWeight100:
2113         return CSSValuePool::singleton().createIdentifierValue(CSSValue100);
2114     case FontWeight200:
2115         return CSSValuePool::singleton().createIdentifierValue(CSSValue200);
2116     case FontWeight300:
2117         return CSSValuePool::singleton().createIdentifierValue(CSSValue300);
2118     case FontWeightNormal:
2119         return CSSValuePool::singleton().createIdentifierValue(CSSValueNormal);
2120     case FontWeight500:
2121         return CSSValuePool::singleton().createIdentifierValue(CSSValue500);
2122     case FontWeight600:
2123         return CSSValuePool::singleton().createIdentifierValue(CSSValue600);
2124     case FontWeightBold:
2125         return CSSValuePool::singleton().createIdentifierValue(CSSValueBold);
2126     case FontWeight800:
2127         return CSSValuePool::singleton().createIdentifierValue(CSSValue800);
2128     case FontWeight900:
2129         return CSSValuePool::singleton().createIdentifierValue(CSSValue900);
2130     }
2131     ASSERT_NOT_REACHED();
2132     return CSSValuePool::singleton().createIdentifierValue(CSSValueNormal);
2133 }
2134
2135 static Ref<CSSValue> fontSynthesisFromStyle(const RenderStyle& style)
2136 {
2137     if (style.fontDescription().fontSynthesis() == FontSynthesisNone)
2138         return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
2139
2140     auto list = CSSValueList::createSpaceSeparated();
2141     if (style.fontDescription().fontSynthesis() & FontSynthesisStyle)
2142         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueStyle));
2143     if (style.fontDescription().fontSynthesis() & FontSynthesisWeight)
2144         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueWeight));
2145     return Ref<CSSValue>(list.get());
2146 }
2147
2148 typedef const Length& (RenderStyle::*RenderStyleLengthGetter)() const;
2149 typedef LayoutUnit (RenderBoxModelObject::*RenderBoxComputedCSSValueGetter)() const;
2150
2151 template<RenderStyleLengthGetter lengthGetter, RenderBoxComputedCSSValueGetter computedCSSValueGetter>
2152 inline RefPtr<CSSValue> zoomAdjustedPaddingOrMarginPixelValue(const RenderStyle& style, RenderObject* renderer)
2153 {
2154     Length unzoomzedLength = (style.*lengthGetter)();
2155     if (!is<RenderBox>(renderer) || unzoomzedLength.isFixed())
2156         return zoomAdjustedPixelValueForLength(unzoomzedLength, style);
2157     return zoomAdjustedPixelValue((downcast<RenderBox>(*renderer).*computedCSSValueGetter)(), style);
2158 }
2159
2160 template<RenderStyleLengthGetter lengthGetter>
2161 inline bool paddingOrMarginIsRendererDependent(const RenderStyle* style, RenderObject* renderer)
2162 {
2163     if (!renderer || !renderer->isBox())
2164         return false;
2165     return !(style && (style->*lengthGetter)().isFixed());
2166 }
2167
2168 static CSSValueID convertToPageBreak(BreakBetween value)
2169 {
2170     if (value == PageBreakBetween || value == LeftPageBreakBetween || value == RightPageBreakBetween
2171         || value == RectoPageBreakBetween || value == VersoPageBreakBetween)
2172         return CSSValueAlways; // CSS 2.1 allows us to map these to always.
2173     if (value == AvoidBreakBetween || value == AvoidPageBreakBetween)
2174         return CSSValueAvoid;
2175     return CSSValueAuto;
2176 }
2177
2178 static CSSValueID convertToColumnBreak(BreakBetween value)
2179 {
2180     if (value == ColumnBreakBetween)
2181         return CSSValueAlways;
2182     if (value == AvoidBreakBetween || value == AvoidColumnBreakBetween)
2183         return CSSValueAvoid;
2184     return CSSValueAuto;
2185 }
2186
2187 static CSSValueID convertToPageBreak(BreakInside value)
2188 {
2189     if (value == AvoidBreakInside || value == AvoidPageBreakInside)
2190         return CSSValueAvoid;
2191     return CSSValueAuto;
2192 }
2193
2194 static CSSValueID convertToColumnBreak(BreakInside value)
2195 {
2196     if (value == AvoidBreakInside || value == AvoidColumnBreakInside)
2197         return CSSValueAvoid;
2198     return CSSValueAuto;
2199 }
2200
2201 #if ENABLE(CSS_REGIONS)
2202 static CSSValueID convertToRegionBreak(BreakBetween value)
2203 {
2204     if (value == RegionBreakBetween)
2205         return CSSValueAlways;
2206     if (value == AvoidBreakBetween || value == AvoidRegionBreakBetween)
2207         return CSSValueAvoid;
2208     return CSSValueAuto;
2209 }
2210     
2211 static CSSValueID convertToRegionBreak(BreakInside value)
2212 {
2213     if (value == AvoidBreakInside || value == AvoidRegionBreakInside)
2214         return CSSValueAvoid;
2215     return CSSValueAuto;
2216 }
2217 #endif
2218     
2219 static bool isLayoutDependent(CSSPropertyID propertyID, const RenderStyle* style, RenderObject* renderer)
2220 {
2221     switch (propertyID) {
2222     case CSSPropertyWidth:
2223     case CSSPropertyHeight:
2224     case CSSPropertyPerspectiveOrigin:
2225     case CSSPropertyTransformOrigin:
2226     case CSSPropertyTransform:
2227     case CSSPropertyFilter:
2228 #if ENABLE(FILTERS_LEVEL_2)
2229     case CSSPropertyWebkitBackdropFilter:
2230 #endif
2231         return true;
2232     case CSSPropertyMargin: {
2233         if (!renderer || !renderer->isBox())
2234             return false;
2235         return !(style && style->marginTop().isFixed() && style->marginRight().isFixed()
2236             && style->marginBottom().isFixed() && style->marginLeft().isFixed());
2237     }
2238     case CSSPropertyMarginTop:
2239         return paddingOrMarginIsRendererDependent<&RenderStyle::marginTop>(style, renderer);
2240     case CSSPropertyMarginRight:
2241         return paddingOrMarginIsRendererDependent<&RenderStyle::marginRight>(style, renderer);
2242     case CSSPropertyMarginBottom:
2243         return paddingOrMarginIsRendererDependent<&RenderStyle::marginBottom>(style, renderer);
2244     case CSSPropertyMarginLeft:
2245         return paddingOrMarginIsRendererDependent<&RenderStyle::marginLeft>(style, renderer);
2246     case CSSPropertyPadding: {
2247         if (!renderer || !renderer->isBox())
2248             return false;
2249         return !(style && style->paddingTop().isFixed() && style->paddingRight().isFixed()
2250             && style->paddingBottom().isFixed() && style->paddingLeft().isFixed());
2251     }
2252     case CSSPropertyPaddingTop:
2253         return paddingOrMarginIsRendererDependent<&RenderStyle::paddingTop>(style, renderer);
2254     case CSSPropertyPaddingRight:
2255         return paddingOrMarginIsRendererDependent<&RenderStyle::paddingRight>(style, renderer);
2256     case CSSPropertyPaddingBottom:
2257         return paddingOrMarginIsRendererDependent<&RenderStyle::paddingBottom>(style, renderer);
2258     case CSSPropertyPaddingLeft:
2259         return paddingOrMarginIsRendererDependent<&RenderStyle::paddingLeft>(style, renderer); 
2260 #if ENABLE(CSS_GRID_LAYOUT)
2261     case CSSPropertyGridTemplateColumns:
2262     case CSSPropertyGridTemplateRows:
2263     case CSSPropertyGridTemplate:
2264     case CSSPropertyGrid:
2265         return renderer && renderer->isRenderGrid();
2266 #endif
2267     default:
2268         return false;
2269     }
2270 }
2271
2272 Element* ComputedStyleExtractor::styledElement()
2273 {
2274     if (!m_element)
2275         return nullptr;
2276     PseudoElement* pseudoElement;
2277     if (m_pseudoElementSpecifier == BEFORE && (pseudoElement = m_element->beforePseudoElement()))
2278         return pseudoElement;
2279     if (m_pseudoElementSpecifier == AFTER && (pseudoElement = m_element->afterPseudoElement()))
2280         return pseudoElement;
2281     return m_element.get();
2282 }
2283
2284 #if ENABLE(CSS_GRID_LAYOUT)
2285 static StyleSelfAlignmentData resolveLegacyJustifyItems(const StyleSelfAlignmentData& data)
2286 {
2287     if (data.positionType() == LegacyPosition)
2288         return { data.position(), OverflowAlignmentDefault };
2289     return data;
2290 }
2291
2292 static StyleSelfAlignmentData resolveJustifyItemsAuto(const StyleSelfAlignmentData& data, Node* parent)
2293 {
2294     if (data.position() != ItemPositionAuto)
2295         return data;
2296
2297     // If the inherited value of justify-items includes the 'legacy' keyword, 'auto' computes to the inherited value.
2298     const auto& inheritedValue = (!parent || !parent->computedStyle()) ? RenderStyle::initialDefaultAlignment() : parent->computedStyle()->justifyItems();
2299     if (inheritedValue.positionType() == LegacyPosition)
2300         return inheritedValue;
2301     if (inheritedValue.position() == ItemPositionAuto)
2302         return resolveJustifyItemsAuto(inheritedValue, parent->parentNode());
2303     return { ItemPositionNormal, OverflowAlignmentDefault };
2304 }
2305
2306 static StyleSelfAlignmentData resolveJustifySelfAuto(const StyleSelfAlignmentData& data, Node* parent)
2307 {
2308     if (data.position() != ItemPositionAuto)
2309         return data;
2310
2311     // The 'auto' keyword computes to the computed value of justify-items on the parent or 'normal' if the box has no parent.
2312     if (!parent || !parent->computedStyle())
2313         return { ItemPositionNormal, OverflowAlignmentDefault };
2314     return resolveLegacyJustifyItems(resolveJustifyItemsAuto(parent->computedStyle()->justifyItems(), parent->parentNode()));
2315 }
2316 #endif
2317
2318 static StyleSelfAlignmentData resolveAlignSelfAuto(const StyleSelfAlignmentData& data, Node* parent)
2319 {
2320     if (data.position() != ItemPositionAuto)
2321         return data;
2322
2323     // The 'auto' keyword computes to the computed value of align-items on the parent or 'normal' if the box has no parent.
2324     if (!parent || !parent->computedStyle())
2325         return { ItemPositionNormal, OverflowAlignmentDefault };
2326     return parent->computedStyle()->alignItems();
2327 }
2328
2329 static bool isImplicitlyInheritedGridOrFlexProperty(CSSPropertyID propertyID)
2330 {
2331     // It would be nice if grid and flex worked within normal CSS mechanisms and not invented their own inheritance system.
2332     switch (propertyID) {
2333     case CSSPropertyAlignSelf:
2334 #if ENABLE(CSS_GRID_LAYOUT)
2335     case CSSPropertyJustifySelf:
2336     case CSSPropertyJustifyItems:
2337 #endif
2338     // FIXME: In StyleResolver::adjustRenderStyle z-index is adjusted based on the parent display property for grid/flex.
2339     case CSSPropertyZIndex:
2340         return true;
2341     default:
2342         return false;
2343     }
2344 }
2345
2346 RefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropertyID propertyID, EUpdateLayout updateLayout) const
2347 {
2348     return ComputedStyleExtractor(m_element.ptr(), m_allowVisitedStyle, m_pseudoElementSpecifier).propertyValue(propertyID, updateLayout);
2349 }
2350
2351 Ref<MutableStyleProperties> CSSComputedStyleDeclaration::copyProperties() const
2352 {
2353     return ComputedStyleExtractor(m_element.ptr(), m_allowVisitedStyle, m_pseudoElementSpecifier).copyProperties();
2354 }
2355
2356 static inline bool hasValidStyleForProperty(Element& element, CSSPropertyID propertyID)
2357 {
2358     if (element.styleValidity() != Style::Validity::Valid)
2359         return false;
2360     if (element.document().hasPendingForcedStyleRecalc())
2361         return false;
2362     if (!element.document().childNeedsStyleRecalc())
2363         return true;
2364
2365     bool isInherited = CSSProperty::isInheritedProperty(propertyID) || isImplicitlyInheritedGridOrFlexProperty(propertyID);
2366     bool maybeExplicitlyInherited = !isInherited;
2367
2368     const auto* currentElement = &element;
2369     for (auto& ancestor : composedTreeAncestors(element)) {
2370         if (ancestor.styleValidity() >= Style::Validity::SubtreeInvalid)
2371             return false;
2372
2373         if (maybeExplicitlyInherited) {
2374             auto* style = currentElement->renderStyle();
2375             maybeExplicitlyInherited = !style || style->hasExplicitlyInheritedProperties();
2376         }
2377
2378         if ((isInherited || maybeExplicitlyInherited) && ancestor.styleValidity() == Style::Validity::ElementInvalid)
2379             return false;
2380
2381         if (ancestor.directChildNeedsStyleRecalc() && currentElement->styleIsAffectedByPreviousSibling())
2382             return false;
2383
2384         currentElement = &ancestor;
2385     }
2386
2387     return true;
2388 }
2389
2390 static bool updateStyleIfNeededForProperty(Element& element, CSSPropertyID propertyID)
2391 {
2392     auto& document = element.document();
2393
2394     document.styleScope().flushPendingUpdate();
2395
2396     if (hasValidStyleForProperty(element, propertyID))
2397         return false;
2398
2399     document.updateStyleIfNeeded();
2400     return true;
2401 }
2402
2403 static inline const RenderStyle* computeRenderStyleForProperty(Element& element, PseudoId pseudoElementSpecifier, CSSPropertyID propertyID, std::unique_ptr<RenderStyle>& ownedStyle)
2404 {
2405     auto* renderer = element.renderer();
2406
2407     if (renderer && renderer->isComposited() && AnimationController::supportsAcceleratedAnimationOfProperty(propertyID)) {
2408         ownedStyle = renderer->animation().getAnimatedStyleForRenderer(*renderer);
2409         if (pseudoElementSpecifier && !element.isPseudoElement()) {
2410             // FIXME: This cached pseudo style will only exist if the animation has been run at least once.
2411             return ownedStyle->getCachedPseudoStyle(pseudoElementSpecifier);
2412         }
2413         return ownedStyle.get();
2414     }
2415
2416     return element.computedStyle(element.isPseudoElement() ? NOPSEUDO : pseudoElementSpecifier);
2417 }
2418
2419 static Ref<CSSValue> shapePropertyValue(const RenderStyle& style, const ShapeValue* shapeValue)
2420 {
2421     if (!shapeValue)
2422         return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
2423
2424     if (shapeValue->type() == ShapeValue::Type::Box)
2425         return CSSValuePool::singleton().createValue(shapeValue->cssBox());
2426
2427     if (shapeValue->type() == ShapeValue::Type::Image) {
2428         if (shapeValue->image())
2429             return shapeValue->image()->cssValue();
2430         return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
2431     }
2432
2433     ASSERT(shapeValue->type() == ShapeValue::Type::Shape);
2434
2435     RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2436     list->append(valueForBasicShape(style, *shapeValue->shape()));
2437     if (shapeValue->cssBox() != BoxMissing)
2438         list->append(CSSValuePool::singleton().createValue(shapeValue->cssBox()));
2439     return list.releaseNonNull();
2440 }
2441
2442 static Ref<CSSValueList> valueForItemPositionWithOverflowAlignment(const StyleSelfAlignmentData& data)
2443 {
2444     auto& cssValuePool = CSSValuePool::singleton();
2445     auto result = CSSValueList::createSpaceSeparated();
2446     if (data.positionType() == LegacyPosition)
2447         result.get().append(cssValuePool.createIdentifierValue(CSSValueLegacy));
2448     result.get().append(cssValuePool.createValue(data.position()));
2449     if (data.position() >= ItemPositionCenter && data.overflow() != OverflowAlignmentDefault)
2450         result.get().append(cssValuePool.createValue(data.overflow()));
2451     ASSERT(result.get().length() <= 2);
2452     return result;
2453 }
2454
2455 static Ref<CSSValueList> valueForContentPositionAndDistributionWithOverflowAlignment(const StyleContentAlignmentData& data, CSSValueID normalBehaviorValueID)
2456 {
2457     auto& cssValuePool = CSSValuePool::singleton();
2458     auto result = CSSValueList::createSpaceSeparated();
2459     if (data.distribution() != ContentDistributionDefault)
2460         result.get().append(cssValuePool.createValue(data.distribution()));
2461     if (data.distribution() == ContentDistributionDefault || data.position() != ContentPositionNormal) {
2462         bool gridEnabled = false;
2463 #if ENABLE(CSS_GRID_LAYOUT)
2464         gridEnabled = RuntimeEnabledFeatures::sharedFeatures().isCSSGridLayoutEnabled();
2465 #endif
2466         if (data.position() != ContentPositionNormal || gridEnabled)
2467             result.get().append(cssValuePool.createValue(data.position()));
2468         else
2469             result.get().append(cssValuePool.createIdentifierValue(normalBehaviorValueID));
2470     }
2471     if ((data.position() >= ContentPositionCenter || data.distribution() != ContentDistributionDefault) && data.overflow() != OverflowAlignmentDefault)
2472         result.get().append(cssValuePool.createValue(data.overflow()));
2473     ASSERT(result.get().length() > 0);
2474     ASSERT(result.get().length() <= 3);
2475     return result;
2476 }
2477
2478 inline static bool isFlexOrGrid(ContainerNode* element)
2479 {
2480     return element && element->computedStyle() && element->computedStyle()->isDisplayFlexibleOrGridBox();
2481 }
2482
2483 RefPtr<CSSValue> ComputedStyleExtractor::customPropertyValue(const String& propertyName)
2484 {
2485     Element* styledElement = this->styledElement();
2486     if (!styledElement)
2487         return nullptr;
2488     
2489     if (updateStyleIfNeededForProperty(*styledElement, CSSPropertyCustom)) {
2490         // Style update may change styledElement() to PseudoElement or back.
2491         styledElement = this->styledElement();
2492     }
2493
2494     std::unique_ptr<RenderStyle> ownedStyle;
2495     auto* style = computeRenderStyleForProperty(*styledElement, m_pseudoElementSpecifier, CSSPropertyCustom, ownedStyle);
2496     if (!style || !style->hasCustomProperty(propertyName))
2497         return nullptr;
2498
2499     return style->getCustomPropertyValue(propertyName);
2500 }
2501
2502 String ComputedStyleExtractor::customPropertyText(const String& propertyName)
2503 {
2504     RefPtr<CSSValue> propertyValue = customPropertyValue(propertyName);
2505     return propertyValue ? propertyValue->cssText() : emptyString();
2506 }
2507
2508 RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID, EUpdateLayout updateLayout)
2509 {
2510     auto* styledElement = this->styledElement();
2511     if (!styledElement)
2512         return nullptr;
2513
2514     std::unique_ptr<RenderStyle> ownedStyle;
2515     const RenderStyle* style = nullptr;
2516     RenderObject* renderer = nullptr;
2517     bool forceFullLayout = false;
2518     if (updateLayout) {
2519         Document& document = m_element->document();
2520
2521         if (updateStyleIfNeededForProperty(*styledElement, propertyID)) {
2522             // Style update may change styledElement() to PseudoElement or back.
2523             styledElement = this->styledElement();
2524         }
2525         renderer = styledElement->renderer();
2526
2527         if (propertyID == CSSPropertyDisplay && !renderer && is<SVGElement>(*styledElement) && !downcast<SVGElement>(*styledElement).isValid())
2528             return nullptr;
2529
2530         style = computeRenderStyleForProperty(*styledElement, m_pseudoElementSpecifier, propertyID, ownedStyle);
2531
2532         // FIXME: Some of these cases could be narrowed down or optimized better.
2533         forceFullLayout = isLayoutDependent(propertyID, style, renderer)
2534             || styledElement->isInShadowTree()
2535             || (document.styleScope().resolverIfExists() && document.styleScope().resolverIfExists()->hasViewportDependentMediaQueries() && document.ownerElement());
2536
2537         if (forceFullLayout) {
2538             document.updateLayoutIgnorePendingStylesheets();
2539             styledElement = this->styledElement();
2540         }
2541     }
2542
2543     if (!updateLayout || forceFullLayout) {
2544         style = computeRenderStyleForProperty(*styledElement, m_pseudoElementSpecifier, propertyID, ownedStyle);
2545         renderer = styledElement->renderer();
2546     }
2547
2548     if (!style)
2549         return nullptr;
2550
2551     auto& cssValuePool = CSSValuePool::singleton();
2552     propertyID = CSSProperty::resolveDirectionAwareProperty(propertyID, style->direction(), style->writingMode());
2553
2554     switch (propertyID) {
2555         case CSSPropertyInvalid:
2556             break;
2557
2558         case CSSPropertyBackgroundColor:
2559             return cssValuePool.createColorValue(m_allowVisitedStyle? style->visitedDependentColor(CSSPropertyBackgroundColor) : style->backgroundColor());
2560         case CSSPropertyBackgroundImage:
2561         case CSSPropertyWebkitMaskImage: {
2562             const FillLayer* layers = propertyID == CSSPropertyWebkitMaskImage ? style->maskLayers() : style->backgroundLayers();
2563             if (!layers)
2564                 return cssValuePool.createIdentifierValue(CSSValueNone);
2565
2566             if (!layers->next()) {
2567                 if (layers->image())
2568                     return layers->image()->cssValue();
2569
2570                 return cssValuePool.createIdentifierValue(CSSValueNone);
2571             }
2572
2573             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2574             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) {
2575                 if (currLayer->image())
2576                     list->append(currLayer->image()->cssValue());
2577                 else
2578                     list->append(cssValuePool.createIdentifierValue(CSSValueNone));
2579             }
2580             return list;
2581         }
2582         case CSSPropertyBackgroundSize:
2583         case CSSPropertyWebkitBackgroundSize:
2584         case CSSPropertyWebkitMaskSize: {
2585             const FillLayer* layers = propertyID == CSSPropertyWebkitMaskSize ? style->maskLayers() : style->backgroundLayers();
2586             if (!layers->next())
2587                 return fillSizeToCSSValue(layers->size(), *style);
2588
2589             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2590             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
2591                 list->append(fillSizeToCSSValue(currLayer->size(), *style));
2592
2593             return list;
2594         }
2595         case CSSPropertyBackgroundRepeat:
2596         case CSSPropertyWebkitMaskRepeat: {
2597             const FillLayer* layers = propertyID == CSSPropertyWebkitMaskRepeat ? style->maskLayers() : style->backgroundLayers();
2598             if (!layers->next())
2599                 return fillRepeatToCSSValue(layers->repeatX(), layers->repeatY());
2600
2601             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2602             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
2603                 list->append(fillRepeatToCSSValue(currLayer->repeatX(), currLayer->repeatY()));
2604
2605             return list;
2606         }
2607         case CSSPropertyWebkitMaskSourceType: {
2608             const FillLayer* layers = style->maskLayers();
2609
2610             if (!layers)
2611                 return cssValuePool.createIdentifierValue(CSSValueNone);
2612
2613             if (!layers->next())
2614                 return fillSourceTypeToCSSValue(layers->maskSourceType());
2615
2616             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2617             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
2618                 list->append(fillSourceTypeToCSSValue(currLayer->maskSourceType()));
2619
2620             return list;
2621         }
2622         case CSSPropertyWebkitBackgroundComposite:
2623         case CSSPropertyWebkitMaskComposite: {
2624             const FillLayer* layers = propertyID == CSSPropertyWebkitMaskComposite ? style->maskLayers() : style->backgroundLayers();
2625             if (!layers->next())
2626                 return cssValuePool.createValue(layers->composite());
2627
2628             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2629             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
2630                 list->append(cssValuePool.createValue(currLayer->composite()));
2631
2632             return list;
2633         }
2634         case CSSPropertyBackgroundAttachment: {
2635             const FillLayer* layers = style->backgroundLayers();
2636             if (!layers->next())
2637                 return cssValuePool.createValue(layers->attachment());
2638
2639             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2640             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
2641                 list->append(cssValuePool.createValue(currLayer->attachment()));
2642
2643             return list;
2644         }
2645         case CSSPropertyBackgroundClip:
2646         case CSSPropertyBackgroundOrigin:
2647         case CSSPropertyWebkitBackgroundClip:
2648         case CSSPropertyWebkitBackgroundOrigin:
2649         case CSSPropertyWebkitMaskClip:
2650         case CSSPropertyWebkitMaskOrigin: {
2651             const FillLayer* layers = (propertyID == CSSPropertyWebkitMaskClip || propertyID == CSSPropertyWebkitMaskOrigin) ? style->maskLayers() : style->backgroundLayers();
2652             bool isClip = propertyID == CSSPropertyBackgroundClip || propertyID == CSSPropertyWebkitBackgroundClip || propertyID == CSSPropertyWebkitMaskClip;
2653             if (!layers->next()) {
2654                 EFillBox box = isClip ? layers->clip() : layers->origin();
2655                 return cssValuePool.createValue(box);
2656             }
2657
2658             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2659             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) {
2660                 EFillBox box = isClip ? currLayer->clip() : currLayer->origin();
2661                 list->append(cssValuePool.createValue(box));
2662             }
2663
2664             return list;
2665         }
2666         case CSSPropertyBackgroundPosition:
2667         case CSSPropertyWebkitMaskPosition: {
2668             const FillLayer* layers = propertyID == CSSPropertyWebkitMaskPosition ? style->maskLayers() : style->backgroundLayers();
2669             if (!layers->next())
2670                 return createPositionListForLayer(propertyID, layers, *style);
2671
2672             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2673             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
2674                 list->append(createPositionListForLayer(propertyID, currLayer, *style));
2675             return list;
2676         }
2677         case CSSPropertyBackgroundPositionX:
2678         case CSSPropertyWebkitMaskPositionX: {
2679             const FillLayer* layers = propertyID == CSSPropertyWebkitMaskPositionX ? style->maskLayers() : style->backgroundLayers();
2680             if (!layers->next())
2681                 return cssValuePool.createValue(layers->xPosition());
2682
2683             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2684             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
2685                 list->append(cssValuePool.createValue(currLayer->xPosition()));
2686
2687             return list;
2688         }
2689         case CSSPropertyBackgroundPositionY:
2690         case CSSPropertyWebkitMaskPositionY: {
2691             const FillLayer* layers = propertyID == CSSPropertyWebkitMaskPositionY ? style->maskLayers() : style->backgroundLayers();
2692             if (!layers->next())
2693                 return cssValuePool.createValue(layers->yPosition());
2694
2695             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2696             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
2697                 list->append(cssValuePool.createValue(currLayer->yPosition()));
2698
2699             return list;
2700         }
2701         case CSSPropertyBorderCollapse:
2702             if (style->borderCollapse())
2703                 return cssValuePool.createIdentifierValue(CSSValueCollapse);
2704             return cssValuePool.createIdentifierValue(CSSValueSeparate);
2705         case CSSPropertyBorderSpacing: {
2706             RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2707             list->append(zoomAdjustedPixelValue(style->horizontalBorderSpacing(), *style));
2708             list->append(zoomAdjustedPixelValue(style->verticalBorderSpacing(), *style));
2709             return list;
2710         }
2711         case CSSPropertyWebkitBorderHorizontalSpacing:
2712             return zoomAdjustedPixelValue(style->horizontalBorderSpacing(), *style);
2713         case CSSPropertyWebkitBorderVerticalSpacing:
2714             return zoomAdjustedPixelValue(style->verticalBorderSpacing(), *style);
2715         case CSSPropertyBorderImageSource:
2716             if (style->borderImageSource())
2717                 return style->borderImageSource()->cssValue();
2718             return cssValuePool.createIdentifierValue(CSSValueNone);
2719         case CSSPropertyBorderTopColor:
2720             return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyBorderTopColor)) : currentColorOrValidColor(style, style->borderTopColor());
2721         case CSSPropertyBorderRightColor:
2722             return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyBorderRightColor)) : currentColorOrValidColor(style, style->borderRightColor());
2723         case CSSPropertyBorderBottomColor:
2724             return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyBorderBottomColor)) : currentColorOrValidColor(style, style->borderBottomColor());
2725         case CSSPropertyBorderLeftColor:
2726             return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyBorderLeftColor)) : currentColorOrValidColor(style, style->borderLeftColor());
2727         case CSSPropertyBorderTopStyle:
2728             return cssValuePool.createValue(style->borderTopStyle());
2729         case CSSPropertyBorderRightStyle:
2730             return cssValuePool.createValue(style->borderRightStyle());
2731         case CSSPropertyBorderBottomStyle:
2732             return cssValuePool.createValue(style->borderBottomStyle());
2733         case CSSPropertyBorderLeftStyle:
2734             return cssValuePool.createValue(style->borderLeftStyle());
2735         case CSSPropertyBorderTopWidth:
2736             return zoomAdjustedPixelValue(style->borderTopWidth(), *style);
2737         case CSSPropertyBorderRightWidth:
2738             return zoomAdjustedPixelValue(style->borderRightWidth(), *style);
2739         case CSSPropertyBorderBottomWidth:
2740             return zoomAdjustedPixelValue(style->borderBottomWidth(), *style);
2741         case CSSPropertyBorderLeftWidth:
2742             return zoomAdjustedPixelValue(style->borderLeftWidth(), *style);
2743         case CSSPropertyBottom:
2744             return positionOffsetValue(*style, CSSPropertyBottom);
2745         case CSSPropertyWebkitBoxAlign:
2746             return cssValuePool.createValue(style->boxAlign());
2747 #if ENABLE(CSS_BOX_DECORATION_BREAK)
2748         case CSSPropertyWebkitBoxDecorationBreak:
2749             if (style->boxDecorationBreak() == DSLICE)
2750                 return cssValuePool.createIdentifierValue(CSSValueSlice);
2751         return cssValuePool.createIdentifierValue(CSSValueClone);
2752 #endif
2753         case CSSPropertyWebkitBoxDirection:
2754             return cssValuePool.createValue(style->boxDirection());
2755         case CSSPropertyWebkitBoxFlex:
2756             return cssValuePool.createValue(style->boxFlex(), CSSPrimitiveValue::CSS_NUMBER);
2757         case CSSPropertyWebkitBoxFlexGroup:
2758             return cssValuePool.createValue(style->boxFlexGroup(), CSSPrimitiveValue::CSS_NUMBER);
2759         case CSSPropertyWebkitBoxLines:
2760             return cssValuePool.createValue(style->boxLines());
2761         case CSSPropertyWebkitBoxOrdinalGroup:
2762             return cssValuePool.createValue(style->boxOrdinalGroup(), CSSPrimitiveValue::CSS_NUMBER);
2763         case CSSPropertyWebkitBoxOrient:
2764             return cssValuePool.createValue(style->boxOrient());
2765         case CSSPropertyWebkitBoxPack:
2766             return cssValuePool.createValue(style->boxPack());
2767         case CSSPropertyWebkitBoxReflect:
2768             return valueForReflection(style->boxReflect(), *style);
2769         case CSSPropertyBoxShadow:
2770         case CSSPropertyWebkitBoxShadow:
2771             return valueForShadow(style->boxShadow(), propertyID, *style);
2772         case CSSPropertyCaptionSide:
2773             return cssValuePool.createValue(style->captionSide());
2774         case CSSPropertyClear:
2775             return cssValuePool.createValue(style->clear());
2776         case CSSPropertyColor:
2777             return cssValuePool.createColorValue(m_allowVisitedStyle ? style->visitedDependentColor(CSSPropertyColor) : style->color());
2778         case CSSPropertyWebkitPrintColorAdjust:
2779             return cssValuePool.createValue(style->printColorAdjust());
2780         case CSSPropertyWebkitColumnAxis:
2781             return cssValuePool.createValue(style->columnAxis());
2782         case CSSPropertyColumnCount:
2783             if (style->hasAutoColumnCount())
2784                 return cssValuePool.createIdentifierValue(CSSValueAuto);
2785             return cssValuePool.createValue(style->columnCount(), CSSPrimitiveValue::CSS_NUMBER);
2786         case CSSPropertyColumnFill:
2787             return cssValuePool.createValue(style->columnFill());
2788         case CSSPropertyColumnGap:
2789             if (style->hasNormalColumnGap())
2790                 return cssValuePool.createIdentifierValue(CSSValueNormal);
2791             return zoomAdjustedPixelValue(style->columnGap(), *style);
2792         case CSSPropertyWebkitColumnProgression:
2793             return cssValuePool.createValue(style->columnProgression());
2794         case CSSPropertyColumnRuleColor:
2795             return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyOutlineColor)) : currentColorOrValidColor(style, style->columnRuleColor());
2796         case CSSPropertyColumnRuleStyle:
2797             return cssValuePool.createValue(style->columnRuleStyle());
2798         case CSSPropertyColumnRuleWidth:
2799             return zoomAdjustedPixelValue(style->columnRuleWidth(), *style);
2800         case CSSPropertyColumnSpan:
2801             return cssValuePool.createIdentifierValue(style->columnSpan() ? CSSValueAll : CSSValueNone);
2802         case CSSPropertyWebkitColumnBreakAfter:
2803             return cssValuePool.createValue(convertToColumnBreak(style->breakAfter()));
2804         case CSSPropertyWebkitColumnBreakBefore:
2805             return cssValuePool.createValue(convertToColumnBreak(style->breakBefore()));
2806         case CSSPropertyWebkitColumnBreakInside:
2807             return cssValuePool.createValue(convertToColumnBreak(style->breakInside()));
2808         case CSSPropertyColumnWidth:
2809             if (style->hasAutoColumnWidth())
2810                 return cssValuePool.createIdentifierValue(CSSValueAuto);
2811             return zoomAdjustedPixelValue(style->columnWidth(), *style);
2812         case CSSPropertyTabSize:
2813             return cssValuePool.createValue(style->tabSize(), CSSPrimitiveValue::CSS_NUMBER);
2814 #if ENABLE(CSS_REGIONS)
2815         case CSSPropertyWebkitRegionBreakAfter:
2816             return cssValuePool.createValue(convertToRegionBreak(style->breakAfter()));
2817         case CSSPropertyWebkitRegionBreakBefore:
2818             return cssValuePool.createValue(convertToRegionBreak(style->breakBefore()));
2819         case CSSPropertyWebkitRegionBreakInside:
2820             return cssValuePool.createValue(convertToRegionBreak(style->breakInside()));
2821 #endif
2822         case CSSPropertyCursor: {
2823             RefPtr<CSSValueList> list;
2824             CursorList* cursors = style->cursors();
2825             if (cursors && cursors->size() > 0) {
2826                 list = CSSValueList::createCommaSeparated();
2827                 for (unsigned i = 0; i < cursors->size(); ++i)
2828                     if (StyleImage* image = cursors->at(i).image())
2829                         list->append(image->cssValue());
2830             }
2831             auto value = cssValuePool.createValue(style->cursor());
2832             if (list) {
2833                 list->append(WTFMove(value));
2834                 return list;
2835             }
2836             return WTFMove(value);
2837         }
2838 #if ENABLE(CURSOR_VISIBILITY)
2839         case CSSPropertyWebkitCursorVisibility:
2840             return cssValuePool.createValue(style->cursorVisibility());
2841 #endif
2842         case CSSPropertyDirection:
2843             return cssValuePool.createValue(style->direction());
2844         case CSSPropertyDisplay:
2845             return cssValuePool.createValue(style->display());
2846         case CSSPropertyEmptyCells:
2847             return cssValuePool.createValue(style->emptyCells());
2848         case CSSPropertyAlignContent:
2849             return valueForContentPositionAndDistributionWithOverflowAlignment(style->alignContent(), CSSValueStretch);
2850         case CSSPropertyAlignItems:
2851             return valueForItemPositionWithOverflowAlignment(style->alignItems());
2852         case CSSPropertyAlignSelf:
2853             return valueForItemPositionWithOverflowAlignment(resolveAlignSelfAuto(style->alignSelf(), styledElement->parentNode()));
2854         case CSSPropertyFlex:
2855             return getCSSPropertyValuesForShorthandProperties(flexShorthand());
2856         case CSSPropertyFlexBasis:
2857             return cssValuePool.createValue(style->flexBasis());
2858         case CSSPropertyFlexDirection:
2859             return cssValuePool.createValue(style->flexDirection());
2860         case CSSPropertyFlexFlow:
2861             return getCSSPropertyValuesForShorthandProperties(flexFlowShorthand());
2862         case CSSPropertyFlexGrow:
2863             return cssValuePool.createValue(style->flexGrow());
2864         case CSSPropertyFlexShrink:
2865             return cssValuePool.createValue(style->flexShrink());
2866         case CSSPropertyFlexWrap:
2867             return cssValuePool.createValue(style->flexWrap());
2868         case CSSPropertyJustifyContent:
2869             return valueForContentPositionAndDistributionWithOverflowAlignment(style->justifyContent(), CSSValueFlexStart);
2870 #if ENABLE(CSS_GRID_LAYOUT)
2871         case CSSPropertyJustifyItems:
2872             return valueForItemPositionWithOverflowAlignment(resolveJustifyItemsAuto(style->justifyItems(), styledElement->parentNode()));
2873         case CSSPropertyJustifySelf:
2874             return valueForItemPositionWithOverflowAlignment(resolveJustifySelfAuto(style->justifySelf(), styledElement->parentNode()));
2875 #endif
2876         case CSSPropertyOrder:
2877             return cssValuePool.createValue(style->order(), CSSPrimitiveValue::CSS_NUMBER);
2878         case CSSPropertyFloat:
2879             if (style->display() != NONE && style->hasOutOfFlowPosition())
2880                 return cssValuePool.createIdentifierValue(CSSValueNone);
2881             return cssValuePool.createValue(style->floating());
2882         case CSSPropertyFont: {
2883             RefPtr<CSSFontValue> computedFont = CSSFontValue::create();
2884             computedFont->style = fontStyleFromStyle(style);
2885             if (style->fontDescription().variantCaps() == FontVariantCaps::Small)
2886                 computedFont->variant = CSSValuePool::singleton().createIdentifierValue(CSSValueSmallCaps);
2887             else
2888                 computedFont->variant = CSSValuePool::singleton().createIdentifierValue(CSSValueNormal);
2889             computedFont->weight = fontWeightFromStyle(style);
2890             computedFont->size = fontSizeFromStyle(*style);
2891             computedFont->lineHeight = lineHeightFromStyle(*style);
2892             computedFont->family = fontFamilyFromStyle(style);
2893             return computedFont;
2894         }
2895         case CSSPropertyFontFamily: {
2896             RefPtr<CSSValueList> fontFamilyList = fontFamilyFromStyle(style);
2897             // If there's only a single family, return that as a CSSPrimitiveValue.
2898             // NOTE: Gecko always returns this as a comma-separated CSSPrimitiveValue string.
2899             if (fontFamilyList->length() == 1)
2900                 return fontFamilyList->item(0);
2901             return fontFamilyList;
2902         }
2903         case CSSPropertyFontSize:
2904             return fontSizeFromStyle(*style);
2905         case CSSPropertyFontStyle:
2906             return fontStyleFromStyle(style);
2907         case CSSPropertyFontVariant:
2908             return fontVariantFromStyle(style);
2909         case CSSPropertyFontWeight:
2910             return fontWeightFromStyle(style);
2911         case CSSPropertyFontSynthesis:
2912             return fontSynthesisFromStyle(*style);
2913         case CSSPropertyFontFeatureSettings: {
2914             const FontFeatureSettings& featureSettings = style->fontDescription().featureSettings();
2915             if (!featureSettings.size())
2916                 return cssValuePool.createIdentifierValue(CSSValueNormal);
2917             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2918             for (auto& feature : featureSettings)
2919                 list->append(CSSFontFeatureValue::create(FontTag(feature.tag()), feature.value()));
2920             return list;
2921         }
2922 #if ENABLE(VARIATION_FONTS)
2923         case CSSPropertyFontVariationSettings: {
2924             if (styledElement->document().settings() && styledElement->document().settings()->variationFontsEnabled()) {
2925                 const FontVariationSettings& variationSettings = style->fontDescription().variationSettings();
2926                 if (variationSettings.isEmpty())
2927                     return cssValuePool.createIdentifierValue(CSSValueNormal);
2928                 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2929                 for (auto& feature : variationSettings)
2930                     list->append(CSSFontVariationValue::create(feature.tag(), feature.value()));
2931                 return list;
2932             }
2933             break;
2934         }
2935 #endif
2936 #if ENABLE(CSS_GRID_LAYOUT)
2937         case CSSPropertyGridAutoFlow: {
2938             RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2939             ASSERT(style->isGridAutoFlowDirectionRow() || style->isGridAutoFlowDirectionColumn());
2940             if (style->isGridAutoFlowDirectionRow())
2941                 list->append(cssValuePool.createIdentifierValue(CSSValueRow));
2942             else
2943                 list->append(cssValuePool.createIdentifierValue(CSSValueColumn));
2944
2945             if (style->isGridAutoFlowAlgorithmDense())
2946                 list->append(cssValuePool.createIdentifierValue(CSSValueDense));
2947
2948             return list;
2949         }
2950
2951         // Specs mention that getComputedStyle() should return the used value of the property instead of the computed
2952         // one for grid-template-{rows|columns} but not for the grid-auto-{rows|columns} as things like
2953         // grid-auto-columns: 2fr; cannot be resolved to a value in pixels as the '2fr' means very different things
2954         // depending on the size of the explicit grid or the number of implicit tracks added to the grid. See
2955         // http://lists.w3.org/Archives/Public/www-style/2013Nov/0014.html
2956         case CSSPropertyGridAutoColumns:
2957             return valueForGridTrackSizeList(ForColumns, *style);
2958         case CSSPropertyGridAutoRows:
2959             return valueForGridTrackSizeList(ForRows, *style);
2960
2961         case CSSPropertyGridTemplateColumns:
2962             return valueForGridTrackList(ForColumns, renderer, *style);
2963         case CSSPropertyGridTemplateRows:
2964             return valueForGridTrackList(ForRows, renderer, *style);
2965
2966         case CSSPropertyGridColumnStart:
2967             return valueForGridPosition(style->gridItemColumnStart());
2968         case CSSPropertyGridColumnEnd:
2969             return valueForGridPosition(style->gridItemColumnEnd());
2970         case CSSPropertyGridRowStart:
2971             return valueForGridPosition(style->gridItemRowStart());
2972         case CSSPropertyGridRowEnd:
2973             return valueForGridPosition(style->gridItemRowEnd());
2974         case CSSPropertyGridArea:
2975             return getCSSPropertyValuesForGridShorthand(gridAreaShorthand());
2976         case CSSPropertyGridTemplate:
2977             return getCSSPropertyValuesForGridShorthand(gridTemplateShorthand());
2978         case CSSPropertyGrid:
2979             return getCSSPropertyValuesForGridShorthand(gridShorthand());
2980         case CSSPropertyGridColumn:
2981             return getCSSPropertyValuesForGridShorthand(gridColumnShorthand());
2982         case CSSPropertyGridRow:
2983             return getCSSPropertyValuesForGridShorthand(gridRowShorthand());
2984
2985         case CSSPropertyGridTemplateAreas:
2986             if (!style->namedGridAreaRowCount()) {
2987                 ASSERT(!style->namedGridAreaColumnCount());
2988                 return cssValuePool.createIdentifierValue(CSSValueNone);
2989             }
2990
2991             return CSSGridTemplateAreasValue::create(style->namedGridArea(), style->namedGridAreaRowCount(), style->namedGridAreaColumnCount());
2992         case CSSPropertyGridColumnGap:
2993             return zoomAdjustedPixelValueForLength(style->gridColumnGap(), *style);
2994         case CSSPropertyGridRowGap:
2995             return zoomAdjustedPixelValueForLength(style->gridRowGap(), *style);
2996         case CSSPropertyGridGap:
2997             return getCSSPropertyValuesForGridShorthand(gridGapShorthand());
2998 #endif /* ENABLE(CSS_GRID_LAYOUT) */
2999         case CSSPropertyHeight:
3000             if (renderer && !renderer->isRenderSVGModelObject()) {
3001                 // According to http://www.w3.org/TR/CSS2/visudet.html#the-height-property,
3002                 // the "height" property does not apply for non-replaced inline elements.
3003                 if (!renderer->isReplaced() && renderer->isInline())
3004                     return cssValuePool.createIdentifierValue(CSSValueAuto);
3005                 return zoomAdjustedPixelValue(sizingBox(*renderer).height(), *style);
3006             }
3007             return zoomAdjustedPixelValueForLength(style->height(), *style);
3008         case CSSPropertyWebkitHyphens:
3009             return cssValuePool.createValue(style->hyphens());
3010         case CSSPropertyWebkitHyphenateCharacter:
3011             if (style->hyphenationString().isNull())
3012                 return cssValuePool.createIdentifierValue(CSSValueAuto);
3013             return cssValuePool.createValue(style->hyphenationString(), CSSPrimitiveValue::CSS_STRING);
3014         case CSSPropertyWebkitHyphenateLimitAfter:
3015             if (style->hyphenationLimitAfter() < 0)
3016                 return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
3017             return CSSPrimitiveValue::create(style->hyphenationLimitAfter(), CSSPrimitiveValue::CSS_NUMBER);
3018         case CSSPropertyWebkitHyphenateLimitBefore:
3019             if (style->hyphenationLimitBefore() < 0)
3020                 return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
3021             return CSSPrimitiveValue::create(style->hyphenationLimitBefore(), CSSPrimitiveValue::CSS_NUMBER);
3022         case CSSPropertyWebkitHyphenateLimitLines:
3023             if (style->hyphenationLimitLines() < 0)
3024                 return CSSPrimitiveValue::createIdentifier(CSSValueNoLimit);
3025             return CSSPrimitiveValue::create(style->hyphenationLimitLines(), CSSPrimitiveValue::CSS_NUMBER);
3026         case CSSPropertyWebkitBorderFit:
3027             if (style->borderFit() == BorderFitBorder)
3028                 return cssValuePool.createIdentifierValue(CSSValueBorder);
3029             return cssValuePool.createIdentifierValue(CSSValueLines);
3030 #if ENABLE(CSS_IMAGE_ORIENTATION)
3031         case CSSPropertyImageOrientation:
3032             return cssValuePool.createValue(style->imageOrientation());
3033 #endif
3034         case CSSPropertyImageRendering:
3035             return CSSPrimitiveValue::create(style->imageRendering());
3036 #if ENABLE(CSS_IMAGE_RESOLUTION)
3037         case CSSPropertyImageResolution:
3038             return cssValuePool.createValue(style->imageResolution(), CSSPrimitiveValue::CSS_DPPX);
3039 #endif
3040         case CSSPropertyLeft:
3041             return positionOffsetValue(*style, CSSPropertyLeft);
3042         case CSSPropertyLetterSpacing:
3043             if (!style->letterSpacing())
3044                 return cssValuePool.createIdentifierValue(CSSValueNormal);
3045             return zoomAdjustedPixelValue(style->letterSpacing(), *style);
3046         case CSSPropertyWebkitLineClamp:
3047             if (style->lineClamp().isNone())
3048                 return cssValuePool.createIdentifierValue(CSSValueNone);
3049             return cssValuePool.createValue(style->lineClamp().value(), style->lineClamp().isPercentage() ? CSSPrimitiveValue::CSS_PERCENTAGE : CSSPrimitiveValue::CSS_NUMBER);
3050         case CSSPropertyLineHeight:
3051             return lineHeightFromStyle(*style);
3052         case CSSPropertyListStyleImage:
3053             if (style->listStyleImage())
3054                 return style->listStyleImage()->cssValue();
3055             return cssValuePool.createIdentifierValue(CSSValueNone);
3056         case CSSPropertyListStylePosition:
3057             return cssValuePool.createValue(style->listStylePosition());
3058         case CSSPropertyListStyleType:
3059             return cssValuePool.createValue(style->listStyleType());
3060         case CSSPropertyWebkitLocale:
3061             if (style->locale().isNull())
3062                 return cssValuePool.createIdentifierValue(CSSValueAuto);
3063             return cssValuePool.createValue(style->locale(), CSSPrimitiveValue::CSS_STRING);
3064         case CSSPropertyMarginTop:
3065             return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::marginTop, &RenderBoxModelObject::marginTop>(*style, renderer);
3066         case CSSPropertyMarginRight: {
3067             Length marginRight = style->marginRight();
3068             if (marginRight.isFixed() || !is<RenderBox>(renderer))
3069                 return zoomAdjustedPixelValueForLength(marginRight, *style);
3070             float value;
3071             if (marginRight.isPercentOrCalculated()) {
3072                 // RenderBox gives a marginRight() that is the distance between the right-edge of the child box
3073                 // and the right-edge of the containing box, when display == BLOCK. Let's calculate the absolute
3074                 // value of the specified margin-right % instead of relying on RenderBox's marginRight() value.
3075                 value = minimumValueForLength(marginRight, downcast<RenderBox>(*renderer).containingBlockLogicalWidthForContent());
3076             } else
3077                 value = downcast<RenderBox>(*renderer).marginRight();
3078             return zoomAdjustedPixelValue(value, *style);
3079         }
3080         case CSSPropertyMarginBottom:
3081             return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::marginBottom, &RenderBoxModelObject::marginBottom>(*style, renderer);
3082         case CSSPropertyMarginLeft:
3083             return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::marginLeft, &RenderBoxModelObject::marginLeft>(*style, renderer);
3084         case CSSPropertyWebkitMarqueeDirection:
3085             return cssValuePool.createValue(style->marqueeDirection());
3086         case CSSPropertyWebkitMarqueeIncrement:
3087             return cssValuePool.createValue(style->marqueeIncrement());
3088         case CSSPropertyWebkitMarqueeRepetition:
3089             if (style->marqueeLoopCount() < 0)
3090                 return cssValuePool.createIdentifierValue(CSSValueInfinite);
3091             return cssValuePool.createValue(style->marqueeLoopCount(), CSSPrimitiveValue::CSS_NUMBER);
3092         case CSSPropertyWebkitMarqueeStyle:
3093             return cssValuePool.createValue(style->marqueeBehavior());
3094         case CSSPropertyWebkitUserModify:
3095             return cssValuePool.createValue(style->userModify());
3096         case CSSPropertyMaxHeight: {
3097             const Length& maxHeight = style->maxHeight();
3098             if (maxHeight.isUndefined())
3099                 return cssValuePool.createIdentifierValue(CSSValueNone);
3100             return zoomAdjustedPixelValueForLength(maxHeight, *style);
3101         }
3102         case CSSPropertyMaxWidth: {
3103             const Length& maxWidth = style->maxWidth();
3104             if (maxWidth.isUndefined())
3105                 return cssValuePool.createIdentifierValue(CSSValueNone);
3106             return zoomAdjustedPixelValueForLength(maxWidth, *style);
3107         }
3108         case CSSPropertyMinHeight:
3109             if (style->minHeight().isAuto()) {
3110                 if (isFlexOrGrid(styledElement->parentNode()))
3111                     return cssValuePool.createIdentifierValue(CSSValueAuto);
3112                 return zoomAdjustedPixelValue(0, *style);
3113             }
3114             return zoomAdjustedPixelValueForLength(style->minHeight(), *style);
3115         case CSSPropertyMinWidth:
3116             if (style->minWidth().isAuto()) {
3117                 if (isFlexOrGrid(styledElement->parentNode()))
3118                     return cssValuePool.createIdentifierValue(CSSValueAuto);
3119                 return zoomAdjustedPixelValue(0, *style);
3120             }
3121             return zoomAdjustedPixelValueForLength(style->minWidth(), *style);
3122         case CSSPropertyObjectFit:
3123             return cssValuePool.createValue(style->objectFit());
3124         case CSSPropertyObjectPosition: {
3125             RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
3126             list->append(zoomAdjustedPixelValueForLength(style->objectPosition().x(), *style));
3127             list->append(zoomAdjustedPixelValueForLength(style->objectPosition().y(), *style));
3128             return list;
3129         }
3130         case CSSPropertyOpacity:
3131             return cssValuePool.createValue(style->opacity(), CSSPrimitiveValue::CSS_NUMBER);
3132         case CSSPropertyOrphans:
3133             if (style->hasAutoOrphans())
3134                 return cssValuePool.createIdentifierValue(CSSValueAuto);
3135             return cssValuePool.createValue(style->orphans(), CSSPrimitiveValue::CSS_NUMBER);
3136         case CSSPropertyOutlineColor:
3137             return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyOutlineColor)) : currentColorOrValidColor(style, style->outlineColor());
3138         case CSSPropertyOutlineOffset:
3139             return zoomAdjustedPixelValue(style->outlineOffset(), *style);
3140         case CSSPropertyOutlineStyle:
3141             if (style->outlineStyleIsAuto())
3142                 return cssValuePool.createIdentifierValue(CSSValueAuto);
3143             return cssValuePool.createValue(style->outlineStyle());
3144         case CSSPropertyOutlineWidth:
3145             return zoomAdjustedPixelValue(style->outlineWidth(), *style);
3146         case CSSPropertyOverflow:
3147             return cssValuePool.createValue(std::max(style->overflowX(), style->overflowY()));
3148         case CSSPropertyOverflowWrap:
3149             return cssValuePool.createValue(style->overflowWrap());
3150         case CSSPropertyOverflowX:
3151             return cssValuePool.createValue(style->overflowX());
3152         case CSSPropertyOverflowY:
3153             return cssValuePool.createValue(style->overflowY());
3154         case CSSPropertyPaddingTop:
3155             return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::paddingTop, &RenderBoxModelObject::computedCSSPaddingTop>(*style, renderer);
3156         case CSSPropertyPaddingRight:
3157             return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::paddingRight, &RenderBoxModelObject::computedCSSPaddingRight>(*style, renderer);
3158         case CSSPropertyPaddingBottom:
3159             return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::paddingBottom, &RenderBoxModelObject::computedCSSPaddingBottom>(*style, renderer);
3160         case CSSPropertyPaddingLeft:
3161             return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::paddingLeft, &RenderBoxModelObject::computedCSSPaddingLeft>(*style, renderer);
3162         case CSSPropertyPageBreakAfter:
3163             return cssValuePool.createValue(convertToPageBreak(style->breakAfter()));
3164         case CSSPropertyPageBreakBefore:
3165             return cssValuePool.createValue(convertToPageBreak(style->breakBefore()));
3166         case CSSPropertyPageBreakInside:
3167             return cssValuePool.createValue(convertToPageBreak(style->breakInside()));
3168         case CSSPropertyBreakAfter:
3169             return cssValuePool.createValue(style->breakAfter());
3170         case CSSPropertyBreakBefore:
3171             return cssValuePool.createValue(style->breakBefore());
3172         case CSSPropertyBreakInside:
3173             return cssValuePool.createValue(style->breakInside());
3174         case CSSPropertyHangingPunctuation:
3175             return hangingPunctuationToCSSValue(style->hangingPunctuation());
3176         case CSSPropertyPosition:
3177             return cssValuePool.createValue(style->position());
3178         case CSSPropertyRight:
3179             return positionOffsetValue(*style, CSSPropertyRight);
3180         case CSSPropertyWebkitRubyPosition:
3181             return cssValuePool.createValue(style->rubyPosition());
3182         case CSSPropertyTableLayout:
3183             return cssValuePool.createValue(style->tableLayout());
3184         case CSSPropertyTextAlign:
3185             return cssValuePool.createValue(style->textAlign());
3186         case CSSPropertyTextDecoration:
3187             return renderTextDecorationFlagsToCSSValue(style->textDecoration());
3188 #if ENABLE(CSS3_TEXT)
3189         case CSSPropertyWebkitTextAlignLast:
3190             return cssValuePool.createValue(style->textAlignLast());
3191         case CSSPropertyWebkitTextJustify:
3192             return cssValuePool.createValue(style->textJustify());
3193 #endif // CSS3_TEXT
3194         case CSSPropertyWebkitTextDecoration:
3195             return getCSSPropertyValuesForShorthandProperties(webkitTextDecorationShorthand());
3196         case CSSPropertyWebkitTextDecorationLine:
3197             return renderTextDecorationFlagsToCSSValue(style->textDecoration());
3198         case CSSPropertyWebkitTextDecorationStyle:
3199             return renderTextDecorationStyleFlagsToCSSValue(style->textDecorationStyle());
3200         case CSSPropertyWebkitTextDecorationColor:
3201             return currentColorOrValidColor(style, style->textDecorationColor());
3202         case CSSPropertyWebkitTextDecorationSkip:
3203             return renderTextDecorationSkipFlagsToCSSValue(style->textDecorationSkip());
3204         case CSSPropertyWebkitTextUnderlinePosition:
3205             return cssValuePool.createValue(style->textUnderlinePosition());
3206         case CSSPropertyWebkitTextDecorationsInEffect:
3207             return renderTextDecorationFlagsToCSSValue(style->textDecorationsInEffect());
3208         case CSSPropertyWebkitTextFillColor:
3209             return currentColorOrValidColor(style, style->textFillColor());
3210         case CSSPropertyWebkitTextEmphasisColor:
3211             return currentColorOrValidColor(style, style->textEmphasisColor());
3212         case CSSPropertyWebkitTextEmphasisPosition:
3213             return renderEmphasisPositionFlagsToCSSValue(style->textEmphasisPosition());
3214         case CSSPropertyWebkitTextEmphasisStyle:
3215             switch (style->textEmphasisMark()) {
3216             case TextEmphasisMarkNone:
3217                 return cssValuePool.createIdentifierValue(CSSValueNone);
3218             case TextEmphasisMarkCustom:
3219                 return cssValuePool.createValue(style->textEmphasisCustomMark(), CSSPrimitiveValue::CSS_STRING);
3220             case TextEmphasisMarkAuto:
3221                 ASSERT_NOT_REACHED();
3222 #if ASSERT_DISABLED
3223                 FALLTHROUGH;
3224 #endif
3225             case TextEmphasisMarkDot:
3226             case TextEmphasisMarkCircle:
3227             case TextEmphasisMarkDoubleCircle:
3228             case TextEmphasisMarkTriangle:
3229             case TextEmphasisMarkSesame: {
3230                 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
3231                 list->append(cssValuePool.createValue(style->textEmphasisFill()));
3232                 list->append(cssValuePool.createValue(style->textEmphasisMark()));
3233                 return list;
3234             }
3235             }
3236         case CSSPropertyTextIndent: {
3237             // If CSS3_TEXT is disabled or text-indent has only one value(<length> | <percentage>),
3238             // getPropertyCSSValue() returns CSSValue.
3239             RefPtr<CSSValue> textIndent = zoomAdjustedPixelValueForLength(style->textIndent(), *style);
3240 #if ENABLE(CSS3_TEXT)
3241             // If CSS3_TEXT is enabled and text-indent has -webkit-each-line or -webkit-hanging,
3242             // getPropertyCSSValue() returns CSSValueList.
3243             if (style->textIndentLine() == TextIndentEachLine || style->textIndentType() == TextIndentHanging) {
3244                 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
3245                 list->append(textIndent.releaseNonNull());
3246                 if (style->textIndentLine() == TextIndentEachLine)
3247                     list->append(cssValuePool.createIdentifierValue(CSSValueWebkitEachLine));
3248                 if (style->textIndentType() == TextIndentHanging)
3249                     list->append(cssValuePool.createIdentifierValue(CSSValueWebkitHanging));
3250                 return list;
3251             }
3252 #endif
3253             return textIndent;
3254         }
3255         case CSSPropertyTextShadow:
3256             return valueForShadow(style->textShadow(), propertyID, *style);
3257         case CSSPropertyTextRendering:
3258             return cssValuePool.createValue(style->fontDescription().textRenderingMode());
3259         case CSSPropertyTextOverflow:
3260             if (style->textOverflow())
3261                 return cssValuePool.createIdentifierValue(CSSValueEllipsis);
3262             return cssValuePool.createIdentifierValue(CSSValueClip);
3263         case CSSPropertyWebkitTextSecurity:
3264             return cssValuePool.createValue(style->textSecurity());
3265 #if ENABLE(TEXT_AUTOSIZING)
3266         case CSSPropertyWebkitTextSizeAdjust:
3267             if (style->textSizeAdjust().isAuto())
3268                 return cssValuePool.createIdentifierValue(CSSValueAuto);
3269             if (style->textSizeAdjust().isNone())
3270                 return cssValuePool.createIdentifierValue(CSSValueNone);
3271             return CSSPrimitiveValue::create(style->textSizeAdjust().percentage(), CSSPrimitiveValue::CSS_PERCENTAGE);
3272 #endif
3273         case CSSPropertyWebkitTextStrokeColor:
3274             return currentColorOrValidColor(style, style->textStrokeColor());
3275         case CSSPropertyWebkitTextStrokeWidth:
3276             return zoomAdjustedPixelValue(style->textStrokeWidth(), *style);
3277         case CSSPropertyTextTransform:
3278             return cssValuePool.createValue(style->textTransform());
3279         case CSSPropertyTop:
3280             return positionOffsetValue(*style, CSSPropertyTop);
3281         case CSSPropertyUnicodeBidi:
3282             return cssValuePool.createValue(style->unicodeBidi());
3283         case CSSPropertyVerticalAlign:
3284             switch (style->verticalAlign()) {
3285                 case BASELINE:
3286                     return cssValuePool.createIdentifierValue(CSSValueBaseline);
3287                 case MIDDLE:
3288                     return cssValuePool.createIdentifierValue(CSSValueMiddle);
3289                 case SUB:
3290                     return cssValuePool.createIdentifierValue(CSSValueSub);
3291                 case SUPER:
3292                     return cssValuePool.createIdentifierValue(CSSValueSuper);
3293                 case TEXT_TOP:
3294                     return cssValuePool.createIdentifierValue(CSSValueTextTop);
3295                 case TEXT_BOTTOM:
3296                     return cssValuePool.createIdentifierValue(CSSValueTextBottom);
3297                 case TOP:
3298                     return cssValuePool.createIdentifierValue(CSSValueTop);
3299                 case BOTTOM:
3300                     return cssValuePool.createIdentifierValue(CSSValueBottom);
3301                 case BASELINE_MIDDLE:
3302                     return cssValuePool.createIdentifierValue(CSSValueWebkitBaselineMiddle);
3303                 case LENGTH:
3304                     return cssValuePool.createValue(style->verticalAlignLength());
3305             }
3306             ASSERT_NOT_REACHED();
3307             return nullptr;
3308         case CSSPropertyVisibility:
3309             return cssValuePool.createValue(style->visibility());
3310         case CSSPropertyWhiteSpace:
3311             return cssValuePool.createValue(style->whiteSpace());
3312         case CSSPropertyWidows:
3313             if (style->hasAutoWidows())
3314                 return cssValuePool.createIdentifierValue(CSSValueAuto);
3315             return cssValuePool.createValue(style->widows(), CSSPrimitiveValue::CSS_NUMBER);
3316         case CSSPropertyWidth:
3317             if (renderer && !renderer->isRenderSVGModelObject()) {
3318                 // According to http://www.w3.org/TR/CSS2/visudet.html#the-width-property,
3319                 // the "width" property does not apply for non-replaced inline elements.
3320                 if (!renderer->isReplaced() && renderer->isInline())
3321                     return cssValuePool.createIdentifierValue(CSSValueAuto);
3322                 return zoomAdjustedPixelValue(sizingBox(*renderer).width(), *style);
3323             }
3324             return zoomAdjustedPixelValueForLength(style->width(), *style);
3325         case CSSPropertyWillChange:
3326             return getWillChangePropertyValue(style->willChange());
3327             break;
3328         case CSSPropertyWordBreak:
3329             return cssValuePool.createValue(style->wordBreak());
3330         case CSSPropertyWordSpacing:
3331             return zoomAdjustedPixelValue(style->fontCascade().wordSpacing(), *style);
3332         case CSSPropertyWordWrap:
3333             return cssValuePool.createValue(style->overflowWrap());
3334         case CSSPropertyWebkitLineBreak:
3335             return cssValuePool.createValue(style->lineBreak());
3336         case CSSPropertyWebkitNbspMode:
3337             return cssValuePool.createValue(style->nbspMode());
3338         case CSSPropertyResize:
3339             return cssValuePool.createValue(style->resize());
3340         case CSSPropertyWebkitFontKerning:
3341             return cssValuePool.createValue(style->fontDescription().kerning());
3342         case CSSPropertyWebkitFontSmoothing:
3343             return cssValuePool.createValue(style->fontDescription().fontSmoothing());
3344         case CSSPropertyFontVariantLigatures:
3345             return fontVariantLigaturesPropertyValue(style->fontDescription().variantCommonLigatures(), style->fontDescription().variantDiscretionaryLigatures(), style->fontDescription().variantHistoricalLigatures(), style->fontDescription().variantContextualAlternates());
3346         case CSSPropertyFontVariantPosition:
3347             return fontVariantPositionPropertyValue(style->fontDescription().variantPosition());
3348         case CSSPropertyFontVariantCaps:
3349             return fontVariantCapsPropertyValue(style->fontDescription().variantCaps());
3350         case CSSPropertyFontVariantNumeric:
3351             return fontVariantNumericPropertyValue(style->fontDescription().variantNumericFigure(), style->fontDescription().variantNumericSpacing(), style->fontDescription().variantNumericFraction(), style->fontDescription().variantNumericOrdinal(), style->fontDescription().variantNumericSlashedZero());
3352         case CSSPropertyFontVariantAlternates:
3353             return fontVariantAlternatesPropertyValue(style->fontDescription().variantAlternates());
3354         case CSSPropertyFontVariantEastAsian:
3355             return fontVariantEastAsianPropertyValue(style->fontDescription().variantEastAsianVariant(), style->fontDescription().variantEastAsianWidth(), style->fontDescription().variantEastAsianRuby());
3356         case CSSPropertyZIndex:
3357             if (style->hasAutoZIndex())
3358                 return cssValuePool.createIdentifierValue(CSSValueAuto);
3359             return cssValuePool.createValue(style->zIndex(), CSSPrimitiveValue::CSS_NUMBER);
3360         case CSSPropertyZoom:
3361             return cssValuePool.createValue(style->zoom(), CSSPrimitiveValue::CSS_NUMBER);
3362         case CSSPropertyBoxSizing:
3363             if (style->boxSizing() == CONTENT_BOX)
3364                 return cssValuePool.createIdentifierValue(CSSValueContentBox);
3365             return cssValuePool.createIdentifierValue(CSSValueBorderBox);
3366 #if ENABLE(DASHBOARD_SUPPORT)
3367         case CSSPropertyWebkitDashboardRegion:
3368         {
3369             const Vector<StyleDashboardRegion>& regions = style->dashboardRegions();
3370             unsigned count = regions.size();
3371             if (count == 1 && regions[0].type == StyleDashboardRegion::None)
3372                 return cssValuePool.createIdentifierValue(CSSValueNone);
3373
3374             RefPtr<DashboardRegion> firstRegion;
3375             DashboardRegion* previousRegion = nullptr;
3376             for (unsigned i = 0; i < count; i++) {
3377                 auto region = DashboardRegion::create();
3378                 StyleDashboardRegion styleRegion = regions[i];
3379
3380                 region->m_label = styleRegion.label;
3381                 LengthBox offset = styleRegion.offset;
3382                 region->setTop(zoomAdjustedPixelValue(offset.top().value(), *style));
3383                 region->setRight(zoomAdjustedPixelValue(offset.right().value(), *style));
3384                 region->setBottom(zoomAdjustedPixelValue(offset.bottom().value(), *style));
3385                 region->setLeft(zoomAdjustedPixelValue(offset.left().value(), *style));
3386                 region->m_isRectangle = (styleRegion.type == StyleDashboardRegion::Rectangle);
3387                 region->m_isCircle = (styleRegion.type == StyleDashboardRegion::Circle);
3388
3389                 if (previousRegion)
3390                     previousRegion->m_next = region.copyRef();
3391                 else
3392                     firstRegion = region.copyRef();
3393                 previousRegion = region.ptr();
3394             }
3395             return cssValuePool.createValue(WTFMove(firstRegion));
3396         }
3397 #endif
3398         case CSSPropertyAnimationDelay:
3399             return getDelayValue(style->animations());
3400         case CSSPropertyAnimationDirection: {
3401             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
3402             const AnimationList* t = style->animations();
3403             if (t) {
3404                 for (size_t i = 0; i < t->size(); ++i) {
3405                     switch (t->animation(i).direction()) {
3406                     case Animation::AnimationDirectionNormal:
3407                         list->append(cssValuePool.createIdentifierValue(CSSValueNormal));
3408                         break;
3409                     case Animation::AnimationDirectionAlternate:
3410                         list->append(cssValuePool.createIdentifierValue(CSSValueAlternate));
3411                         break;
3412                     case Animation::AnimationDirectionReverse:
3413                         list->append(cssValuePool.createIdentifierValue(CSSValueReverse));
3414                         break;
3415                     case Animation::AnimationDirectionAlternateReverse:
3416                         list->append(cssValuePool.createIdentifierValue(CSSValueAlternateReverse));
3417                         break;
3418                     }
3419                 }
3420             } else
3421                 list->append(cssValuePool.createIdentifierValue(CSSValueNormal));
3422             return list;
3423         }
3424         case CSSPropertyAnimationDuration:
3425             return getDurationValue(style->animations());
3426         case CSSPropertyAnimationFillMode: {
3427             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
3428             const AnimationList* t = style->animations();
3429             if (t) {
3430                 for (size_t i = 0; i < t->size(); ++i) {
3431                     switch (t->animation(i).fillMode()) {
3432                     case AnimationFillModeNone:
3433                         list->append(cssValuePool.createIdentifierValue(CSSValueNone));
3434                         break;
3435                     case AnimationFillModeForwards:
3436                         list->append(cssValuePool.createIdentifierValue(CSSValueForwards));
3437                         break;
3438                     case AnimationFillModeBackwards:
3439                         list->append(cssValuePool.createIdentifierValue(CSSValueBackwards));
3440                         break;
3441                     case AnimationFillModeBoth:
3442                         list->append(cssValuePool.createIdentifierValue(CSSValueBoth));
3443                         break;
3444                     }
3445                 }
3446             } else
3447                 list->append(cssValuePool.createIdentifierValue(CSSValueNone));
3448             return list;
3449         }
3450         case CSSPropertyAnimationIterationCount: {
3451             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
3452             const AnimationList* t = style->animations();
3453             if (t) {
3454                 for (size_t i = 0; i < t->size(); ++i) {
3455                     double iterationCount = t->animation(i).iterationCount();
3456                     if (iterationCount == Animation::IterationCountInfinite)
3457                         list->append(cssValuePool.createIdentifierValue(CSSValueInfinite));
3458                     else
3459                         list->append(cssValuePool.createValue(iterationCount, CSSPrimitiveValue::CSS_NUMBER));
3460                 }
3461             } else
3462                 list->append(cssValuePool.createValue(Animation::initialIterationCount(), CSSPrimitiveValue::CSS_NUMBER));
3463             return list;
3464         }
3465         case CSSPropertyAnimationName: {
3466             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
3467             const AnimationList* t = style->animations();
3468             if (t) {
3469                 for (size_t i = 0; i < t->size(); ++i)
3470                     list->append(cssValuePool.createValue(t->animation(i).name(), CSSPrimitiveValue::CSS_STRING));
3471             } else
3472                 list->append(cssValuePool.createIdentifierValue(CSSValueNone));
3473             return list;
3474         }
3475         case CSSPropertyAnimationPlayState: {
3476             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
3477             const AnimationList* t = style->animations();
3478             if (t) {
3479                 for (size_t i = 0; i < t->size(); ++i) {
3480                     int prop = t->animation(i).playState();
3481                     if (prop == AnimPlayStatePlaying)
3482                         list->append(cssValuePool.createIdentifierValue(CSSValueRunning));
3483                     else
3484                         list->append(cssValuePool.createIdentifierValue(CSSValuePaused));
3485                 }
3486             } else
3487                 list->append(cssValuePool.createIdentifierValue(CSSValueRunning));
3488             return list;
3489         }
3490         case CSSPropertyAnimationTimingFunction:
3491             return getTimingFunctionValue(style->animations());
3492 #if ENABLE(CSS_ANIMATIONS_LEVEL_2)
3493         case CSSPropertyWebkitAnimationTrigger:
3494             return getAnimationTriggerValue(style->animations(), *style);
3495 #endif
3496         case CSSPropertyWebkitAppearance:
3497             return cssValuePool.createValue(style->appearance());
3498         case CSSPropertyWebkitAspectRatio:
3499             if (style->aspectRatioType() == AspectRatioAuto)
3500                 return cssValuePool.createIdentifierValue(CSSValueAuto);
3501             if (style->aspectRatioType() == AspectRatioFromDimensions)
3502                 return cssValuePool.createIdentifierValue(CSSValueFromDimensions);
3503             if (style->aspectRatioType() == AspectRatioFromIntrinsic)
3504                 return cssValuePool.createIdentifierValue(CSSValueFromIntrinsic);
3505             return CSSAspectRatioValue::create(style->aspectRatioNumerator(), style->aspectRatioDenominator());
3506         case CSSPropertyWebkitBackfaceVisibility:
3507             return cssValuePool.createIdentifierValue((style->backfaceVisibility() == BackfaceVisibilityHidden) ? CSSValueHidden : CSSValueVisible);
3508         case CSSPropertyWebkitBorderImage:
3509             return valueForNinePieceImage(style->borderImage());
3510         case CSSPropertyBorderImageOutset:
3511             return valueForNinePieceImageQuad(style->borderImage().outset());
3512         case CSSPropertyBorderImageRepeat:
3513             return valueForNinePieceImageRepeat(style->borderImage());
3514         case CSSPropertyBorderImageSlice:
3515             return valueForNinePieceImageSlice(style->borderImage());
3516         case CSSPropertyBorderImageWidth:
3517             return valueForNinePieceImageQuad(style->borderImage().borderSlices());
3518         case CSSPropertyWebkitMaskBoxImage:
3519             return valueForNinePieceImage(style->maskBoxImage());
3520         case CSSPropertyWebkitMaskBoxImageOutset:
3521             return valueForNinePieceImageQuad(style->maskBoxImage().outset());
3522         case CSSPropertyWebkitMaskBoxImageRepeat:
3523             return valueForNinePieceImageRepeat(style->maskBoxImage());
3524         case CSSPropertyWebkitMaskBoxImageSlice:
3525             return valueForNinePieceImageSlice(style->maskBoxImage());
3526         case CSSPropertyWebkitMaskBoxImageWidth:
3527             return valueForNinePieceImageQuad(style->maskBoxImage().borderSlices());
3528         case CSSPropertyWebkitMaskBoxImageSource:
3529             if (style->maskBoxImageSource())
3530                 return style->maskBoxImageSource()->cssValue();
3531             return cssValuePool.createIdentifierValue(CSSValueNone);
3532         case CSSPropertyWebkitFontSizeDelta:
3533             // Not a real style property -- used by the editing engine -- so has no computed value.
3534             break;
3535         case CSSPropertyWebkitInitialLetter: {
3536             Ref<CSSPrimitiveValue> drop = !style->initialLetterDrop() ? cssValuePool.createIdentifierValue(CSSValueNormal) : cssValuePool.createValue(style->initialLetterDrop(), CSSPrimitiveValue::CSS_NUMBER);
3537             Ref<CSSPrimitiveValue> size = !style->initialLetterHeight() ? cssValuePool.createIdentifierValue(CSSValueNormal) : cssValuePool.createValue(style->initialLetterHeight(), CSSPrimitiveValue::CSS_NUMBER);
3538             return cssValuePool.createValue(Pair::create(WTFMove(drop), WTFMove(size)));
3539         }
3540         case CSSPropertyWebkitMarginBottomCollapse:
3541         case CSSPropertyWebkitMarginAfterCollapse:
3542             return cssValuePool.createValue(style->marginAfterCollapse());
3543         case CSSPropertyWebkitMarginTopCollapse:
3544         case CSSPropertyWebkitMarginBeforeCollapse:
3545             return cssValuePool.createValue(style->marginBeforeCollapse());
3546 #if ENABLE(ACCELERATED_OVERFLOW_SCROLLING)
3547         case CSSPropertyWebkitOverflowScrolling:
3548             if (!style->useTouchOverflowScrolling())
3549                 return cssValuePool.createIdentifierValue(CSSValueAuto);
3550             return cssValuePool.createIdentifierValue(CSSValueTouch);
3551 #endif
3552         case CSSPropertyPerspective:
3553             if (!style->hasPerspective())
3554                 return cssValuePool.createIdentifierValue(CSSValueNone);
3555             return zoomAdjustedPixelValue(style->perspective(), *style);
3556         case CSSPropertyPerspectiveOrigin: {
3557             RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
3558             if (renderer) {
3559                 LayoutRect box;
3560                 if (is<RenderBox>(*renderer))
3561                     box = downcast<RenderBox>(*renderer).borderBoxRect();
3562
3563                 list->append(zoomAdjustedPixelValue(minimumValueForLength(style->perspectiveOriginX(), box.width()), *style));
3564                 list->append(zoomAdjustedPixelValue(minimumValueForLength(style->perspectiveOriginY(), box.height()), *style));
3565             }
3566             else {
3567                 list->append(zoomAdjustedPixelValueForLength(style->perspectiveOriginX(), *style));
3568                 list->append(zoomAdjustedPixelValueForLength(style->perspectiveOriginY(), *style));
3569
3570             }
3571             return list;
3572         }
3573         case CSSPropertyWebkitRtlOrdering:
3574             return cssValuePool.createIdentifierValue(style->rtlOrdering() ? CSSValueVisual : CSSValueLogical);
3575 #if ENABLE(TOUCH_EVENTS)
3576         case CSSPropertyWebkitTapHighlightColor:
3577             return currentColorOrValidColor(style, style->tapHighlightColor());
3578         case CSSPropertyTouchAction:
3579             return cssValuePool.createValue(style->touchAction());
3580 #endif
3581 #if PLATFORM(IOS)
3582         case CSSPropertyWebkitTouchCallout:
3583             return cssValuePool.createIdentifierValue(style->touchCalloutEnabled() ? CSSValueDefault : CSSValueNone);
3584 #endif
3585         case CSSPropertyWebkitUserDrag:
3586             return cssValuePool.createValue(style->userDrag());
3587         case CSSPropertyWebkitUserSelect:
3588             return cssValuePool.createValue(style->userSelect());
3589         case CSSPropertyBorderBottomLeftRadius:
3590             return getBorderRadiusCornerValue(style->borderBottomLeftRadius(), *style);
3591         case CSSPropertyBorderBottomRightRadius:
3592             return getBorderRadiusCornerValue(style->borderBottomRightRadius(), *style);
3593         case CSSPropertyBorderTopLeftRadius:
3594             return getBorderRadiusCornerValue(style->borderTopLeftRadius(), *style);
3595         case CSSPropertyBorderTopRightRadius:
3596             return getBorderRadiusCornerValue(style->borderTopRightRadius(), *style);
3597         case CSSPropertyClip: {
3598             if (!style->hasClip())
3599                 return cssValuePool.createIdentifierValue(CSSValueAuto);
3600             auto rect = Rect::create();
3601             rect->setTop(autoOrZoomAdjustedValue(style->clip().top(), *style));
3602             rect->setRight(autoOrZoomAdjustedValue(style->clip().right(), *style));
3603             rect->setBottom(autoOrZoomAdjustedValue(style->clip().bottom(), *style));
3604             rect->setLeft(autoOrZoomAdjustedValue(style->clip().left(), *style));
3605             return cssValuePool.createValue(WTFMove(rect));
3606         }
3607         case CSSPropertySpeak:
3608             return cssValuePool.createValue(style->speak());
3609         case CSSPropertyTransform:
3610             return computedTransform(renderer, *style);
3611         case CSSPropertyTransformOrigin: {
3612             RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
3613             if (renderer) {
3614                 LayoutRect box;
3615                 if (is<RenderBox>(*renderer))
3616                     box = downcast<RenderBox>(*renderer).borderBoxRect();
3617
3618                 list->append(zoomAdjustedPixelValue(minimumValueForLength(style->transformOriginX(), box.width()), *style));
3619                 list->append(zoomAdjustedPixelValue(minimumValueForLength(style->transformOriginY(), box.height()), *style));
3620                 if (style->transformOriginZ() != 0)
3621                     list->append(zoomAdjustedPixelValue(style->transformOriginZ(), *style));
3622             } else {
3623                 list->append(zoomAdjustedPixelValueForLength(style->transformOriginX(), *style));
3624                 list->append(zoomAdjustedPixelValueForLength(style->transformOriginY(), *style));
3625                 if (style->transformOriginZ() != 0)
3626                     list->append(zoomAdjustedPixelValue(style->transformOriginZ(), *style));
3627             }
3628             return list;
3629         }
3630         case CSSPropertyTransformStyle:
3631         case CSSPropertyWebkitTransformStyle:
3632             return cssValuePool.createIdentifierValue((style->transformStyle3D() == TransformStyle3DPreserve3D) ? CSSValuePreserve3d : CSSValueFlat);
3633         case CSSPropertyTransitionDelay:
3634             return getDelayValue(style->transitions());
3635         case CSSPropertyTransitionDuration:
3636             return getDurationValue(style->transitions());
3637         case CSSPropertyTransitionProperty:
3638             return getTransitionPropertyValue(style->transitions());
3639         case CSSPropertyTransitionTimingFunction:
3640             return getTimingFunctionValue(style->transitions());
3641         case CSSPropertyTransition: {
3642             const AnimationList* animList = style->transitions();
3643             if (animList) {
3644                 RefPtr<CSSValueList> transitionsList = CSSValueList::createCommaSeparated();
3645                 for (size_t i = 0; i < animList->size(); ++i) {
3646                     RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
3647                     const Animation& animation = animList->animation(i);
3648                     list->append(createTransitionPropertyValue(animation));
3649                     list->append(cssValuePool.createValue(animation.duration(), CSSPrimitiveValue::CSS_S));
3650                     list->append(createTimingFunctionValue(animation.timingFunction().get()));
3651                     list->append(cssValuePool.createValue(animation.delay(), CSSPrimitiveValue::CSS_S));
3652                     transitionsList->append(list.releaseNonNull());
3653                 }
3654                 return transitionsList;
3655             }
3656
3657             RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
3658             // transition-property default value.
3659             list->append(cssValuePool.createIdentifierValue(CSSValueAll));
3660             list->append(cssValuePool.createValue(Animation::initialDuration(), CSSPrimitiveValue::CSS_S));
3661             list->append(createTimingFunctionValue(Animation::initialTimingFunction().get()));
3662             list->append(cssValuePool.createValue(Animation::initialDelay(), CSSPrimitiveValue::CSS_S));
3663             return list;
3664         }
3665         case CSSPropertyPointerEvents:
3666             return cssValuePool.createValue(style->pointerEvents());
3667         case CSSPropertyWebkitLineGrid:
3668             if (style->lineGrid().isNull())
3669                 return cssValuePool.createIdentifierValue(CSSValueNone);
3670             return cssValuePool.createValue(style->lineGrid(), CSSPrimitiveValue::CSS_STRING);
3671         case CSSPropertyWebkitLineSnap:
3672             return CSSPrimitiveValue::create(style->lineSnap());
3673         case CSSPropertyWebkitLineAlign:
3674             return CSSPrimitiveValue::create(style->lineAlign());
3675         case CSSPropertyWritingMode:
3676             return cssValuePool.createValue(style->writingMode());
3677         case CSSPropertyWebkitTextCombine: