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