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