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