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