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