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