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