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