[CSS Grid Layout] Implement justify-self and justify-item css properties.
[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_RENDERING) 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     if (isRenderGrid) {
1057         const Vector<LayoutUnit>& trackPositions = direction == ForColumns ? downcast<RenderGrid>(*renderer).columnPositions() : downcast<RenderGrid>(*renderer).rowPositions();
1058         // There are at least #tracks + 1 grid lines (trackPositions). Apart from that, the grid container can generate implicit grid tracks,
1059         // so we'll have more trackPositions than trackSizes as the latter only contain the explicit grid.
1060         ASSERT(trackPositions.size() - 1 >= trackSizes.size());
1061
1062         for (unsigned i = 0; i < trackPositions.size() - 1; ++i) {
1063             addValuesForNamedGridLinesAtIndex(orderedNamedGridLines, i, list.get());
1064             list.get().append(zoomAdjustedPixelValue(trackPositions[i + 1] - trackPositions[i], style));
1065         }
1066     } else {
1067         for (unsigned i = 0; i < trackSizes.size(); ++i) {
1068             addValuesForNamedGridLinesAtIndex(orderedNamedGridLines, i, list.get());
1069             list.get().append(specifiedValueForGridTrackSize(trackSizes[i], style));
1070         }
1071     }
1072
1073     // Those are the trailing <ident>* allowed in the syntax.
1074     addValuesForNamedGridLinesAtIndex(orderedNamedGridLines, trackSizes.size(), list.get());
1075     return WTF::move(list);
1076 }
1077
1078 static Ref<CSSValue> valueForGridPosition(const GridPosition& position)
1079 {
1080     if (position.isAuto())
1081         return cssValuePool().createIdentifierValue(CSSValueAuto);
1082
1083     if (position.isNamedGridArea())
1084         return cssValuePool().createValue(position.namedGridLine(), CSSPrimitiveValue::CSS_STRING);
1085
1086     auto list = CSSValueList::createSpaceSeparated();
1087     if (position.isSpan()) {
1088         list.get().append(cssValuePool().createIdentifierValue(CSSValueSpan));
1089         list.get().append(cssValuePool().createValue(position.spanPosition(), CSSPrimitiveValue::CSS_NUMBER));
1090     } else
1091         list.get().append(cssValuePool().createValue(position.integerPosition(), CSSPrimitiveValue::CSS_NUMBER));
1092
1093     if (!position.namedGridLine().isNull())
1094         list.get().append(cssValuePool().createValue(position.namedGridLine(), CSSPrimitiveValue::CSS_STRING));
1095     return WTF::move(list);
1096 }
1097 #endif
1098
1099 static Ref<CSSValue> createTransitionPropertyValue(const Animation& animation)
1100 {
1101     if (animation.animationMode() == Animation::AnimateNone)
1102         return cssValuePool().createIdentifierValue(CSSValueNone);
1103     if (animation.animationMode() == Animation::AnimateAll)
1104         return cssValuePool().createIdentifierValue(CSSValueAll);
1105     return cssValuePool().createValue(getPropertyNameString(animation.property()), CSSPrimitiveValue::CSS_STRING);
1106 }
1107
1108 static Ref<CSSValueList> getTransitionPropertyValue(const AnimationList* animList)
1109 {
1110     auto list = CSSValueList::createCommaSeparated();
1111     if (animList) {
1112         for (size_t i = 0; i < animList->size(); ++i)
1113             list.get().append(createTransitionPropertyValue(animList->animation(i)));
1114     } else
1115         list.get().append(cssValuePool().createIdentifierValue(CSSValueAll));
1116     return list;
1117 }
1118
1119 #if ENABLE(CSS_SCROLL_SNAP)
1120 static Ref<CSSValueList> scrollSnapDestination(RenderStyle& style, const LengthSize& destination)
1121 {
1122     auto list = CSSValueList::createSpaceSeparated();
1123     list.get().append(zoomAdjustedPixelValueForLength(destination.width(), &style));
1124     list.get().append(zoomAdjustedPixelValueForLength(destination.height(), &style));
1125     return list;
1126 }
1127
1128 static Ref<CSSValue> scrollSnapPoints(RenderStyle& style, const ScrollSnapPoints* points)
1129 {
1130     if (!points)
1131         return cssValuePool().createIdentifierValue(CSSValueNone);
1132
1133     if (points->usesElements)
1134         return cssValuePool().createIdentifierValue(CSSValueElements);
1135     auto list = CSSValueList::createSpaceSeparated();
1136     for (auto& point : points->offsets)
1137         list.get().append(zoomAdjustedPixelValueForLength(point, &style));
1138     if (points->hasRepeat)
1139         list.get().append(cssValuePool().createValue(LengthRepeat::create(zoomAdjustedPixelValueForLength(points->repeatOffset, &style))));
1140     return WTF::move(list);
1141 }
1142
1143 static Ref<CSSValue> scrollSnapCoordinates(RenderStyle& style, const Vector<LengthSize>& coordinates)
1144 {
1145     if (coordinates.isEmpty())
1146         return cssValuePool().createIdentifierValue(CSSValueNone);
1147
1148     auto list = CSSValueList::createCommaSeparated();
1149
1150     for (auto& coordinate : coordinates) {
1151         auto pair = CSSValueList::createSpaceSeparated();
1152         pair.get().append(zoomAdjustedPixelValueForLength(coordinate.width(), &style));
1153         pair.get().append(zoomAdjustedPixelValueForLength(coordinate.height(), &style));
1154         list.get().append(WTF::move(pair));
1155     }
1156
1157     return WTF::move(list);
1158 }
1159 #endif
1160
1161 static Ref<CSSValueList> getDelayValue(const AnimationList* animList)
1162 {
1163     auto list = CSSValueList::createCommaSeparated();
1164     if (animList) {
1165         for (size_t i = 0; i < animList->size(); ++i)
1166             list.get().append(cssValuePool().createValue(animList->animation(i).delay(), CSSPrimitiveValue::CSS_S));
1167     } else {
1168         // Note that initialAnimationDelay() is used for both transitions and animations
1169         list.get().append(cssValuePool().createValue(Animation::initialDelay(), CSSPrimitiveValue::CSS_S));
1170     }
1171     return list;
1172 }
1173
1174 static Ref<CSSValueList> getDurationValue(const AnimationList* animList)
1175 {
1176     auto list = CSSValueList::createCommaSeparated();
1177     if (animList) {
1178         for (size_t i = 0; i < animList->size(); ++i)
1179             list.get().append(cssValuePool().createValue(animList->animation(i).duration(), CSSPrimitiveValue::CSS_S));
1180     } else {
1181         // Note that initialAnimationDuration() is used for both transitions and animations
1182         list.get().append(cssValuePool().createValue(Animation::initialDuration(), CSSPrimitiveValue::CSS_S));
1183     }
1184     return list;
1185 }
1186
1187 static Ref<CSSValue> createTimingFunctionValue(const TimingFunction* timingFunction)
1188 {
1189     switch (timingFunction->type()) {
1190     case TimingFunction::CubicBezierFunction: {
1191         const CubicBezierTimingFunction* bezierTimingFunction = static_cast<const CubicBezierTimingFunction*>(timingFunction);
1192         if (bezierTimingFunction->timingFunctionPreset() != CubicBezierTimingFunction::Custom) {
1193             CSSValueID valueId = CSSValueInvalid;
1194             switch (bezierTimingFunction->timingFunctionPreset()) {
1195             case CubicBezierTimingFunction::Ease:
1196                 valueId = CSSValueEase;
1197                 break;
1198             case CubicBezierTimingFunction::EaseIn:
1199                 valueId = CSSValueEaseIn;
1200                 break;
1201             case CubicBezierTimingFunction::EaseOut:
1202                 valueId = CSSValueEaseOut;
1203                 break;
1204             default:
1205                 ASSERT(bezierTimingFunction->timingFunctionPreset() == CubicBezierTimingFunction::EaseInOut);
1206                 valueId = CSSValueEaseInOut;
1207                 break;
1208             }
1209             return cssValuePool().createIdentifierValue(valueId);
1210         }
1211         return CSSCubicBezierTimingFunctionValue::create(bezierTimingFunction->x1(), bezierTimingFunction->y1(), bezierTimingFunction->x2(), bezierTimingFunction->y2());
1212     }
1213     case TimingFunction::StepsFunction: {
1214         const StepsTimingFunction* stepsTimingFunction = static_cast<const StepsTimingFunction*>(timingFunction);
1215         return CSSStepsTimingFunctionValue::create(stepsTimingFunction->numberOfSteps(), stepsTimingFunction->stepAtStart());
1216     }
1217     default:
1218         ASSERT(timingFunction->type() == TimingFunction::LinearFunction);
1219         return cssValuePool().createIdentifierValue(CSSValueLinear);
1220     }
1221 }
1222
1223 static Ref<CSSValueList> getTimingFunctionValue(const AnimationList* animList)
1224 {
1225     auto list = CSSValueList::createCommaSeparated();
1226     if (animList) {
1227         for (size_t i = 0; i < animList->size(); ++i)
1228             list.get().append(createTimingFunctionValue(animList->animation(i).timingFunction().get()));
1229     } else
1230         // Note that initialAnimationTimingFunction() is used for both transitions and animations
1231         list.get().append(createTimingFunctionValue(Animation::initialTimingFunction().get()));
1232     return list;
1233 }
1234
1235 #if ENABLE(CSS_ANIMATIONS_LEVEL_2)
1236 static Ref<CSSValue> createAnimationTriggerValue(const AnimationTrigger* trigger, const RenderStyle* style)
1237 {
1238     switch (trigger->type()) {
1239     case AnimationTrigger::AnimationTriggerType::ScrollAnimationTriggerType: {
1240         auto& scrollAnimationTrigger = downcast<ScrollAnimationTrigger>(*trigger);
1241         if (scrollAnimationTrigger.endValue().isAuto())
1242             return CSSAnimationTriggerScrollValue::create(zoomAdjustedPixelValueForLength(scrollAnimationTrigger.startValue(), style));
1243         return CSSAnimationTriggerScrollValue::create(zoomAdjustedPixelValueForLength(scrollAnimationTrigger.startValue(), style),
1244                                                       zoomAdjustedPixelValueForLength(scrollAnimationTrigger.endValue(), style));
1245     }
1246     default:
1247         ASSERT(trigger->type() == AnimationTrigger::AnimationTriggerType::AutoAnimationTriggerType);
1248         return cssValuePool().createIdentifierValue(CSSValueAuto);
1249     }
1250 }
1251
1252 static Ref<CSSValueList> getAnimationTriggerValue(const AnimationList* animList, const RenderStyle* style)
1253 {
1254     auto list = CSSValueList::createCommaSeparated();
1255     if (animList) {
1256         for (size_t i = 0; i < animList->size(); ++i)
1257             list.get().append(createAnimationTriggerValue(animList->animation(i).trigger().get(), style));
1258     } else
1259         list.get().append(createAnimationTriggerValue(Animation::initialTrigger().get(), style));
1260
1261     return list;
1262 }
1263 #endif
1264
1265 static Ref<CSSValue> createLineBoxContainValue(unsigned lineBoxContain)
1266 {
1267     if (!lineBoxContain)
1268         return cssValuePool().createIdentifierValue(CSSValueNone);
1269     return CSSLineBoxContainValue::create(lineBoxContain);
1270 }
1271
1272 ComputedStyleExtractor::ComputedStyleExtractor(PassRefPtr<Node> node, bool allowVisitedStyle, PseudoId pseudoElementSpecifier)
1273     : m_node(node)
1274     , m_pseudoElementSpecifier(pseudoElementSpecifier)
1275     , m_allowVisitedStyle(allowVisitedStyle)
1276 {
1277 }
1278
1279
1280 CSSComputedStyleDeclaration::CSSComputedStyleDeclaration(PassRefPtr<Node> n, bool allowVisitedStyle, const String& pseudoElementName)
1281     : m_node(n)
1282     , m_allowVisitedStyle(allowVisitedStyle)
1283     , m_refCount(1)
1284 {
1285     unsigned nameWithoutColonsStart = pseudoElementName[0] == ':' ? (pseudoElementName[1] == ':' ? 2 : 1) : 0;
1286     m_pseudoElementSpecifier = CSSSelector::pseudoId(CSSSelector::parsePseudoElementType(
1287     (pseudoElementName.substringSharingImpl(nameWithoutColonsStart))));
1288 }
1289
1290 CSSComputedStyleDeclaration::~CSSComputedStyleDeclaration()
1291 {
1292 }
1293
1294 void CSSComputedStyleDeclaration::ref()
1295 {
1296     ++m_refCount;
1297 }
1298
1299 void CSSComputedStyleDeclaration::deref()
1300 {
1301     ASSERT(m_refCount);
1302     if (!--m_refCount)
1303         delete this;
1304 }
1305
1306 String CSSComputedStyleDeclaration::cssText() const
1307 {
1308     StringBuilder result;
1309
1310     for (unsigned i = 0; i < numComputedProperties; i++) {
1311         if (i)
1312             result.append(' ');
1313         result.append(getPropertyName(computedProperties[i]));
1314         result.appendLiteral(": ");
1315         result.append(getPropertyValue(computedProperties[i]));
1316         result.append(';');
1317     }
1318
1319     return result.toString();
1320 }
1321
1322 void CSSComputedStyleDeclaration::setCssText(const String&, ExceptionCode& ec)
1323 {
1324     ec = NO_MODIFICATION_ALLOWED_ERR;
1325 }
1326
1327 PassRefPtr<CSSPrimitiveValue> ComputedStyleExtractor::getFontSizeCSSValuePreferringKeyword() const
1328 {
1329     if (!m_node)
1330         return nullptr;
1331
1332     m_node->document().updateLayoutIgnorePendingStylesheets();
1333
1334     RefPtr<RenderStyle> style = m_node->computedStyle(m_pseudoElementSpecifier);
1335     if (!style)
1336         return nullptr;
1337
1338     if (CSSValueID sizeIdentifier = style->fontDescription().keywordSizeAsIdentifier())
1339         return cssValuePool().createIdentifierValue(sizeIdentifier);
1340
1341     return zoomAdjustedPixelValue(style->fontDescription().computedPixelSize(), style.get());
1342 }
1343
1344 bool ComputedStyleExtractor::useFixedFontDefaultSize() const
1345 {
1346     if (!m_node)
1347         return false;
1348
1349     RefPtr<RenderStyle> style = m_node->computedStyle(m_pseudoElementSpecifier);
1350     if (!style)
1351         return false;
1352
1353     return style->fontDescription().useFixedDefaultSize();
1354 }
1355
1356
1357 static CSSValueID identifierForFamily(const AtomicString& family)
1358 {
1359     if (family == cursiveFamily)
1360         return CSSValueCursive;
1361     if (family == fantasyFamily)
1362         return CSSValueFantasy;
1363     if (family == monospaceFamily)
1364         return CSSValueMonospace;
1365     if (family == pictographFamily)
1366         return CSSValueWebkitPictograph;
1367     if (family == sansSerifFamily)
1368         return CSSValueSansSerif;
1369     if (family == serifFamily)
1370         return CSSValueSerif;
1371     return CSSValueInvalid;
1372 }
1373
1374 static Ref<CSSPrimitiveValue> valueForFamily(const AtomicString& family)
1375 {
1376     if (CSSValueID familyIdentifier = identifierForFamily(family))
1377         return cssValuePool().createIdentifierValue(familyIdentifier);
1378     return cssValuePool().createFontFamilyValue(family);
1379 }
1380
1381 static Ref<CSSValue> renderTextDecorationFlagsToCSSValue(int textDecoration)
1382 {
1383     // Blink value is ignored.
1384     RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
1385     if (textDecoration & TextDecorationUnderline)
1386         list->append(cssValuePool().createIdentifierValue(CSSValueUnderline));
1387     if (textDecoration & TextDecorationOverline)
1388         list->append(cssValuePool().createIdentifierValue(CSSValueOverline));
1389     if (textDecoration & TextDecorationLineThrough)
1390         list->append(cssValuePool().createIdentifierValue(CSSValueLineThrough));
1391 #if ENABLE(LETTERPRESS)
1392     if (textDecoration & TextDecorationLetterpress)
1393         list->append(cssValuePool().createIdentifierValue(CSSValueWebkitLetterpress));
1394 #endif
1395
1396     if (!list->length())
1397         return cssValuePool().createIdentifierValue(CSSValueNone);
1398     return list.releaseNonNull();
1399 }
1400
1401 static Ref<CSSValue> renderTextDecorationStyleFlagsToCSSValue(TextDecorationStyle textDecorationStyle)
1402 {
1403     switch (textDecorationStyle) {
1404     case TextDecorationStyleSolid:
1405         return cssValuePool().createIdentifierValue(CSSValueSolid);
1406     case TextDecorationStyleDouble:
1407         return cssValuePool().createIdentifierValue(CSSValueDouble);
1408     case TextDecorationStyleDotted:
1409         return cssValuePool().createIdentifierValue(CSSValueDotted);
1410     case TextDecorationStyleDashed:
1411         return cssValuePool().createIdentifierValue(CSSValueDashed);
1412     case TextDecorationStyleWavy:
1413         return cssValuePool().createIdentifierValue(CSSValueWavy);
1414     }
1415
1416     ASSERT_NOT_REACHED();
1417     return cssValuePool().createExplicitInitialValue();
1418 }
1419
1420 static Ref<CSSValue> renderTextDecorationSkipFlagsToCSSValue(TextDecorationSkip textDecorationSkip)
1421 {
1422     switch (textDecorationSkip) {
1423     case TextDecorationSkipAuto:
1424         return cssValuePool().createIdentifierValue(CSSValueAuto);
1425     case TextDecorationSkipNone:
1426         return cssValuePool().createIdentifierValue(CSSValueNone);
1427     case TextDecorationSkipInk:
1428         return cssValuePool().createIdentifierValue(CSSValueInk);
1429     case TextDecorationSkipObjects:
1430         return cssValuePool().createIdentifierValue(CSSValueObjects);
1431     }
1432
1433     ASSERT_NOT_REACHED();
1434     return cssValuePool().createExplicitInitialValue();
1435 }
1436
1437 static Ref<CSSValue> renderEmphasisPositionFlagsToCSSValue(TextEmphasisPosition textEmphasisPosition)
1438 {
1439     ASSERT(!((textEmphasisPosition & TextEmphasisPositionOver) && (textEmphasisPosition & TextEmphasisPositionUnder)));
1440     ASSERT(!((textEmphasisPosition & TextEmphasisPositionLeft) && (textEmphasisPosition & TextEmphasisPositionRight)));
1441     RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
1442     if (textEmphasisPosition & TextEmphasisPositionOver)
1443         list->append(cssValuePool().createIdentifierValue(CSSValueOver));
1444     if (textEmphasisPosition & TextEmphasisPositionUnder)
1445         list->append(cssValuePool().createIdentifierValue(CSSValueUnder));
1446     if (textEmphasisPosition & TextEmphasisPositionLeft)
1447         list->append(cssValuePool().createIdentifierValue(CSSValueLeft));
1448     if (textEmphasisPosition & TextEmphasisPositionRight)
1449         list->append(cssValuePool().createIdentifierValue(CSSValueRight));
1450
1451     if (!list->length())
1452         return cssValuePool().createIdentifierValue(CSSValueNone);
1453     return list.releaseNonNull();
1454 }
1455
1456 static Ref<CSSValue> fillRepeatToCSSValue(EFillRepeat xRepeat, EFillRepeat yRepeat)
1457 {
1458     // For backwards compatibility, if both values are equal, just return one of them. And
1459     // if the two values are equivalent to repeat-x or repeat-y, just return the shorthand.
1460     if (xRepeat == yRepeat)
1461         return cssValuePool().createValue(xRepeat);
1462     if (xRepeat == RepeatFill && yRepeat == NoRepeatFill)
1463         return cssValuePool().createIdentifierValue(CSSValueRepeatX);
1464     if (xRepeat == NoRepeatFill && yRepeat == RepeatFill)
1465         return cssValuePool().createIdentifierValue(CSSValueRepeatY);
1466
1467     auto list = CSSValueList::createSpaceSeparated();
1468     list.get().append(cssValuePool().createValue(xRepeat));
1469     list.get().append(cssValuePool().createValue(yRepeat));
1470     return WTF::move(list);
1471 }
1472
1473 static Ref<CSSValue> fillSourceTypeToCSSValue(EMaskSourceType type)
1474 {
1475     switch (type) {
1476     case MaskAlpha:
1477         return cssValuePool().createValue(CSSValueAlpha);
1478     default:
1479         ASSERT(type == MaskLuminance);
1480         return cssValuePool().createValue(CSSValueLuminance);
1481     }
1482 }
1483
1484 static Ref<CSSValue> fillSizeToCSSValue(const FillSize& fillSize, const RenderStyle* style)
1485 {
1486     if (fillSize.type == Contain)
1487         return cssValuePool().createIdentifierValue(CSSValueContain);
1488
1489     if (fillSize.type == Cover)
1490         return cssValuePool().createIdentifierValue(CSSValueCover);
1491
1492     if (fillSize.size.height().isAuto())
1493         return zoomAdjustedPixelValueForLength(fillSize.size.width(), style);
1494
1495     auto list = CSSValueList::createSpaceSeparated();
1496     list.get().append(zoomAdjustedPixelValueForLength(fillSize.size.width(), style));
1497     list.get().append(zoomAdjustedPixelValueForLength(fillSize.size.height(), style));
1498     return WTF::move(list);
1499 }
1500
1501 static Ref<CSSValue> altTextToCSSValue(const RenderStyle* style)
1502 {
1503     return cssValuePool().createValue(style->contentAltText(), CSSPrimitiveValue::CSS_STRING);
1504 }
1505     
1506 static Ref<CSSValueList> contentToCSSValue(const RenderStyle* style)
1507 {
1508     auto list = CSSValueList::createSpaceSeparated();
1509     for (const ContentData* contentData = style->contentData(); contentData; contentData = contentData->next()) {
1510         if (is<CounterContentData>(*contentData))
1511             list.get().append(cssValuePool().createValue(downcast<CounterContentData>(*contentData).counter().identifier(), CSSPrimitiveValue::CSS_COUNTER_NAME));
1512         else if (is<ImageContentData>(*contentData))
1513             list.get().append(*downcast<ImageContentData>(*contentData).image().cssValue());
1514         else if (is<TextContentData>(*contentData))
1515             list.get().append(cssValuePool().createValue(downcast<TextContentData>(*contentData).text(), CSSPrimitiveValue::CSS_STRING));
1516     }
1517     if (style->hasFlowFrom())
1518         list.get().append(cssValuePool().createValue(style->regionThread(), CSSPrimitiveValue::CSS_STRING));
1519     return list;
1520 }
1521
1522 static PassRefPtr<CSSValue> counterToCSSValue(const RenderStyle* style, CSSPropertyID propertyID)
1523 {
1524     const CounterDirectiveMap* map = style->counterDirectives();
1525     if (!map)
1526         return nullptr;
1527
1528     RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
1529     for (CounterDirectiveMap::const_iterator it = map->begin(); it != map->end(); ++it) {
1530         list->append(cssValuePool().createValue(it->key, CSSPrimitiveValue::CSS_STRING));
1531         short number = propertyID == CSSPropertyCounterIncrement ? it->value.incrementValue() : it->value.resetValue();
1532         list->append(cssValuePool().createValue((double)number, CSSPrimitiveValue::CSS_NUMBER));
1533     }
1534     return list.release();
1535 }
1536
1537 static void logUnimplementedPropertyID(CSSPropertyID propertyID)
1538 {
1539     static NeverDestroyed<HashSet<CSSPropertyID>> propertyIDSet;
1540     if (!propertyIDSet.get().add(propertyID).isNewEntry)
1541         return;
1542
1543     LOG_ERROR("WebKit does not yet implement getComputedStyle for '%s'.", getPropertyName(propertyID));
1544 }
1545
1546 static Ref<CSSValueList> fontFamilyFromStyle(RenderStyle* style)
1547 {
1548     auto list = CSSValueList::createCommaSeparated();
1549     for (unsigned i = 0; i < style->fontCascade().familyCount(); ++i)
1550         list.get().append(valueForFamily(style->fontCascade().familyAt(i)));
1551     return list;
1552 }
1553
1554 static Ref<CSSPrimitiveValue> lineHeightFromStyle(RenderStyle* style)
1555 {
1556     Length length = style->lineHeight();
1557     if (length.isNegative()) // If true, line-height not set; use the font's line spacing.
1558         return zoomAdjustedPixelValue(style->fontMetrics().floatLineSpacing(), style);
1559     if (length.isPercentNotCalculated()) {
1560         // This is imperfect, because it doesn't include the zoom factor and the real computation
1561         // for how high to be in pixels does include things like minimum font size and the zoom factor.
1562         // On the other hand, since font-size doesn't include the zoom factor, we really can't do
1563         // that here either.
1564         return zoomAdjustedPixelValue(static_cast<int>(length.percent() * style->fontDescription().specifiedSize()) / 100, style);
1565     }
1566     return zoomAdjustedPixelValue(floatValueForLength(length, 0), style);
1567 }
1568
1569 static Ref<CSSPrimitiveValue> fontSizeFromStyle(RenderStyle* style)
1570 {
1571     return zoomAdjustedPixelValue(style->fontDescription().computedPixelSize(), style);
1572 }
1573
1574 static Ref<CSSPrimitiveValue> fontStyleFromStyle(RenderStyle* style)
1575 {
1576     if (style->fontDescription().italic())
1577         return cssValuePool().createIdentifierValue(CSSValueItalic);
1578     return cssValuePool().createIdentifierValue(CSSValueNormal);
1579 }
1580
1581 static Ref<CSSPrimitiveValue> fontVariantFromStyle(RenderStyle* style)
1582 {
1583     if (style->fontDescription().smallCaps())
1584         return cssValuePool().createIdentifierValue(CSSValueSmallCaps);
1585     return cssValuePool().createIdentifierValue(CSSValueNormal);
1586 }
1587
1588 static Ref<CSSPrimitiveValue> fontWeightFromStyle(RenderStyle* style)
1589 {
1590     switch (style->fontDescription().weight()) {
1591     case FontWeight100:
1592         return cssValuePool().createIdentifierValue(CSSValue100);
1593     case FontWeight200:
1594         return cssValuePool().createIdentifierValue(CSSValue200);
1595     case FontWeight300:
1596         return cssValuePool().createIdentifierValue(CSSValue300);
1597     case FontWeightNormal:
1598         return cssValuePool().createIdentifierValue(CSSValueNormal);
1599     case FontWeight500:
1600         return cssValuePool().createIdentifierValue(CSSValue500);
1601     case FontWeight600:
1602         return cssValuePool().createIdentifierValue(CSSValue600);
1603     case FontWeightBold:
1604         return cssValuePool().createIdentifierValue(CSSValueBold);
1605     case FontWeight800:
1606         return cssValuePool().createIdentifierValue(CSSValue800);
1607     case FontWeight900:
1608         return cssValuePool().createIdentifierValue(CSSValue900);
1609     }
1610     ASSERT_NOT_REACHED();
1611     return cssValuePool().createIdentifierValue(CSSValueNormal);
1612 }
1613
1614 typedef const Length& (RenderStyle::*RenderStyleLengthGetter)() const;
1615 typedef LayoutUnit (RenderBoxModelObject::*RenderBoxComputedCSSValueGetter)() const;
1616
1617 template<RenderStyleLengthGetter lengthGetter, RenderBoxComputedCSSValueGetter computedCSSValueGetter>
1618 inline PassRefPtr<CSSValue> zoomAdjustedPaddingOrMarginPixelValue(RenderStyle* style, RenderObject* renderer)
1619 {
1620     Length unzoomzedLength = (style->*lengthGetter)();
1621     if (!is<RenderBox>(renderer) || unzoomzedLength.isFixed())
1622         return zoomAdjustedPixelValueForLength(unzoomzedLength, style);
1623     return zoomAdjustedPixelValue((downcast<RenderBox>(*renderer).*computedCSSValueGetter)(), style);
1624 }
1625
1626 template<RenderStyleLengthGetter lengthGetter>
1627 inline bool paddingOrMarginIsRendererDependent(RenderStyle* style, RenderObject* renderer)
1628 {
1629     if (!renderer || !renderer->isBox())
1630         return false;
1631     return !(style && (style->*lengthGetter)().isFixed());
1632 }
1633
1634 static bool isLayoutDependent(CSSPropertyID propertyID, RenderStyle* style, RenderObject* renderer)
1635 {
1636     switch (propertyID) {
1637     case CSSPropertyWidth:
1638     case CSSPropertyHeight:
1639 #if ENABLE(CSS_GRID_LAYOUT)
1640     case CSSPropertyWebkitGridTemplateColumns:
1641     case CSSPropertyWebkitGridTemplateRows:
1642 #endif
1643     case CSSPropertyPerspectiveOrigin:
1644     case CSSPropertyTransformOrigin:
1645     case CSSPropertyTransform:
1646     case CSSPropertyWebkitFilter:
1647 #if ENABLE(FILTERS_LEVEL_2)
1648     case CSSPropertyWebkitBackdropFilter:
1649 #endif
1650         return true;
1651     case CSSPropertyMargin: {
1652         if (!renderer || !renderer->isBox())
1653             return false;
1654         return !(style && style->marginTop().isFixed() && style->marginRight().isFixed()
1655             && style->marginBottom().isFixed() && style->marginLeft().isFixed());
1656     }
1657     case CSSPropertyMarginTop:
1658         return paddingOrMarginIsRendererDependent<&RenderStyle::marginTop>(style, renderer);
1659     case CSSPropertyMarginRight:
1660         return paddingOrMarginIsRendererDependent<&RenderStyle::marginRight>(style, renderer);
1661     case CSSPropertyMarginBottom:
1662         return paddingOrMarginIsRendererDependent<&RenderStyle::marginBottom>(style, renderer);
1663     case CSSPropertyMarginLeft:
1664         return paddingOrMarginIsRendererDependent<&RenderStyle::marginLeft>(style, renderer);
1665     case CSSPropertyPadding: {
1666         if (!renderer || !renderer->isBox())
1667             return false;
1668         return !(style && style->paddingTop().isFixed() && style->paddingRight().isFixed()
1669             && style->paddingBottom().isFixed() && style->paddingLeft().isFixed());
1670     }
1671     case CSSPropertyPaddingTop:
1672         return paddingOrMarginIsRendererDependent<&RenderStyle::paddingTop>(style, renderer);
1673     case CSSPropertyPaddingRight:
1674         return paddingOrMarginIsRendererDependent<&RenderStyle::paddingRight>(style, renderer);
1675     case CSSPropertyPaddingBottom:
1676         return paddingOrMarginIsRendererDependent<&RenderStyle::paddingBottom>(style, renderer);
1677     case CSSPropertyPaddingLeft:
1678         return paddingOrMarginIsRendererDependent<&RenderStyle::paddingLeft>(style, renderer); 
1679     default:
1680         return false;
1681     }
1682 }
1683
1684 Node* ComputedStyleExtractor::styledNode() const
1685 {
1686     if (!m_node)
1687         return nullptr;
1688     if (!is<Element>(*m_node))
1689         return m_node.get();
1690     Element& element = downcast<Element>(*m_node);
1691     PseudoElement* pseudoElement;
1692     if (m_pseudoElementSpecifier == BEFORE && (pseudoElement = element.beforePseudoElement()))
1693         return pseudoElement;
1694     if (m_pseudoElementSpecifier == AFTER && (pseudoElement = element.afterPseudoElement()))
1695         return pseudoElement;
1696     return &element;
1697 }
1698
1699 static ItemPosition resolveContainerAlignmentAuto(ItemPosition position, RenderObject* element)
1700 {
1701     if (position != ItemPositionAuto || !element)
1702         return position;
1703
1704     bool isFlexOrGrid = element->style().isDisplayFlexibleOrGridBox();
1705     return isFlexOrGrid ? ItemPositionStretch : ItemPositionStart;
1706 }
1707
1708 static ItemPosition resolveSelfAlignmentAuto(ItemPosition position, OverflowAlignment& overflow, RenderObject* element)
1709 {
1710     if (position != ItemPositionAuto || !element || element->isOutOfFlowPositioned())
1711         return position;
1712
1713     RenderBlock* parent = element->containingBlock();
1714     if (!parent)
1715         return ItemPositionStart;
1716
1717     overflow = parent->style().alignItemsOverflowAlignment();
1718     return resolveContainerAlignmentAuto(parent->style().alignItems(), parent);
1719 }
1720
1721 PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropertyID propertyID, EUpdateLayout updateLayout) const
1722 {
1723     return ComputedStyleExtractor(m_node, m_allowVisitedStyle, m_pseudoElementSpecifier).propertyValue(propertyID, updateLayout);
1724 }
1725
1726 Ref<MutableStyleProperties> CSSComputedStyleDeclaration::copyProperties() const
1727 {
1728     return ComputedStyleExtractor(m_node, m_allowVisitedStyle, m_pseudoElementSpecifier).copyProperties();
1729 }
1730
1731 static inline bool nodeOrItsAncestorNeedsStyleRecalc(const Node& node)
1732 {
1733     if (node.needsStyleRecalc())
1734         return true;
1735
1736     const Node* currentNode = &node;
1737     const Element* ancestor = currentNode->parentOrShadowHostElement();
1738     while (ancestor) {
1739         if (ancestor->needsStyleRecalc())
1740             return true;
1741
1742         if (ancestor->directChildNeedsStyleRecalc() && currentNode->styleIsAffectedByPreviousSibling())
1743             return true;
1744
1745         currentNode = ancestor;
1746         ancestor = currentNode->parentOrShadowHostElement();
1747     }
1748     return false;
1749 }
1750
1751 static inline bool updateStyleIfNeededForNode(const Node& node)
1752 {
1753     Document& document = node.document();
1754     if (!document.hasPendingForcedStyleRecalc() && !(document.childNeedsStyleRecalc() && nodeOrItsAncestorNeedsStyleRecalc(node)))
1755         return false;
1756     document.updateStyleIfNeeded();
1757     return true;
1758 }
1759
1760 static inline PassRefPtr<RenderStyle> computeRenderStyleForProperty(Node* styledNode, PseudoId pseudoElementSpecifier, CSSPropertyID propertyID)
1761 {
1762     RenderObject* renderer = styledNode->renderer();
1763
1764     if (renderer && renderer->isComposited() && AnimationController::supportsAcceleratedAnimationOfProperty(propertyID)) {
1765         RefPtr<RenderStyle> style = renderer->animation().getAnimatedStyleForRenderer(downcast<RenderElement>(*renderer));
1766         if (pseudoElementSpecifier && !styledNode->isPseudoElement()) {
1767             // FIXME: This cached pseudo style will only exist if the animation has been run at least once.
1768             return style->getCachedPseudoStyle(pseudoElementSpecifier);
1769         }
1770         return style.release();
1771     }
1772
1773     return styledNode->computedStyle(styledNode->isPseudoElement() ? NOPSEUDO : pseudoElementSpecifier);
1774 }
1775
1776 #if ENABLE(CSS_SHAPES)
1777 static Ref<CSSValue> shapePropertyValue(const RenderStyle* style, const ShapeValue* shapeValue)
1778 {
1779     if (!shapeValue)
1780         return cssValuePool().createIdentifierValue(CSSValueNone);
1781
1782     if (shapeValue->type() == ShapeValue::Type::Box)
1783         return cssValuePool().createValue(shapeValue->cssBox());
1784
1785     if (shapeValue->type() == ShapeValue::Type::Image) {
1786         if (shapeValue->image())
1787             return *shapeValue->image()->cssValue();
1788         return cssValuePool().createIdentifierValue(CSSValueNone);
1789     }
1790
1791     ASSERT(shapeValue->type() == ShapeValue::Type::Shape);
1792
1793     RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
1794     list->append(valueForBasicShape(style, *shapeValue->shape()));
1795     if (shapeValue->cssBox() != BoxMissing)
1796         list->append(cssValuePool().createValue(shapeValue->cssBox()));
1797     return list.releaseNonNull();
1798 }
1799 #endif
1800
1801 static PassRefPtr<CSSValueList> valueForItemPositionWithOverflowAlignment(ItemPosition itemPosition, OverflowAlignment overflowAlignment, ItemPositionType positionType)
1802 {
1803     RefPtr<CSSValueList> result = CSSValueList::createSpaceSeparated();
1804     if (positionType == LegacyPosition)
1805         result->append(CSSPrimitiveValue::createIdentifier(CSSValueLegacy));
1806     result->append(cssValuePool().createValue(itemPosition));
1807     if (overflowAlignment != OverflowAlignmentDefault)
1808         result->append(cssValuePool().createValue(overflowAlignment));
1809     ASSERT(result->length() <= 2);
1810     return result.release();
1811 }
1812
1813 PassRefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID, EUpdateLayout updateLayout) const
1814 {
1815     Node* styledNode = this->styledNode();
1816     if (!styledNode)
1817         return nullptr;
1818
1819     RefPtr<RenderStyle> style;
1820     RenderObject* renderer = nullptr;
1821     bool forceFullLayout = false;
1822     if (updateLayout) {
1823         Document& document = styledNode->document();
1824
1825         if (updateStyleIfNeededForNode(*styledNode)) {
1826             // The style recalc could have caused the styled node to be discarded or replaced
1827             // if it was a PseudoElement so we need to update it.
1828             styledNode = this->styledNode();
1829         }
1830
1831         renderer = styledNode->renderer();
1832
1833         if (propertyID == CSSPropertyDisplay && !renderer && is<SVGElement>(*styledNode) && !downcast<SVGElement>(*styledNode).isValid())
1834             return nullptr;
1835
1836         style = computeRenderStyleForProperty(styledNode, m_pseudoElementSpecifier, propertyID);
1837
1838         // FIXME: Some of these cases could be narrowed down or optimized better.
1839         forceFullLayout = isLayoutDependent(propertyID, style.get(), renderer)
1840             || styledNode->isInShadowTree()
1841             || (document.styleResolverIfExists() && document.styleResolverIfExists()->hasViewportDependentMediaQueries() && document.ownerElement());
1842
1843         if (forceFullLayout) {
1844             document.updateLayoutIgnorePendingStylesheets();
1845             styledNode = this->styledNode();
1846         }
1847     }
1848
1849     if (!updateLayout || forceFullLayout) {
1850         style = computeRenderStyleForProperty(styledNode, m_pseudoElementSpecifier, propertyID);
1851         renderer = styledNode->renderer();
1852     }
1853
1854     if (!style)
1855         return nullptr;
1856
1857     propertyID = CSSProperty::resolveDirectionAwareProperty(propertyID, style->direction(), style->writingMode());
1858
1859     switch (propertyID) {
1860         case CSSPropertyInvalid:
1861             break;
1862
1863         case CSSPropertyBackgroundColor:
1864             return cssValuePool().createColorValue(m_allowVisitedStyle? style->visitedDependentColor(CSSPropertyBackgroundColor).rgb() : style->backgroundColor().rgb());
1865         case CSSPropertyBackgroundImage: {
1866             const FillLayer* layers = style->backgroundLayers();
1867             if (!layers)
1868                 return cssValuePool().createIdentifierValue(CSSValueNone);
1869
1870             if (!layers->next()) {
1871                 if (layers->image())
1872                     return layers->image()->cssValue();
1873
1874                 return cssValuePool().createIdentifierValue(CSSValueNone);
1875             }
1876
1877             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1878             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) {
1879                 if (currLayer->image())
1880                     list->append(*currLayer->image()->cssValue());
1881                 else
1882                     list->append(cssValuePool().createIdentifierValue(CSSValueNone));
1883             }
1884             return list.release();
1885         }
1886         case CSSPropertyWebkitMaskImage: {
1887             const FillLayer* layers = style->maskLayers();
1888             if (!layers)
1889                 return cssValuePool().createIdentifierValue(CSSValueNone);
1890
1891             if (!layers->next()) {
1892                 if (layers->maskImage().get())
1893                     return layers->maskImage()->cssValue();
1894
1895                 return cssValuePool().createIdentifierValue(CSSValueNone);
1896             }
1897
1898             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1899             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) {
1900                 if (currLayer->maskImage().get())
1901                     list->append(*currLayer->maskImage()->cssValue());
1902                 else
1903                     list->append(cssValuePool().createIdentifierValue(CSSValueNone));
1904             }
1905             return list.release();
1906         }
1907         case CSSPropertyBackgroundSize:
1908         case CSSPropertyWebkitBackgroundSize:
1909         case CSSPropertyWebkitMaskSize: {
1910             const FillLayer* layers = propertyID == CSSPropertyWebkitMaskSize ? style->maskLayers() : style->backgroundLayers();
1911             if (!layers->next())
1912                 return fillSizeToCSSValue(layers->size(), style.get());
1913
1914             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1915             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
1916                 list->append(fillSizeToCSSValue(currLayer->size(), style.get()));
1917
1918             return list.release();
1919         }
1920         case CSSPropertyBackgroundRepeat:
1921         case CSSPropertyWebkitMaskRepeat: {
1922             const FillLayer* layers = propertyID == CSSPropertyWebkitMaskRepeat ? style->maskLayers() : style->backgroundLayers();
1923             if (!layers->next())
1924                 return fillRepeatToCSSValue(layers->repeatX(), layers->repeatY());
1925
1926             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1927             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
1928                 list->append(fillRepeatToCSSValue(currLayer->repeatX(), currLayer->repeatY()));
1929
1930             return list.release();
1931         }
1932         case CSSPropertyWebkitMaskSourceType: {
1933             const FillLayer* layers = style->maskLayers();
1934
1935             if (!layers)
1936                 return cssValuePool().createIdentifierValue(CSSValueNone);
1937
1938             if (!layers->next())
1939                 return fillSourceTypeToCSSValue(layers->maskSourceType());
1940
1941             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1942             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
1943                 list->append(fillSourceTypeToCSSValue(currLayer->maskSourceType()));
1944
1945             return list.release();
1946         }
1947         case CSSPropertyWebkitBackgroundComposite:
1948         case CSSPropertyWebkitMaskComposite: {
1949             const FillLayer* layers = propertyID == CSSPropertyWebkitMaskComposite ? style->maskLayers() : style->backgroundLayers();
1950             if (!layers->next())
1951                 return cssValuePool().createValue(layers->composite());
1952
1953             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1954             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
1955                 list->append(cssValuePool().createValue(currLayer->composite()));
1956
1957             return list.release();
1958         }
1959         case CSSPropertyBackgroundAttachment: {
1960             const FillLayer* layers = style->backgroundLayers();
1961             if (!layers->next())
1962                 return cssValuePool().createValue(layers->attachment());
1963
1964             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1965             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
1966                 list->append(cssValuePool().createValue(currLayer->attachment()));
1967
1968             return list.release();
1969         }
1970         case CSSPropertyBackgroundClip:
1971         case CSSPropertyBackgroundOrigin:
1972         case CSSPropertyWebkitBackgroundClip:
1973         case CSSPropertyWebkitBackgroundOrigin:
1974         case CSSPropertyWebkitMaskClip:
1975         case CSSPropertyWebkitMaskOrigin: {
1976             const FillLayer* layers = (propertyID == CSSPropertyWebkitMaskClip || propertyID == CSSPropertyWebkitMaskOrigin) ? style->maskLayers() : style->backgroundLayers();
1977             bool isClip = propertyID == CSSPropertyBackgroundClip || propertyID == CSSPropertyWebkitBackgroundClip || propertyID == CSSPropertyWebkitMaskClip;
1978             if (!layers->next()) {
1979                 EFillBox box = isClip ? layers->clip() : layers->origin();
1980                 return cssValuePool().createValue(box);
1981             }
1982
1983             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1984             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) {
1985                 EFillBox box = isClip ? currLayer->clip() : currLayer->origin();
1986                 list->append(cssValuePool().createValue(box));
1987             }
1988
1989             return list.release();
1990         }
1991         case CSSPropertyBackgroundPosition:
1992         case CSSPropertyWebkitMaskPosition: {
1993             const FillLayer* layers = propertyID == CSSPropertyWebkitMaskPosition ? style->maskLayers() : style->backgroundLayers();
1994             if (!layers->next())
1995                 return createPositionListForLayer(propertyID, layers, style.get());
1996
1997             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1998             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
1999                 list->append(createPositionListForLayer(propertyID, currLayer, style.get()));
2000             return list.release();
2001         }
2002         case CSSPropertyBackgroundPositionX:
2003         case CSSPropertyWebkitMaskPositionX: {
2004             const FillLayer* layers = propertyID == CSSPropertyWebkitMaskPositionX ? style->maskLayers() : style->backgroundLayers();
2005             if (!layers->next())
2006                 return cssValuePool().createValue(layers->xPosition());
2007
2008             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2009             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
2010                 list->append(cssValuePool().createValue(currLayer->xPosition()));
2011
2012             return list.release();
2013         }
2014         case CSSPropertyBackgroundPositionY:
2015         case CSSPropertyWebkitMaskPositionY: {
2016             const FillLayer* layers = propertyID == CSSPropertyWebkitMaskPositionY ? style->maskLayers() : style->backgroundLayers();
2017             if (!layers->next())
2018                 return cssValuePool().createValue(layers->yPosition());
2019
2020             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2021             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
2022                 list->append(cssValuePool().createValue(currLayer->yPosition()));
2023
2024             return list.release();
2025         }
2026         case CSSPropertyBorderCollapse:
2027             if (style->borderCollapse())
2028                 return cssValuePool().createIdentifierValue(CSSValueCollapse);
2029             return cssValuePool().createIdentifierValue(CSSValueSeparate);
2030         case CSSPropertyBorderSpacing: {
2031             RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2032             list->append(zoomAdjustedPixelValue(style->horizontalBorderSpacing(), style.get()));
2033             list->append(zoomAdjustedPixelValue(style->verticalBorderSpacing(), style.get()));
2034             return list.release();
2035         }
2036         case CSSPropertyWebkitBorderHorizontalSpacing:
2037             return zoomAdjustedPixelValue(style->horizontalBorderSpacing(), style.get());
2038         case CSSPropertyWebkitBorderVerticalSpacing:
2039             return zoomAdjustedPixelValue(style->verticalBorderSpacing(), style.get());
2040         case CSSPropertyBorderImageSource:
2041             if (style->borderImageSource())
2042                 return style->borderImageSource()->cssValue();
2043             return cssValuePool().createIdentifierValue(CSSValueNone);
2044         case CSSPropertyBorderTopColor:
2045             return m_allowVisitedStyle ? cssValuePool().createColorValue(style->visitedDependentColor(CSSPropertyBorderTopColor).rgb()) : currentColorOrValidColor(style.get(), style->borderTopColor());
2046         case CSSPropertyBorderRightColor:
2047             return m_allowVisitedStyle ? cssValuePool().createColorValue(style->visitedDependentColor(CSSPropertyBorderRightColor).rgb()) : currentColorOrValidColor(style.get(), style->borderRightColor());
2048         case CSSPropertyBorderBottomColor:
2049             return m_allowVisitedStyle ? cssValuePool().createColorValue(style->visitedDependentColor(CSSPropertyBorderBottomColor).rgb()) : currentColorOrValidColor(style.get(), style->borderBottomColor());
2050         case CSSPropertyBorderLeftColor:
2051             return m_allowVisitedStyle ? cssValuePool().createColorValue(style->visitedDependentColor(CSSPropertyBorderLeftColor).rgb()) : currentColorOrValidColor(style.get(), style->borderLeftColor());
2052         case CSSPropertyBorderTopStyle:
2053             return cssValuePool().createValue(style->borderTopStyle());
2054         case CSSPropertyBorderRightStyle:
2055             return cssValuePool().createValue(style->borderRightStyle());
2056         case CSSPropertyBorderBottomStyle:
2057             return cssValuePool().createValue(style->borderBottomStyle());
2058         case CSSPropertyBorderLeftStyle:
2059             return cssValuePool().createValue(style->borderLeftStyle());
2060         case CSSPropertyBorderTopWidth:
2061             return zoomAdjustedPixelValue(style->borderTopWidth(), style.get());
2062         case CSSPropertyBorderRightWidth:
2063             return zoomAdjustedPixelValue(style->borderRightWidth(), style.get());
2064         case CSSPropertyBorderBottomWidth:
2065             return zoomAdjustedPixelValue(style->borderBottomWidth(), style.get());
2066         case CSSPropertyBorderLeftWidth:
2067             return zoomAdjustedPixelValue(style->borderLeftWidth(), style.get());
2068         case CSSPropertyBottom:
2069             return positionOffsetValue(style.get(), CSSPropertyBottom);
2070         case CSSPropertyWebkitBoxAlign:
2071             return cssValuePool().createValue(style->boxAlign());
2072 #if ENABLE(CSS_BOX_DECORATION_BREAK)
2073         case CSSPropertyWebkitBoxDecorationBreak:
2074             if (style->boxDecorationBreak() == DSLICE)
2075                 return cssValuePool().createIdentifierValue(CSSValueSlice);
2076         return cssValuePool().createIdentifierValue(CSSValueClone);
2077 #endif
2078         case CSSPropertyWebkitBoxDirection:
2079             return cssValuePool().createValue(style->boxDirection());
2080         case CSSPropertyWebkitBoxFlex:
2081             return cssValuePool().createValue(style->boxFlex(), CSSPrimitiveValue::CSS_NUMBER);
2082         case CSSPropertyWebkitBoxFlexGroup:
2083             return cssValuePool().createValue(style->boxFlexGroup(), CSSPrimitiveValue::CSS_NUMBER);
2084         case CSSPropertyWebkitBoxLines:
2085             return cssValuePool().createValue(style->boxLines());
2086         case CSSPropertyWebkitBoxOrdinalGroup:
2087             return cssValuePool().createValue(style->boxOrdinalGroup(), CSSPrimitiveValue::CSS_NUMBER);
2088         case CSSPropertyWebkitBoxOrient:
2089             return cssValuePool().createValue(style->boxOrient());
2090         case CSSPropertyWebkitBoxPack:
2091             return cssValuePool().createValue(style->boxPack());
2092         case CSSPropertyWebkitBoxReflect:
2093             return valueForReflection(style->boxReflect(), style.get());
2094         case CSSPropertyBoxShadow:
2095         case CSSPropertyWebkitBoxShadow:
2096             return valueForShadow(style->boxShadow(), propertyID, style.get());
2097         case CSSPropertyCaptionSide:
2098             return cssValuePool().createValue(style->captionSide());
2099         case CSSPropertyClear:
2100             return cssValuePool().createValue(style->clear());
2101         case CSSPropertyColor:
2102             return cssValuePool().createColorValue(m_allowVisitedStyle ? style->visitedDependentColor(CSSPropertyColor).rgb() : style->color().rgb());
2103         case CSSPropertyWebkitPrintColorAdjust:
2104             return cssValuePool().createValue(style->printColorAdjust());
2105         case CSSPropertyWebkitColumnAxis:
2106             return cssValuePool().createValue(style->columnAxis());
2107         case CSSPropertyColumnCount:
2108             if (style->hasAutoColumnCount())
2109                 return cssValuePool().createIdentifierValue(CSSValueAuto);
2110             return cssValuePool().createValue(style->columnCount(), CSSPrimitiveValue::CSS_NUMBER);
2111         case CSSPropertyColumnFill:
2112             return cssValuePool().createValue(style->columnFill());
2113         case CSSPropertyColumnGap:
2114             if (style->hasNormalColumnGap())
2115                 return cssValuePool().createIdentifierValue(CSSValueNormal);
2116             return zoomAdjustedPixelValue(style->columnGap(), style.get());
2117         case CSSPropertyColumnProgression:
2118             return cssValuePool().createValue(style->columnProgression());
2119         case CSSPropertyColumnRuleColor:
2120             return m_allowVisitedStyle ? cssValuePool().createColorValue(style->visitedDependentColor(CSSPropertyOutlineColor).rgb()) : currentColorOrValidColor(style.get(), style->columnRuleColor());
2121         case CSSPropertyColumnRuleStyle:
2122             return cssValuePool().createValue(style->columnRuleStyle());
2123         case CSSPropertyColumnRuleWidth:
2124             return zoomAdjustedPixelValue(style->columnRuleWidth(), style.get());
2125         case CSSPropertyColumnSpan:
2126             return cssValuePool().createIdentifierValue(style->columnSpan() ? CSSValueAll : CSSValueNone);
2127         case CSSPropertyWebkitColumnBreakAfter:
2128             return cssValuePool().createValue(style->columnBreakAfter());
2129         case CSSPropertyWebkitColumnBreakBefore:
2130             return cssValuePool().createValue(style->columnBreakBefore());
2131         case CSSPropertyWebkitColumnBreakInside:
2132             return cssValuePool().createValue(style->columnBreakInside());
2133         case CSSPropertyColumnWidth:
2134             if (style->hasAutoColumnWidth())
2135                 return cssValuePool().createIdentifierValue(CSSValueAuto);
2136             return zoomAdjustedPixelValue(style->columnWidth(), style.get());
2137         case CSSPropertyTabSize:
2138             return cssValuePool().createValue(style->tabSize(), CSSPrimitiveValue::CSS_NUMBER);
2139 #if ENABLE(CSS_REGIONS)
2140         case CSSPropertyWebkitRegionBreakAfter:
2141             return cssValuePool().createValue(style->regionBreakAfter());
2142         case CSSPropertyWebkitRegionBreakBefore:
2143             return cssValuePool().createValue(style->regionBreakBefore());
2144         case CSSPropertyWebkitRegionBreakInside:
2145             return cssValuePool().createValue(style->regionBreakInside());
2146 #endif
2147         case CSSPropertyCursor: {
2148             RefPtr<CSSValueList> list;
2149             CursorList* cursors = style->cursors();
2150             if (cursors && cursors->size() > 0) {
2151                 list = CSSValueList::createCommaSeparated();
2152                 for (unsigned i = 0; i < cursors->size(); ++i)
2153                     if (StyleImage* image = cursors->at(i).image())
2154                         list->append(*image->cssValue());
2155             }
2156             auto value = cssValuePool().createValue(style->cursor());
2157             if (list) {
2158                 list->append(WTF::move(value));
2159                 return list.release();
2160             }
2161             return WTF::move(value);
2162         }
2163 #if ENABLE(CURSOR_VISIBILITY)
2164         case CSSPropertyWebkitCursorVisibility:
2165             return cssValuePool().createValue(style->cursorVisibility());
2166 #endif
2167         case CSSPropertyDirection:
2168             return cssValuePool().createValue(style->direction());
2169         case CSSPropertyDisplay:
2170             return cssValuePool().createValue(style->display());
2171         case CSSPropertyEmptyCells:
2172             return cssValuePool().createValue(style->emptyCells());
2173         case CSSPropertyAlignContent:
2174             return cssValuePool().createValue(style->alignContent());
2175         case CSSPropertyAlignItems:
2176             return valueForItemPositionWithOverflowAlignment(resolveContainerAlignmentAuto(style->alignItems(), renderer), style->alignItemsOverflowAlignment(), NonLegacyPosition);
2177         case CSSPropertyAlignSelf: {
2178             OverflowAlignment overflow = style->alignSelfOverflowAlignment();
2179             ItemPosition alignSelf = resolveSelfAlignmentAuto(style->alignSelf(), overflow, renderer);
2180             return valueForItemPositionWithOverflowAlignment(alignSelf, overflow, NonLegacyPosition);
2181         }
2182         case CSSPropertyFlex:
2183             return getCSSPropertyValuesForShorthandProperties(flexShorthand());
2184         case CSSPropertyFlexBasis:
2185             return cssValuePool().createValue(style->flexBasis());
2186         case CSSPropertyFlexDirection:
2187             return cssValuePool().createValue(style->flexDirection());
2188         case CSSPropertyFlexFlow:
2189             return getCSSPropertyValuesForShorthandProperties(flexFlowShorthand());
2190         case CSSPropertyFlexGrow:
2191             return cssValuePool().createValue(style->flexGrow());
2192         case CSSPropertyFlexShrink:
2193             return cssValuePool().createValue(style->flexShrink());
2194         case CSSPropertyFlexWrap:
2195             return cssValuePool().createValue(style->flexWrap());
2196         case CSSPropertyJustifyContent:
2197             return cssValuePool().createValue(style->justifyContent());
2198         case CSSPropertyJustifyItems:
2199             return valueForItemPositionWithOverflowAlignment(resolveContainerAlignmentAuto(style->justifyItems(), renderer), style->justifyItemsOverflowAlignment(), style->justifyItemsPositionType());
2200         case CSSPropertyJustifySelf: {
2201             OverflowAlignment overflow = style->justifySelfOverflowAlignment();
2202             ItemPosition justifySelf = resolveSelfAlignmentAuto(style->justifySelf(), overflow, renderer);
2203             return valueForItemPositionWithOverflowAlignment(justifySelf, overflow, NonLegacyPosition);
2204         }
2205         case CSSPropertyOrder:
2206             return cssValuePool().createValue(style->order(), CSSPrimitiveValue::CSS_NUMBER);
2207         case CSSPropertyFloat:
2208             if (style->display() != NONE && style->hasOutOfFlowPosition())
2209                 return cssValuePool().createIdentifierValue(CSSValueNone);
2210             return cssValuePool().createValue(style->floating());
2211         case CSSPropertyFont: {
2212             RefPtr<CSSFontValue> computedFont = CSSFontValue::create();
2213             computedFont->style = fontStyleFromStyle(style.get());
2214             computedFont->variant = fontVariantFromStyle(style.get());
2215             computedFont->weight = fontWeightFromStyle(style.get());
2216             computedFont->size = fontSizeFromStyle(style.get());
2217             computedFont->lineHeight = lineHeightFromStyle(style.get());
2218             computedFont->family = fontFamilyFromStyle(style.get());
2219             return computedFont.release();
2220         }
2221         case CSSPropertyFontFamily: {
2222             RefPtr<CSSValueList> fontFamilyList = fontFamilyFromStyle(style.get());
2223             // If there's only a single family, return that as a CSSPrimitiveValue.
2224             // NOTE: Gecko always returns this as a comma-separated CSSPrimitiveValue string.
2225             if (fontFamilyList->length() == 1)
2226                 return fontFamilyList->item(0);
2227             return fontFamilyList.release();
2228         }
2229         case CSSPropertyFontSize:
2230             return fontSizeFromStyle(style.get());
2231         case CSSPropertyFontStyle:
2232             return fontStyleFromStyle(style.get());
2233         case CSSPropertyFontVariant:
2234             return fontVariantFromStyle(style.get());
2235         case CSSPropertyFontWeight:
2236             return fontWeightFromStyle(style.get());
2237         case CSSPropertyWebkitFontFeatureSettings: {
2238             const FontFeatureSettings* featureSettings = style->fontDescription().featureSettings();
2239             if (!featureSettings || !featureSettings->size())
2240                 return cssValuePool().createIdentifierValue(CSSValueNormal);
2241             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2242             for (unsigned i = 0; i < featureSettings->size(); ++i) {
2243                 const FontFeature& feature = featureSettings->at(i);
2244                 list->append(CSSFontFeatureValue::create(feature.tag(), feature.value()));
2245             }
2246             return list.release();
2247         }
2248 #if ENABLE(CSS_GRID_LAYOUT)
2249         case CSSPropertyWebkitGridAutoFlow: {
2250             RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2251             ASSERT(style->isGridAutoFlowDirectionRow() || style->isGridAutoFlowDirectionColumn());
2252             if (style->isGridAutoFlowDirectionRow())
2253                 list->append(cssValuePool().createIdentifierValue(CSSValueRow));
2254             else
2255                 list->append(cssValuePool().createIdentifierValue(CSSValueColumn));
2256
2257             if (style->isGridAutoFlowAlgorithmDense())
2258                 list->append(cssValuePool().createIdentifierValue(CSSValueDense));
2259
2260             return list.release();
2261         }
2262
2263         // Specs mention that getComputedStyle() should return the used value of the property instead of the computed
2264         // one for grid-definition-{rows|columns} but not for the grid-auto-{rows|columns} as things like
2265         // grid-auto-columns: 2fr; cannot be resolved to a value in pixels as the '2fr' means very different things
2266         // depending on the size of the explicit grid or the number of implicit tracks added to the grid. See
2267         // http://lists.w3.org/Archives/Public/www-style/2013Nov/0014.html
2268         case CSSPropertyWebkitGridAutoColumns:
2269             return specifiedValueForGridTrackSize(style->gridAutoColumns(), style.get());
2270         case CSSPropertyWebkitGridAutoRows:
2271             return specifiedValueForGridTrackSize(style->gridAutoRows(), style.get());
2272
2273         case CSSPropertyWebkitGridTemplateColumns:
2274             return valueForGridTrackList(ForColumns, renderer, style.get());
2275         case CSSPropertyWebkitGridTemplateRows:
2276             return valueForGridTrackList(ForRows, renderer, style.get());
2277
2278         case CSSPropertyWebkitGridColumnStart:
2279             return valueForGridPosition(style->gridItemColumnStart());
2280         case CSSPropertyWebkitGridColumnEnd:
2281             return valueForGridPosition(style->gridItemColumnEnd());
2282         case CSSPropertyWebkitGridRowStart:
2283             return valueForGridPosition(style->gridItemRowStart());
2284         case CSSPropertyWebkitGridRowEnd:
2285             return valueForGridPosition(style->gridItemRowEnd());
2286         case CSSPropertyWebkitGridArea:
2287             return getCSSPropertyValuesForGridShorthand(webkitGridAreaShorthand());
2288         case CSSPropertyWebkitGridTemplate:
2289             return getCSSPropertyValuesForGridShorthand(webkitGridTemplateShorthand());
2290         case CSSPropertyWebkitGrid:
2291             return getCSSPropertyValuesForGridShorthand(webkitGridShorthand());
2292         case CSSPropertyWebkitGridColumn:
2293             return getCSSPropertyValuesForGridShorthand(webkitGridColumnShorthand());
2294         case CSSPropertyWebkitGridRow:
2295             return getCSSPropertyValuesForGridShorthand(webkitGridRowShorthand());
2296
2297         case CSSPropertyWebkitGridTemplateAreas:
2298             if (!style->namedGridAreaRowCount()) {
2299                 ASSERT(!style->namedGridAreaColumnCount());
2300                 return cssValuePool().createIdentifierValue(CSSValueNone);
2301             }
2302
2303             return CSSGridTemplateAreasValue::create(style->namedGridArea(), style->namedGridAreaRowCount(), style->namedGridAreaColumnCount());
2304 #endif /* ENABLE(CSS_GRID_LAYOUT) */
2305         case CSSPropertyHeight:
2306             if (renderer && !renderer->isRenderSVGModelObject()) {
2307                 // According to http://www.w3.org/TR/CSS2/visudet.html#the-height-property,
2308                 // the "height" property does not apply for non-replaced inline elements.
2309                 if (!renderer->isReplaced() && renderer->isInline())
2310                     return cssValuePool().createIdentifierValue(CSSValueAuto);
2311                 return zoomAdjustedPixelValue(sizingBox(*renderer).height(), style.get());
2312             }
2313             return zoomAdjustedPixelValueForLength(style->height(), style.get());
2314         case CSSPropertyWebkitHyphens:
2315             return cssValuePool().createValue(style->hyphens());
2316         case CSSPropertyWebkitHyphenateCharacter:
2317             if (style->hyphenationString().isNull())
2318                 return cssValuePool().createIdentifierValue(CSSValueAuto);
2319             return cssValuePool().createValue(style->hyphenationString(), CSSPrimitiveValue::CSS_STRING);
2320         case CSSPropertyWebkitHyphenateLimitAfter:
2321             if (style->hyphenationLimitAfter() < 0)
2322                 return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
2323             return CSSPrimitiveValue::create(style->hyphenationLimitAfter(), CSSPrimitiveValue::CSS_NUMBER);
2324         case CSSPropertyWebkitHyphenateLimitBefore:
2325             if (style->hyphenationLimitBefore() < 0)
2326                 return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
2327             return CSSPrimitiveValue::create(style->hyphenationLimitBefore(), CSSPrimitiveValue::CSS_NUMBER);
2328         case CSSPropertyWebkitHyphenateLimitLines:
2329             if (style->hyphenationLimitLines() < 0)
2330                 return CSSPrimitiveValue::createIdentifier(CSSValueNoLimit);
2331             return CSSPrimitiveValue::create(style->hyphenationLimitLines(), CSSPrimitiveValue::CSS_NUMBER);
2332         case CSSPropertyWebkitBorderFit:
2333             if (style->borderFit() == BorderFitBorder)
2334                 return cssValuePool().createIdentifierValue(CSSValueBorder);
2335             return cssValuePool().createIdentifierValue(CSSValueLines);
2336 #if ENABLE(CSS_IMAGE_ORIENTATION)
2337         case CSSPropertyImageOrientation:
2338             return cssValuePool().createValue(style->imageOrientation());
2339 #endif
2340         case CSSPropertyImageRendering:
2341             return CSSPrimitiveValue::create(style->imageRendering());
2342 #if ENABLE(CSS_IMAGE_RESOLUTION)
2343         case CSSPropertyImageResolution:
2344             return cssValuePool().createValue(style->imageResolution(), CSSPrimitiveValue::CSS_DPPX);
2345 #endif
2346         case CSSPropertyLeft:
2347             return positionOffsetValue(style.get(), CSSPropertyLeft);
2348         case CSSPropertyLetterSpacing:
2349             if (!style->letterSpacing())
2350                 return cssValuePool().createIdentifierValue(CSSValueNormal);
2351             return zoomAdjustedPixelValue(style->letterSpacing(), style.get());
2352         case CSSPropertyWebkitLineClamp:
2353             if (style->lineClamp().isNone())
2354                 return cssValuePool().createIdentifierValue(CSSValueNone);
2355             return cssValuePool().createValue(style->lineClamp().value(), style->lineClamp().isPercentage() ? CSSPrimitiveValue::CSS_PERCENTAGE : CSSPrimitiveValue::CSS_NUMBER);
2356         case CSSPropertyLineHeight:
2357             return lineHeightFromStyle(style.get());
2358         case CSSPropertyListStyleImage:
2359             if (style->listStyleImage())
2360                 return style->listStyleImage()->cssValue();
2361             return cssValuePool().createIdentifierValue(CSSValueNone);
2362         case CSSPropertyListStylePosition:
2363             return cssValuePool().createValue(style->listStylePosition());
2364         case CSSPropertyListStyleType:
2365             return cssValuePool().createValue(style->listStyleType());
2366         case CSSPropertyWebkitLocale:
2367             if (style->locale().isNull())
2368                 return cssValuePool().createIdentifierValue(CSSValueAuto);
2369             return cssValuePool().createValue(style->locale(), CSSPrimitiveValue::CSS_STRING);
2370         case CSSPropertyMarginTop:
2371             return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::marginTop, &RenderBoxModelObject::marginTop>(style.get(), renderer);
2372         case CSSPropertyMarginRight: {
2373             Length marginRight = style->marginRight();
2374             if (marginRight.isFixed() || !is<RenderBox>(renderer))
2375                 return zoomAdjustedPixelValueForLength(marginRight, style.get());
2376             float value;
2377             if (marginRight.isPercent()) {
2378                 // RenderBox gives a marginRight() that is the distance between the right-edge of the child box
2379                 // and the right-edge of the containing box, when display == BLOCK. Let's calculate the absolute
2380                 // value of the specified margin-right % instead of relying on RenderBox's marginRight() value.
2381                 value = minimumValueForLength(marginRight, downcast<RenderBox>(*renderer).containingBlockLogicalWidthForContent());
2382             } else
2383                 value = downcast<RenderBox>(*renderer).marginRight();
2384             return zoomAdjustedPixelValue(value, style.get());
2385         }
2386         case CSSPropertyMarginBottom:
2387             return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::marginBottom, &RenderBoxModelObject::marginBottom>(style.get(), renderer);
2388         case CSSPropertyMarginLeft:
2389             return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::marginLeft, &RenderBoxModelObject::marginLeft>(style.get(), renderer);
2390         case CSSPropertyWebkitMarqueeDirection:
2391             return cssValuePool().createValue(style->marqueeDirection());
2392         case CSSPropertyWebkitMarqueeIncrement:
2393             return cssValuePool().createValue(style->marqueeIncrement());
2394         case CSSPropertyWebkitMarqueeRepetition:
2395             if (style->marqueeLoopCount() < 0)
2396                 return cssValuePool().createIdentifierValue(CSSValueInfinite);
2397             return cssValuePool().createValue(style->marqueeLoopCount(), CSSPrimitiveValue::CSS_NUMBER);
2398         case CSSPropertyWebkitMarqueeStyle:
2399             return cssValuePool().createValue(style->marqueeBehavior());
2400         case CSSPropertyWebkitUserModify:
2401             return cssValuePool().createValue(style->userModify());
2402         case CSSPropertyMaxHeight: {
2403             const Length& maxHeight = style->maxHeight();
2404             if (maxHeight.isUndefined())
2405                 return cssValuePool().createIdentifierValue(CSSValueNone);
2406             return zoomAdjustedPixelValueForLength(maxHeight, style.get());
2407         }
2408         case CSSPropertyMaxWidth: {
2409             const Length& maxWidth = style->maxWidth();
2410             if (maxWidth.isUndefined())
2411                 return cssValuePool().createIdentifierValue(CSSValueNone);
2412             return zoomAdjustedPixelValueForLength(maxWidth, style.get());
2413         }
2414         case CSSPropertyMinHeight:
2415             // FIXME: For flex-items, min-height:auto should compute to min-content.
2416             if (style->minHeight().isAuto())
2417                 return zoomAdjustedPixelValue(0, style.get());
2418             return zoomAdjustedPixelValueForLength(style->minHeight(), style.get());
2419         case CSSPropertyMinWidth:
2420             // FIXME: For flex-items, min-width:auto should compute to min-content.
2421             if (style->minWidth().isAuto())
2422                 return zoomAdjustedPixelValue(0, style.get());
2423             return zoomAdjustedPixelValueForLength(style->minWidth(), style.get());
2424         case CSSPropertyObjectFit:
2425             return cssValuePool().createValue(style->objectFit());
2426         case CSSPropertyOpacity:
2427             return cssValuePool().createValue(style->opacity(), CSSPrimitiveValue::CSS_NUMBER);
2428         case CSSPropertyOrphans:
2429             if (style->hasAutoOrphans())
2430                 return cssValuePool().createIdentifierValue(CSSValueAuto);
2431             return cssValuePool().createValue(style->orphans(), CSSPrimitiveValue::CSS_NUMBER);
2432         case CSSPropertyOutlineColor:
2433             return m_allowVisitedStyle ? cssValuePool().createColorValue(style->visitedDependentColor(CSSPropertyOutlineColor).rgb()) : currentColorOrValidColor(style.get(), style->outlineColor());
2434         case CSSPropertyOutlineOffset:
2435             return zoomAdjustedPixelValue(style->outlineOffset(), style.get());
2436         case CSSPropertyOutlineStyle:
2437             if (style->outlineStyleIsAuto())
2438                 return cssValuePool().createIdentifierValue(CSSValueAuto);
2439             return cssValuePool().createValue(style->outlineStyle());
2440         case CSSPropertyOutlineWidth:
2441             return zoomAdjustedPixelValue(style->outlineWidth(), style.get());
2442         case CSSPropertyOverflow:
2443             return cssValuePool().createValue(std::max(style->overflowX(), style->overflowY()));
2444         case CSSPropertyOverflowWrap:
2445             return cssValuePool().createValue(style->overflowWrap());
2446         case CSSPropertyOverflowX:
2447             return cssValuePool().createValue(style->overflowX());
2448         case CSSPropertyOverflowY:
2449             return cssValuePool().createValue(style->overflowY());
2450         case CSSPropertyPaddingTop:
2451             return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::paddingTop, &RenderBoxModelObject::computedCSSPaddingTop>(style.get(), renderer);
2452         case CSSPropertyPaddingRight:
2453             return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::paddingRight, &RenderBoxModelObject::computedCSSPaddingRight>(style.get(), renderer);
2454         case CSSPropertyPaddingBottom:
2455             return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::paddingBottom, &RenderBoxModelObject::computedCSSPaddingBottom>(style.get(), renderer);
2456         case CSSPropertyPaddingLeft:
2457             return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::paddingLeft, &RenderBoxModelObject::computedCSSPaddingLeft>(style.get(), renderer);
2458         case CSSPropertyPageBreakAfter:
2459             return cssValuePool().createValue(style->pageBreakAfter());
2460         case CSSPropertyPageBreakBefore:
2461             return cssValuePool().createValue(style->pageBreakBefore());
2462         case CSSPropertyPageBreakInside: {
2463             EPageBreak pageBreak = style->pageBreakInside();
2464             ASSERT(pageBreak != PBALWAYS);
2465             if (pageBreak == PBALWAYS)
2466                 return nullptr;
2467             return cssValuePool().createValue(style->pageBreakInside());
2468         }
2469         case CSSPropertyPosition:
2470             return cssValuePool().createValue(style->position());
2471         case CSSPropertyRight:
2472             return positionOffsetValue(style.get(), CSSPropertyRight);
2473         case CSSPropertyWebkitRubyPosition:
2474             return cssValuePool().createValue(style->rubyPosition());
2475         case CSSPropertyTableLayout:
2476             return cssValuePool().createValue(style->tableLayout());
2477         case CSSPropertyTextAlign:
2478             return cssValuePool().createValue(style->textAlign());
2479         case CSSPropertyTextDecoration:
2480             return renderTextDecorationFlagsToCSSValue(style->textDecoration());
2481 #if ENABLE(CSS3_TEXT)
2482         case CSSPropertyWebkitTextAlignLast:
2483             return cssValuePool().createValue(style->textAlignLast());
2484         case CSSPropertyWebkitTextJustify:
2485             return cssValuePool().createValue(style->textJustify());
2486 #endif // CSS3_TEXT
2487         case CSSPropertyWebkitTextDecoration:
2488             return getCSSPropertyValuesForShorthandProperties(webkitTextDecorationShorthand());
2489         case CSSPropertyWebkitTextDecorationLine:
2490             return renderTextDecorationFlagsToCSSValue(style->textDecoration());
2491         case CSSPropertyWebkitTextDecorationStyle:
2492             return renderTextDecorationStyleFlagsToCSSValue(style->textDecorationStyle());
2493         case CSSPropertyWebkitTextDecorationColor:
2494             return currentColorOrValidColor(style.get(), style->textDecorationColor());
2495         case CSSPropertyWebkitTextDecorationSkip:
2496             return renderTextDecorationSkipFlagsToCSSValue(style->textDecorationSkip());
2497         case CSSPropertyWebkitTextUnderlinePosition:
2498             return cssValuePool().createValue(style->textUnderlinePosition());
2499         case CSSPropertyWebkitTextDecorationsInEffect:
2500             return renderTextDecorationFlagsToCSSValue(style->textDecorationsInEffect());
2501         case CSSPropertyWebkitTextFillColor:
2502             return currentColorOrValidColor(style.get(), style->textFillColor());
2503         case CSSPropertyWebkitTextEmphasisColor:
2504             return currentColorOrValidColor(style.get(), style->textEmphasisColor());
2505         case CSSPropertyWebkitTextEmphasisPosition:
2506             return renderEmphasisPositionFlagsToCSSValue(style->textEmphasisPosition());
2507         case CSSPropertyWebkitTextEmphasisStyle:
2508             switch (style->textEmphasisMark()) {
2509             case TextEmphasisMarkNone:
2510                 return cssValuePool().createIdentifierValue(CSSValueNone);
2511             case TextEmphasisMarkCustom:
2512                 return cssValuePool().createValue(style->textEmphasisCustomMark(), CSSPrimitiveValue::CSS_STRING);
2513             case TextEmphasisMarkAuto:
2514                 ASSERT_NOT_REACHED();
2515 #if ASSERT_DISABLED
2516                 FALLTHROUGH;
2517 #endif
2518             case TextEmphasisMarkDot:
2519             case TextEmphasisMarkCircle:
2520             case TextEmphasisMarkDoubleCircle:
2521             case TextEmphasisMarkTriangle:
2522             case TextEmphasisMarkSesame: {
2523                 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2524                 list->append(cssValuePool().createValue(style->textEmphasisFill()));
2525                 list->append(cssValuePool().createValue(style->textEmphasisMark()));
2526                 return list.release();
2527             }
2528             }
2529         case CSSPropertyTextIndent: {
2530             // If CSS3_TEXT is disabled or text-indent has only one value(<length> | <percentage>),
2531             // getPropertyCSSValue() returns CSSValue.
2532             RefPtr<CSSValue> textIndent = zoomAdjustedPixelValueForLength(style->textIndent(), style.get());
2533 #if ENABLE(CSS3_TEXT)
2534             // If CSS3_TEXT is enabled and text-indent has -webkit-each-line or -webkit-hanging,
2535             // getPropertyCSSValue() returns CSSValueList.
2536             if (style->textIndentLine() == TextIndentEachLine || style->textIndentType() == TextIndentHanging) {
2537                 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2538                 list->append(textIndent.releaseNonNull());
2539                 if (style->textIndentLine() == TextIndentEachLine)
2540                     list->append(cssValuePool().createIdentifierValue(CSSValueWebkitEachLine));
2541                 if (style->textIndentType() == TextIndentHanging)
2542                     list->append(cssValuePool().createIdentifierValue(CSSValueWebkitHanging));
2543                 return list.release();
2544             }
2545 #endif
2546             return textIndent.release();
2547         }
2548         case CSSPropertyTextShadow:
2549             return valueForShadow(style->textShadow(), propertyID, style.get());
2550         case CSSPropertyTextRendering:
2551             return cssValuePool().createValue(style->fontDescription().textRenderingMode());
2552         case CSSPropertyTextOverflow:
2553             if (style->textOverflow())
2554                 return cssValuePool().createIdentifierValue(CSSValueEllipsis);
2555             return cssValuePool().createIdentifierValue(CSSValueClip);
2556         case CSSPropertyWebkitTextSecurity:
2557             return cssValuePool().createValue(style->textSecurity());
2558 #if ENABLE(IOS_TEXT_AUTOSIZING)
2559         case CSSPropertyWebkitTextSizeAdjust:
2560             if (style->textSizeAdjust().isAuto())
2561                 return cssValuePool().createIdentifierValue(CSSValueAuto);
2562             if (style->textSizeAdjust().isNone())
2563                 return cssValuePool().createIdentifierValue(CSSValueNone);
2564             return CSSPrimitiveValue::create(style->textSizeAdjust().percentage(), CSSPrimitiveValue::CSS_PERCENTAGE);
2565 #endif
2566         case CSSPropertyWebkitTextStrokeColor:
2567             return currentColorOrValidColor(style.get(), style->textStrokeColor());
2568         case CSSPropertyWebkitTextStrokeWidth:
2569             return zoomAdjustedPixelValue(style->textStrokeWidth(), style.get());
2570         case CSSPropertyTextTransform:
2571             return cssValuePool().createValue(style->textTransform());
2572         case CSSPropertyTop:
2573             return positionOffsetValue(style.get(), CSSPropertyTop);
2574         case CSSPropertyUnicodeBidi:
2575             return cssValuePool().createValue(style->unicodeBidi());
2576         case CSSPropertyVerticalAlign:
2577             switch (style->verticalAlign()) {
2578                 case BASELINE:
2579                     return cssValuePool().createIdentifierValue(CSSValueBaseline);
2580                 case MIDDLE:
2581                     return cssValuePool().createIdentifierValue(CSSValueMiddle);
2582                 case SUB:
2583                     return cssValuePool().createIdentifierValue(CSSValueSub);
2584                 case SUPER:
2585                     return cssValuePool().createIdentifierValue(CSSValueSuper);
2586                 case TEXT_TOP:
2587                     return cssValuePool().createIdentifierValue(CSSValueTextTop);
2588                 case TEXT_BOTTOM:
2589                     return cssValuePool().createIdentifierValue(CSSValueTextBottom);
2590                 case TOP:
2591                     return cssValuePool().createIdentifierValue(CSSValueTop);
2592                 case BOTTOM:
2593                     return cssValuePool().createIdentifierValue(CSSValueBottom);
2594                 case BASELINE_MIDDLE:
2595                     return cssValuePool().createIdentifierValue(CSSValueWebkitBaselineMiddle);
2596                 case LENGTH:
2597                     return cssValuePool().createValue(style->verticalAlignLength());
2598             }
2599             ASSERT_NOT_REACHED();
2600             return nullptr;
2601         case CSSPropertyVisibility:
2602             return cssValuePool().createValue(style->visibility());
2603         case CSSPropertyWhiteSpace:
2604             return cssValuePool().createValue(style->whiteSpace());
2605         case CSSPropertyWidows:
2606             if (style->hasAutoWidows())
2607                 return cssValuePool().createIdentifierValue(CSSValueAuto);
2608             return cssValuePool().createValue(style->widows(), CSSPrimitiveValue::CSS_NUMBER);
2609         case CSSPropertyWidth:
2610             if (renderer && !renderer->isRenderSVGModelObject()) {
2611                 // According to http://www.w3.org/TR/CSS2/visudet.html#the-width-property,
2612                 // the "width" property does not apply for non-replaced inline elements.
2613                 if (!renderer->isReplaced() && renderer->isInline())
2614                     return cssValuePool().createIdentifierValue(CSSValueAuto);
2615                 return zoomAdjustedPixelValue(sizingBox(*renderer).width(), style.get());
2616             }
2617             return zoomAdjustedPixelValueForLength(style->width(), style.get());
2618         case CSSPropertyWordBreak:
2619             return cssValuePool().createValue(style->wordBreak());
2620         case CSSPropertyWordSpacing:
2621             return zoomAdjustedPixelValue(style->fontCascade().wordSpacing(), style.get());
2622         case CSSPropertyWordWrap:
2623             return cssValuePool().createValue(style->overflowWrap());
2624         case CSSPropertyWebkitLineBreak:
2625             return cssValuePool().createValue(style->lineBreak());
2626         case CSSPropertyWebkitNbspMode:
2627             return cssValuePool().createValue(style->nbspMode());
2628         case CSSPropertyResize:
2629             return cssValuePool().createValue(style->resize());
2630         case CSSPropertyWebkitFontKerning:
2631             return cssValuePool().createValue(style->fontDescription().kerning());
2632         case CSSPropertyWebkitFontSmoothing:
2633             return cssValuePool().createValue(style->fontDescription().fontSmoothing());
2634         case CSSPropertyWebkitFontVariantLigatures: {
2635             FontDescription::LigaturesState commonLigaturesState = style->fontDescription().commonLigaturesState();
2636             FontDescription::LigaturesState discretionaryLigaturesState = style->fontDescription().discretionaryLigaturesState();
2637             FontDescription::LigaturesState historicalLigaturesState = style->fontDescription().historicalLigaturesState();
2638             if (commonLigaturesState == FontDescription::NormalLigaturesState && discretionaryLigaturesState == FontDescription::NormalLigaturesState
2639                 && historicalLigaturesState == FontDescription::NormalLigaturesState)
2640                 return cssValuePool().createIdentifierValue(CSSValueNormal);
2641
2642             RefPtr<CSSValueList> valueList = CSSValueList::createSpaceSeparated();
2643             if (commonLigaturesState != FontDescription::NormalLigaturesState)
2644                 valueList->append(cssValuePool().createIdentifierValue(commonLigaturesState == FontDescription::DisabledLigaturesState ? CSSValueNoCommonLigatures : CSSValueCommonLigatures));
2645             if (discretionaryLigaturesState != FontDescription::NormalLigaturesState)
2646                 valueList->append(cssValuePool().createIdentifierValue(discretionaryLigaturesState == FontDescription::DisabledLigaturesState ? CSSValueNoDiscretionaryLigatures : CSSValueDiscretionaryLigatures));
2647             if (historicalLigaturesState != FontDescription::NormalLigaturesState)
2648                 valueList->append(cssValuePool().createIdentifierValue(historicalLigaturesState == FontDescription::DisabledLigaturesState ? CSSValueNoHistoricalLigatures : CSSValueHistoricalLigatures));
2649             return valueList;
2650         }
2651         case CSSPropertyZIndex:
2652             if (style->hasAutoZIndex())
2653                 return cssValuePool().createIdentifierValue(CSSValueAuto);
2654             return cssValuePool().createValue(style->zIndex(), CSSPrimitiveValue::CSS_NUMBER);
2655         case CSSPropertyZoom:
2656             return cssValuePool().createValue(style->zoom(), CSSPrimitiveValue::CSS_NUMBER);
2657         case CSSPropertyBoxSizing:
2658             if (style->boxSizing() == CONTENT_BOX)
2659                 return cssValuePool().createIdentifierValue(CSSValueContentBox);
2660             return cssValuePool().createIdentifierValue(CSSValueBorderBox);
2661 #if ENABLE(DASHBOARD_SUPPORT)
2662         case CSSPropertyWebkitDashboardRegion:
2663         {
2664             const Vector<StyleDashboardRegion>& regions = style->dashboardRegions();
2665             unsigned count = regions.size();
2666             if (count == 1 && regions[0].type == StyleDashboardRegion::None)
2667                 return cssValuePool().createIdentifierValue(CSSValueNone);
2668
2669             RefPtr<DashboardRegion> firstRegion;
2670             DashboardRegion* previousRegion = nullptr;
2671             for (unsigned i = 0; i < count; i++) {
2672                 RefPtr<DashboardRegion> region = DashboardRegion::create();
2673                 StyleDashboardRegion styleRegion = regions[i];
2674
2675                 region->m_label = styleRegion.label;
2676                 LengthBox offset = styleRegion.offset;
2677                 region->setTop(zoomAdjustedPixelValue(offset.top().value(), style.get()));
2678                 region->setRight(zoomAdjustedPixelValue(offset.right().value(), style.get()));
2679                 region->setBottom(zoomAdjustedPixelValue(offset.bottom().value(), style.get()));
2680                 region->setLeft(zoomAdjustedPixelValue(offset.left().value(), style.get()));
2681                 region->m_isRectangle = (styleRegion.type == StyleDashboardRegion::Rectangle);
2682                 region->m_isCircle = (styleRegion.type == StyleDashboardRegion::Circle);
2683
2684                 if (previousRegion)
2685                     previousRegion->m_next = region;
2686                 else
2687                     firstRegion = region;
2688                 previousRegion = region.get();
2689             }
2690             return cssValuePool().createValue(firstRegion.release());
2691         }
2692 #endif
2693         case CSSPropertyAnimationDelay:
2694         case CSSPropertyWebkitAnimationDelay:
2695             return getDelayValue(style->animations());
2696         case CSSPropertyAnimationDirection:
2697         case CSSPropertyWebkitAnimationDirection: {
2698             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2699             const AnimationList* t = style->animations();
2700             if (t) {
2701                 for (size_t i = 0; i < t->size(); ++i) {
2702                     switch (t->animation(i).direction()) {
2703                     case Animation::AnimationDirectionNormal:
2704                         list->append(cssValuePool().createIdentifierValue(CSSValueNormal));
2705                         break;
2706                     case Animation::AnimationDirectionAlternate:
2707                         list->append(cssValuePool().createIdentifierValue(CSSValueAlternate));
2708                         break;
2709                     case Animation::AnimationDirectionReverse:
2710                         list->append(cssValuePool().createIdentifierValue(CSSValueReverse));
2711                         break;
2712                     case Animation::AnimationDirectionAlternateReverse:
2713                         list->append(cssValuePool().createIdentifierValue(CSSValueAlternateReverse));
2714                         break;
2715                     }
2716                 }
2717             } else
2718                 list->append(cssValuePool().createIdentifierValue(CSSValueNormal));
2719             return list.release();
2720         }
2721         case CSSPropertyAnimationDuration:
2722         case CSSPropertyWebkitAnimationDuration:
2723             return getDurationValue(style->animations());
2724         case CSSPropertyAnimationFillMode:
2725         case CSSPropertyWebkitAnimationFillMode: {
2726             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2727             const AnimationList* t = style->animations();
2728             if (t) {
2729                 for (size_t i = 0; i < t->size(); ++i) {
2730                     switch (t->animation(i).fillMode()) {
2731                     case AnimationFillModeNone:
2732                         list->append(cssValuePool().createIdentifierValue(CSSValueNone));
2733                         break;
2734                     case AnimationFillModeForwards:
2735                         list->append(cssValuePool().createIdentifierValue(CSSValueForwards));
2736                         break;
2737                     case AnimationFillModeBackwards:
2738                         list->append(cssValuePool().createIdentifierValue(CSSValueBackwards));
2739                         break;
2740                     case AnimationFillModeBoth:
2741                         list->append(cssValuePool().createIdentifierValue(CSSValueBoth));
2742                         break;
2743                     }
2744                 }
2745             } else
2746                 list->append(cssValuePool().createIdentifierValue(CSSValueNone));
2747             return list.release();
2748         }
2749         case CSSPropertyAnimationIterationCount:
2750         case CSSPropertyWebkitAnimationIterationCount: {
2751             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2752             const AnimationList* t = style->animations();
2753             if (t) {
2754                 for (size_t i = 0; i < t->size(); ++i) {
2755                     double iterationCount = t->animation(i).iterationCount();
2756                     if (iterationCount == Animation::IterationCountInfinite)
2757                         list->append(cssValuePool().createIdentifierValue(CSSValueInfinite));
2758                     else
2759                         list->append(cssValuePool().createValue(iterationCount, CSSPrimitiveValue::CSS_NUMBER));
2760                 }
2761             } else
2762                 list->append(cssValuePool().createValue(Animation::initialIterationCount(), CSSPrimitiveValue::CSS_NUMBER));
2763             return list.release();
2764         }
2765         case CSSPropertyAnimationName:
2766         case CSSPropertyWebkitAnimationName: {
2767             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2768             const AnimationList* t = style->animations();
2769             if (t) {
2770                 for (size_t i = 0; i < t->size(); ++i)
2771                     list->append(cssValuePool().createValue(t->animation(i).name(), CSSPrimitiveValue::CSS_STRING));
2772             } else
2773                 list->append(cssValuePool().createIdentifierValue(CSSValueNone));
2774             return list.release();
2775         }
2776         case CSSPropertyAnimationPlayState:
2777         case CSSPropertyWebkitAnimationPlayState: {
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                     int prop = t->animation(i).playState();
2783                     if (prop == AnimPlayStatePlaying)
2784                         list->append(cssValuePool().createIdentifierValue(CSSValueRunning));
2785                     else
2786                         list->append(cssValuePool().createIdentifierValue(CSSValuePaused));
2787                 }
2788             } else
2789                 list->append(cssValuePool().createIdentifierValue(CSSValueRunning));
2790             return list.release();
2791         }
2792         case CSSPropertyAnimationTimingFunction:
2793         case CSSPropertyWebkitAnimationTimingFunction:
2794             return getTimingFunctionValue(style->animations());
2795 #if ENABLE(CSS_ANIMATIONS_LEVEL_2)
2796         case CSSPropertyWebkitAnimationTrigger:
2797             return getAnimationTriggerValue(style->animations(), style.get());
2798 #endif
2799         case CSSPropertyWebkitAppearance:
2800             return cssValuePool().createValue(style->appearance());
2801         case CSSPropertyWebkitAspectRatio:
2802             if (style->aspectRatioType() == AspectRatioAuto)
2803                 return cssValuePool().createIdentifierValue(CSSValueAuto);
2804             if (style->aspectRatioType() == AspectRatioFromDimensions)
2805                 return cssValuePool().createIdentifierValue(CSSValueFromDimensions);
2806             if (style->aspectRatioType() == AspectRatioFromIntrinsic)
2807                 return cssValuePool().createIdentifierValue(CSSValueFromIntrinsic);
2808             return CSSAspectRatioValue::create(style->aspectRatioNumerator(), style->aspectRatioDenominator());
2809         case CSSPropertyWebkitBackfaceVisibility:
2810             return cssValuePool().createIdentifierValue((style->backfaceVisibility() == BackfaceVisibilityHidden) ? CSSValueHidden : CSSValueVisible);
2811         case CSSPropertyWebkitBorderImage:
2812             return valueForNinePieceImage(style->borderImage());
2813         case CSSPropertyBorderImageOutset:
2814             return valueForNinePieceImageQuad(style->borderImage().outset());
2815         case CSSPropertyBorderImageRepeat:
2816             return valueForNinePieceImageRepeat(style->borderImage());
2817         case CSSPropertyBorderImageSlice:
2818             return valueForNinePieceImageSlice(style->borderImage());
2819         case CSSPropertyBorderImageWidth:
2820             return valueForNinePieceImageQuad(style->borderImage().borderSlices());
2821         case CSSPropertyWebkitMaskBoxImage:
2822             return valueForNinePieceImage(style->maskBoxImage());
2823         case CSSPropertyWebkitMaskBoxImageOutset:
2824             return valueForNinePieceImageQuad(style->maskBoxImage().outset());
2825         case CSSPropertyWebkitMaskBoxImageRepeat:
2826             return valueForNinePieceImageRepeat(style->maskBoxImage());
2827         case CSSPropertyWebkitMaskBoxImageSlice:
2828             return valueForNinePieceImageSlice(style->maskBoxImage());
2829         case CSSPropertyWebkitMaskBoxImageWidth:
2830             return valueForNinePieceImageQuad(style->maskBoxImage().borderSlices());
2831         case CSSPropertyWebkitMaskBoxImageSource:
2832             if (style->maskBoxImageSource())
2833                 return style->maskBoxImageSource()->cssValue();
2834             return cssValuePool().createIdentifierValue(CSSValueNone);
2835         case CSSPropertyWebkitFontSizeDelta:
2836             // Not a real style property -- used by the editing engine -- so has no computed value.
2837             break;
2838         case CSSPropertyWebkitInitialLetter: {
2839             RefPtr<CSSPrimitiveValue> drop = !style->initialLetterDrop() ? cssValuePool().createIdentifierValue(CSSValueNormal) : cssValuePool().createValue(style->initialLetterDrop(), CSSPrimitiveValue::CSS_NUMBER);
2840             RefPtr<CSSPrimitiveValue> size = !style->initialLetterHeight() ? cssValuePool().createIdentifierValue(CSSValueNormal) : cssValuePool().createValue(style->initialLetterHeight(), CSSPrimitiveValue::CSS_NUMBER);
2841             return cssValuePool().createValue(Pair::create(drop.release(), size.release()));
2842         }
2843         case CSSPropertyWebkitMarginBottomCollapse:
2844         case CSSPropertyWebkitMarginAfterCollapse:
2845             return cssValuePool().createValue(style->marginAfterCollapse());
2846         case CSSPropertyWebkitMarginTopCollapse:
2847         case CSSPropertyWebkitMarginBeforeCollapse:
2848             return cssValuePool().createValue(style->marginBeforeCollapse());
2849 #if ENABLE(ACCELERATED_OVERFLOW_SCROLLING)
2850         case CSSPropertyWebkitOverflowScrolling:
2851             if (!style->useTouchOverflowScrolling())
2852                 return cssValuePool().createIdentifierValue(CSSValueAuto);
2853             return cssValuePool().createIdentifierValue(CSSValueTouch);
2854 #endif
2855         case CSSPropertyPerspective:
2856             if (!style->hasPerspective())
2857                 return cssValuePool().createIdentifierValue(CSSValueNone);
2858             return zoomAdjustedPixelValue(style->perspective(), style.get());
2859         case CSSPropertyPerspectiveOrigin: {
2860             RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2861             if (renderer) {
2862                 LayoutRect box;
2863                 if (is<RenderBox>(*renderer))
2864                     box = downcast<RenderBox>(*renderer).borderBoxRect();
2865
2866                 list->append(zoomAdjustedPixelValue(minimumValueForLength(style->perspectiveOriginX(), box.width()), style.get()));
2867                 list->append(zoomAdjustedPixelValue(minimumValueForLength(style->perspectiveOriginY(), box.height()), style.get()));
2868             }
2869             else {
2870                 list->append(zoomAdjustedPixelValueForLength(style->perspectiveOriginX(), style.get()));
2871                 list->append(zoomAdjustedPixelValueForLength(style->perspectiveOriginY(), style.get()));
2872
2873             }
2874             return list.release();
2875         }
2876         case CSSPropertyWebkitRtlOrdering:
2877             return cssValuePool().createIdentifierValue(style->rtlOrdering() ? CSSValueVisual : CSSValueLogical);
2878 #if ENABLE(TOUCH_EVENTS)
2879         case CSSPropertyWebkitTapHighlightColor:
2880             return currentColorOrValidColor(style.get(), style->tapHighlightColor());
2881 #endif
2882 #if PLATFORM(IOS)
2883         case CSSPropertyWebkitTouchCallout:
2884             return cssValuePool().createIdentifierValue(style->touchCalloutEnabled() ? CSSValueDefault : CSSValueNone);
2885 #endif
2886         case CSSPropertyWebkitUserDrag:
2887             return cssValuePool().createValue(style->userDrag());
2888         case CSSPropertyWebkitUserSelect:
2889             return cssValuePool().createValue(style->userSelect());
2890         case CSSPropertyBorderBottomLeftRadius:
2891             return getBorderRadiusCornerValue(style->borderBottomLeftRadius(), style.get());
2892         case CSSPropertyBorderBottomRightRadius:
2893             return getBorderRadiusCornerValue(style->borderBottomRightRadius(), style.get());
2894         case CSSPropertyBorderTopLeftRadius:
2895             return getBorderRadiusCornerValue(style->borderTopLeftRadius(), style.get());
2896         case CSSPropertyBorderTopRightRadius:
2897             return getBorderRadiusCornerValue(style->borderTopRightRadius(), style.get());
2898         case CSSPropertyClip: {
2899             if (!style->hasClip())
2900                 return cssValuePool().createIdentifierValue(CSSValueAuto);
2901             RefPtr<Rect> rect = Rect::create();
2902             rect->setTop(autoOrZoomAdjustedValue(style->clip().top(), style.get()));
2903             rect->setRight(autoOrZoomAdjustedValue(style->clip().right(), style.get()));
2904             rect->setBottom(autoOrZoomAdjustedValue(style->clip().bottom(), style.get()));
2905             rect->setLeft(autoOrZoomAdjustedValue(style->clip().left(), style.get()));
2906             return cssValuePool().createValue(rect.release());
2907         }
2908         case CSSPropertySpeak:
2909             return cssValuePool().createValue(style->speak());
2910         case CSSPropertyTransform:
2911             return computedTransform(renderer, style.get());
2912         case CSSPropertyTransformOrigin: {
2913             RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2914             if (renderer) {
2915                 LayoutRect box;
2916                 if (is<RenderBox>(*renderer))
2917                     box = downcast<RenderBox>(*renderer).borderBoxRect();
2918
2919                 list->append(zoomAdjustedPixelValue(minimumValueForLength(style->transformOriginX(), box.width()), style.get()));
2920                 list->append(zoomAdjustedPixelValue(minimumValueForLength(style->transformOriginY(), box.height()), style.get()));
2921                 if (style->transformOriginZ() != 0)
2922                     list->append(zoomAdjustedPixelValue(style->transformOriginZ(), style.get()));
2923             } else {
2924                 list->append(zoomAdjustedPixelValueForLength(style->transformOriginX(), style.get()));
2925                 list->append(zoomAdjustedPixelValueForLength(style->transformOriginY(), style.get()));
2926                 if (style->transformOriginZ() != 0)
2927                     list->append(zoomAdjustedPixelValue(style->transformOriginZ(), style.get()));
2928             }
2929             return list.release();
2930         }
2931         case CSSPropertyTransformStyle:
2932         case CSSPropertyWebkitTransformStyle:
2933             return cssValuePool().createIdentifierValue((style->transformStyle3D() == TransformStyle3DPreserve3D) ? CSSValuePreserve3d : CSSValueFlat);
2934         case CSSPropertyTransitionDelay:
2935         case CSSPropertyWebkitTransitionDelay:
2936             return getDelayValue(style->transitions());
2937         case CSSPropertyTransitionDuration:
2938         case CSSPropertyWebkitTransitionDuration:
2939             return getDurationValue(style->transitions());
2940         case CSSPropertyTransitionProperty:
2941         case CSSPropertyWebkitTransitionProperty:
2942             return getTransitionPropertyValue(style->transitions());
2943         case CSSPropertyTransitionTimingFunction:
2944         case CSSPropertyWebkitTransitionTimingFunction:
2945             return getTimingFunctionValue(style->transitions());
2946         case CSSPropertyTransition:
2947         case CSSPropertyWebkitTransition: {
2948             const AnimationList* animList = style->transitions();
2949             if (animList) {
2950                 RefPtr<CSSValueList> transitionsList = CSSValueList::createCommaSeparated();
2951                 for (size_t i = 0; i < animList->size(); ++i) {
2952                     RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2953                     const Animation& animation = animList->animation(i);
2954                     list->append(createTransitionPropertyValue(animation));
2955                     list->append(cssValuePool().createValue(animation.duration(), CSSPrimitiveValue::CSS_S));
2956                     list->append(createTimingFunctionValue(animation.timingFunction().get()));
2957                     list->append(cssValuePool().createValue(animation.delay(), CSSPrimitiveValue::CSS_S));
2958                     transitionsList->append(list.releaseNonNull());
2959                 }
2960                 return transitionsList.release();
2961             }
2962
2963             RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2964             // transition-property default value.
2965             list->append(cssValuePool().createIdentifierValue(CSSValueAll));
2966             list->append(cssValuePool().createValue(Animation::initialDuration(), CSSPrimitiveValue::CSS_S));
2967             list->append(createTimingFunctionValue(Animation::initialTimingFunction().get()));
2968             list->append(cssValuePool().createValue(Animation::initialDelay(), CSSPrimitiveValue::CSS_S));
2969             return list.release();
2970         }
2971         case CSSPropertyPointerEvents:
2972             return cssValuePool().createValue(style->pointerEvents());
2973         case CSSPropertyWebkitColorCorrection:
2974             return cssValuePool().createValue(style->colorSpace());
2975         case CSSPropertyWebkitLineGrid:
2976             if (style->lineGrid().isNull())
2977                 return cssValuePool().createIdentifierValue(CSSValueNone);
2978             return cssValuePool().createValue(style->lineGrid(), CSSPrimitiveValue::CSS_STRING);
2979         case CSSPropertyWebkitLineSnap:
2980             return CSSPrimitiveValue::create(style->lineSnap());
2981         case CSSPropertyWebkitLineAlign:
2982             return CSSPrimitiveValue::create(style->lineAlign());
2983         case CSSPropertyWebkitWritingMode:
2984             return cssValuePool().createValue(style->writingMode());
2985         case CSSPropertyWebkitTextCombine:
2986             return cssValuePool().createValue(style->textCombine());
2987         case CSSPropertyWebkitTextOrientation:
2988             return CSSPrimitiveValue::create(style->textOrientation());
2989         case CSSPropertyWebkitLineBoxContain:
2990             return createLineBoxContainValue(style->lineBoxContain());
2991         case CSSPropertyAlt:
2992             return altTextToCSSValue(style.get());
2993         case CSSPropertyContent:
2994             return contentToCSSValue(style.get());
2995         case CSSPropertyCounterIncrement:
2996             return counterToCSSValue(style.get(), propertyID);
2997         case CSSPropertyCounterReset:
2998             return counterToCSSValue(style.get(), propertyID);
2999         case CSSPropertyWebkitClipPath: {
3000             ClipPathOperation* operation = style->clipPath();
3001             if (!operation)
3002                 return cssValuePool().createIdentifierValue(CSSValueNone);
3003             if (is<ReferenceClipPathOperation>(*operation)) {
3004                 const auto& referenceOperation = downcast<ReferenceClipPathOperation>(*operation);
3005                 return CSSPrimitiveValue::create(referenceOperation.url(), CSSPrimitiveValue::CSS_URI);
3006             }
3007             RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
3008             if (is<ShapeClipPathOperation>(*operation)) {
3009                 const auto& shapeOperation = downcast<ShapeClipPathOperation>(*operation);
3010                 list->append(valueForBasicShape(style.get(), shapeOperation.basicShape()));
3011                 if (shapeOperation.referenceBox() != BoxMissing)
3012                     list->append(cssValuePool().createValue(shapeOperation.referenceBox()));
3013             }
3014             if (is<BoxClipPathOperation>(*operation)) {
3015                 const auto& boxOperation = downcast<BoxClipPathOperation>(*operation);
3016                 list->append(cssValuePool().createValue(boxOperation.referenceBox()));
3017             }
3018             return list.release();
3019         }
3020 #if ENABLE(CSS_REGIONS)
3021         case CSSPropertyWebkitFlowInto:
3022             if (!style->hasFlowInto())
3023                 return cssValuePool().createIdentifierValue(CSSValueNone);
3024             return cssValuePool().createValue(style->flowThread(), CSSPrimitiveValue::CSS_STRING);
3025         case CSSPropertyWebkitFlowFrom:
3026             if (!style->hasFlowFrom())
3027                 return cssValuePool().createIdentifierValue(CSSValueNone);
3028             return cssValuePool().createValue(style->regionThread(), CSSPrimitiveValue::CSS_STRING);
3029         case CSSPropertyWebkitRegionFragment:
3030             return cssValuePool().createValue(style->regionFragment());
3031 #endif
3032 #if ENABLE(CSS_SHAPES)
3033         case CSSPropertyWebkitShapeMargin:
3034             return cssValuePool().createValue(style->shapeMargin(), style.get());
3035         case CSSPropertyWebkitShapeImageThreshold:
3036             return cssValuePool().createValue(style->shapeImageThreshold(), CSSPrimitiveValue::CSS_NUMBER);
3037         case CSSPropertyWebkitShapeOutside:
3038             return shapePropertyValue(style.get(), style->shapeOutside());
3039 #endif
3040         case CSSPropertyWebkitFilter:
3041             return valueForFilter(style.get(), style->filter());
3042 #if ENABLE(FILTERS_LEVEL_2)
3043         case CSSPropertyWebkitBackdropFilter:
3044             return valueForFilter(style.get(), style->backdropFilter());
3045 #endif
3046 #if ENABLE(CSS_COMPOSITING)
3047         case CSSPropertyMixBlendMode:
3048             return cssValuePool().createValue(style->blendMode());
3049         case CSSPropertyIsolation:
3050             return cssValuePool().createValue(style->isolation());
3051 #endif
3052         case CSSPropertyBackgroundBlendMode: {
3053             const FillLayer* layers = style->backgroundLayers();
3054             if (!layers->next())
3055                 return cssValuePool().createValue(layers->blendMode());
3056
3057             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
3058             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
3059                 list->append(cssValuePool().createValue(currLayer->blendMode()));
3060
3061             return list.release();
3062         }
3063         case CSSPropertyBackground:
3064             return getBackgroundShorthandValue();
3065         case CSSPropertyBorder: {
3066             RefPtr<CSSValue> value = propertyValue(CSSPropertyBorderTop, DoNotUpdateLayout);
3067             const CSSPropertyID properties[3] = { CSSPropertyBorderRight, CSSPropertyBorderBottom, CSSPropertyBorderLeft };
3068             for (auto& property : properties) {
3069                 if (!compareCSSValuePtr<CSSValue>(value, propertyValue(property, DoNotUpdateLayout)))
3070                     return nullptr;
3071             }
3072             return value.release();
3073         }
3074         case CSSPropertyBorderBottom:
3075             return getCSSPropertyValuesForShorthandProperties(borderBottomShorthand());
3076         case CSSPropertyBorderColor:
3077             return getCSSPropertyValuesForSidesShorthand(borderColorShorthand());
3078         case CSSPropertyBorderLeft:
3079             return getCSSPropertyValuesForShorthandProperties(borderLeftShorthand());
3080         case CSSPropertyBorderImage:
3081             return valueForNinePieceImage(style->borderImage());
3082         case CSSPropertyBorderRadius:
3083             return getBorderRadiusShorthandValue(style.get());
3084         case CSSPropertyBorderRight:
3085             return getCSSPropertyValuesForShorthandProperties(borderRightShorthand());
3086         case CSSPropertyBorderStyle:
3087             return getCSSPropertyValuesForSidesShorthand(borderStyleShorthand());
3088         case CSSPropertyBorderTop:
3089             return getCSSPropertyValuesForShorthandProperties(borderTopShorthand());
3090         case CSSPropertyBorderWidth:
3091             return getCSSPropertyValuesForSidesShorthand(borderWidthShorthand());
3092         case CSSPropertyColumnRule:
3093             return getCSSPropertyValuesForShorthandProperties(columnRuleShorthand());
3094         case CSSPropertyColumns:
3095             return getCSSPropertyValuesForShorthandProperties(columnsShorthand());
3096         case CSSPropertyListStyle:
3097             return getCSSPropertyValuesForShorthandProperties(listStyleShorthand());
3098         case CSSPropertyMargin:
3099             return getCSSPropertyValuesForSidesShorthand(marginShorthand());
3100         case CSSPropertyOutline:
3101             return getCSSPropertyValuesForShorthandProperties(outlineShorthand());
3102         case CSSPropertyPadding:
3103             return getCSSPropertyValuesForSidesShorthand(paddingShorthand());
3104
3105 #if ENABLE(CSS_SCROLL_SNAP)
3106         case CSSPropertyWebkitScrollSnapType:
3107             return cssValuePool().createValue(style->scrollSnapType());
3108         case CSSPropertyWebkitScrollSnapDestination:
3109             return scrollSnapDestination(*style, style->scrollSnapDestination());
3110         case CSSPropertyWebkitScrollSnapPointsX:
3111             return scrollSnapPoints(*style, style->scrollSnapPointsX());
3112         case CSSPropertyWebkitScrollSnapPointsY:
3113             return scrollSnapPoints(*style, style->scrollSnapPointsY());
3114         case CSSPropertyWebkitScrollSnapCoordinate:
3115             return scrollSnapCoordinates(*style, style->scrollSnapCoordinates());
3116 #endif
3117
3118 #if ENABLE(CSS_TRAILING_WORD)
3119         case CSSPropertyAppleTrailingWord:
3120             return cssValuePool().createValue(style->trailingWord());
3121 #endif
3122
3123         /* Individual properties not part of the spec */
3124         case CSSPropertyBackgroundRepeatX:
3125         case CSSPropertyBackgroundRepeatY:
3126             break;
3127
3128         // Length properties for SVG.
3129         case CSSPropertyCx:
3130             return zoomAdjustedPixelValueForLength(style->svgStyle().cx(), style.get());
3131         case CSSPropertyCy:
3132             return zoomAdjustedPixelValueForLength(style->svgStyle().cy(), style.get());
3133         case CSSPropertyR:
3134             return zoomAdjustedPixelValueForLength(style->svgStyle().r(), style.get());
3135         case CSSPropertyRx: