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