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