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