2011-05-19 Mike Lawther <mikelawther@chromium.org>
[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 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 "ContentData.h"
29 #include "CounterContent.h"
30 #include "CursorList.h"
31 #include "CSSBorderImageValue.h"
32 #include "CSSLineBoxContainValue.h"
33 #include "CSSMutableStyleDeclaration.h"
34 #include "CSSPrimitiveValue.h"
35 #include "CSSPrimitiveValueCache.h"
36 #include "CSSPrimitiveValueMappings.h"
37 #include "CSSProperty.h"
38 #include "CSSPropertyNames.h"
39 #include "CSSReflectValue.h"
40 #include "CSSSelector.h"
41 #include "CSSTimingFunctionValue.h"
42 #include "CSSValueList.h"
43 #include "Document.h"
44 #include "ExceptionCode.h"
45 #include "Rect.h"
46 #include "RenderBox.h"
47 #include "RenderLayer.h"
48 #include "ShadowValue.h"
49 #include "WebKitCSSTransformValue.h"
50
51 #if ENABLE(DASHBOARD_SUPPORT)
52 #include "DashboardRegion.h"
53 #endif
54
55 namespace WebCore {
56
57 // List of all properties we know how to compute, omitting shorthands.
58 static const int computedProperties[] = {
59     CSSPropertyBackgroundAttachment,
60     CSSPropertyBackgroundClip,
61     CSSPropertyBackgroundColor,
62     CSSPropertyBackgroundImage,
63     CSSPropertyBackgroundOrigin,
64     CSSPropertyBackgroundPosition, // more-specific background-position-x/y are non-standard
65     CSSPropertyBackgroundRepeat,
66     CSSPropertyBackgroundSize,
67     CSSPropertyBorderBottomColor,
68     CSSPropertyBorderBottomLeftRadius,
69     CSSPropertyBorderBottomRightRadius,
70     CSSPropertyBorderBottomStyle,
71     CSSPropertyBorderBottomWidth,
72     CSSPropertyBorderCollapse,
73     CSSPropertyBorderLeftColor,
74     CSSPropertyBorderLeftStyle,
75     CSSPropertyBorderLeftWidth,
76     CSSPropertyBorderRightColor,
77     CSSPropertyBorderRightStyle,
78     CSSPropertyBorderRightWidth,
79     CSSPropertyBorderTopColor,
80     CSSPropertyBorderTopLeftRadius,
81     CSSPropertyBorderTopRightRadius,
82     CSSPropertyBorderTopStyle,
83     CSSPropertyBorderTopWidth,
84     CSSPropertyBottom,
85     CSSPropertyBoxShadow,
86     CSSPropertyBoxSizing,
87     CSSPropertyCaptionSide,
88     CSSPropertyClear,
89     CSSPropertyClip,
90     CSSPropertyColor,
91     CSSPropertyCursor,
92     CSSPropertyDirection,
93     CSSPropertyDisplay,
94     CSSPropertyEmptyCells,
95     CSSPropertyFloat,
96     CSSPropertyFontFamily,
97     CSSPropertyFontSize,
98     CSSPropertyFontStyle,
99     CSSPropertyFontVariant,
100     CSSPropertyFontWeight,
101     CSSPropertyHeight,
102     CSSPropertyImageRendering,
103     CSSPropertyLeft,
104     CSSPropertyLetterSpacing,
105     CSSPropertyLineHeight,
106     CSSPropertyListStyleImage,
107     CSSPropertyListStylePosition,
108     CSSPropertyListStyleType,
109     CSSPropertyMarginBottom,
110     CSSPropertyMarginLeft,
111     CSSPropertyMarginRight,
112     CSSPropertyMarginTop,
113     CSSPropertyMaxHeight,
114     CSSPropertyMaxWidth,
115     CSSPropertyMinHeight,
116     CSSPropertyMinWidth,
117     CSSPropertyOpacity,
118     CSSPropertyOrphans,
119     CSSPropertyOutlineColor,
120     CSSPropertyOutlineStyle,
121     CSSPropertyOutlineWidth,
122     CSSPropertyOverflowX,
123     CSSPropertyOverflowY,
124     CSSPropertyPaddingBottom,
125     CSSPropertyPaddingLeft,
126     CSSPropertyPaddingRight,
127     CSSPropertyPaddingTop,
128     CSSPropertyPageBreakAfter,
129     CSSPropertyPageBreakBefore,
130     CSSPropertyPageBreakInside,
131     CSSPropertyPointerEvents,
132     CSSPropertyPosition,
133     CSSPropertyResize,
134     CSSPropertyRight,
135     CSSPropertySpeak,
136     CSSPropertyTableLayout,
137     CSSPropertyTextAlign,
138     CSSPropertyTextDecoration,
139     CSSPropertyTextIndent,
140     CSSPropertyTextRendering,
141     CSSPropertyTextShadow,
142     CSSPropertyTextOverflow,
143     CSSPropertyTextTransform,
144     CSSPropertyTop,
145     CSSPropertyUnicodeBidi,
146     CSSPropertyVerticalAlign,
147     CSSPropertyVisibility,
148     CSSPropertyWhiteSpace,
149     CSSPropertyWidows,
150     CSSPropertyWidth,
151     CSSPropertyWordBreak,
152     CSSPropertyWordSpacing,
153     CSSPropertyWordWrap,
154     CSSPropertyZIndex,
155     CSSPropertyZoom,
156
157     CSSPropertyWebkitAnimationDelay,
158     CSSPropertyWebkitAnimationDirection,
159     CSSPropertyWebkitAnimationDuration,
160     CSSPropertyWebkitAnimationFillMode,
161     CSSPropertyWebkitAnimationIterationCount,
162     CSSPropertyWebkitAnimationName,
163     CSSPropertyWebkitAnimationPlayState,
164     CSSPropertyWebkitAnimationTimingFunction,
165     CSSPropertyWebkitAppearance,
166     CSSPropertyWebkitBackfaceVisibility,
167     CSSPropertyWebkitBackgroundClip,
168     CSSPropertyWebkitBackgroundComposite,
169     CSSPropertyWebkitBackgroundOrigin,
170     CSSPropertyWebkitBackgroundSize,
171     CSSPropertyWebkitBorderFit,
172     CSSPropertyWebkitBorderHorizontalSpacing,
173     CSSPropertyWebkitBorderImage,
174     CSSPropertyWebkitBorderVerticalSpacing,
175     CSSPropertyWebkitBoxAlign,
176     CSSPropertyWebkitBoxDirection,
177     CSSPropertyWebkitBoxFlex,
178     CSSPropertyWebkitBoxFlexGroup,
179     CSSPropertyWebkitBoxLines,
180     CSSPropertyWebkitBoxOrdinalGroup,
181     CSSPropertyWebkitBoxOrient,
182     CSSPropertyWebkitBoxPack,
183     CSSPropertyWebkitBoxReflect,
184     CSSPropertyWebkitBoxShadow,
185     CSSPropertyWebkitColorCorrection,
186     CSSPropertyWebkitColumnBreakAfter,
187     CSSPropertyWebkitColumnBreakBefore,
188     CSSPropertyWebkitColumnBreakInside,
189     CSSPropertyWebkitColumnCount,
190     CSSPropertyWebkitColumnGap,
191     CSSPropertyWebkitColumnRuleColor,
192     CSSPropertyWebkitColumnRuleStyle,
193     CSSPropertyWebkitColumnRuleWidth,
194     CSSPropertyWebkitColumnSpan,
195     CSSPropertyWebkitColumnWidth,
196 #if ENABLE(DASHBOARD_SUPPORT)
197     CSSPropertyWebkitDashboardRegion,
198 #endif
199     CSSPropertyWebkitFontSmoothing,
200     CSSPropertyWebkitHighlight,
201     CSSPropertyWebkitHyphenateCharacter,
202     CSSPropertyWebkitHyphenateLimitAfter,
203     CSSPropertyWebkitHyphenateLimitBefore,
204     CSSPropertyWebkitHyphens,
205     CSSPropertyWebkitLineBoxContain,
206     CSSPropertyWebkitLineBreak,
207     CSSPropertyWebkitLineClamp,
208     CSSPropertyWebkitLocale,
209     CSSPropertyWebkitMarginBeforeCollapse,
210     CSSPropertyWebkitMarginAfterCollapse,
211     CSSPropertyWebkitMarqueeDirection,
212     CSSPropertyWebkitMarqueeIncrement,
213     CSSPropertyWebkitMarqueeRepetition,
214     CSSPropertyWebkitMarqueeStyle,
215     CSSPropertyWebkitMaskAttachment,
216     CSSPropertyWebkitMaskBoxImage,
217     CSSPropertyWebkitMaskClip,
218     CSSPropertyWebkitMaskComposite,
219     CSSPropertyWebkitMaskImage,
220     CSSPropertyWebkitMaskOrigin,
221     CSSPropertyWebkitMaskPosition,
222     CSSPropertyWebkitMaskRepeat,
223     CSSPropertyWebkitMaskSize,
224     CSSPropertyWebkitNbspMode,
225     CSSPropertyWebkitPerspective,
226     CSSPropertyWebkitPerspectiveOrigin,
227     CSSPropertyWebkitRtlOrdering,
228     CSSPropertyWebkitTextCombine,
229     CSSPropertyWebkitTextDecorationsInEffect,
230     CSSPropertyWebkitTextEmphasisColor,
231     CSSPropertyWebkitTextEmphasisPosition,
232     CSSPropertyWebkitTextEmphasisStyle,
233     CSSPropertyWebkitTextFillColor,
234     CSSPropertyWebkitTextOrientation,
235     CSSPropertyWebkitTextSecurity,
236     CSSPropertyWebkitTextStrokeColor,
237     CSSPropertyWebkitTextStrokeWidth,
238     CSSPropertyWebkitTransform,
239     CSSPropertyWebkitTransformOrigin,
240     CSSPropertyWebkitTransformStyle,
241     CSSPropertyWebkitTransitionDelay,
242     CSSPropertyWebkitTransitionDuration,
243     CSSPropertyWebkitTransitionProperty,
244     CSSPropertyWebkitTransitionTimingFunction,
245     CSSPropertyWebkitUserDrag,
246     CSSPropertyWebkitUserModify,
247     CSSPropertyWebkitUserSelect,
248     CSSPropertyWebkitWritingMode
249
250 #if ENABLE(SVG)
251     ,
252     CSSPropertyClipPath,
253     CSSPropertyClipRule,
254     CSSPropertyMask,
255     CSSPropertyFilter,
256     CSSPropertyFloodColor,
257     CSSPropertyFloodOpacity,
258     CSSPropertyLightingColor,
259     CSSPropertyStopColor,
260     CSSPropertyStopOpacity,
261     CSSPropertyColorInterpolation,
262     CSSPropertyColorInterpolationFilters,
263     CSSPropertyColorRendering,
264     CSSPropertyFill,
265     CSSPropertyFillOpacity,
266     CSSPropertyFillRule,
267     CSSPropertyMarkerEnd,
268     CSSPropertyMarkerMid,
269     CSSPropertyMarkerStart,
270     CSSPropertyShapeRendering,
271     CSSPropertyStroke,
272     CSSPropertyStrokeDasharray,
273     CSSPropertyStrokeDashoffset,
274     CSSPropertyStrokeLinecap,
275     CSSPropertyStrokeLinejoin,
276     CSSPropertyStrokeMiterlimit,
277     CSSPropertyStrokeOpacity,
278     CSSPropertyStrokeWidth,
279     CSSPropertyAlignmentBaseline,
280     CSSPropertyBaselineShift,
281     CSSPropertyDominantBaseline,
282     CSSPropertyKerning,
283     CSSPropertyTextAnchor,
284     CSSPropertyWritingMode,
285     CSSPropertyGlyphOrientationHorizontal,
286     CSSPropertyGlyphOrientationVertical,
287     CSSPropertyWebkitSvgShadow,
288     CSSPropertyVectorEffect
289 #endif
290 };
291
292 const unsigned numComputedProperties = WTF_ARRAY_LENGTH(computedProperties);
293
294 static int valueForRepeatRule(int rule)
295 {
296     switch (rule) {
297         case RepeatImageRule:
298             return CSSValueRepeat;
299         case RoundImageRule:
300             return CSSValueRound;
301         default:
302             return CSSValueStretch;
303     }
304 }
305         
306 static PassRefPtr<CSSValue> valueForNinePieceImage(const NinePieceImage& image, CSSPrimitiveValueCache* primitiveValueCache)
307 {
308     if (!image.hasImage())
309         return primitiveValueCache->createIdentifierValue(CSSValueNone);
310     
311     // Image first.
312     RefPtr<CSSValue> imageValue;
313     if (image.image())
314         imageValue = image.image()->cssValue();
315     
316     // Create the slices.
317     RefPtr<CSSPrimitiveValue> top;
318     if (image.slices().top().isPercent())
319         top = primitiveValueCache->createValue(image.slices().top().value(), CSSPrimitiveValue::CSS_PERCENTAGE);
320     else
321         top = primitiveValueCache->createValue(image.slices().top().value(), CSSPrimitiveValue::CSS_NUMBER);
322         
323     RefPtr<CSSPrimitiveValue> right;
324     if (image.slices().right().isPercent())
325         right = primitiveValueCache->createValue(image.slices().right().value(), CSSPrimitiveValue::CSS_PERCENTAGE);
326     else
327         right = primitiveValueCache->createValue(image.slices().right().value(), CSSPrimitiveValue::CSS_NUMBER);
328         
329     RefPtr<CSSPrimitiveValue> bottom;
330     if (image.slices().bottom().isPercent())
331         bottom = primitiveValueCache->createValue(image.slices().bottom().value(), CSSPrimitiveValue::CSS_PERCENTAGE);
332     else
333         bottom = primitiveValueCache->createValue(image.slices().bottom().value(), CSSPrimitiveValue::CSS_NUMBER);
334     
335     RefPtr<CSSPrimitiveValue> left;
336     if (image.slices().left().isPercent())
337         left = primitiveValueCache->createValue(image.slices().left().value(), CSSPrimitiveValue::CSS_PERCENTAGE);
338     else
339         left = primitiveValueCache->createValue(image.slices().left().value(), CSSPrimitiveValue::CSS_NUMBER);
340
341     RefPtr<Rect> rect = Rect::create();
342     rect->setTop(top);
343     rect->setRight(right);
344     rect->setBottom(bottom);
345     rect->setLeft(left);
346
347     return CSSBorderImageValue::create(imageValue, rect, valueForRepeatRule(image.horizontalRule()), valueForRepeatRule(image.verticalRule()));
348 }
349
350 inline static PassRefPtr<CSSPrimitiveValue> zoomAdjustedPixelValue(int value, const RenderStyle* style, CSSPrimitiveValueCache* primitiveValueCache)
351 {
352     return primitiveValueCache->createValue(adjustForAbsoluteZoom(value, style), CSSPrimitiveValue::CSS_PX);
353 }
354
355 inline static PassRefPtr<CSSPrimitiveValue> zoomAdjustedNumberValue(double value, const RenderStyle* style, CSSPrimitiveValueCache* primitiveValueCache)
356 {
357     return primitiveValueCache->createValue(value / style->effectiveZoom(), CSSPrimitiveValue::CSS_NUMBER);
358 }
359
360 static PassRefPtr<CSSValue> zoomAdjustedPixelValueForLength(const Length& length, const RenderStyle* style, CSSPrimitiveValueCache* primitiveValueCache)
361 {
362     if (length.isFixed())
363         return zoomAdjustedPixelValue(length.value(), style, primitiveValueCache);
364     return primitiveValueCache->createValue(length);
365 }
366
367 static PassRefPtr<CSSValue> valueForReflection(const StyleReflection* reflection, const RenderStyle* style, CSSPrimitiveValueCache* primitiveValueCache)
368 {
369     if (!reflection)
370         return primitiveValueCache->createIdentifierValue(CSSValueNone);
371
372     RefPtr<CSSPrimitiveValue> offset;
373     if (reflection->offset().isPercent())
374         offset = primitiveValueCache->createValue(reflection->offset().percent(), CSSPrimitiveValue::CSS_PERCENTAGE);
375     else
376         offset = zoomAdjustedPixelValue(reflection->offset().value(), style, primitiveValueCache);
377     
378     return CSSReflectValue::create(reflection->direction(), offset.release(), valueForNinePieceImage(reflection->mask(), primitiveValueCache));
379 }
380
381 static PassRefPtr<CSSValue> getPositionOffsetValue(RenderStyle* style, int propertyID, CSSPrimitiveValueCache* primitiveValueCache)
382 {
383     if (!style)
384         return 0;
385
386     Length l;
387     switch (propertyID) {
388         case CSSPropertyLeft:
389             l = style->left();
390             break;
391         case CSSPropertyRight:
392             l = style->right();
393             break;
394         case CSSPropertyTop:
395             l = style->top();
396             break;
397         case CSSPropertyBottom:
398             l = style->bottom();
399             break;
400         default:
401             return 0;
402     }
403
404     if (style->position() == AbsolutePosition || style->position() == FixedPosition) {
405         if (l.type() == WebCore::Fixed)
406             return zoomAdjustedPixelValue(l.value(), style, primitiveValueCache);
407         return primitiveValueCache->createValue(l);
408     }
409
410     if (style->position() == RelativePosition)
411         // FIXME: It's not enough to simply return "auto" values for one offset if the other side is defined.
412         // In other words if left is auto and right is not auto, then left's computed value is negative right().
413         // So we should get the opposite length unit and see if it is auto.
414         return primitiveValueCache->createValue(l);
415
416     return primitiveValueCache->createIdentifierValue(CSSValueAuto);
417 }
418
419 PassRefPtr<CSSPrimitiveValue> CSSComputedStyleDeclaration::currentColorOrValidColor(RenderStyle* style, const Color& color) const
420 {
421     // This function does NOT look at visited information, so that computed style doesn't expose that.
422     CSSPrimitiveValueCache* primitiveValueCache = m_node->document()->cssPrimitiveValueCache().get();
423     if (!color.isValid())
424         return primitiveValueCache->createColorValue(style->color().rgb());
425     return primitiveValueCache->createColorValue(color.rgb());
426 }
427
428 static PassRefPtr<CSSValue> getBorderRadiusCornerValue(LengthSize radius, const RenderStyle* style, CSSPrimitiveValueCache* primitiveValueCache)
429 {
430     RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
431     if (radius.width() == radius.height()) {
432         if (radius.width().type() == Percent)
433             return primitiveValueCache->createValue(radius.width().percent(), CSSPrimitiveValue::CSS_PERCENTAGE);
434         return zoomAdjustedPixelValue(radius.width().value(), style, primitiveValueCache);
435     }
436     if (radius.width().type() == Percent)
437         list->append(primitiveValueCache->createValue(radius.width().percent(), CSSPrimitiveValue::CSS_PERCENTAGE));
438     else
439         list->append(zoomAdjustedPixelValue(radius.width().value(), style, primitiveValueCache));
440     if (radius.height().type() == Percent)
441         list->append(primitiveValueCache->createValue(radius.height().percent(), CSSPrimitiveValue::CSS_PERCENTAGE));
442     else
443         list->append(zoomAdjustedPixelValue(radius.height().value(), style, primitiveValueCache));
444     return list.release();
445 }
446
447 static IntRect sizingBox(RenderObject* renderer)
448 {
449     if (!renderer->isBox())
450         return IntRect();
451     
452     RenderBox* box = toRenderBox(renderer);
453     return box->style()->boxSizing() == CONTENT_BOX ? box->contentBoxRect() : box->borderBoxRect();
454 }
455
456 static inline bool hasCompositedLayer(RenderObject* renderer)
457 {
458     return renderer && renderer->hasLayer() && toRenderBoxModelObject(renderer)->layer()->isComposited();
459 }
460
461 static PassRefPtr<CSSValue> computedTransform(RenderObject* renderer, const RenderStyle* style, CSSPrimitiveValueCache* primitiveValueCache)
462 {
463     if (!renderer || style->transform().operations().isEmpty())
464         return primitiveValueCache->createIdentifierValue(CSSValueNone);
465     
466     IntRect box = sizingBox(renderer);
467
468     TransformationMatrix transform;
469     style->applyTransform(transform, box.size(), RenderStyle::ExcludeTransformOrigin);
470     // Note that this does not flatten to an affine transform if ENABLE(3D_RENDERING) is off, by design.
471
472     RefPtr<WebKitCSSTransformValue> transformVal;
473
474     // FIXME: Need to print out individual functions (https://bugs.webkit.org/show_bug.cgi?id=23924)
475     if (transform.isAffine()) {
476         transformVal = WebKitCSSTransformValue::create(WebKitCSSTransformValue::MatrixTransformOperation);
477
478         transformVal->append(primitiveValueCache->createValue(transform.a(), CSSPrimitiveValue::CSS_NUMBER));
479         transformVal->append(primitiveValueCache->createValue(transform.b(), CSSPrimitiveValue::CSS_NUMBER));
480         transformVal->append(primitiveValueCache->createValue(transform.c(), CSSPrimitiveValue::CSS_NUMBER));
481         transformVal->append(primitiveValueCache->createValue(transform.d(), CSSPrimitiveValue::CSS_NUMBER));
482         transformVal->append(zoomAdjustedNumberValue(transform.e(), style, primitiveValueCache));
483         transformVal->append(zoomAdjustedNumberValue(transform.f(), style, primitiveValueCache));
484     } else {
485         transformVal = WebKitCSSTransformValue::create(WebKitCSSTransformValue::Matrix3DTransformOperation);
486
487         transformVal->append(primitiveValueCache->createValue(transform.m11(), CSSPrimitiveValue::CSS_NUMBER));
488         transformVal->append(primitiveValueCache->createValue(transform.m12(), CSSPrimitiveValue::CSS_NUMBER));
489         transformVal->append(primitiveValueCache->createValue(transform.m13(), CSSPrimitiveValue::CSS_NUMBER));
490         transformVal->append(primitiveValueCache->createValue(transform.m14(), CSSPrimitiveValue::CSS_NUMBER));
491
492         transformVal->append(primitiveValueCache->createValue(transform.m21(), CSSPrimitiveValue::CSS_NUMBER));
493         transformVal->append(primitiveValueCache->createValue(transform.m22(), CSSPrimitiveValue::CSS_NUMBER));
494         transformVal->append(primitiveValueCache->createValue(transform.m23(), CSSPrimitiveValue::CSS_NUMBER));
495         transformVal->append(primitiveValueCache->createValue(transform.m24(), CSSPrimitiveValue::CSS_NUMBER));
496
497         transformVal->append(primitiveValueCache->createValue(transform.m31(), CSSPrimitiveValue::CSS_NUMBER));
498         transformVal->append(primitiveValueCache->createValue(transform.m32(), CSSPrimitiveValue::CSS_NUMBER));
499         transformVal->append(primitiveValueCache->createValue(transform.m33(), CSSPrimitiveValue::CSS_NUMBER));
500         transformVal->append(primitiveValueCache->createValue(transform.m34(), CSSPrimitiveValue::CSS_NUMBER));
501
502         transformVal->append(zoomAdjustedNumberValue(transform.m41(), style, primitiveValueCache));
503         transformVal->append(zoomAdjustedNumberValue(transform.m42(), style, primitiveValueCache));
504         transformVal->append(zoomAdjustedNumberValue(transform.m43(), style, primitiveValueCache));
505         transformVal->append(primitiveValueCache->createValue(transform.m44(), CSSPrimitiveValue::CSS_NUMBER));
506     }
507
508     RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
509     list->append(transformVal);
510
511     return list.release();
512 }
513
514 static PassRefPtr<CSSValue> getDelayValue(const AnimationList* animList, CSSPrimitiveValueCache* primitiveValueCache)
515 {
516     RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
517     if (animList) {
518         for (size_t i = 0; i < animList->size(); ++i)
519             list->append(primitiveValueCache->createValue(animList->animation(i)->delay(), CSSPrimitiveValue::CSS_S));
520     } else {
521         // Note that initialAnimationDelay() is used for both transitions and animations
522         list->append(primitiveValueCache->createValue(Animation::initialAnimationDelay(), CSSPrimitiveValue::CSS_S));
523     }
524     return list.release();
525 }
526
527 static PassRefPtr<CSSValue> getDurationValue(const AnimationList* animList, CSSPrimitiveValueCache* primitiveValueCache)
528 {
529     RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
530     if (animList) {
531         for (size_t i = 0; i < animList->size(); ++i)
532             list->append(primitiveValueCache->createValue(animList->animation(i)->duration(), CSSPrimitiveValue::CSS_S));
533     } else {
534         // Note that initialAnimationDuration() is used for both transitions and animations
535         list->append(primitiveValueCache->createValue(Animation::initialAnimationDuration(), CSSPrimitiveValue::CSS_S));
536     }
537     return list.release();
538 }
539
540 static PassRefPtr<CSSValue> getTimingFunctionValue(const AnimationList* animList)
541 {
542     RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
543     if (animList) {
544         for (size_t i = 0; i < animList->size(); ++i) {
545             const TimingFunction* tf = animList->animation(i)->timingFunction().get();
546             if (tf->isCubicBezierTimingFunction()) {
547                 const CubicBezierTimingFunction* ctf = static_cast<const CubicBezierTimingFunction*>(tf);
548                 list->append(CSSCubicBezierTimingFunctionValue::create(ctf->x1(), ctf->y1(), ctf->x2(), ctf->y2()));
549             } else if (tf->isStepsTimingFunction()) {
550                 const StepsTimingFunction* stf = static_cast<const StepsTimingFunction*>(tf);
551                 list->append(CSSStepsTimingFunctionValue::create(stf->numberOfSteps(), stf->stepAtStart()));
552             } else {
553                 list->append(CSSLinearTimingFunctionValue::create());
554             }
555         }
556     } else {
557         // Note that initialAnimationTimingFunction() is used for both transitions and animations
558         RefPtr<TimingFunction> tf = Animation::initialAnimationTimingFunction();
559         if (tf->isCubicBezierTimingFunction()) {
560             const CubicBezierTimingFunction* ctf = static_cast<const CubicBezierTimingFunction*>(tf.get());
561             list->append(CSSCubicBezierTimingFunctionValue::create(ctf->x1(), ctf->y1(), ctf->x2(), ctf->y2()));
562         } else if (tf->isStepsTimingFunction()) {
563             const StepsTimingFunction* stf = static_cast<const StepsTimingFunction*>(tf.get());
564             list->append(CSSStepsTimingFunctionValue::create(stf->numberOfSteps(), stf->stepAtStart()));
565         } else {
566             list->append(CSSLinearTimingFunctionValue::create());
567         }
568     }
569     return list.release();
570 }
571
572 static PassRefPtr<CSSValue> createLineBoxContainValue(CSSPrimitiveValueCache* primitiveValueCache, unsigned lineBoxContain)
573 {
574     if (!lineBoxContain)
575         return primitiveValueCache->createIdentifierValue(CSSValueNone);
576     return CSSLineBoxContainValue::create(lineBoxContain);
577 }
578
579 CSSComputedStyleDeclaration::CSSComputedStyleDeclaration(PassRefPtr<Node> n, bool allowVisitedStyle, const String& pseudoElementName)
580     : m_node(n)
581     , m_allowVisitedStyle(allowVisitedStyle)
582 {
583     unsigned nameWithoutColonsStart = pseudoElementName[0] == ':' ? (pseudoElementName[1] == ':' ? 2 : 1) : 0;
584     m_pseudoElementSpecifier = CSSSelector::pseudoId(CSSSelector::parsePseudoType(
585         AtomicString(pseudoElementName.substring(nameWithoutColonsStart))));
586 }
587
588 CSSComputedStyleDeclaration::~CSSComputedStyleDeclaration()
589 {
590 }
591
592 String CSSComputedStyleDeclaration::cssText() const
593 {
594     String result("");
595
596     for (unsigned i = 0; i < numComputedProperties; i++) {
597         if (i)
598             result += " ";
599         result += getPropertyName(static_cast<CSSPropertyID>(computedProperties[i]));
600         result += ": ";
601         result += getPropertyValue(computedProperties[i]);
602         result += ";";
603     }
604
605     return result;
606 }
607
608 void CSSComputedStyleDeclaration::setCssText(const String&, ExceptionCode& ec)
609 {
610     ec = NO_MODIFICATION_ALLOWED_ERR;
611 }
612
613 static int cssIdentifierForFontSizeKeyword(int keywordSize)
614 {
615     ASSERT_ARG(keywordSize, keywordSize);
616     ASSERT_ARG(keywordSize, keywordSize <= 8);
617     return CSSValueXxSmall + keywordSize - 1;
618 }
619
620 PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getFontSizeCSSValuePreferringKeyword() const
621 {
622     if (!m_node)
623         return 0;
624
625     m_node->document()->updateLayoutIgnorePendingStylesheets();
626
627     RefPtr<RenderStyle> style = m_node->computedStyle(m_pseudoElementSpecifier);
628     if (!style)
629         return 0;
630     
631     CSSPrimitiveValueCache* primitiveValueCache = m_node->document()->cssPrimitiveValueCache().get();
632
633     if (int keywordSize = style->fontDescription().keywordSize())
634         return primitiveValueCache->createIdentifierValue(cssIdentifierForFontSizeKeyword(keywordSize));
635
636
637     return zoomAdjustedPixelValue(style->fontDescription().computedPixelSize(), style.get(), primitiveValueCache);
638 }
639
640 bool CSSComputedStyleDeclaration::useFixedFontDefaultSize() const
641 {
642     if (!m_node)
643         return false;
644
645     RefPtr<RenderStyle> style = m_node->computedStyle(m_pseudoElementSpecifier);
646     if (!style)
647         return false;
648
649     return style->fontDescription().useFixedDefaultSize();
650 }
651
652 PassRefPtr<CSSValue> CSSComputedStyleDeclaration::valueForShadow(const ShadowData* shadow, int id, RenderStyle* style) const
653 {
654     CSSPrimitiveValueCache* primitiveValueCache = m_node->document()->cssPrimitiveValueCache().get();
655     if (!shadow)
656         return primitiveValueCache->createIdentifierValue(CSSValueNone);
657
658     CSSPropertyID propertyID = static_cast<CSSPropertyID>(id);
659
660     RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
661     for (const ShadowData* s = shadow; s; s = s->next()) {
662         RefPtr<CSSPrimitiveValue> x = zoomAdjustedPixelValue(s->x(), style, primitiveValueCache);
663         RefPtr<CSSPrimitiveValue> y = zoomAdjustedPixelValue(s->y(), style, primitiveValueCache);
664         RefPtr<CSSPrimitiveValue> blur = zoomAdjustedPixelValue(s->blur(), style, primitiveValueCache);
665         RefPtr<CSSPrimitiveValue> spread = propertyID == CSSPropertyTextShadow ? PassRefPtr<CSSPrimitiveValue>() : zoomAdjustedPixelValue(s->spread(), style, primitiveValueCache);
666         RefPtr<CSSPrimitiveValue> style = propertyID == CSSPropertyTextShadow || s->style() == Normal ? PassRefPtr<CSSPrimitiveValue>() : primitiveValueCache->createIdentifierValue(CSSValueInset);
667         RefPtr<CSSPrimitiveValue> color = primitiveValueCache->createColorValue(s->color().rgb());
668         list->prepend(ShadowValue::create(x.release(), y.release(), blur.release(), spread.release(), style.release(), color.release()));
669     }
670     return list.release();
671 }
672
673 PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int propertyID) const
674 {
675     return getPropertyCSSValue(propertyID, UpdateLayout);
676 }
677
678 static int identifierForFamily(const AtomicString& family)
679 {
680     DEFINE_STATIC_LOCAL(AtomicString, cursiveFamily, ("-webkit-cursive")); 
681     DEFINE_STATIC_LOCAL(AtomicString, fantasyFamily, ("-webkit-fantasy")); 
682     DEFINE_STATIC_LOCAL(AtomicString, monospaceFamily, ("-webkit-monospace")); 
683     DEFINE_STATIC_LOCAL(AtomicString, sansSerifFamily, ("-webkit-sans-serif")); 
684     DEFINE_STATIC_LOCAL(AtomicString, serifFamily, ("-webkit-serif")); 
685     if (family == cursiveFamily)
686         return CSSValueCursive;
687     if (family == fantasyFamily)
688         return CSSValueFantasy;
689     if (family == monospaceFamily)
690         return CSSValueMonospace;
691     if (family == sansSerifFamily)
692         return CSSValueSansSerif;
693     if (family == serifFamily)
694         return CSSValueSerif;
695     return 0;
696 }
697
698 static PassRefPtr<CSSPrimitiveValue> valueForFamily(const AtomicString& family, CSSPrimitiveValueCache* primitiveValueCache)
699 {
700     if (int familyIdentifier = identifierForFamily(family))
701         return primitiveValueCache->createIdentifierValue(familyIdentifier);
702     return primitiveValueCache->createValue(family.string(), CSSPrimitiveValue::CSS_STRING);
703 }
704
705 static PassRefPtr<CSSValue> renderTextDecorationFlagsToCSSValue(int textDecoration, CSSPrimitiveValueCache* primitiveValueCache)
706 {
707     RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
708     if (textDecoration & UNDERLINE)
709         list->append(primitiveValueCache->createIdentifierValue(CSSValueUnderline));
710     if (textDecoration & OVERLINE)
711         list->append(primitiveValueCache->createIdentifierValue(CSSValueOverline));
712     if (textDecoration & LINE_THROUGH)
713         list->append(primitiveValueCache->createIdentifierValue(CSSValueLineThrough));
714     if (textDecoration & BLINK)
715         list->append(primitiveValueCache->createIdentifierValue(CSSValueBlink));
716
717     if (!list->length())
718         return primitiveValueCache->createIdentifierValue(CSSValueNone);
719     return list;
720 }
721
722 static PassRefPtr<CSSValue> fillRepeatToCSSValue(EFillRepeat xRepeat, EFillRepeat yRepeat, CSSPrimitiveValueCache* primitiveValueCache)
723 {
724     // For backwards compatibility, if both values are equal, just return one of them. And
725     // if the two values are equivalent to repeat-x or repeat-y, just return the shorthand.
726     if (xRepeat == yRepeat)
727         return primitiveValueCache->createValue(xRepeat);
728     if (xRepeat == RepeatFill && yRepeat == NoRepeatFill)
729         return primitiveValueCache->createIdentifierValue(CSSValueRepeatX);
730     if (xRepeat == NoRepeatFill && yRepeat == RepeatFill)
731         return primitiveValueCache->createIdentifierValue(CSSValueRepeatY);
732
733     RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
734     list->append(primitiveValueCache->createValue(xRepeat));
735     list->append(primitiveValueCache->createValue(yRepeat));
736     return list.release();
737 }
738
739 static PassRefPtr<CSSValue> fillSizeToCSSValue(const FillSize& fillSize, CSSPrimitiveValueCache* primitiveValueCache)
740 {
741     if (fillSize.type == Contain)
742         return primitiveValueCache->createIdentifierValue(CSSValueContain);
743
744     if (fillSize.type == Cover)
745         return primitiveValueCache->createIdentifierValue(CSSValueCover);
746
747     RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
748     list->append(primitiveValueCache->createValue(fillSize.size.width()));
749     list->append(primitiveValueCache->createValue(fillSize.size.height()));
750     return list.release();
751 }
752
753 static PassRefPtr<CSSValue> contentToCSSValue(const RenderStyle* style, CSSPrimitiveValueCache* primitiveValueCache)
754 {
755     RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
756     for (const ContentData* contentData = style->contentData(); contentData; contentData = contentData->next()) {
757         if (contentData->isCounter()) {
758             const CounterContent* counter = contentData->counter();
759             ASSERT(counter);
760             list->append(primitiveValueCache->createValue(counter->identifier(), CSSPrimitiveValue::CSS_COUNTER_NAME));
761         } else if (contentData->isImage()) {
762             const StyleImage* image = contentData->image();
763             ASSERT(image);
764             list->append(image->cssValue());
765         } else if (contentData->isText())
766             list->append(primitiveValueCache->createValue(contentData->text(), CSSPrimitiveValue::CSS_STRING));
767     }
768     return list.release();
769 }
770
771 static PassRefPtr<CSSValue> counterToCSSValue(const RenderStyle* style, int propertyID, CSSPrimitiveValueCache* primitiveValueCache)
772 {
773     const CounterDirectiveMap* map = style->counterDirectives();
774     if (!map)
775         return 0;
776
777     RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
778     for (CounterDirectiveMap::const_iterator it = map->begin(); it != map->end(); ++it) {
779         list->append(primitiveValueCache->createValue(it->first.get(), CSSPrimitiveValue::CSS_STRING));
780         short number = propertyID == CSSPropertyCounterIncrement ? it->second.m_incrementValue : it->second.m_resetValue;
781         list->append(primitiveValueCache->createValue((double)number, CSSPrimitiveValue::CSS_NUMBER));
782     }
783     return list.release();
784 }
785
786 static void logUnimplementedPropertyID(int propertyID)
787 {
788     DEFINE_STATIC_LOCAL(HashSet<int>, propertyIDSet, ());
789     if (!propertyIDSet.add(propertyID).second)
790         return;
791
792     LOG_ERROR("WebKit does not yet implement getComputedStyle for '%s'.", getPropertyName(static_cast<CSSPropertyID>(propertyID)));
793
794
795 PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int propertyID, EUpdateLayout updateLayout) const
796 {
797     Node* node = m_node.get();
798     if (!node)
799         return 0;
800
801     // Make sure our layout is up to date before we allow a query on these attributes.
802     if (updateLayout)
803         node->document()->updateLayoutIgnorePendingStylesheets();
804
805     RenderObject* renderer = node->renderer();
806
807     RefPtr<RenderStyle> style;
808     if (renderer && hasCompositedLayer(renderer) && AnimationController::supportsAcceleratedAnimationOfProperty(static_cast<CSSPropertyID>(propertyID))) {
809         style = renderer->animation()->getAnimatedStyleForRenderer(renderer);
810         if (m_pseudoElementSpecifier) {
811             // FIXME: This cached pseudo style will only exist if the animation has been run at least once.
812             style = style->getCachedPseudoStyle(m_pseudoElementSpecifier);
813         }
814     } else
815         style = node->computedStyle(m_pseudoElementSpecifier);
816
817     if (!style)
818         return 0;
819     
820     CSSPrimitiveValueCache* primitiveValueCache = node->document()->cssPrimitiveValueCache().get();
821
822     propertyID = CSSProperty::resolveDirectionAwareProperty(propertyID, style->direction(), style->writingMode());
823
824     switch (static_cast<CSSPropertyID>(propertyID)) {
825         case CSSPropertyInvalid:
826             break;
827
828         case CSSPropertyBackgroundColor:
829             return primitiveValueCache->createColorValue(m_allowVisitedStyle? style->visitedDependentColor(CSSPropertyBackgroundColor).rgb() : style->backgroundColor().rgb());
830         case CSSPropertyBackgroundImage:
831         case CSSPropertyWebkitMaskImage: {
832             const FillLayer* layers = propertyID == CSSPropertyWebkitMaskImage ? style->maskLayers() : style->backgroundLayers();
833             if (!layers)
834                 return primitiveValueCache->createIdentifierValue(CSSValueNone);
835
836             if (!layers->next()) {
837                 if (layers->image())
838                     return layers->image()->cssValue();
839
840                 return primitiveValueCache->createIdentifierValue(CSSValueNone);
841             }
842
843             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
844             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) {
845                 if (currLayer->image())
846                     list->append(currLayer->image()->cssValue());
847                 else
848                     list->append(primitiveValueCache->createIdentifierValue(CSSValueNone));
849             }
850             return list.release();
851         }
852         case CSSPropertyBackgroundSize:
853         case CSSPropertyWebkitBackgroundSize:
854         case CSSPropertyWebkitMaskSize: {
855             const FillLayer* layers = propertyID == CSSPropertyWebkitMaskSize ? style->maskLayers() : style->backgroundLayers();
856             if (!layers->next())
857                 return fillSizeToCSSValue(layers->size(), primitiveValueCache);
858
859             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
860             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
861                 list->append(fillSizeToCSSValue(currLayer->size(), primitiveValueCache));
862
863             return list.release();
864         }
865         case CSSPropertyBackgroundRepeat:
866         case CSSPropertyWebkitMaskRepeat: {
867             const FillLayer* layers = propertyID == CSSPropertyWebkitMaskRepeat ? style->maskLayers() : style->backgroundLayers();
868             if (!layers->next())
869                 return fillRepeatToCSSValue(layers->repeatX(), layers->repeatY(), primitiveValueCache);
870
871             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
872             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
873                 list->append(fillRepeatToCSSValue(currLayer->repeatX(), currLayer->repeatY(), primitiveValueCache));
874
875             return list.release();
876         }
877         case CSSPropertyWebkitBackgroundComposite:
878         case CSSPropertyWebkitMaskComposite: {
879             const FillLayer* layers = propertyID == CSSPropertyWebkitMaskComposite ? style->maskLayers() : style->backgroundLayers();
880             if (!layers->next())
881                 return primitiveValueCache->createValue(layers->composite());
882
883             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
884             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
885                 list->append(primitiveValueCache->createValue(currLayer->composite()));
886
887             return list.release();
888         }
889         case CSSPropertyBackgroundAttachment:
890         case CSSPropertyWebkitMaskAttachment: {
891             const FillLayer* layers = propertyID == CSSPropertyWebkitMaskAttachment ? style->maskLayers() : style->backgroundLayers();
892             if (!layers->next())
893                 return primitiveValueCache->createValue(layers->attachment());
894
895             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
896             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
897                 list->append(primitiveValueCache->createValue(currLayer->attachment()));
898
899             return list.release();
900         }
901         case CSSPropertyBackgroundClip:
902         case CSSPropertyBackgroundOrigin:
903         case CSSPropertyWebkitBackgroundClip:
904         case CSSPropertyWebkitBackgroundOrigin:
905         case CSSPropertyWebkitMaskClip:
906         case CSSPropertyWebkitMaskOrigin: {
907             const FillLayer* layers = (propertyID == CSSPropertyWebkitMaskClip || propertyID == CSSPropertyWebkitMaskOrigin) ? style->maskLayers() : style->backgroundLayers();
908             bool isClip = propertyID == CSSPropertyBackgroundClip || propertyID == CSSPropertyWebkitBackgroundClip || propertyID == CSSPropertyWebkitMaskClip;
909             if (!layers->next()) {
910                 EFillBox box = isClip ? layers->clip() : layers->origin();
911                 return primitiveValueCache->createValue(box);
912             }
913             
914             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
915             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) {
916                 EFillBox box = isClip ? currLayer->clip() : currLayer->origin();
917                 list->append(primitiveValueCache->createValue(box));
918             }
919
920             return list.release();
921         }
922         case CSSPropertyBackgroundPosition:
923         case CSSPropertyWebkitMaskPosition: {
924             const FillLayer* layers = propertyID == CSSPropertyWebkitMaskPosition ? style->maskLayers() : style->backgroundLayers();
925             if (!layers->next()) {
926                 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
927                 list->append(primitiveValueCache->createValue(layers->xPosition()));
928                 list->append(primitiveValueCache->createValue(layers->yPosition()));
929                 return list.release();
930             }
931
932             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
933             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) {
934                 RefPtr<CSSValueList> positionList = CSSValueList::createSpaceSeparated();
935                 positionList->append(primitiveValueCache->createValue(currLayer->xPosition()));
936                 positionList->append(primitiveValueCache->createValue(currLayer->yPosition()));
937                 list->append(positionList);
938             }
939
940             return list.release();
941         }
942         case CSSPropertyBackgroundPositionX:
943         case CSSPropertyWebkitMaskPositionX: {
944             const FillLayer* layers = propertyID == CSSPropertyWebkitMaskPositionX ? style->maskLayers() : style->backgroundLayers();
945             if (!layers->next())
946                 return primitiveValueCache->createValue(layers->xPosition());
947
948             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
949             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
950                 list->append(primitiveValueCache->createValue(currLayer->xPosition()));
951
952             return list.release();
953         }
954         case CSSPropertyBackgroundPositionY:
955         case CSSPropertyWebkitMaskPositionY: {
956             const FillLayer* layers = propertyID == CSSPropertyWebkitMaskPositionY ? style->maskLayers() : style->backgroundLayers();
957             if (!layers->next())
958                 return primitiveValueCache->createValue(layers->yPosition());
959
960             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
961             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
962                 list->append(primitiveValueCache->createValue(currLayer->yPosition()));
963
964             return list.release();
965         }
966         case CSSPropertyBorderCollapse:
967             if (style->borderCollapse())
968                 return primitiveValueCache->createIdentifierValue(CSSValueCollapse);
969             return primitiveValueCache->createIdentifierValue(CSSValueSeparate);
970         case CSSPropertyBorderSpacing: {
971             RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
972             list->append(zoomAdjustedPixelValue(style->horizontalBorderSpacing(), style.get(), primitiveValueCache));
973             list->append(zoomAdjustedPixelValue(style->verticalBorderSpacing(), style.get(), primitiveValueCache));
974             return list.release();
975         }  
976         case CSSPropertyWebkitBorderHorizontalSpacing:
977             return zoomAdjustedPixelValue(style->horizontalBorderSpacing(), style.get(), primitiveValueCache);
978         case CSSPropertyWebkitBorderVerticalSpacing:
979             return zoomAdjustedPixelValue(style->verticalBorderSpacing(), style.get(), primitiveValueCache);
980         case CSSPropertyBorderTopColor:
981             return m_allowVisitedStyle ? primitiveValueCache->createColorValue(style->visitedDependentColor(CSSPropertyBorderTopColor).rgb()) : currentColorOrValidColor(style.get(), style->borderTopColor());
982         case CSSPropertyBorderRightColor:
983             return m_allowVisitedStyle ? primitiveValueCache->createColorValue(style->visitedDependentColor(CSSPropertyBorderRightColor).rgb()) : currentColorOrValidColor(style.get(), style->borderRightColor());
984         case CSSPropertyBorderBottomColor:
985             return m_allowVisitedStyle ? primitiveValueCache->createColorValue(style->visitedDependentColor(CSSPropertyBorderBottomColor).rgb()) : currentColorOrValidColor(style.get(), style->borderBottomColor());
986         case CSSPropertyBorderLeftColor:
987             return m_allowVisitedStyle ? primitiveValueCache->createColorValue(style->visitedDependentColor(CSSPropertyBorderLeftColor).rgb()) : currentColorOrValidColor(style.get(), style->borderLeftColor());
988         case CSSPropertyBorderTopStyle:
989             return primitiveValueCache->createValue(style->borderTopStyle());
990         case CSSPropertyBorderRightStyle:
991             return primitiveValueCache->createValue(style->borderRightStyle());
992         case CSSPropertyBorderBottomStyle:
993             return primitiveValueCache->createValue(style->borderBottomStyle());
994         case CSSPropertyBorderLeftStyle:
995             return primitiveValueCache->createValue(style->borderLeftStyle());
996         case CSSPropertyBorderTopWidth:
997             return zoomAdjustedPixelValue(style->borderTopWidth(), style.get(), primitiveValueCache);
998         case CSSPropertyBorderRightWidth:
999             return zoomAdjustedPixelValue(style->borderRightWidth(), style.get(), primitiveValueCache);
1000         case CSSPropertyBorderBottomWidth:
1001             return zoomAdjustedPixelValue(style->borderBottomWidth(), style.get(), primitiveValueCache);
1002         case CSSPropertyBorderLeftWidth:
1003             return zoomAdjustedPixelValue(style->borderLeftWidth(), style.get(), primitiveValueCache);
1004         case CSSPropertyBottom:
1005             return getPositionOffsetValue(style.get(), CSSPropertyBottom, primitiveValueCache);
1006         case CSSPropertyWebkitBoxAlign:
1007             return primitiveValueCache->createValue(style->boxAlign());
1008         case CSSPropertyWebkitBoxDirection:
1009             return primitiveValueCache->createValue(style->boxDirection());
1010         case CSSPropertyWebkitBoxFlex:
1011             return primitiveValueCache->createValue(style->boxFlex(), CSSPrimitiveValue::CSS_NUMBER);
1012         case CSSPropertyWebkitBoxFlexGroup:
1013             return primitiveValueCache->createValue(style->boxFlexGroup(), CSSPrimitiveValue::CSS_NUMBER);
1014         case CSSPropertyWebkitBoxLines:
1015             return primitiveValueCache->createValue(style->boxLines());
1016         case CSSPropertyWebkitBoxOrdinalGroup:
1017             return primitiveValueCache->createValue(style->boxOrdinalGroup(), CSSPrimitiveValue::CSS_NUMBER);
1018         case CSSPropertyWebkitBoxOrient:
1019             return primitiveValueCache->createValue(style->boxOrient());
1020         case CSSPropertyWebkitBoxPack: {
1021             EBoxAlignment boxPack = style->boxPack();
1022             ASSERT(boxPack != BSTRETCH);
1023             ASSERT(boxPack != BBASELINE);
1024             if (boxPack == BJUSTIFY || boxPack== BBASELINE)
1025                 return 0;
1026             return primitiveValueCache->createValue(boxPack);
1027         }
1028         case CSSPropertyWebkitBoxReflect:
1029             return valueForReflection(style->boxReflect(), style.get(), primitiveValueCache);
1030         case CSSPropertyBoxShadow:
1031         case CSSPropertyWebkitBoxShadow:
1032             return valueForShadow(style->boxShadow(), propertyID, style.get());
1033         case CSSPropertyCaptionSide:
1034             return primitiveValueCache->createValue(style->captionSide());
1035         case CSSPropertyClear:
1036             return primitiveValueCache->createValue(style->clear());
1037         case CSSPropertyColor:
1038             return primitiveValueCache->createColorValue(m_allowVisitedStyle ? style->visitedDependentColor(CSSPropertyColor).rgb() : style->color().rgb());
1039         case CSSPropertyWebkitColumnCount:
1040             if (style->hasAutoColumnCount())
1041                 return primitiveValueCache->createIdentifierValue(CSSValueAuto);
1042             return primitiveValueCache->createValue(style->columnCount(), CSSPrimitiveValue::CSS_NUMBER);
1043         case CSSPropertyWebkitColumnGap:
1044             if (style->hasNormalColumnGap())
1045                 return primitiveValueCache->createIdentifierValue(CSSValueNormal);
1046             return zoomAdjustedPixelValue(style->columnGap(), style.get(), primitiveValueCache);
1047         case CSSPropertyWebkitColumnRuleColor:
1048             return m_allowVisitedStyle ? primitiveValueCache->createColorValue(style->visitedDependentColor(CSSPropertyOutlineColor).rgb()) : currentColorOrValidColor(style.get(), style->columnRuleColor());
1049         case CSSPropertyWebkitColumnRuleStyle:
1050             return primitiveValueCache->createValue(style->columnRuleStyle());
1051         case CSSPropertyWebkitColumnRuleWidth:
1052             return zoomAdjustedPixelValue(style->columnRuleWidth(), style.get(), primitiveValueCache);
1053         case CSSPropertyWebkitColumnSpan:
1054             if (style->columnSpan())
1055                 return primitiveValueCache->createIdentifierValue(CSSValueAll);
1056             return primitiveValueCache->createValue(1, CSSPrimitiveValue::CSS_NUMBER);
1057         case CSSPropertyWebkitColumnBreakAfter:
1058             return primitiveValueCache->createValue(style->columnBreakAfter());
1059         case CSSPropertyWebkitColumnBreakBefore:
1060             return primitiveValueCache->createValue(style->columnBreakBefore());
1061         case CSSPropertyWebkitColumnBreakInside:
1062             return primitiveValueCache->createValue(style->columnBreakInside());
1063         case CSSPropertyWebkitColumnWidth:
1064             if (style->hasAutoColumnWidth())
1065                 return primitiveValueCache->createIdentifierValue(CSSValueAuto);
1066             return zoomAdjustedPixelValue(style->columnWidth(), style.get(), primitiveValueCache);
1067         case CSSPropertyCursor: {
1068             RefPtr<CSSValueList> list;
1069             CursorList* cursors = style->cursors();
1070             if (cursors && cursors->size() > 0) {
1071                 list = CSSValueList::createCommaSeparated();
1072                 for (unsigned i = 0; i < cursors->size(); ++i)
1073                     if (StyleImage* image = cursors->at(i).image())
1074                         list->append(image->cssValue());
1075             }
1076             RefPtr<CSSValue> value = primitiveValueCache->createValue(style->cursor());
1077             if (list) {
1078                 list->append(value);
1079                 return list.release();
1080             }
1081             return value.release();
1082         }
1083         case CSSPropertyDirection:
1084             return primitiveValueCache->createValue(style->direction());
1085         case CSSPropertyDisplay:
1086             return primitiveValueCache->createValue(style->display());
1087         case CSSPropertyEmptyCells:
1088             return primitiveValueCache->createValue(style->emptyCells());
1089         case CSSPropertyFloat:
1090             return primitiveValueCache->createValue(style->floating());
1091         case CSSPropertyFontFamily: {
1092             const FontFamily& firstFamily = style->fontDescription().family();
1093             if (!firstFamily.next())
1094                 return valueForFamily(firstFamily.family(), primitiveValueCache);
1095             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1096             for (const FontFamily* family = &firstFamily; family; family = family->next())
1097                 list->append(valueForFamily(family->family(), primitiveValueCache));
1098             return list.release();
1099         }
1100         case CSSPropertyFontSize:
1101             return zoomAdjustedPixelValue(style->fontDescription().computedPixelSize(), style.get(), primitiveValueCache);
1102         case CSSPropertyFontStyle:
1103             if (style->fontDescription().italic())
1104                 return primitiveValueCache->createIdentifierValue(CSSValueItalic);
1105             return primitiveValueCache->createIdentifierValue(CSSValueNormal);
1106         case CSSPropertyFontVariant:
1107             if (style->fontDescription().smallCaps())
1108                 return primitiveValueCache->createIdentifierValue(CSSValueSmallCaps);
1109             return primitiveValueCache->createIdentifierValue(CSSValueNormal);
1110         case CSSPropertyFontWeight:
1111             switch (style->fontDescription().weight()) {
1112                 case FontWeight100:
1113                     return primitiveValueCache->createIdentifierValue(CSSValue100);
1114                 case FontWeight200:
1115                     return primitiveValueCache->createIdentifierValue(CSSValue200);
1116                 case FontWeight300:
1117                     return primitiveValueCache->createIdentifierValue(CSSValue300);
1118                 case FontWeightNormal:
1119                     return primitiveValueCache->createIdentifierValue(CSSValueNormal);
1120                 case FontWeight500:
1121                     return primitiveValueCache->createIdentifierValue(CSSValue500);
1122                 case FontWeight600:
1123                     return primitiveValueCache->createIdentifierValue(CSSValue600);
1124                 case FontWeightBold:
1125                     return primitiveValueCache->createIdentifierValue(CSSValueBold);
1126                 case FontWeight800:
1127                     return primitiveValueCache->createIdentifierValue(CSSValue800);
1128                 case FontWeight900:
1129                     return primitiveValueCache->createIdentifierValue(CSSValue900);
1130             }
1131             ASSERT_NOT_REACHED();
1132             return primitiveValueCache->createIdentifierValue(CSSValueNormal);
1133         case CSSPropertyHeight:
1134             if (renderer)
1135                 return zoomAdjustedPixelValue(sizingBox(renderer).height(), style.get(), primitiveValueCache);
1136             return zoomAdjustedPixelValueForLength(style->height(), style.get(), primitiveValueCache);
1137         case CSSPropertyWebkitHighlight:
1138             if (style->highlight() == nullAtom)
1139                 return primitiveValueCache->createIdentifierValue(CSSValueNone);
1140             return primitiveValueCache->createValue(style->highlight(), CSSPrimitiveValue::CSS_STRING);
1141         case CSSPropertyWebkitHyphens:
1142             return primitiveValueCache->createValue(style->hyphens());
1143         case CSSPropertyWebkitHyphenateCharacter:
1144             if (style->hyphenationString().isNull())
1145                 return primitiveValueCache->createIdentifierValue(CSSValueAuto);
1146             return primitiveValueCache->createValue(style->hyphenationString(), CSSPrimitiveValue::CSS_STRING);
1147         case CSSPropertyWebkitHyphenateLimitAfter:
1148             if (style->hyphenationLimitAfter() < 0)
1149                 return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
1150             return CSSPrimitiveValue::create(style->hyphenationLimitAfter(), CSSPrimitiveValue::CSS_NUMBER);
1151         case CSSPropertyWebkitHyphenateLimitBefore:
1152             if (style->hyphenationLimitBefore() < 0)
1153                 return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
1154             return CSSPrimitiveValue::create(style->hyphenationLimitBefore(), CSSPrimitiveValue::CSS_NUMBER);
1155         case CSSPropertyWebkitBorderFit:
1156             if (style->borderFit() == BorderFitBorder)
1157                 return primitiveValueCache->createIdentifierValue(CSSValueBorder);
1158             return primitiveValueCache->createIdentifierValue(CSSValueLines);
1159         case CSSPropertyImageRendering:
1160             return CSSPrimitiveValue::create(style->imageRendering());
1161         case CSSPropertyLeft:
1162             return getPositionOffsetValue(style.get(), CSSPropertyLeft, primitiveValueCache);
1163         case CSSPropertyLetterSpacing:
1164             if (!style->letterSpacing())
1165                 return primitiveValueCache->createIdentifierValue(CSSValueNormal);
1166             return zoomAdjustedPixelValue(style->letterSpacing(), style.get(), primitiveValueCache);
1167         case CSSPropertyWebkitLineClamp:
1168             if (style->lineClamp().isNone())
1169                 return primitiveValueCache->createIdentifierValue(CSSValueNone);
1170             return primitiveValueCache->createValue(style->lineClamp().value(), style->lineClamp().isPercentage() ? CSSPrimitiveValue::CSS_PERCENTAGE : CSSPrimitiveValue::CSS_NUMBER);
1171         case CSSPropertyLineHeight: {
1172             Length length = style->lineHeight();
1173             if (length.isNegative())
1174                 return primitiveValueCache->createIdentifierValue(CSSValueNormal);
1175             if (length.isPercent())
1176                 // This is imperfect, because it doesn't include the zoom factor and the real computation
1177                 // for how high to be in pixels does include things like minimum font size and the zoom factor.
1178                 // On the other hand, since font-size doesn't include the zoom factor, we really can't do
1179                 // that here either.
1180                 return zoomAdjustedPixelValue(static_cast<int>(length.percent() * style->fontDescription().specifiedSize()) / 100, style.get(), primitiveValueCache);
1181             return zoomAdjustedPixelValue(length.value(), style.get(), primitiveValueCache);
1182         }
1183         case CSSPropertyListStyleImage:
1184             if (style->listStyleImage())
1185                 return style->listStyleImage()->cssValue();
1186             return primitiveValueCache->createIdentifierValue(CSSValueNone);
1187         case CSSPropertyListStylePosition:
1188             return primitiveValueCache->createValue(style->listStylePosition());
1189         case CSSPropertyListStyleType:
1190             return primitiveValueCache->createValue(style->listStyleType());
1191         case CSSPropertyWebkitLocale:
1192             if (style->locale().isNull())
1193                 return primitiveValueCache->createIdentifierValue(CSSValueAuto);
1194             return primitiveValueCache->createValue(style->locale(), CSSPrimitiveValue::CSS_STRING);
1195         case CSSPropertyMarginTop: {
1196             Length marginTop = style->marginTop();
1197             if (marginTop.isPercent())
1198                 return primitiveValueCache->createValue(marginTop);
1199             return zoomAdjustedPixelValue(marginTop.value(), style.get(), primitiveValueCache);
1200         }
1201         case CSSPropertyMarginRight: {
1202             Length marginRight = style->marginRight();
1203             if (marginRight.isPercent())
1204                 return primitiveValueCache->createValue(marginRight);
1205             return zoomAdjustedPixelValue(marginRight.value(), style.get(), primitiveValueCache);
1206         }
1207         case CSSPropertyMarginBottom: {
1208             Length marginBottom = style->marginBottom();
1209             if (marginBottom.isPercent())
1210                 return primitiveValueCache->createValue(marginBottom);
1211             return zoomAdjustedPixelValue(marginBottom.value(), style.get(), primitiveValueCache);
1212         }
1213         case CSSPropertyMarginLeft: {
1214             Length marginLeft = style->marginLeft();
1215             if (marginLeft.isPercent())
1216                 return primitiveValueCache->createValue(marginLeft);
1217             return zoomAdjustedPixelValue(marginLeft.value(), style.get(), primitiveValueCache);
1218         }
1219         case CSSPropertyWebkitMarqueeDirection:
1220             return primitiveValueCache->createValue(style->marqueeDirection());
1221         case CSSPropertyWebkitMarqueeIncrement:
1222             return primitiveValueCache->createValue(style->marqueeIncrement());
1223         case CSSPropertyWebkitMarqueeRepetition:
1224             if (style->marqueeLoopCount() < 0)
1225                 return primitiveValueCache->createIdentifierValue(CSSValueInfinite);
1226             return primitiveValueCache->createValue(style->marqueeLoopCount(), CSSPrimitiveValue::CSS_NUMBER);
1227         case CSSPropertyWebkitMarqueeStyle:
1228             return primitiveValueCache->createValue(style->marqueeBehavior());
1229         case CSSPropertyWebkitUserModify:
1230             return primitiveValueCache->createValue(style->userModify());
1231         case CSSPropertyMaxHeight: {
1232             const Length& maxHeight = style->maxHeight();
1233             if (maxHeight.isFixed() && maxHeight.value() == undefinedLength)
1234                 return primitiveValueCache->createIdentifierValue(CSSValueNone);
1235             return primitiveValueCache->createValue(maxHeight);
1236         }
1237         case CSSPropertyMaxWidth: {
1238             const Length& maxWidth = style->maxWidth();
1239             if (maxWidth.isFixed() && maxWidth.value() == undefinedLength)
1240                 return primitiveValueCache->createIdentifierValue(CSSValueNone);
1241             return primitiveValueCache->createValue(maxWidth);
1242         }
1243         case CSSPropertyMinHeight:
1244             return primitiveValueCache->createValue(style->minHeight());
1245         case CSSPropertyMinWidth:
1246             return primitiveValueCache->createValue(style->minWidth());
1247         case CSSPropertyOpacity:
1248             return primitiveValueCache->createValue(style->opacity(), CSSPrimitiveValue::CSS_NUMBER);
1249         case CSSPropertyOrphans:
1250             return primitiveValueCache->createValue(style->orphans(), CSSPrimitiveValue::CSS_NUMBER);
1251         case CSSPropertyOutlineColor:
1252             return m_allowVisitedStyle ? primitiveValueCache->createColorValue(style->visitedDependentColor(CSSPropertyOutlineColor).rgb()) : currentColorOrValidColor(style.get(), style->outlineColor());
1253         case CSSPropertyOutlineOffset:
1254             return zoomAdjustedPixelValue(style->outlineOffset(), style.get(), primitiveValueCache);
1255         case CSSPropertyOutlineStyle:
1256             if (style->outlineStyleIsAuto())
1257                 return primitiveValueCache->createIdentifierValue(CSSValueAuto);
1258             return primitiveValueCache->createValue(style->outlineStyle());
1259         case CSSPropertyOutlineWidth:
1260             return zoomAdjustedPixelValue(style->outlineWidth(), style.get(), primitiveValueCache);
1261         case CSSPropertyOverflow:
1262             return primitiveValueCache->createValue(max(style->overflowX(), style->overflowY()));
1263         case CSSPropertyOverflowX:
1264             return primitiveValueCache->createValue(style->overflowX());
1265         case CSSPropertyOverflowY:
1266             return primitiveValueCache->createValue(style->overflowY());
1267         case CSSPropertyPaddingTop:
1268             if (renderer && renderer->isBox())
1269                 return zoomAdjustedPixelValue(toRenderBox(renderer)->paddingTop(false), style.get(), primitiveValueCache);
1270             return primitiveValueCache->createValue(style->paddingTop());
1271         case CSSPropertyPaddingRight:
1272             if (renderer && renderer->isBox())
1273                 return zoomAdjustedPixelValue(toRenderBox(renderer)->paddingRight(false), style.get(), primitiveValueCache);
1274             return primitiveValueCache->createValue(style->paddingRight());
1275         case CSSPropertyPaddingBottom:
1276             if (renderer && renderer->isBox())
1277                 return zoomAdjustedPixelValue(toRenderBox(renderer)->paddingBottom(false), style.get(), primitiveValueCache);
1278             return primitiveValueCache->createValue(style->paddingBottom());
1279         case CSSPropertyPaddingLeft:
1280             if (renderer && renderer->isBox())
1281                 return zoomAdjustedPixelValue(toRenderBox(renderer)->paddingLeft(false), style.get(), primitiveValueCache);
1282             return primitiveValueCache->createValue(style->paddingLeft());
1283         case CSSPropertyPageBreakAfter:
1284             return primitiveValueCache->createValue(style->pageBreakAfter());
1285         case CSSPropertyPageBreakBefore:
1286             return primitiveValueCache->createValue(style->pageBreakBefore());
1287         case CSSPropertyPageBreakInside: {
1288             EPageBreak pageBreak = style->pageBreakInside();
1289             ASSERT(pageBreak != PBALWAYS);
1290             if (pageBreak == PBALWAYS)
1291                 return 0;
1292             return primitiveValueCache->createValue(style->pageBreakInside());
1293         }
1294         case CSSPropertyPosition:
1295             return primitiveValueCache->createValue(style->position());
1296         case CSSPropertyRight:
1297             return getPositionOffsetValue(style.get(), CSSPropertyRight, primitiveValueCache);
1298         case CSSPropertyTableLayout:
1299             return primitiveValueCache->createValue(style->tableLayout());
1300         case CSSPropertyTextAlign:
1301             return primitiveValueCache->createValue(style->textAlign());
1302         case CSSPropertyTextDecoration:
1303             return renderTextDecorationFlagsToCSSValue(style->textDecoration(), primitiveValueCache);
1304         case CSSPropertyWebkitTextDecorationsInEffect:
1305             return renderTextDecorationFlagsToCSSValue(style->textDecorationsInEffect(), primitiveValueCache);
1306         case CSSPropertyWebkitTextFillColor:
1307             return currentColorOrValidColor(style.get(), style->textFillColor());
1308         case CSSPropertyWebkitTextEmphasisColor:
1309             return currentColorOrValidColor(style.get(), style->textEmphasisColor());
1310         case CSSPropertyWebkitTextEmphasisPosition:
1311             return primitiveValueCache->createValue(style->textEmphasisPosition());
1312         case CSSPropertyWebkitTextEmphasisStyle:
1313             switch (style->textEmphasisMark()) {
1314             case TextEmphasisMarkNone:
1315                 return primitiveValueCache->createIdentifierValue(CSSValueNone);
1316             case TextEmphasisMarkCustom:
1317                 return primitiveValueCache->createValue(style->textEmphasisCustomMark(), CSSPrimitiveValue::CSS_STRING);
1318             case TextEmphasisMarkAuto:
1319                 ASSERT_NOT_REACHED();
1320                 // Fall through
1321             case TextEmphasisMarkDot:
1322             case TextEmphasisMarkCircle:
1323             case TextEmphasisMarkDoubleCircle:
1324             case TextEmphasisMarkTriangle:
1325             case TextEmphasisMarkSesame: {
1326                 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
1327                 list->append(primitiveValueCache->createValue(style->textEmphasisFill()));
1328                 list->append(primitiveValueCache->createValue(style->textEmphasisMark()));
1329                 return list.release();
1330             }
1331             }
1332         case CSSPropertyTextIndent:
1333             return primitiveValueCache->createValue(style->textIndent());
1334         case CSSPropertyTextShadow:
1335             return valueForShadow(style->textShadow(), propertyID, style.get());
1336         case CSSPropertyTextRendering:
1337             return primitiveValueCache->createValue(style->fontDescription().textRenderingMode());
1338         case CSSPropertyTextOverflow:
1339             if (style->textOverflow())
1340                 return primitiveValueCache->createIdentifierValue(CSSValueEllipsis);
1341             return primitiveValueCache->createIdentifierValue(CSSValueClip);
1342         case CSSPropertyWebkitTextSecurity:
1343             return primitiveValueCache->createValue(style->textSecurity());
1344         case CSSPropertyWebkitTextSizeAdjust:
1345             if (style->textSizeAdjust())
1346                 return primitiveValueCache->createIdentifierValue(CSSValueAuto);
1347             return primitiveValueCache->createIdentifierValue(CSSValueNone);
1348         case CSSPropertyWebkitTextStrokeColor:
1349             return currentColorOrValidColor(style.get(), style->textStrokeColor());
1350         case CSSPropertyWebkitTextStrokeWidth:
1351             return zoomAdjustedPixelValue(style->textStrokeWidth(), style.get(), primitiveValueCache);
1352         case CSSPropertyTextTransform:
1353             return primitiveValueCache->createValue(style->textTransform());
1354         case CSSPropertyTop:
1355             return getPositionOffsetValue(style.get(), CSSPropertyTop, primitiveValueCache);
1356         case CSSPropertyUnicodeBidi:
1357             return primitiveValueCache->createValue(style->unicodeBidi());
1358         case CSSPropertyVerticalAlign:
1359             switch (style->verticalAlign()) {
1360                 case BASELINE:
1361                     return primitiveValueCache->createIdentifierValue(CSSValueBaseline);
1362                 case MIDDLE:
1363                     return primitiveValueCache->createIdentifierValue(CSSValueMiddle);
1364                 case SUB:
1365                     return primitiveValueCache->createIdentifierValue(CSSValueSub);
1366                 case SUPER:
1367                     return primitiveValueCache->createIdentifierValue(CSSValueSuper);
1368                 case TEXT_TOP:
1369                     return primitiveValueCache->createIdentifierValue(CSSValueTextTop);
1370                 case TEXT_BOTTOM:
1371                     return primitiveValueCache->createIdentifierValue(CSSValueTextBottom);
1372                 case TOP:
1373                     return primitiveValueCache->createIdentifierValue(CSSValueTop);
1374                 case BOTTOM:
1375                     return primitiveValueCache->createIdentifierValue(CSSValueBottom);
1376                 case BASELINE_MIDDLE:
1377                     return primitiveValueCache->createIdentifierValue(CSSValueWebkitBaselineMiddle);
1378                 case LENGTH:
1379                     return primitiveValueCache->createValue(style->verticalAlignLength());
1380             }
1381             ASSERT_NOT_REACHED();
1382             return 0;
1383         case CSSPropertyVisibility:
1384             return primitiveValueCache->createValue(style->visibility());
1385         case CSSPropertyWhiteSpace:
1386             return primitiveValueCache->createValue(style->whiteSpace());
1387         case CSSPropertyWidows:
1388             return primitiveValueCache->createValue(style->widows(), CSSPrimitiveValue::CSS_NUMBER);
1389         case CSSPropertyWidth:
1390             if (renderer)
1391                 return zoomAdjustedPixelValue(sizingBox(renderer).width(), style.get(), primitiveValueCache);
1392             return zoomAdjustedPixelValueForLength(style->width(), style.get(), primitiveValueCache);
1393         case CSSPropertyWordBreak:
1394             return primitiveValueCache->createValue(style->wordBreak());
1395         case CSSPropertyWordSpacing:
1396             return zoomAdjustedPixelValue(style->wordSpacing(), style.get(), primitiveValueCache);
1397         case CSSPropertyWordWrap:
1398             return primitiveValueCache->createValue(style->wordWrap());
1399         case CSSPropertyWebkitLineBreak:
1400             return primitiveValueCache->createValue(style->khtmlLineBreak());
1401         case CSSPropertyWebkitNbspMode:
1402             return primitiveValueCache->createValue(style->nbspMode());
1403         case CSSPropertyWebkitMatchNearestMailBlockquoteColor:
1404             return primitiveValueCache->createValue(style->matchNearestMailBlockquoteColor());
1405         case CSSPropertyResize:
1406             return primitiveValueCache->createValue(style->resize());
1407         case CSSPropertyWebkitFontSmoothing:
1408             return primitiveValueCache->createValue(style->fontDescription().fontSmoothing());
1409         case CSSPropertyZIndex:
1410             if (style->hasAutoZIndex())
1411                 return primitiveValueCache->createIdentifierValue(CSSValueAuto);
1412             return primitiveValueCache->createValue(style->zIndex(), CSSPrimitiveValue::CSS_NUMBER);
1413         case CSSPropertyZoom:
1414             return primitiveValueCache->createValue(style->zoom(), CSSPrimitiveValue::CSS_NUMBER);
1415         case CSSPropertyBoxSizing:
1416             if (style->boxSizing() == CONTENT_BOX)
1417                 return primitiveValueCache->createIdentifierValue(CSSValueContentBox);
1418             return primitiveValueCache->createIdentifierValue(CSSValueBorderBox);
1419 #if ENABLE(DASHBOARD_SUPPORT)
1420         case CSSPropertyWebkitDashboardRegion:
1421         {
1422             const Vector<StyleDashboardRegion>& regions = style->dashboardRegions();
1423             unsigned count = regions.size();
1424             if (count == 1 && regions[0].type == StyleDashboardRegion::None)
1425                 return primitiveValueCache->createIdentifierValue(CSSValueNone);
1426
1427             RefPtr<DashboardRegion> firstRegion;
1428             DashboardRegion* previousRegion = 0;
1429             for (unsigned i = 0; i < count; i++) {
1430                 RefPtr<DashboardRegion> region = DashboardRegion::create();
1431                 StyleDashboardRegion styleRegion = regions[i];
1432
1433                 region->m_label = styleRegion.label;
1434                 LengthBox offset = styleRegion.offset;
1435                 region->setTop(zoomAdjustedPixelValue(offset.top().value(), style.get(), primitiveValueCache));
1436                 region->setRight(zoomAdjustedPixelValue(offset.right().value(), style.get(), primitiveValueCache));
1437                 region->setBottom(zoomAdjustedPixelValue(offset.bottom().value(), style.get(), primitiveValueCache));
1438                 region->setLeft(zoomAdjustedPixelValue(offset.left().value(), style.get(), primitiveValueCache));
1439                 region->m_isRectangle = (styleRegion.type == StyleDashboardRegion::Rectangle);
1440                 region->m_isCircle = (styleRegion.type == StyleDashboardRegion::Circle);
1441
1442                 if (previousRegion)
1443                     previousRegion->m_next = region;
1444                 else
1445                     firstRegion = region;
1446                 previousRegion = region.get();
1447             }
1448             return primitiveValueCache->createValue(firstRegion.release());
1449         }
1450 #endif
1451         case CSSPropertyWebkitAnimationDelay:
1452             return getDelayValue(style->animations(), primitiveValueCache);
1453         case CSSPropertyWebkitAnimationDirection: {
1454             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1455             const AnimationList* t = style->animations();
1456             if (t) {
1457                 for (size_t i = 0; i < t->size(); ++i) {
1458                     if (t->animation(i)->direction())
1459                         list->append(primitiveValueCache->createIdentifierValue(CSSValueAlternate));
1460                     else
1461                         list->append(primitiveValueCache->createIdentifierValue(CSSValueNormal));
1462                 }
1463             } else
1464                 list->append(primitiveValueCache->createIdentifierValue(CSSValueNormal));
1465             return list.release();
1466         }
1467         case CSSPropertyWebkitAnimationDuration:
1468             return getDurationValue(style->animations(), primitiveValueCache);
1469         case CSSPropertyWebkitAnimationFillMode: {
1470             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1471             const AnimationList* t = style->animations();
1472             if (t) {
1473                 for (size_t i = 0; i < t->size(); ++i) {
1474                     switch (t->animation(i)->fillMode()) {
1475                     case AnimationFillModeNone:
1476                         list->append(primitiveValueCache->createIdentifierValue(CSSValueNone));
1477                         break;
1478                     case AnimationFillModeForwards:
1479                         list->append(primitiveValueCache->createIdentifierValue(CSSValueForwards));
1480                         break;
1481                     case AnimationFillModeBackwards:
1482                         list->append(primitiveValueCache->createIdentifierValue(CSSValueBackwards));
1483                         break;
1484                     case AnimationFillModeBoth:
1485                         list->append(primitiveValueCache->createIdentifierValue(CSSValueBoth));
1486                         break;
1487                     }
1488                 }
1489             } else
1490                 list->append(primitiveValueCache->createIdentifierValue(CSSValueNone));
1491             return list.release();
1492         }
1493         case CSSPropertyWebkitAnimationIterationCount: {
1494             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1495             const AnimationList* t = style->animations();
1496             if (t) {
1497                 for (size_t i = 0; i < t->size(); ++i) {
1498                     int iterationCount = t->animation(i)->iterationCount();
1499                     if (iterationCount == Animation::IterationCountInfinite)
1500                         list->append(primitiveValueCache->createIdentifierValue(CSSValueInfinite));
1501                     else
1502                         list->append(primitiveValueCache->createValue(iterationCount, CSSPrimitiveValue::CSS_NUMBER));
1503                 }
1504             } else
1505                 list->append(primitiveValueCache->createValue(Animation::initialAnimationIterationCount(), CSSPrimitiveValue::CSS_NUMBER));
1506             return list.release();
1507         }
1508         case CSSPropertyWebkitAnimationName: {
1509             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1510             const AnimationList* t = style->animations();
1511             if (t) {
1512                 for (size_t i = 0; i < t->size(); ++i)
1513                     list->append(primitiveValueCache->createValue(t->animation(i)->name(), CSSPrimitiveValue::CSS_STRING));
1514             } else
1515                 list->append(primitiveValueCache->createIdentifierValue(CSSValueNone));
1516             return list.release();
1517         }
1518         case CSSPropertyWebkitAnimationPlayState: {
1519             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1520             const AnimationList* t = style->animations();
1521             if (t) {
1522                 for (size_t i = 0; i < t->size(); ++i) {
1523                     int prop = t->animation(i)->playState();
1524                     if (prop == AnimPlayStatePlaying)
1525                         list->append(primitiveValueCache->createIdentifierValue(CSSValueRunning));
1526                     else
1527                         list->append(primitiveValueCache->createIdentifierValue(CSSValuePaused));
1528                 }
1529             } else
1530                 list->append(primitiveValueCache->createIdentifierValue(CSSValueRunning));
1531             return list.release();
1532         }
1533         case CSSPropertyWebkitAnimationTimingFunction:
1534             return getTimingFunctionValue(style->animations());
1535         case CSSPropertyWebkitAppearance:
1536             return primitiveValueCache->createValue(style->appearance());
1537         case CSSPropertyWebkitBackfaceVisibility:
1538             return primitiveValueCache->createIdentifierValue((style->backfaceVisibility() == BackfaceVisibilityHidden) ? CSSValueHidden : CSSValueVisible);
1539         case CSSPropertyWebkitBorderImage:
1540             return valueForNinePieceImage(style->borderImage(), primitiveValueCache);
1541         case CSSPropertyWebkitMaskBoxImage:
1542             return valueForNinePieceImage(style->maskBoxImage(), primitiveValueCache);
1543         case CSSPropertyWebkitFontSizeDelta:
1544             // Not a real style property -- used by the editing engine -- so has no computed value.
1545             break;
1546         case CSSPropertyWebkitMarginBottomCollapse:
1547         case CSSPropertyWebkitMarginAfterCollapse:
1548             return primitiveValueCache->createValue(style->marginAfterCollapse());
1549         case CSSPropertyWebkitMarginTopCollapse:
1550         case CSSPropertyWebkitMarginBeforeCollapse:
1551             return primitiveValueCache->createValue(style->marginBeforeCollapse());
1552         case CSSPropertyWebkitPerspective:
1553             if (!style->hasPerspective())
1554                 return primitiveValueCache->createIdentifierValue(CSSValueNone);
1555             return zoomAdjustedPixelValue(style->perspective(), style.get(), primitiveValueCache);
1556         case CSSPropertyWebkitPerspectiveOrigin: {
1557             RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
1558             if (renderer) {
1559                 IntRect box = sizingBox(renderer);
1560                 list->append(zoomAdjustedPixelValue(style->perspectiveOriginX().calcMinValue(box.width()), style.get(), primitiveValueCache));
1561                 list->append(zoomAdjustedPixelValue(style->perspectiveOriginY().calcMinValue(box.height()), style.get(), primitiveValueCache));
1562             }
1563             else {
1564                 list->append(zoomAdjustedPixelValueForLength(style->perspectiveOriginX(), style.get(), primitiveValueCache));
1565                 list->append(zoomAdjustedPixelValueForLength(style->perspectiveOriginY(), style.get(), primitiveValueCache));
1566                 
1567             }
1568             return list.release();
1569         }
1570         case CSSPropertyWebkitRtlOrdering:
1571             if (style->visuallyOrdered())
1572                 return primitiveValueCache->createIdentifierValue(CSSValueVisual);
1573             return primitiveValueCache->createIdentifierValue(CSSValueLogical);
1574         case CSSPropertyWebkitUserDrag:
1575             return primitiveValueCache->createValue(style->userDrag());
1576         case CSSPropertyWebkitUserSelect:
1577             return primitiveValueCache->createValue(style->userSelect());
1578         case CSSPropertyBorderBottomLeftRadius:
1579             return getBorderRadiusCornerValue(style->borderBottomLeftRadius(), style.get(), primitiveValueCache);
1580         case CSSPropertyBorderBottomRightRadius:
1581             return getBorderRadiusCornerValue(style->borderBottomRightRadius(), style.get(), primitiveValueCache);
1582         case CSSPropertyBorderTopLeftRadius:
1583             return getBorderRadiusCornerValue(style->borderTopLeftRadius(), style.get(), primitiveValueCache);
1584         case CSSPropertyBorderTopRightRadius:
1585             return getBorderRadiusCornerValue(style->borderTopRightRadius(), style.get(), primitiveValueCache);
1586         case CSSPropertyClip: {
1587             if (!style->hasClip())
1588                 return primitiveValueCache->createIdentifierValue(CSSValueAuto);
1589             RefPtr<Rect> rect = Rect::create();
1590             rect->setTop(zoomAdjustedPixelValue(style->clip().top().value(), style.get(), primitiveValueCache));
1591             rect->setRight(zoomAdjustedPixelValue(style->clip().right().value(), style.get(), primitiveValueCache));
1592             rect->setBottom(zoomAdjustedPixelValue(style->clip().bottom().value(), style.get(), primitiveValueCache));
1593             rect->setLeft(zoomAdjustedPixelValue(style->clip().left().value(), style.get(), primitiveValueCache));
1594             return primitiveValueCache->createValue(rect.release());
1595         }
1596         case CSSPropertySpeak:
1597             return primitiveValueCache->createValue(style->speak());
1598         case CSSPropertyWebkitTransform:
1599             return computedTransform(renderer, style.get(), primitiveValueCache);
1600         case CSSPropertyWebkitTransformOrigin: {
1601             RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
1602             if (renderer) {
1603                 IntRect box = sizingBox(renderer);
1604                 list->append(zoomAdjustedPixelValue(style->transformOriginX().calcMinValue(box.width()), style.get(), primitiveValueCache));
1605                 list->append(zoomAdjustedPixelValue(style->transformOriginY().calcMinValue(box.height()), style.get(), primitiveValueCache));
1606                 if (style->transformOriginZ() != 0)
1607                     list->append(zoomAdjustedPixelValue(style->transformOriginZ(), style.get(), primitiveValueCache));
1608             } else {
1609                 list->append(zoomAdjustedPixelValueForLength(style->transformOriginX(), style.get(), primitiveValueCache));
1610                 list->append(zoomAdjustedPixelValueForLength(style->transformOriginY(), style.get(), primitiveValueCache));
1611                 if (style->transformOriginZ() != 0)
1612                     list->append(zoomAdjustedPixelValue(style->transformOriginZ(), style.get(), primitiveValueCache));
1613             }
1614             return list.release();
1615         }
1616         case CSSPropertyWebkitTransformStyle:
1617             return primitiveValueCache->createIdentifierValue((style->transformStyle3D() == TransformStyle3DPreserve3D) ? CSSValuePreserve3d : CSSValueFlat);
1618         case CSSPropertyWebkitTransitionDelay:
1619             return getDelayValue(style->transitions(), primitiveValueCache);
1620         case CSSPropertyWebkitTransitionDuration:
1621             return getDurationValue(style->transitions(), primitiveValueCache);
1622         case CSSPropertyWebkitTransitionProperty: {
1623             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1624             const AnimationList* t = style->transitions();
1625             if (t) {
1626                 for (size_t i = 0; i < t->size(); ++i) {
1627                     int prop = t->animation(i)->property();
1628                     RefPtr<CSSValue> propertyValue;
1629                     if (prop == cAnimateNone)
1630                         propertyValue = primitiveValueCache->createIdentifierValue(CSSValueNone);
1631                     else if (prop == cAnimateAll)
1632                         propertyValue = primitiveValueCache->createIdentifierValue(CSSValueAll);
1633                     else
1634                         propertyValue = primitiveValueCache->createValue(getPropertyName(static_cast<CSSPropertyID>(prop)), CSSPrimitiveValue::CSS_STRING);
1635                     list->append(propertyValue);
1636                 }
1637             } else
1638                 list->append(primitiveValueCache->createIdentifierValue(CSSValueAll));
1639             return list.release();
1640         }
1641         case CSSPropertyWebkitTransitionTimingFunction:
1642             return getTimingFunctionValue(style->transitions());
1643         case CSSPropertyPointerEvents:
1644             return primitiveValueCache->createValue(style->pointerEvents());
1645         case CSSPropertyWebkitColorCorrection:
1646             return primitiveValueCache->createValue(style->colorSpace());
1647         case CSSPropertyWebkitWritingMode:
1648             return primitiveValueCache->createValue(style->writingMode());
1649         case CSSPropertyWebkitTextCombine:
1650             return primitiveValueCache->createValue(style->textCombine());
1651         case CSSPropertyWebkitTextOrientation:
1652             return CSSPrimitiveValue::create(style->fontDescription().textOrientation());
1653         case CSSPropertyWebkitLineBoxContain:
1654             return createLineBoxContainValue(primitiveValueCache, style->lineBoxContain());
1655         case CSSPropertyContent:
1656             return contentToCSSValue(style.get(), primitiveValueCache);
1657         case CSSPropertyCounterIncrement:
1658             return counterToCSSValue(style.get(), propertyID, primitiveValueCache);
1659         case CSSPropertyCounterReset:
1660             return counterToCSSValue(style.get(), propertyID, primitiveValueCache);
1661         
1662         /* Shorthand properties, currently not supported see bug 13658*/
1663         case CSSPropertyBackground:
1664         case CSSPropertyBorder:
1665         case CSSPropertyBorderBottom:
1666         case CSSPropertyBorderColor:
1667         case CSSPropertyBorderLeft:
1668         case CSSPropertyBorderRadius:
1669         case CSSPropertyBorderRight:
1670         case CSSPropertyBorderStyle:
1671         case CSSPropertyBorderTop:
1672         case CSSPropertyBorderWidth:
1673         case CSSPropertyFont:
1674         case CSSPropertyListStyle:
1675         case CSSPropertyMargin:
1676         case CSSPropertyOutline:
1677         case CSSPropertyPadding:
1678             break;
1679
1680         /* Individual properties not part of the spec */
1681         case CSSPropertyBackgroundRepeatX:
1682         case CSSPropertyBackgroundRepeatY:
1683             break;
1684
1685         /* Unimplemented CSS 3 properties (including CSS3 shorthand properties) */
1686         case CSSPropertyWebkitTextEmphasis:
1687         case CSSPropertyTextLineThrough:
1688         case CSSPropertyTextLineThroughColor:
1689         case CSSPropertyTextLineThroughMode:
1690         case CSSPropertyTextLineThroughStyle:
1691         case CSSPropertyTextLineThroughWidth:
1692         case CSSPropertyTextOverline:
1693         case CSSPropertyTextOverlineColor:
1694         case CSSPropertyTextOverlineMode:
1695         case CSSPropertyTextOverlineStyle:
1696         case CSSPropertyTextOverlineWidth:
1697         case CSSPropertyTextUnderline:
1698         case CSSPropertyTextUnderlineColor:
1699         case CSSPropertyTextUnderlineMode:
1700         case CSSPropertyTextUnderlineStyle:
1701         case CSSPropertyTextUnderlineWidth:
1702             break;
1703
1704         /* Directional properties are resolved by resolveDirectionAwareProperty() before the switch. */
1705         case CSSPropertyWebkitBorderEnd:
1706         case CSSPropertyWebkitBorderEndColor:
1707         case CSSPropertyWebkitBorderEndStyle:
1708         case CSSPropertyWebkitBorderEndWidth:
1709         case CSSPropertyWebkitBorderStart:
1710         case CSSPropertyWebkitBorderStartColor:
1711         case CSSPropertyWebkitBorderStartStyle:
1712         case CSSPropertyWebkitBorderStartWidth:
1713         case CSSPropertyWebkitBorderAfter:
1714         case CSSPropertyWebkitBorderAfterColor:
1715         case CSSPropertyWebkitBorderAfterStyle:
1716         case CSSPropertyWebkitBorderAfterWidth:
1717         case CSSPropertyWebkitBorderBefore:
1718         case CSSPropertyWebkitBorderBeforeColor:
1719         case CSSPropertyWebkitBorderBeforeStyle:
1720         case CSSPropertyWebkitBorderBeforeWidth:
1721         case CSSPropertyWebkitMarginEnd:
1722         case CSSPropertyWebkitMarginStart:
1723         case CSSPropertyWebkitMarginAfter:
1724         case CSSPropertyWebkitMarginBefore:
1725         case CSSPropertyWebkitPaddingEnd:
1726         case CSSPropertyWebkitPaddingStart:
1727         case CSSPropertyWebkitPaddingAfter:
1728         case CSSPropertyWebkitPaddingBefore:
1729         case CSSPropertyWebkitLogicalWidth:
1730         case CSSPropertyWebkitLogicalHeight:
1731         case CSSPropertyWebkitMinLogicalWidth:
1732         case CSSPropertyWebkitMinLogicalHeight:
1733         case CSSPropertyWebkitMaxLogicalWidth:
1734         case CSSPropertyWebkitMaxLogicalHeight:
1735             ASSERT_NOT_REACHED();
1736             break;
1737
1738         /* Unimplemented @font-face properties */
1739         case CSSPropertyFontStretch:
1740         case CSSPropertySrc:
1741         case CSSPropertyUnicodeRange:
1742             break;
1743
1744         /* Other unimplemented properties */
1745         case CSSPropertyPage: // for @page
1746         case CSSPropertyQuotes: // FIXME: needs implementation
1747         case CSSPropertySize: // for @page
1748             break;
1749
1750         /* Unimplemented -webkit- properties */
1751         case CSSPropertyWebkitAnimation:
1752         case CSSPropertyWebkitBorderRadius:
1753         case CSSPropertyWebkitColumns:
1754         case CSSPropertyWebkitColumnRule:
1755         case CSSPropertyWebkitMarginCollapse:
1756         case CSSPropertyWebkitMarquee:
1757         case CSSPropertyWebkitMarqueeSpeed:
1758         case CSSPropertyWebkitMask:
1759         case CSSPropertyWebkitMaskRepeatX:
1760         case CSSPropertyWebkitMaskRepeatY:
1761         case CSSPropertyWebkitPerspectiveOriginX:
1762         case CSSPropertyWebkitPerspectiveOriginY:
1763         case CSSPropertyWebkitTextStroke:
1764         case CSSPropertyWebkitTransformOriginX:
1765         case CSSPropertyWebkitTransformOriginY:
1766         case CSSPropertyWebkitTransformOriginZ:
1767         case CSSPropertyWebkitTransition:
1768             break;
1769 #if ENABLE(SVG)
1770         case CSSPropertyClipPath:
1771         case CSSPropertyClipRule:
1772         case CSSPropertyMask:
1773         case CSSPropertyEnableBackground:
1774         case CSSPropertyFilter:
1775         case CSSPropertyFloodColor:
1776         case CSSPropertyFloodOpacity:
1777         case CSSPropertyLightingColor:
1778         case CSSPropertyStopColor:
1779         case CSSPropertyStopOpacity:
1780         case CSSPropertyColorInterpolation:
1781         case CSSPropertyColorInterpolationFilters:
1782         case CSSPropertyColorProfile:
1783         case CSSPropertyColorRendering:
1784         case CSSPropertyFill:
1785         case CSSPropertyFillOpacity:
1786         case CSSPropertyFillRule:
1787         case CSSPropertyMarker:
1788         case CSSPropertyMarkerEnd:
1789         case CSSPropertyMarkerMid:
1790         case CSSPropertyMarkerStart:
1791         case CSSPropertyShapeRendering:
1792         case CSSPropertyStroke:
1793         case CSSPropertyStrokeDasharray:
1794         case CSSPropertyStrokeDashoffset:
1795         case CSSPropertyStrokeLinecap:
1796         case CSSPropertyStrokeLinejoin:
1797         case CSSPropertyStrokeMiterlimit:
1798         case CSSPropertyStrokeOpacity:
1799         case CSSPropertyStrokeWidth:
1800         case CSSPropertyAlignmentBaseline:
1801         case CSSPropertyBaselineShift:
1802         case CSSPropertyDominantBaseline:
1803         case CSSPropertyGlyphOrientationHorizontal:
1804         case CSSPropertyGlyphOrientationVertical:
1805         case CSSPropertyKerning:
1806         case CSSPropertyTextAnchor:
1807         case CSSPropertyVectorEffect:
1808         case CSSPropertyWritingMode:
1809         case CSSPropertyWebkitSvgShadow:
1810             return getSVGPropertyCSSValue(propertyID, DoNotUpdateLayout);
1811 #endif
1812     }
1813
1814     logUnimplementedPropertyID(propertyID);
1815     return 0;
1816 }
1817
1818 String CSSComputedStyleDeclaration::getPropertyValue(int propertyID) const
1819 {
1820     RefPtr<CSSValue> value = getPropertyCSSValue(propertyID);
1821     if (value)
1822         return value->cssText();
1823     return "";
1824 }
1825
1826 bool CSSComputedStyleDeclaration::getPropertyPriority(int /*propertyID*/) const
1827 {
1828     // All computed styles have a priority of false (not "important").
1829     return false;
1830 }
1831
1832 String CSSComputedStyleDeclaration::removeProperty(int /*propertyID*/, ExceptionCode& ec)
1833 {
1834     ec = NO_MODIFICATION_ALLOWED_ERR;
1835     return String();
1836 }
1837
1838 void CSSComputedStyleDeclaration::setProperty(int /*propertyID*/, const String& /*value*/, bool /*important*/, ExceptionCode& ec)
1839 {
1840     ec = NO_MODIFICATION_ALLOWED_ERR;
1841 }
1842
1843 unsigned CSSComputedStyleDeclaration::virtualLength() const
1844 {
1845     Node* node = m_node.get();
1846     if (!node)
1847         return 0;
1848
1849     RenderStyle* style = node->computedStyle(m_pseudoElementSpecifier);
1850     if (!style)
1851         return 0;
1852
1853     return numComputedProperties;
1854 }
1855
1856 String CSSComputedStyleDeclaration::item(unsigned i) const
1857 {
1858     if (i >= length())
1859         return "";
1860
1861     return getPropertyName(static_cast<CSSPropertyID>(computedProperties[i]));
1862 }
1863
1864 bool CSSComputedStyleDeclaration::cssPropertyMatches(const CSSProperty* property) const
1865 {
1866     if (property->id() == CSSPropertyFontSize && property->value()->isPrimitiveValue() && m_node) {
1867         m_node->document()->updateLayoutIgnorePendingStylesheets();
1868         RenderStyle* style = m_node->computedStyle(m_pseudoElementSpecifier);
1869         if (style && style->fontDescription().keywordSize()) {
1870             int sizeValue = cssIdentifierForFontSizeKeyword(style->fontDescription().keywordSize());
1871             CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(property->value());
1872             if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_IDENT && primitiveValue->getIdent() == sizeValue)
1873                 return true;
1874         }
1875     }
1876
1877     return CSSStyleDeclaration::cssPropertyMatches(property);
1878 }
1879
1880 PassRefPtr<CSSMutableStyleDeclaration> CSSComputedStyleDeclaration::copy() const
1881 {
1882     return copyPropertiesInSet(computedProperties, numComputedProperties);
1883 }
1884
1885 PassRefPtr<CSSMutableStyleDeclaration> CSSComputedStyleDeclaration::makeMutable()
1886 {
1887     return copy();
1888 }
1889
1890 } // namespace WebCore