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