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