https://bugs.webkit.org/show_bug.cgi?id=39516, back end support for column-span property.
[WebKit-https.git] / WebCore / css / CSSComputedStyleDeclaration.cpp
1 /*
2  * Copyright (C) 2004 Zack Rusin <zack@kde.org>
3  * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
4  * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org>
5  * Copyright (C) 2007 Nicholas Shanks <webkit@nickshanks.com>
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20  * 02110-1301  USA
21  */
22
23 #include "config.h"
24 #include "CSSComputedStyleDeclaration.h"
25
26 #include "AnimationController.h"
27 #include "CSSBorderImageValue.h"
28 #include "CSSMutableStyleDeclaration.h"
29 #include "CSSPrimitiveValue.h"
30 #include "CSSPrimitiveValueMappings.h"
31 #include "CSSProperty.h"
32 #include "CSSPropertyNames.h"
33 #include "CSSReflectValue.h"
34 #include "CSSSelector.h"
35 #include "CSSTimingFunctionValue.h"
36 #include "CSSValueList.h"
37 #include "Document.h"
38 #include "ExceptionCode.h"
39 #include "Rect.h"
40 #include "RenderBox.h"
41 #include "RenderLayer.h"
42 #include "ShadowValue.h"
43 #include "WebKitCSSTransformValue.h"
44
45 #if ENABLE(DASHBOARD_SUPPORT)
46 #include "DashboardRegion.h"
47 #endif
48
49 namespace WebCore {
50
51 // List of all properties we know how to compute, omitting shorthands.
52 static const int computedProperties[] = {
53     CSSPropertyBackgroundAttachment,
54     CSSPropertyBackgroundClip,
55     CSSPropertyBackgroundColor,
56     CSSPropertyBackgroundImage,
57     CSSPropertyBackgroundOrigin,
58     CSSPropertyBackgroundPosition, // more-specific background-position-x/y are non-standard
59     CSSPropertyBackgroundRepeat,
60     CSSPropertyBackgroundSize,
61     CSSPropertyBorderBottomColor,
62     CSSPropertyBorderBottomLeftRadius,
63     CSSPropertyBorderBottomRightRadius,
64     CSSPropertyBorderBottomStyle,
65     CSSPropertyBorderBottomWidth,
66     CSSPropertyBorderCollapse,
67     CSSPropertyBorderLeftColor,
68     CSSPropertyBorderLeftStyle,
69     CSSPropertyBorderLeftWidth,
70     CSSPropertyBorderRightColor,
71     CSSPropertyBorderRightStyle,
72     CSSPropertyBorderRightWidth,
73     CSSPropertyBorderTopColor,
74     CSSPropertyBorderTopLeftRadius,
75     CSSPropertyBorderTopRightRadius,
76     CSSPropertyBorderTopStyle,
77     CSSPropertyBorderTopWidth,
78     CSSPropertyBottom,
79     CSSPropertyCaptionSide,
80     CSSPropertyClear,
81     CSSPropertyClip,
82     CSSPropertyColor,
83     CSSPropertyCursor,
84     CSSPropertyDirection,
85     CSSPropertyDisplay,
86     CSSPropertyEmptyCells,
87     CSSPropertyFloat,
88     CSSPropertyFontFamily,
89     CSSPropertyFontSize,
90     CSSPropertyFontStyle,
91     CSSPropertyFontVariant,
92     CSSPropertyFontWeight,
93     CSSPropertyHeight,
94     CSSPropertyLeft,
95     CSSPropertyLetterSpacing,
96     CSSPropertyLineHeight,
97     CSSPropertyListStyleImage,
98     CSSPropertyListStylePosition,
99     CSSPropertyListStyleType,
100     CSSPropertyMarginBottom,
101     CSSPropertyMarginLeft,
102     CSSPropertyMarginRight,
103     CSSPropertyMarginTop,
104     CSSPropertyMaxHeight,
105     CSSPropertyMaxWidth,
106     CSSPropertyMinHeight,
107     CSSPropertyMinWidth,
108     CSSPropertyOpacity,
109     CSSPropertyOrphans,
110     CSSPropertyOutlineColor,
111     CSSPropertyOutlineStyle,
112     CSSPropertyOutlineWidth,
113     CSSPropertyOverflowX,
114     CSSPropertyOverflowY,
115     CSSPropertyPaddingBottom,
116     CSSPropertyPaddingLeft,
117     CSSPropertyPaddingRight,
118     CSSPropertyPaddingTop,
119     CSSPropertyPageBreakAfter,
120     CSSPropertyPageBreakBefore,
121     CSSPropertyPageBreakInside,
122     CSSPropertyPointerEvents,
123     CSSPropertyPosition,
124     CSSPropertyResize,
125     CSSPropertyRight,
126     CSSPropertyTableLayout,
127     CSSPropertyTextAlign,
128     CSSPropertyTextDecoration,
129     CSSPropertyTextIndent,
130     CSSPropertyTextRendering,
131     CSSPropertyTextShadow,
132     CSSPropertyTextOverflow,
133     CSSPropertyTextTransform,
134     CSSPropertyTop,
135     CSSPropertyUnicodeBidi,
136     CSSPropertyVerticalAlign,
137     CSSPropertyVisibility,
138     CSSPropertyWhiteSpace,
139     CSSPropertyWidows,
140     CSSPropertyWidth,
141     CSSPropertyWordBreak,
142     CSSPropertyWordSpacing,
143     CSSPropertyWordWrap,
144     CSSPropertyZIndex,
145     CSSPropertyZoom,
146
147     CSSPropertyWebkitAnimationDelay,
148     CSSPropertyWebkitAnimationDirection,
149     CSSPropertyWebkitAnimationDuration,
150     CSSPropertyWebkitAnimationFillMode,
151     CSSPropertyWebkitAnimationIterationCount,
152     CSSPropertyWebkitAnimationName,
153     CSSPropertyWebkitAnimationPlayState,
154     CSSPropertyWebkitAnimationTimingFunction,
155     CSSPropertyWebkitAppearance,
156     CSSPropertyWebkitBackfaceVisibility,
157     CSSPropertyWebkitBackgroundClip,
158     CSSPropertyWebkitBackgroundComposite,
159     CSSPropertyWebkitBackgroundOrigin,
160     CSSPropertyWebkitBackgroundSize,
161     CSSPropertyWebkitBorderFit,
162     CSSPropertyWebkitBorderHorizontalSpacing,
163     CSSPropertyWebkitBorderImage,
164     CSSPropertyWebkitBorderVerticalSpacing,
165     CSSPropertyWebkitBoxAlign,
166     CSSPropertyWebkitBoxDirection,
167     CSSPropertyWebkitBoxFlex,
168     CSSPropertyWebkitBoxFlexGroup,
169     CSSPropertyWebkitBoxLines,
170     CSSPropertyWebkitBoxOrdinalGroup,
171     CSSPropertyWebkitBoxOrient,
172     CSSPropertyWebkitBoxPack,
173     CSSPropertyWebkitBoxReflect,
174     CSSPropertyWebkitBoxShadow,
175     CSSPropertyWebkitBoxSizing,
176     CSSPropertyWebkitColorCorrection,
177     CSSPropertyWebkitColumnBreakAfter,
178     CSSPropertyWebkitColumnBreakBefore,
179     CSSPropertyWebkitColumnBreakInside,
180     CSSPropertyWebkitColumnCount,
181     CSSPropertyWebkitColumnGap,
182     CSSPropertyWebkitColumnRuleColor,
183     CSSPropertyWebkitColumnRuleStyle,
184     CSSPropertyWebkitColumnRuleWidth,
185     CSSPropertyWebkitColumnSpan,
186     CSSPropertyWebkitColumnWidth,
187 #if ENABLE(DASHBOARD_SUPPORT)
188     CSSPropertyWebkitDashboardRegion,
189 #endif
190     CSSPropertyWebkitFontSmoothing,
191     CSSPropertyWebkitHighlight,
192     CSSPropertyWebkitLineBreak,
193     CSSPropertyWebkitLineClamp,
194     CSSPropertyWebkitMarginBottomCollapse,
195     CSSPropertyWebkitMarginTopCollapse,
196     CSSPropertyWebkitMarqueeDirection,
197     CSSPropertyWebkitMarqueeIncrement,
198     CSSPropertyWebkitMarqueeRepetition,
199     CSSPropertyWebkitMarqueeStyle,
200     CSSPropertyWebkitMaskAttachment,
201     CSSPropertyWebkitMaskBoxImage,
202     CSSPropertyWebkitMaskClip,
203     CSSPropertyWebkitMaskComposite,
204     CSSPropertyWebkitMaskImage,
205     CSSPropertyWebkitMaskOrigin,
206     CSSPropertyWebkitMaskPosition,
207     CSSPropertyWebkitMaskRepeat,
208     CSSPropertyWebkitMaskSize,
209     CSSPropertyWebkitNbspMode,
210     CSSPropertyWebkitPerspective,
211     CSSPropertyWebkitPerspectiveOrigin,
212     CSSPropertyWebkitRtlOrdering,
213     CSSPropertyWebkitTextDecorationsInEffect,
214     CSSPropertyWebkitTextFillColor,
215     CSSPropertyWebkitTextSecurity,
216     CSSPropertyWebkitTextStrokeColor,
217     CSSPropertyWebkitTextStrokeWidth,
218     CSSPropertyWebkitTransform,
219     CSSPropertyWebkitTransformOrigin,
220     CSSPropertyWebkitTransformStyle,
221     CSSPropertyWebkitTransitionDelay,
222     CSSPropertyWebkitTransitionDuration,
223     CSSPropertyWebkitTransitionProperty,
224     CSSPropertyWebkitTransitionTimingFunction,
225     CSSPropertyWebkitUserDrag,
226     CSSPropertyWebkitUserModify,
227     CSSPropertyWebkitUserSelect
228
229 #if ENABLE(SVG)
230     ,
231     CSSPropertyClipPath,
232     CSSPropertyClipRule,
233     CSSPropertyMask,
234     CSSPropertyFilter,
235     CSSPropertyFloodColor,
236     CSSPropertyFloodOpacity,
237     CSSPropertyLightingColor,
238     CSSPropertyStopColor,
239     CSSPropertyStopOpacity,
240     CSSPropertyColorInterpolation,
241     CSSPropertyColorInterpolationFilters,
242     CSSPropertyColorRendering,
243     CSSPropertyFill,
244     CSSPropertyFillOpacity,
245     CSSPropertyFillRule,
246     CSSPropertyImageRendering,
247     CSSPropertyMarkerEnd,
248     CSSPropertyMarkerMid,
249     CSSPropertyMarkerStart,
250     CSSPropertyShapeRendering,
251     CSSPropertyStroke,
252     CSSPropertyStrokeDasharray,
253     CSSPropertyStrokeDashoffset,
254     CSSPropertyStrokeLinecap,
255     CSSPropertyStrokeLinejoin,
256     CSSPropertyStrokeMiterlimit,
257     CSSPropertyStrokeOpacity,
258     CSSPropertyStrokeWidth,
259     CSSPropertyAlignmentBaseline,
260     CSSPropertyBaselineShift,
261     CSSPropertyDominantBaseline,
262     CSSPropertyKerning,
263     CSSPropertyTextAnchor,
264     CSSPropertyWritingMode,
265     CSSPropertyGlyphOrientationHorizontal,
266     CSSPropertyGlyphOrientationVertical,
267     CSSPropertyWebkitSvgShadow
268 #endif
269 };
270
271 const unsigned numComputedProperties = sizeof(computedProperties) / sizeof(computedProperties[0]);
272
273 static int valueForRepeatRule(int rule)
274 {
275     switch (rule) {
276         case RepeatImageRule:
277             return CSSValueRepeat;
278         case RoundImageRule:
279             return CSSValueRound;
280         default:
281             return CSSValueStretch;
282     }
283 }
284         
285 static PassRefPtr<CSSValue> valueForNinePieceImage(const NinePieceImage& image)
286 {
287     if (!image.hasImage())
288         return CSSPrimitiveValue::createIdentifier(CSSValueNone);
289     
290     // Image first.
291     RefPtr<CSSValue> imageValue;
292     if (image.image())
293         imageValue = image.image()->cssValue();
294     
295     // Create the slices.
296     RefPtr<CSSPrimitiveValue> top;
297     if (image.slices().top().isPercent())
298         top = CSSPrimitiveValue::create(image.slices().top().value(), CSSPrimitiveValue::CSS_PERCENTAGE);
299     else
300         top = CSSPrimitiveValue::create(image.slices().top().value(), CSSPrimitiveValue::CSS_NUMBER);
301         
302     RefPtr<CSSPrimitiveValue> right;
303     if (image.slices().right().isPercent())
304         right = CSSPrimitiveValue::create(image.slices().right().value(), CSSPrimitiveValue::CSS_PERCENTAGE);
305     else
306         right = CSSPrimitiveValue::create(image.slices().right().value(), CSSPrimitiveValue::CSS_NUMBER);
307         
308     RefPtr<CSSPrimitiveValue> bottom;
309     if (image.slices().bottom().isPercent())
310         bottom = CSSPrimitiveValue::create(image.slices().bottom().value(), CSSPrimitiveValue::CSS_PERCENTAGE);
311     else
312         bottom = CSSPrimitiveValue::create(image.slices().bottom().value(), CSSPrimitiveValue::CSS_NUMBER);
313     
314     RefPtr<CSSPrimitiveValue> left;
315     if (image.slices().left().isPercent())
316         left = CSSPrimitiveValue::create(image.slices().left().value(), CSSPrimitiveValue::CSS_PERCENTAGE);
317     else
318         left = CSSPrimitiveValue::create(image.slices().left().value(), CSSPrimitiveValue::CSS_NUMBER);
319
320     RefPtr<Rect> rect = Rect::create();
321     rect->setTop(top);
322     rect->setRight(right);
323     rect->setBottom(bottom);
324     rect->setLeft(left);
325
326     return CSSBorderImageValue::create(imageValue, rect, valueForRepeatRule(image.horizontalRule()), valueForRepeatRule(image.verticalRule()));
327 }
328
329 static PassRefPtr<CSSValue> valueForReflection(const StyleReflection* reflection)
330 {
331     if (!reflection)
332         return CSSPrimitiveValue::createIdentifier(CSSValueNone);
333
334     RefPtr<CSSPrimitiveValue> offset;
335     if (reflection->offset().isPercent())
336         offset = CSSPrimitiveValue::create(reflection->offset().percent(), CSSPrimitiveValue::CSS_PERCENTAGE);
337     else
338         offset = CSSPrimitiveValue::create(reflection->offset().value(), CSSPrimitiveValue::CSS_PX);
339     
340     return CSSReflectValue::create(reflection->direction(), offset.release(), valueForNinePieceImage(reflection->mask()));
341 }
342
343 static PassRefPtr<CSSValue> getPositionOffsetValue(RenderStyle* style, int propertyID)
344 {
345     if (!style)
346         return 0;
347
348     Length l;
349     switch (propertyID) {
350         case CSSPropertyLeft:
351             l = style->left();
352             break;
353         case CSSPropertyRight:
354             l = style->right();
355             break;
356         case CSSPropertyTop:
357             l = style->top();
358             break;
359         case CSSPropertyBottom:
360             l = style->bottom();
361             break;
362         default:
363             return 0;
364     }
365
366     if (style->position() == AbsolutePosition || style->position() == FixedPosition)
367         return CSSPrimitiveValue::create(l);
368
369     if (style->position() == RelativePosition)
370         // FIXME: It's not enough to simply return "auto" values for one offset if the other side is defined.
371         // In other words if left is auto and right is not auto, then left's computed value is negative right().
372         // So we should get the opposite length unit and see if it is auto.
373         return CSSPrimitiveValue::create(l);
374
375     return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
376 }
377
378 PassRefPtr<CSSPrimitiveValue> CSSComputedStyleDeclaration::currentColorOrValidColor(RenderStyle* style, const Color& color) const
379 {
380     // This function does NOT look at visited information, so that computed style doesn't expose that.
381     if (!color.isValid())
382         return CSSPrimitiveValue::createColor(style->color().rgb());
383     return CSSPrimitiveValue::createColor(color.rgb());
384 }
385
386 static PassRefPtr<CSSValue> getBorderRadiusCornerValue(IntSize radius)
387 {
388     if (radius.width() == radius.height())
389         return CSSPrimitiveValue::create(radius.width(), CSSPrimitiveValue::CSS_PX);
390
391     RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
392     list->append(CSSPrimitiveValue::create(radius.width(), CSSPrimitiveValue::CSS_PX));
393     list->append(CSSPrimitiveValue::create(radius.height(), CSSPrimitiveValue::CSS_PX));
394     return list.release();
395 }
396
397 static IntRect sizingBox(RenderObject* renderer)
398 {
399     if (!renderer->isBox())
400         return IntRect();
401     
402     RenderBox* box = toRenderBox(renderer);
403     return box->style()->boxSizing() == CONTENT_BOX ? box->contentBoxRect() : box->borderBoxRect();
404 }
405
406 static inline bool hasCompositedLayer(RenderObject* renderer)
407 {
408     return renderer && renderer->hasLayer() && toRenderBoxModelObject(renderer)->layer()->isComposited();
409 }
410
411 static PassRefPtr<CSSValue> computedTransform(RenderObject* renderer, const RenderStyle* style)
412 {
413     if (!renderer || style->transform().operations().isEmpty())
414         return CSSPrimitiveValue::createIdentifier(CSSValueNone);
415     
416     IntRect box = sizingBox(renderer);
417
418     TransformationMatrix transform;
419     style->applyTransform(transform, box.size(), RenderStyle::ExcludeTransformOrigin);
420     // Note that this does not flatten to an affine transform if ENABLE(3D_RENDERING) is off, by design.
421
422     RefPtr<WebKitCSSTransformValue> transformVal;
423
424     // FIXME: Need to print out individual functions (https://bugs.webkit.org/show_bug.cgi?id=23924)
425     if (transform.isAffine()) {
426         transformVal = WebKitCSSTransformValue::create(WebKitCSSTransformValue::MatrixTransformOperation);
427
428         transformVal->append(CSSPrimitiveValue::create(transform.a(), CSSPrimitiveValue::CSS_NUMBER));
429         transformVal->append(CSSPrimitiveValue::create(transform.b(), CSSPrimitiveValue::CSS_NUMBER));
430         transformVal->append(CSSPrimitiveValue::create(transform.c(), CSSPrimitiveValue::CSS_NUMBER));
431         transformVal->append(CSSPrimitiveValue::create(transform.d(), CSSPrimitiveValue::CSS_NUMBER));
432         transformVal->append(CSSPrimitiveValue::create(transform.e(), CSSPrimitiveValue::CSS_NUMBER));
433         transformVal->append(CSSPrimitiveValue::create(transform.f(), CSSPrimitiveValue::CSS_NUMBER));
434     } else {
435         transformVal = WebKitCSSTransformValue::create(WebKitCSSTransformValue::Matrix3DTransformOperation);
436
437         transformVal->append(CSSPrimitiveValue::create(transform.m11(), CSSPrimitiveValue::CSS_NUMBER));
438         transformVal->append(CSSPrimitiveValue::create(transform.m12(), CSSPrimitiveValue::CSS_NUMBER));
439         transformVal->append(CSSPrimitiveValue::create(transform.m13(), CSSPrimitiveValue::CSS_NUMBER));
440         transformVal->append(CSSPrimitiveValue::create(transform.m14(), CSSPrimitiveValue::CSS_NUMBER));
441
442         transformVal->append(CSSPrimitiveValue::create(transform.m21(), CSSPrimitiveValue::CSS_NUMBER));
443         transformVal->append(CSSPrimitiveValue::create(transform.m22(), CSSPrimitiveValue::CSS_NUMBER));
444         transformVal->append(CSSPrimitiveValue::create(transform.m23(), CSSPrimitiveValue::CSS_NUMBER));
445         transformVal->append(CSSPrimitiveValue::create(transform.m24(), CSSPrimitiveValue::CSS_NUMBER));
446
447         transformVal->append(CSSPrimitiveValue::create(transform.m31(), CSSPrimitiveValue::CSS_NUMBER));
448         transformVal->append(CSSPrimitiveValue::create(transform.m32(), CSSPrimitiveValue::CSS_NUMBER));
449         transformVal->append(CSSPrimitiveValue::create(transform.m33(), CSSPrimitiveValue::CSS_NUMBER));
450         transformVal->append(CSSPrimitiveValue::create(transform.m34(), CSSPrimitiveValue::CSS_NUMBER));
451
452         transformVal->append(CSSPrimitiveValue::create(transform.m41(), CSSPrimitiveValue::CSS_NUMBER));
453         transformVal->append(CSSPrimitiveValue::create(transform.m42(), CSSPrimitiveValue::CSS_NUMBER));
454         transformVal->append(CSSPrimitiveValue::create(transform.m43(), CSSPrimitiveValue::CSS_NUMBER));
455         transformVal->append(CSSPrimitiveValue::create(transform.m44(), CSSPrimitiveValue::CSS_NUMBER));
456     }
457
458     RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
459     list->append(transformVal);
460
461     return list.release();
462 }
463
464 static PassRefPtr<CSSValue> getDelayValue(const AnimationList* animList)
465 {
466     RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
467     if (animList) {
468         for (size_t i = 0; i < animList->size(); ++i)
469             list->append(CSSPrimitiveValue::create(animList->animation(i)->delay(), CSSPrimitiveValue::CSS_S));
470     } else {
471         // Note that initialAnimationDelay() is used for both transitions and animations
472         list->append(CSSPrimitiveValue::create(Animation::initialAnimationDelay(), CSSPrimitiveValue::CSS_S));
473     }
474     return list.release();
475 }
476
477 static PassRefPtr<CSSValue> getDurationValue(const AnimationList* animList)
478 {
479     RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
480     if (animList) {
481         for (size_t i = 0; i < animList->size(); ++i)
482             list->append(CSSPrimitiveValue::create(animList->animation(i)->duration(), CSSPrimitiveValue::CSS_S));
483     } else {
484         // Note that initialAnimationDuration() is used for both transitions and animations
485         list->append(CSSPrimitiveValue::create(Animation::initialAnimationDuration(), CSSPrimitiveValue::CSS_S));
486     }
487     return list.release();
488 }
489
490 static PassRefPtr<CSSValue> getTimingFunctionValue(const AnimationList* animList)
491 {
492     RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
493     if (animList) {
494         for (size_t i = 0; i < animList->size(); ++i) {
495             const TimingFunction& tf = animList->animation(i)->timingFunction();
496             list->append(CSSTimingFunctionValue::create(tf.x1(), tf.y1(), tf.x2(), tf.y2()));
497         }
498     } else {
499         // Note that initialAnimationTimingFunction() is used for both transitions and animations
500         const TimingFunction& tf = Animation::initialAnimationTimingFunction();
501         list->append(CSSTimingFunctionValue::create(tf.x1(), tf.y1(), tf.x2(), tf.y2()));
502     }
503     return list.release();
504 }
505
506 CSSComputedStyleDeclaration::CSSComputedStyleDeclaration(PassRefPtr<Node> n, bool allowVisitedStyle, const String& pseudoElementName)
507     : m_node(n)
508     , m_allowVisitedStyle(allowVisitedStyle)
509 {
510     unsigned nameWithoutColonsStart = pseudoElementName[0] == ':' ? (pseudoElementName[1] == ':' ? 2 : 1) : 0;
511     m_pseudoElementSpecifier = CSSSelector::pseudoId(CSSSelector::parsePseudoType(
512         AtomicString(pseudoElementName.substring(nameWithoutColonsStart))));
513 }
514
515 CSSComputedStyleDeclaration::~CSSComputedStyleDeclaration()
516 {
517 }
518
519 String CSSComputedStyleDeclaration::cssText() const
520 {
521     String result("");
522
523     for (unsigned i = 0; i < numComputedProperties; i++) {
524         if (i)
525             result += " ";
526         result += getPropertyName(static_cast<CSSPropertyID>(computedProperties[i]));
527         result += ": ";
528         result += getPropertyValue(computedProperties[i]);
529         result += ";";
530     }
531
532     return result;
533 }
534
535 void CSSComputedStyleDeclaration::setCssText(const String&, ExceptionCode& ec)
536 {
537     ec = NO_MODIFICATION_ALLOWED_ERR;
538 }
539
540 static int cssIdentifierForFontSizeKeyword(int keywordSize)
541 {
542     ASSERT_ARG(keywordSize, keywordSize);
543     ASSERT_ARG(keywordSize, keywordSize <= 8);
544     return CSSValueXxSmall + keywordSize - 1;
545 }
546
547 PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getFontSizeCSSValuePreferringKeyword() const
548 {
549     Node* node = m_node.get();
550     if (!node)
551         return 0;
552
553     node->document()->updateLayoutIgnorePendingStylesheets();
554
555     RefPtr<RenderStyle> style = node->computedStyle(m_pseudoElementSpecifier);
556     if (!style)
557         return 0;
558
559     if (int keywordSize = style->fontDescription().keywordSize())
560         return CSSPrimitiveValue::createIdentifier(cssIdentifierForFontSizeKeyword(keywordSize));
561
562     return CSSPrimitiveValue::create(style->fontDescription().computedPixelSize(), CSSPrimitiveValue::CSS_PX);
563 }
564
565 PassRefPtr<CSSValue> CSSComputedStyleDeclaration::valueForShadow(const ShadowData* shadow, int id) const
566 {
567     if (!shadow)
568         return CSSPrimitiveValue::createIdentifier(CSSValueNone);
569
570     CSSPropertyID propertyID = static_cast<CSSPropertyID>(id);
571
572     RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
573     for (const ShadowData* s = shadow; s; s = s->next()) {
574         RefPtr<CSSPrimitiveValue> x = CSSPrimitiveValue::create(s->x(), CSSPrimitiveValue::CSS_PX);
575         RefPtr<CSSPrimitiveValue> y = CSSPrimitiveValue::create(s->y(), CSSPrimitiveValue::CSS_PX);
576         RefPtr<CSSPrimitiveValue> blur = CSSPrimitiveValue::create(s->blur(), CSSPrimitiveValue::CSS_PX);
577         RefPtr<CSSPrimitiveValue> spread = propertyID == CSSPropertyTextShadow ? 0 : CSSPrimitiveValue::create(s->spread(), CSSPrimitiveValue::CSS_PX);
578         RefPtr<CSSPrimitiveValue> style = propertyID == CSSPropertyTextShadow || s->style() == Normal ? 0 : CSSPrimitiveValue::createIdentifier(CSSValueInset);
579         RefPtr<CSSPrimitiveValue> color = CSSPrimitiveValue::createColor(s->color().rgb());
580         list->prepend(ShadowValue::create(x.release(), y.release(), blur.release(), spread.release(), style.release(), color.release()));
581     }
582     return list.release();
583 }
584
585 PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int propertyID) const
586 {
587     return getPropertyCSSValue(propertyID, UpdateLayout);
588 }
589
590 static int identifierForFamily(const AtomicString& family)
591 {
592     DEFINE_STATIC_LOCAL(AtomicString, cursiveFamily, ("-webkit-cursive")); 
593     DEFINE_STATIC_LOCAL(AtomicString, fantasyFamily, ("-webkit-fantasy")); 
594     DEFINE_STATIC_LOCAL(AtomicString, monospaceFamily, ("-webkit-monospace")); 
595     DEFINE_STATIC_LOCAL(AtomicString, sansSerifFamily, ("-webkit-sans-serif")); 
596     DEFINE_STATIC_LOCAL(AtomicString, serifFamily, ("-webkit-serif")); 
597     if (family == cursiveFamily)
598         return CSSValueCursive;
599     if (family == fantasyFamily)
600         return CSSValueFantasy;
601     if (family == monospaceFamily)
602         return CSSValueMonospace;
603     if (family == sansSerifFamily)
604         return CSSValueSansSerif;
605     if (family == serifFamily)
606         return CSSValueSerif;
607     return 0;
608 }
609
610 static PassRefPtr<CSSPrimitiveValue> valueForFamily(const AtomicString& family)
611 {
612     if (int familyIdentifier = identifierForFamily(family))
613         return CSSPrimitiveValue::createIdentifier(familyIdentifier);
614     return CSSPrimitiveValue::create(family.string(), CSSPrimitiveValue::CSS_STRING);
615 }
616
617 static PassRefPtr<CSSValue> renderTextDecorationFlagsToCSSValue(int textDecoration)
618 {
619     RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
620     if (textDecoration & UNDERLINE)
621         list->append(CSSPrimitiveValue::createIdentifier(CSSValueUnderline));
622     if (textDecoration & OVERLINE)
623         list->append(CSSPrimitiveValue::createIdentifier(CSSValueOverline));
624     if (textDecoration & LINE_THROUGH)
625         list->append(CSSPrimitiveValue::createIdentifier(CSSValueLineThrough));
626     if (textDecoration & BLINK)
627         list->append(CSSPrimitiveValue::createIdentifier(CSSValueBlink));
628
629     if (!list->length())
630         return CSSPrimitiveValue::createIdentifier(CSSValueNone);
631     return list;
632 }
633
634 static PassRefPtr<CSSValue> fillRepeatToCSSValue(EFillRepeat xRepeat, EFillRepeat yRepeat)
635 {
636     // For backwards compatibility, if both values are equal, just return one of them. And
637     // if the two values are equivalent to repeat-x or repeat-y, just return the shorthand.
638     if (xRepeat == yRepeat)
639         return CSSPrimitiveValue::create(xRepeat);
640     if (xRepeat == RepeatFill && yRepeat == NoRepeatFill)
641         return CSSPrimitiveValue::createIdentifier(CSSValueRepeatX);
642     if (xRepeat == NoRepeatFill && yRepeat == RepeatFill)
643         return CSSPrimitiveValue::createIdentifier(CSSValueRepeatY);
644
645     RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
646     list->append(CSSPrimitiveValue::create(xRepeat));
647     list->append(CSSPrimitiveValue::create(yRepeat));
648     return list.release();
649 }
650
651 static void logUnimplementedPropertyID(int propertyID)
652 {
653     DEFINE_STATIC_LOCAL(HashSet<int>, propertyIDSet, ());
654     if (!propertyIDSet.add(propertyID).second)
655         return;
656
657     LOG_ERROR("WebKit does not yet implement getComputedStyle for '%s'.", getPropertyName(static_cast<CSSPropertyID>(propertyID)));
658
659
660 PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int propertyID, EUpdateLayout updateLayout) const
661 {
662     Node* node = m_node.get();
663     if (!node)
664         return 0;
665
666     // Make sure our layout is up to date before we allow a query on these attributes.
667     if (updateLayout)
668         node->document()->updateLayoutIgnorePendingStylesheets();
669
670     RenderObject* renderer = node->renderer();
671
672     RefPtr<RenderStyle> style;
673     if (renderer && hasCompositedLayer(renderer) && AnimationController::supportsAcceleratedAnimationOfProperty(static_cast<CSSPropertyID>(propertyID))) {
674         style = renderer->animation()->getAnimatedStyleForRenderer(renderer);
675         if (m_pseudoElementSpecifier) {
676             // FIXME: This cached pseudo style will only exist if the animation has been run at least once.
677             style = style->getCachedPseudoStyle(m_pseudoElementSpecifier);
678         }
679     } else
680         style = node->computedStyle(m_pseudoElementSpecifier);
681
682     if (!style)
683         return 0;
684
685     switch (static_cast<CSSPropertyID>(propertyID)) {
686         case CSSPropertyInvalid:
687             break;
688
689         case CSSPropertyBackgroundColor:
690             return CSSPrimitiveValue::createColor(m_allowVisitedStyle? style->visitedDependentColor(CSSPropertyBackgroundColor).rgb() : style->backgroundColor().rgb());
691         case CSSPropertyBackgroundImage:
692             if (style->backgroundImage())
693                 return style->backgroundImage()->cssValue();
694             return CSSPrimitiveValue::createIdentifier(CSSValueNone);
695         case CSSPropertyBackgroundSize:
696         case CSSPropertyWebkitBackgroundSize: {
697             EFillSizeType size = style->backgroundSizeType();
698             if (size == Contain)
699                 return CSSPrimitiveValue::createIdentifier(CSSValueContain);
700             if (size == Cover)
701                 return CSSPrimitiveValue::createIdentifier(CSSValueCover);
702             RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
703             list->append(CSSPrimitiveValue::create(style->backgroundSizeLength().width()));
704             list->append(CSSPrimitiveValue::create(style->backgroundSizeLength().height()));
705             return list.release();
706         }  
707         case CSSPropertyBackgroundRepeat:
708             return fillRepeatToCSSValue(style->backgroundRepeatX(), style->backgroundRepeatY());
709         case CSSPropertyWebkitBackgroundComposite:
710             return CSSPrimitiveValue::create(style->backgroundComposite());
711         case CSSPropertyBackgroundAttachment:
712             return CSSPrimitiveValue::create(style->backgroundAttachment());
713         case CSSPropertyBackgroundClip:
714         case CSSPropertyBackgroundOrigin:
715         case CSSPropertyWebkitBackgroundClip:
716         case CSSPropertyWebkitBackgroundOrigin: {
717             EFillBox box = (propertyID == CSSPropertyWebkitBackgroundClip || propertyID == CSSPropertyBackgroundClip) ? style->backgroundClip() : style->backgroundOrigin();
718             return CSSPrimitiveValue::create(box);
719         }
720         case CSSPropertyBackgroundPosition: {
721             RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
722
723             list->append(CSSPrimitiveValue::create(style->backgroundXPosition()));
724             list->append(CSSPrimitiveValue::create(style->backgroundYPosition()));
725
726             return list.release();
727         }
728         case CSSPropertyBackgroundPositionX:
729             return CSSPrimitiveValue::create(style->backgroundXPosition());
730         case CSSPropertyBackgroundPositionY:
731             return CSSPrimitiveValue::create(style->backgroundYPosition());
732         case CSSPropertyBorderCollapse:
733             if (style->borderCollapse())
734                 return CSSPrimitiveValue::createIdentifier(CSSValueCollapse);
735             return CSSPrimitiveValue::createIdentifier(CSSValueSeparate);
736         case CSSPropertyBorderSpacing: {
737             RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
738             list->append(CSSPrimitiveValue::create(style->horizontalBorderSpacing(), CSSPrimitiveValue::CSS_PX));
739             list->append(CSSPrimitiveValue::create(style->verticalBorderSpacing(), CSSPrimitiveValue::CSS_PX));
740             return list.release();
741         }  
742         case CSSPropertyWebkitBorderHorizontalSpacing:
743             return CSSPrimitiveValue::create(style->horizontalBorderSpacing(), CSSPrimitiveValue::CSS_PX);
744         case CSSPropertyWebkitBorderVerticalSpacing:
745             return CSSPrimitiveValue::create(style->verticalBorderSpacing(), CSSPrimitiveValue::CSS_PX);
746         case CSSPropertyBorderTopColor:
747             return m_allowVisitedStyle ? CSSPrimitiveValue::createColor(style->visitedDependentColor(CSSPropertyBorderTopColor).rgb()) : currentColorOrValidColor(style.get(), style->borderTopColor());
748         case CSSPropertyBorderRightColor:
749             return m_allowVisitedStyle ? CSSPrimitiveValue::createColor(style->visitedDependentColor(CSSPropertyBorderRightColor).rgb()) : currentColorOrValidColor(style.get(), style->borderRightColor());
750         case CSSPropertyBorderBottomColor:
751             return m_allowVisitedStyle ? CSSPrimitiveValue::createColor(style->visitedDependentColor(CSSPropertyBorderBottomColor).rgb()) : currentColorOrValidColor(style.get(), style->borderBottomColor());
752         case CSSPropertyBorderLeftColor:
753             return m_allowVisitedStyle ? CSSPrimitiveValue::createColor(style->visitedDependentColor(CSSPropertyBorderLeftColor).rgb()) : currentColorOrValidColor(style.get(), style->borderLeftColor());
754         case CSSPropertyBorderTopStyle:
755             return CSSPrimitiveValue::create(style->borderTopStyle());
756         case CSSPropertyBorderRightStyle:
757             return CSSPrimitiveValue::create(style->borderRightStyle());
758         case CSSPropertyBorderBottomStyle:
759             return CSSPrimitiveValue::create(style->borderBottomStyle());
760         case CSSPropertyBorderLeftStyle:
761             return CSSPrimitiveValue::create(style->borderLeftStyle());
762         case CSSPropertyBorderTopWidth:
763             return CSSPrimitiveValue::create(style->borderTopWidth(), CSSPrimitiveValue::CSS_PX);
764         case CSSPropertyBorderRightWidth:
765             return CSSPrimitiveValue::create(style->borderRightWidth(), CSSPrimitiveValue::CSS_PX);
766         case CSSPropertyBorderBottomWidth:
767             return CSSPrimitiveValue::create(style->borderBottomWidth(), CSSPrimitiveValue::CSS_PX);
768         case CSSPropertyBorderLeftWidth:
769             return CSSPrimitiveValue::create(style->borderLeftWidth(), CSSPrimitiveValue::CSS_PX);
770         case CSSPropertyBottom:
771             return getPositionOffsetValue(style.get(), CSSPropertyBottom);
772         case CSSPropertyWebkitBoxAlign:
773             return CSSPrimitiveValue::create(style->boxAlign());
774         case CSSPropertyWebkitBoxDirection:
775             return CSSPrimitiveValue::create(style->boxDirection());
776         case CSSPropertyWebkitBoxFlex:
777             return CSSPrimitiveValue::create(style->boxFlex(), CSSPrimitiveValue::CSS_NUMBER);
778         case CSSPropertyWebkitBoxFlexGroup:
779             return CSSPrimitiveValue::create(style->boxFlexGroup(), CSSPrimitiveValue::CSS_NUMBER);
780         case CSSPropertyWebkitBoxLines:
781             return CSSPrimitiveValue::create(style->boxLines());
782         case CSSPropertyWebkitBoxOrdinalGroup:
783             return CSSPrimitiveValue::create(style->boxOrdinalGroup(), CSSPrimitiveValue::CSS_NUMBER);
784         case CSSPropertyWebkitBoxOrient:
785             return CSSPrimitiveValue::create(style->boxOrient());
786         case CSSPropertyWebkitBoxPack: {
787             EBoxAlignment boxPack = style->boxPack();
788             ASSERT(boxPack != BSTRETCH);
789             ASSERT(boxPack != BBASELINE);
790             if (boxPack == BJUSTIFY || boxPack== BBASELINE)
791                 return 0;
792             return CSSPrimitiveValue::create(boxPack);
793         }
794         case CSSPropertyWebkitBoxReflect:
795             return valueForReflection(style->boxReflect());
796         case CSSPropertyWebkitBoxShadow:
797             return valueForShadow(style->boxShadow(), propertyID);
798         case CSSPropertyCaptionSide:
799             return CSSPrimitiveValue::create(style->captionSide());
800         case CSSPropertyClear:
801             return CSSPrimitiveValue::create(style->clear());
802         case CSSPropertyColor:
803             return CSSPrimitiveValue::createColor(m_allowVisitedStyle ? style->visitedDependentColor(CSSPropertyColor).rgb() : style->color().rgb());
804         case CSSPropertyWebkitColumnCount:
805             if (style->hasAutoColumnCount())
806                 return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
807             return CSSPrimitiveValue::create(style->columnCount(), CSSPrimitiveValue::CSS_NUMBER);
808         case CSSPropertyWebkitColumnGap:
809             if (style->hasNormalColumnGap())
810                 return CSSPrimitiveValue::createIdentifier(CSSValueNormal);
811             return CSSPrimitiveValue::create(style->columnGap(), CSSPrimitiveValue::CSS_NUMBER);
812         case CSSPropertyWebkitColumnRuleColor:
813             return m_allowVisitedStyle ? CSSPrimitiveValue::createColor(style->visitedDependentColor(CSSPropertyOutlineColor).rgb()) : currentColorOrValidColor(style.get(), style->columnRuleColor());
814         case CSSPropertyWebkitColumnRuleStyle:
815             return CSSPrimitiveValue::create(style->columnRuleStyle());
816         case CSSPropertyWebkitColumnRuleWidth:
817             return CSSPrimitiveValue::create(style->columnRuleWidth(), CSSPrimitiveValue::CSS_PX);
818         case CSSPropertyWebkitColumnSpan:
819             if (style->columnSpan())
820                 return CSSPrimitiveValue::createIdentifier(CSSValueAll);
821             return CSSPrimitiveValue::create(1, CSSPrimitiveValue::CSS_NUMBER);
822         case CSSPropertyWebkitColumnBreakAfter:
823             return CSSPrimitiveValue::create(style->columnBreakAfter());
824         case CSSPropertyWebkitColumnBreakBefore:
825             return CSSPrimitiveValue::create(style->columnBreakBefore());
826         case CSSPropertyWebkitColumnBreakInside:
827             return CSSPrimitiveValue::create(style->columnBreakInside());
828         case CSSPropertyWebkitColumnWidth:
829             if (style->hasAutoColumnWidth())
830                 return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
831             return CSSPrimitiveValue::create(style->columnWidth(), CSSPrimitiveValue::CSS_NUMBER);
832         case CSSPropertyCursor: {
833             RefPtr<CSSValueList> list;
834             CursorList* cursors = style->cursors();
835             if (cursors && cursors->size() > 0) {
836                 list = CSSValueList::createCommaSeparated();
837                 for (unsigned i = 0; i < cursors->size(); ++i)
838                     list->append(CSSPrimitiveValue::create((*cursors)[i].image()->url(), CSSPrimitiveValue::CSS_URI));
839             }
840             RefPtr<CSSValue> value = CSSPrimitiveValue::create(style->cursor());
841             if (list) {
842                 list->append(value);
843                 return list.release();
844             }
845             return value.release();
846         }
847         case CSSPropertyDirection:
848             return CSSPrimitiveValue::create(style->direction());
849         case CSSPropertyDisplay:
850             return CSSPrimitiveValue::create(style->display());
851         case CSSPropertyEmptyCells:
852             return CSSPrimitiveValue::create(style->emptyCells());
853         case CSSPropertyFloat:
854             return CSSPrimitiveValue::create(style->floating());
855         case CSSPropertyFontFamily: {
856             const FontFamily& firstFamily = style->fontDescription().family();
857             if (!firstFamily.next())
858                 return valueForFamily(firstFamily.family());
859             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
860             for (const FontFamily* family = &firstFamily; family; family = family->next())
861                 list->append(valueForFamily(family->family()));
862             return list.release();
863         }
864         case CSSPropertyFontSize:
865             return CSSPrimitiveValue::create(style->fontDescription().computedPixelSize(), CSSPrimitiveValue::CSS_PX);
866         case CSSPropertyWebkitBinding:
867             break;
868         case CSSPropertyFontStyle:
869             if (style->fontDescription().italic())
870                 return CSSPrimitiveValue::createIdentifier(CSSValueItalic);
871             return CSSPrimitiveValue::createIdentifier(CSSValueNormal);
872         case CSSPropertyFontVariant:
873             if (style->fontDescription().smallCaps())
874                 return CSSPrimitiveValue::createIdentifier(CSSValueSmallCaps);
875             return CSSPrimitiveValue::createIdentifier(CSSValueNormal);
876         case CSSPropertyFontWeight:
877             switch (style->fontDescription().weight()) {
878                 case FontWeight100:
879                     return CSSPrimitiveValue::createIdentifier(CSSValue100);
880                 case FontWeight200:
881                     return CSSPrimitiveValue::createIdentifier(CSSValue200);
882                 case FontWeight300:
883                     return CSSPrimitiveValue::createIdentifier(CSSValue300);
884                 case FontWeightNormal:
885                     return CSSPrimitiveValue::createIdentifier(CSSValueNormal);
886                 case FontWeight500:
887                     return CSSPrimitiveValue::createIdentifier(CSSValue500);
888                 case FontWeight600:
889                     return CSSPrimitiveValue::createIdentifier(CSSValue600);
890                 case FontWeightBold:
891                     return CSSPrimitiveValue::createIdentifier(CSSValueBold);
892                 case FontWeight800:
893                     return CSSPrimitiveValue::createIdentifier(CSSValue800);
894                 case FontWeight900:
895                     return CSSPrimitiveValue::createIdentifier(CSSValue900);
896             }
897             ASSERT_NOT_REACHED();
898             return CSSPrimitiveValue::createIdentifier(CSSValueNormal);
899         case CSSPropertyHeight:
900             if (renderer)
901                 return CSSPrimitiveValue::create(sizingBox(renderer).height(), CSSPrimitiveValue::CSS_PX);
902             return CSSPrimitiveValue::create(style->height());
903         case CSSPropertyWebkitHighlight:
904             if (style->highlight() == nullAtom)
905                 return CSSPrimitiveValue::createIdentifier(CSSValueNone);
906             return CSSPrimitiveValue::create(style->highlight(), CSSPrimitiveValue::CSS_STRING);
907         case CSSPropertyWebkitBorderFit:
908             if (style->borderFit() == BorderFitBorder)
909                 return CSSPrimitiveValue::createIdentifier(CSSValueBorder);
910             return CSSPrimitiveValue::createIdentifier(CSSValueLines);
911         case CSSPropertyLeft:
912             return getPositionOffsetValue(style.get(), CSSPropertyLeft);
913         case CSSPropertyLetterSpacing:
914             if (!style->letterSpacing())
915                 return CSSPrimitiveValue::createIdentifier(CSSValueNormal);
916             return CSSPrimitiveValue::create(style->letterSpacing(), CSSPrimitiveValue::CSS_PX);
917         case CSSPropertyWebkitLineClamp:
918             if (style->lineClamp().isNone())
919                 return CSSPrimitiveValue::createIdentifier(CSSValueNone);
920             return CSSPrimitiveValue::create(style->lineClamp().value(), style->lineClamp().isPercentage() ? CSSPrimitiveValue::CSS_PERCENTAGE : CSSPrimitiveValue::CSS_NUMBER);
921         case CSSPropertyLineHeight: {
922             Length length = style->lineHeight();
923             if (length.isNegative())
924                 return CSSPrimitiveValue::createIdentifier(CSSValueNormal);
925             if (length.isPercent())
926                 // This is imperfect, because it doesn't include the zoom factor and the real computation
927                 // for how high to be in pixels does include things like minimum font size and the zoom factor.
928                 // On the other hand, since font-size doesn't include the zoom factor, we really can't do
929                 // that here either.
930                 return CSSPrimitiveValue::create(static_cast<int>(length.percent() * style->fontDescription().specifiedSize()) / 100, CSSPrimitiveValue::CSS_PX);
931             return CSSPrimitiveValue::create(length.value(), CSSPrimitiveValue::CSS_PX);
932         }
933         case CSSPropertyListStyleImage:
934             if (style->listStyleImage())
935                 return style->listStyleImage()->cssValue();
936             return CSSPrimitiveValue::createIdentifier(CSSValueNone);
937         case CSSPropertyListStylePosition:
938             return CSSPrimitiveValue::create(style->listStylePosition());
939         case CSSPropertyListStyleType:
940             return CSSPrimitiveValue::create(style->listStyleType());
941         case CSSPropertyMarginTop:
942             if (renderer && renderer->isBox())
943                 // FIXME: Supposed to return the percentage if percentage was specified.
944                 return CSSPrimitiveValue::create(toRenderBox(renderer)->marginTop(), CSSPrimitiveValue::CSS_PX);
945             return CSSPrimitiveValue::create(style->marginTop());
946         case CSSPropertyMarginRight:
947             if (renderer && renderer->isBox())
948                 // FIXME: Supposed to return the percentage if percentage was specified.
949                 return CSSPrimitiveValue::create(toRenderBox(renderer)->marginRight(), CSSPrimitiveValue::CSS_PX);
950             return CSSPrimitiveValue::create(style->marginRight());
951         case CSSPropertyMarginBottom:
952             if (renderer && renderer->isBox())
953                 // FIXME: Supposed to return the percentage if percentage was specified.
954                 return CSSPrimitiveValue::create(toRenderBox(renderer)->marginBottom(), CSSPrimitiveValue::CSS_PX);
955             return CSSPrimitiveValue::create(style->marginBottom());
956         case CSSPropertyMarginLeft:
957             if (renderer && renderer->isBox())
958                 // FIXME: Supposed to return the percentage if percentage was specified.
959                 return CSSPrimitiveValue::create(toRenderBox(renderer)->marginLeft(), CSSPrimitiveValue::CSS_PX);
960             return CSSPrimitiveValue::create(style->marginLeft());
961         case CSSPropertyWebkitMarqueeDirection:
962             return CSSPrimitiveValue::create(style->marqueeDirection());
963         case CSSPropertyWebkitMarqueeIncrement:
964             return CSSPrimitiveValue::create(style->marqueeIncrement());
965         case CSSPropertyWebkitMarqueeRepetition:
966             if (style->marqueeLoopCount() < 0)
967                 return CSSPrimitiveValue::createIdentifier(CSSValueInfinite);
968             return CSSPrimitiveValue::create(style->marqueeLoopCount(), CSSPrimitiveValue::CSS_NUMBER);
969         case CSSPropertyWebkitMarqueeStyle:
970             return CSSPrimitiveValue::create(style->marqueeBehavior());
971         case CSSPropertyWebkitMaskImage:
972             if (style->maskImage())
973                 return style->maskImage()->cssValue();
974             return CSSPrimitiveValue::createIdentifier(CSSValueNone);
975         case CSSPropertyWebkitMaskSize: {
976             EFillSizeType size = style->maskSizeType();
977             if (size == Contain)
978                 return CSSPrimitiveValue::createIdentifier(CSSValueContain);
979             if (size == Cover)
980                 return CSSPrimitiveValue::createIdentifier(CSSValueCover);
981             RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
982             list->append(CSSPrimitiveValue::create(style->maskSizeLength().width()));
983             list->append(CSSPrimitiveValue::create(style->maskSizeLength().height()));
984             return list.release();
985         }  
986         case CSSPropertyWebkitMaskRepeat:
987             return fillRepeatToCSSValue(style->maskRepeatX(), style->maskRepeatY());
988         case CSSPropertyWebkitMaskAttachment:
989             return CSSPrimitiveValue::create(style->maskAttachment());
990         case CSSPropertyWebkitMaskComposite:
991             return CSSPrimitiveValue::create(style->maskComposite());
992         case CSSPropertyWebkitMaskClip:
993         case CSSPropertyWebkitMaskOrigin: {
994             EFillBox box = (propertyID == CSSPropertyWebkitMaskClip ? style->maskClip() : style->maskOrigin());
995             return CSSPrimitiveValue::create(box);
996         }
997         case CSSPropertyWebkitMaskPosition: {
998             RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
999
1000             list->append(CSSPrimitiveValue::create(style->maskXPosition()));
1001             list->append(CSSPrimitiveValue::create(style->maskYPosition()));
1002
1003             return list.release();
1004         }
1005         case CSSPropertyWebkitMaskPositionX:
1006             return CSSPrimitiveValue::create(style->maskXPosition());
1007         case CSSPropertyWebkitMaskPositionY:
1008             return CSSPrimitiveValue::create(style->maskYPosition());
1009         case CSSPropertyWebkitUserModify:
1010             return CSSPrimitiveValue::create(style->userModify());
1011         case CSSPropertyMaxHeight: {
1012             const Length& maxHeight = style->maxHeight();
1013             if (maxHeight.isFixed() && maxHeight.value() == undefinedLength)
1014                 return CSSPrimitiveValue::createIdentifier(CSSValueNone);
1015             return CSSPrimitiveValue::create(maxHeight);
1016         }
1017         case CSSPropertyMaxWidth: {
1018             const Length& maxWidth = style->maxWidth();
1019             if (maxWidth.isFixed() && maxWidth.value() == undefinedLength)
1020                 return CSSPrimitiveValue::createIdentifier(CSSValueNone);
1021             return CSSPrimitiveValue::create(maxWidth);
1022         }
1023         case CSSPropertyMinHeight:
1024             return CSSPrimitiveValue::create(style->minHeight());
1025         case CSSPropertyMinWidth:
1026             return CSSPrimitiveValue::create(style->minWidth());
1027         case CSSPropertyOpacity:
1028             return CSSPrimitiveValue::create(style->opacity(), CSSPrimitiveValue::CSS_NUMBER);
1029         case CSSPropertyOrphans:
1030             return CSSPrimitiveValue::create(style->orphans(), CSSPrimitiveValue::CSS_NUMBER);
1031         case CSSPropertyOutlineColor:
1032             return m_allowVisitedStyle ? CSSPrimitiveValue::createColor(style->visitedDependentColor(CSSPropertyOutlineColor).rgb()) : currentColorOrValidColor(style.get(), style->outlineColor());
1033         case CSSPropertyOutlineStyle:
1034             if (style->outlineStyleIsAuto())
1035                 return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
1036             return CSSPrimitiveValue::create(style->outlineStyle());
1037         case CSSPropertyOutlineWidth:
1038             return CSSPrimitiveValue::create(style->outlineWidth(), CSSPrimitiveValue::CSS_PX);
1039         case CSSPropertyOverflow:
1040             return CSSPrimitiveValue::create(max(style->overflowX(), style->overflowY()));
1041         case CSSPropertyOverflowX:
1042             return CSSPrimitiveValue::create(style->overflowX());
1043         case CSSPropertyOverflowY:
1044             return CSSPrimitiveValue::create(style->overflowY());
1045         case CSSPropertyPaddingTop:
1046             if (renderer && renderer->isBox())
1047                 return CSSPrimitiveValue::create(toRenderBox(renderer)->paddingTop(false), CSSPrimitiveValue::CSS_PX);
1048             return CSSPrimitiveValue::create(style->paddingTop());
1049         case CSSPropertyPaddingRight:
1050             if (renderer && renderer->isBox())
1051                 return CSSPrimitiveValue::create(toRenderBox(renderer)->paddingRight(false), CSSPrimitiveValue::CSS_PX);
1052             return CSSPrimitiveValue::create(style->paddingRight());
1053         case CSSPropertyPaddingBottom:
1054             if (renderer && renderer->isBox())
1055                 return CSSPrimitiveValue::create(toRenderBox(renderer)->paddingBottom(false), CSSPrimitiveValue::CSS_PX);
1056             return CSSPrimitiveValue::create(style->paddingBottom());
1057         case CSSPropertyPaddingLeft:
1058             if (renderer && renderer->isBox())
1059                 return CSSPrimitiveValue::create(toRenderBox(renderer)->paddingLeft(false), CSSPrimitiveValue::CSS_PX);
1060             return CSSPrimitiveValue::create(style->paddingLeft());
1061         case CSSPropertyPageBreakAfter:
1062             return CSSPrimitiveValue::create(style->pageBreakAfter());
1063         case CSSPropertyPageBreakBefore:
1064             return CSSPrimitiveValue::create(style->pageBreakBefore());
1065         case CSSPropertyPageBreakInside: {
1066             EPageBreak pageBreak = style->pageBreakInside();
1067             ASSERT(pageBreak != PBALWAYS);
1068             if (pageBreak == PBALWAYS)
1069                 return 0;
1070             return CSSPrimitiveValue::create(style->pageBreakInside());
1071         }
1072         case CSSPropertyPosition:
1073             return CSSPrimitiveValue::create(style->position());
1074         case CSSPropertyRight:
1075             return getPositionOffsetValue(style.get(), CSSPropertyRight);
1076         case CSSPropertyTableLayout:
1077             return CSSPrimitiveValue::create(style->tableLayout());
1078         case CSSPropertyTextAlign:
1079             return CSSPrimitiveValue::create(style->textAlign());
1080         case CSSPropertyTextDecoration:
1081             return renderTextDecorationFlagsToCSSValue(style->textDecoration());
1082         case CSSPropertyWebkitTextDecorationsInEffect:
1083             return renderTextDecorationFlagsToCSSValue(style->textDecorationsInEffect());
1084         case CSSPropertyWebkitTextFillColor:
1085             return currentColorOrValidColor(style.get(), style->textFillColor());
1086         case CSSPropertyTextIndent:
1087             return CSSPrimitiveValue::create(style->textIndent());
1088         case CSSPropertyTextShadow:
1089             return valueForShadow(style->textShadow(), propertyID);
1090         case CSSPropertyTextRendering:
1091             return CSSPrimitiveValue::create(style->fontDescription().textRenderingMode());
1092         case CSSPropertyTextOverflow:
1093             if (style->textOverflow())
1094                 return CSSPrimitiveValue::createIdentifier(CSSValueEllipsis);
1095             return CSSPrimitiveValue::createIdentifier(CSSValueClip);
1096         case CSSPropertyWebkitTextSecurity:
1097             return CSSPrimitiveValue::create(style->textSecurity());
1098         case CSSPropertyWebkitTextSizeAdjust:
1099             if (style->textSizeAdjust())
1100                 return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
1101             return CSSPrimitiveValue::createIdentifier(CSSValueNone);
1102         case CSSPropertyWebkitTextStrokeColor:
1103             return currentColorOrValidColor(style.get(), style->textStrokeColor());
1104         case CSSPropertyWebkitTextStrokeWidth:
1105             return CSSPrimitiveValue::create(style->textStrokeWidth(), CSSPrimitiveValue::CSS_PX);
1106         case CSSPropertyTextTransform:
1107             return CSSPrimitiveValue::create(style->textTransform());
1108         case CSSPropertyTop:
1109             return getPositionOffsetValue(style.get(), CSSPropertyTop);
1110         case CSSPropertyUnicodeBidi:
1111             return CSSPrimitiveValue::create(style->unicodeBidi());
1112         case CSSPropertyVerticalAlign:
1113             switch (style->verticalAlign()) {
1114                 case BASELINE:
1115                     return CSSPrimitiveValue::createIdentifier(CSSValueBaseline);
1116                 case MIDDLE:
1117                     return CSSPrimitiveValue::createIdentifier(CSSValueMiddle);
1118                 case SUB:
1119                     return CSSPrimitiveValue::createIdentifier(CSSValueSub);
1120                 case SUPER:
1121                     return CSSPrimitiveValue::createIdentifier(CSSValueSuper);
1122                 case TEXT_TOP:
1123                     return CSSPrimitiveValue::createIdentifier(CSSValueTextTop);
1124                 case TEXT_BOTTOM:
1125                     return CSSPrimitiveValue::createIdentifier(CSSValueTextBottom);
1126                 case TOP:
1127                     return CSSPrimitiveValue::createIdentifier(CSSValueTop);
1128                 case BOTTOM:
1129                     return CSSPrimitiveValue::createIdentifier(CSSValueBottom);
1130                 case BASELINE_MIDDLE:
1131                     return CSSPrimitiveValue::createIdentifier(CSSValueWebkitBaselineMiddle);
1132                 case LENGTH:
1133                     return CSSPrimitiveValue::create(style->verticalAlignLength());
1134             }
1135             ASSERT_NOT_REACHED();
1136             return 0;
1137         case CSSPropertyVisibility:
1138             return CSSPrimitiveValue::create(style->visibility());
1139         case CSSPropertyWhiteSpace:
1140             return CSSPrimitiveValue::create(style->whiteSpace());
1141         case CSSPropertyWidows:
1142             return CSSPrimitiveValue::create(style->widows(), CSSPrimitiveValue::CSS_NUMBER);
1143         case CSSPropertyWidth:
1144             if (renderer)
1145                 return CSSPrimitiveValue::create(sizingBox(renderer).width(), CSSPrimitiveValue::CSS_PX);
1146             return CSSPrimitiveValue::create(style->width());
1147         case CSSPropertyWordBreak:
1148             return CSSPrimitiveValue::create(style->wordBreak());
1149         case CSSPropertyWordSpacing:
1150             return CSSPrimitiveValue::create(style->wordSpacing(), CSSPrimitiveValue::CSS_PX);
1151         case CSSPropertyWordWrap:
1152             return CSSPrimitiveValue::create(style->wordWrap());
1153         case CSSPropertyWebkitLineBreak:
1154             return CSSPrimitiveValue::create(style->khtmlLineBreak());
1155         case CSSPropertyWebkitNbspMode:
1156             return CSSPrimitiveValue::create(style->nbspMode());
1157         case CSSPropertyWebkitMatchNearestMailBlockquoteColor:
1158             return CSSPrimitiveValue::create(style->matchNearestMailBlockquoteColor());
1159         case CSSPropertyResize:
1160             return CSSPrimitiveValue::create(style->resize());
1161         case CSSPropertyWebkitFontSmoothing:
1162             return CSSPrimitiveValue::create(style->fontDescription().fontSmoothing());
1163         case CSSPropertyZIndex:
1164             if (style->hasAutoZIndex())
1165                 return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
1166             return CSSPrimitiveValue::create(style->zIndex(), CSSPrimitiveValue::CSS_NUMBER);
1167         case CSSPropertyZoom:
1168             return CSSPrimitiveValue::create(style->zoom(), CSSPrimitiveValue::CSS_NUMBER);
1169         case CSSPropertyWebkitBoxSizing:
1170             if (style->boxSizing() == CONTENT_BOX)
1171                 return CSSPrimitiveValue::createIdentifier(CSSValueContentBox);
1172             return CSSPrimitiveValue::createIdentifier(CSSValueBorderBox);
1173 #if ENABLE(DASHBOARD_SUPPORT)
1174         case CSSPropertyWebkitDashboardRegion:
1175         {
1176             const Vector<StyleDashboardRegion>& regions = style->dashboardRegions();
1177             unsigned count = regions.size();
1178             if (count == 1 && regions[0].type == StyleDashboardRegion::None)
1179                 return CSSPrimitiveValue::createIdentifier(CSSValueNone);
1180
1181             RefPtr<DashboardRegion> firstRegion;
1182             DashboardRegion* previousRegion = 0;
1183             for (unsigned i = 0; i < count; i++) {
1184                 RefPtr<DashboardRegion> region = DashboardRegion::create();
1185                 StyleDashboardRegion styleRegion = regions[i];
1186
1187                 region->m_label = styleRegion.label;
1188                 LengthBox offset = styleRegion.offset;
1189                 region->setTop(CSSPrimitiveValue::create(offset.top().value(), CSSPrimitiveValue::CSS_PX));
1190                 region->setRight(CSSPrimitiveValue::create(offset.right().value(), CSSPrimitiveValue::CSS_PX));
1191                 region->setBottom(CSSPrimitiveValue::create(offset.bottom().value(), CSSPrimitiveValue::CSS_PX));
1192                 region->setLeft(CSSPrimitiveValue::create(offset.left().value(), CSSPrimitiveValue::CSS_PX));
1193                 region->m_isRectangle = (styleRegion.type == StyleDashboardRegion::Rectangle);
1194                 region->m_isCircle = (styleRegion.type == StyleDashboardRegion::Circle);
1195
1196                 if (previousRegion)
1197                     previousRegion->m_next = region;
1198                 else
1199                     firstRegion = region;
1200                 previousRegion = region.get();
1201             }
1202             return CSSPrimitiveValue::create(firstRegion.release());
1203         }
1204 #endif
1205         case CSSPropertyWebkitAnimationDelay:
1206             return getDelayValue(style->animations());
1207         case CSSPropertyWebkitAnimationDirection: {
1208             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1209             const AnimationList* t = style->animations();
1210             if (t) {
1211                 for (size_t i = 0; i < t->size(); ++i) {
1212                     if (t->animation(i)->direction())
1213                         list->append(CSSPrimitiveValue::createIdentifier(CSSValueAlternate));
1214                     else
1215                         list->append(CSSPrimitiveValue::createIdentifier(CSSValueNormal));
1216                 }
1217             } else
1218                 list->append(CSSPrimitiveValue::createIdentifier(CSSValueNormal));
1219             return list.release();
1220         }
1221         case CSSPropertyWebkitAnimationDuration:
1222             return getDurationValue(style->animations());
1223         case CSSPropertyWebkitAnimationFillMode: {
1224             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1225             const AnimationList* t = style->animations();
1226             if (t) {
1227                 for (size_t i = 0; i < t->size(); ++i) {
1228                     switch (t->animation(i)->fillMode()) {
1229                     case AnimationFillModeNone:
1230                         list->append(CSSPrimitiveValue::createIdentifier(CSSValueNone));
1231                         break;
1232                     case AnimationFillModeForwards:
1233                         list->append(CSSPrimitiveValue::createIdentifier(CSSValueForwards));
1234                         break;
1235                     case AnimationFillModeBackwards:
1236                         list->append(CSSPrimitiveValue::createIdentifier(CSSValueBackwards));
1237                         break;
1238                     case AnimationFillModeBoth:
1239                         list->append(CSSPrimitiveValue::createIdentifier(CSSValueBoth));
1240                         break;
1241                     }
1242                 }
1243             } else
1244                 list->append(CSSPrimitiveValue::createIdentifier(CSSValueNone));
1245             return list.release();
1246         }
1247         case CSSPropertyWebkitAnimationIterationCount: {
1248             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1249             const AnimationList* t = style->animations();
1250             if (t) {
1251                 for (size_t i = 0; i < t->size(); ++i) {
1252                     int iterationCount = t->animation(i)->iterationCount();
1253                     if (iterationCount == Animation::IterationCountInfinite)
1254                         list->append(CSSPrimitiveValue::createIdentifier(CSSValueInfinite));
1255                     else
1256                         list->append(CSSPrimitiveValue::create(iterationCount, CSSPrimitiveValue::CSS_NUMBER));
1257                 }
1258             } else
1259                 list->append(CSSPrimitiveValue::create(Animation::initialAnimationIterationCount(), CSSPrimitiveValue::CSS_NUMBER));
1260             return list.release();
1261         }
1262         case CSSPropertyWebkitAnimationName: {
1263             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1264             const AnimationList* t = style->animations();
1265             if (t) {
1266                 for (size_t i = 0; i < t->size(); ++i) {
1267                     list->append(CSSPrimitiveValue::create(t->animation(i)->name(), CSSPrimitiveValue::CSS_STRING));
1268                 }
1269             } else
1270                 list->append(CSSPrimitiveValue::createIdentifier(CSSValueNone));
1271             return list.release();
1272         }
1273         case CSSPropertyWebkitAnimationPlayState: {
1274             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1275             const AnimationList* t = style->animations();
1276             if (t) {
1277                 for (size_t i = 0; i < t->size(); ++i) {
1278                     int prop = t->animation(i)->playState();
1279                     if (prop == AnimPlayStatePlaying)
1280                         list->append(CSSPrimitiveValue::createIdentifier(CSSValueRunning));
1281                     else
1282                         list->append(CSSPrimitiveValue::createIdentifier(CSSValuePaused));
1283                 }
1284             } else
1285                 list->append(CSSPrimitiveValue::createIdentifier(CSSValueRunning));
1286             return list.release();
1287         }
1288         case CSSPropertyWebkitAnimationTimingFunction:
1289             return getTimingFunctionValue(style->animations());
1290         case CSSPropertyWebkitAppearance:
1291             return CSSPrimitiveValue::create(style->appearance());
1292         case CSSPropertyWebkitBackfaceVisibility:
1293             return CSSPrimitiveValue::createIdentifier((style->backfaceVisibility() == BackfaceVisibilityHidden) ? CSSValueHidden : CSSValueVisible);
1294         case CSSPropertyWebkitBorderImage:
1295             return valueForNinePieceImage(style->borderImage());
1296         case CSSPropertyWebkitMaskBoxImage:
1297             return valueForNinePieceImage(style->maskBoxImage());
1298         case CSSPropertyWebkitFontSizeDelta:
1299             // Not a real style property -- used by the editing engine -- so has no computed value.
1300             break;
1301         case CSSPropertyWebkitMarginBottomCollapse:
1302             return CSSPrimitiveValue::create(style->marginBottomCollapse());
1303         case CSSPropertyWebkitMarginTopCollapse:
1304             return CSSPrimitiveValue::create(style->marginTopCollapse());
1305         case CSSPropertyWebkitPerspective:
1306             if (!style->hasPerspective())
1307                 return CSSPrimitiveValue::createIdentifier(CSSValueNone);
1308             return CSSPrimitiveValue::create(style->perspective(), CSSPrimitiveValue::CSS_NUMBER);
1309         case CSSPropertyWebkitPerspectiveOrigin: {
1310             RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
1311             if (renderer) {
1312                 IntRect box = sizingBox(renderer);
1313                 list->append(CSSPrimitiveValue::create(style->perspectiveOriginX().calcMinValue(box.width()), CSSPrimitiveValue::CSS_PX));
1314                 list->append(CSSPrimitiveValue::create(style->perspectiveOriginY().calcMinValue(box.height()), CSSPrimitiveValue::CSS_PX));
1315             }
1316             else {
1317                 list->append(CSSPrimitiveValue::create(style->perspectiveOriginX()));
1318                 list->append(CSSPrimitiveValue::create(style->perspectiveOriginY()));
1319             }
1320             return list.release();
1321         }
1322         case CSSPropertyWebkitRtlOrdering:
1323             if (style->visuallyOrdered())
1324                 return CSSPrimitiveValue::createIdentifier(CSSValueVisual);
1325             return CSSPrimitiveValue::createIdentifier(CSSValueLogical);
1326         case CSSPropertyWebkitUserDrag:
1327             return CSSPrimitiveValue::create(style->userDrag());
1328         case CSSPropertyWebkitUserSelect:
1329             return CSSPrimitiveValue::create(style->userSelect());
1330         case CSSPropertyBorderBottomLeftRadius:
1331             return getBorderRadiusCornerValue(style->borderBottomLeftRadius());
1332         case CSSPropertyBorderBottomRightRadius:
1333             return getBorderRadiusCornerValue(style->borderBottomRightRadius());
1334         case CSSPropertyBorderTopLeftRadius:
1335             return getBorderRadiusCornerValue(style->borderTopLeftRadius());
1336         case CSSPropertyBorderTopRightRadius:
1337             return getBorderRadiusCornerValue(style->borderTopRightRadius());
1338         case CSSPropertyClip: {
1339             if (!style->hasClip())
1340                 return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
1341             RefPtr<Rect> rect = Rect::create();
1342             rect->setTop(CSSPrimitiveValue::create(style->clip().top().value(), CSSPrimitiveValue::CSS_PX));
1343             rect->setRight(CSSPrimitiveValue::create(style->clip().right().value(), CSSPrimitiveValue::CSS_PX));
1344             rect->setBottom(CSSPrimitiveValue::create(style->clip().bottom().value(), CSSPrimitiveValue::CSS_PX));
1345             rect->setLeft(CSSPrimitiveValue::create(style->clip().left().value(), CSSPrimitiveValue::CSS_PX));
1346             return CSSPrimitiveValue::create(rect.release());
1347         }
1348         case CSSPropertyWebkitTransform:
1349             return computedTransform(renderer, style.get());
1350         case CSSPropertyWebkitTransformOrigin: {
1351             RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
1352             if (renderer) {
1353                 IntRect box = sizingBox(renderer);
1354                 list->append(CSSPrimitiveValue::create(style->transformOriginX().calcMinValue(box.width()), CSSPrimitiveValue::CSS_PX));
1355                 list->append(CSSPrimitiveValue::create(style->transformOriginY().calcMinValue(box.height()), CSSPrimitiveValue::CSS_PX));
1356                 if (style->transformOriginZ() != 0)
1357                     list->append(CSSPrimitiveValue::create(style->transformOriginZ(), CSSPrimitiveValue::CSS_PX));
1358             } else {
1359                 list->append(CSSPrimitiveValue::create(style->transformOriginX()));
1360                 list->append(CSSPrimitiveValue::create(style->transformOriginY()));
1361                 if (style->transformOriginZ() != 0)
1362                     list->append(CSSPrimitiveValue::create(style->transformOriginZ(), CSSPrimitiveValue::CSS_PX));
1363             }
1364             return list.release();
1365         }
1366         case CSSPropertyWebkitTransformStyle:
1367             return CSSPrimitiveValue::createIdentifier((style->transformStyle3D() == TransformStyle3DPreserve3D) ? CSSValuePreserve3d : CSSValueFlat);
1368         case CSSPropertyWebkitTransitionDelay:
1369             return getDelayValue(style->transitions());
1370         case CSSPropertyWebkitTransitionDuration:
1371             return getDurationValue(style->transitions());
1372         case CSSPropertyWebkitTransitionProperty: {
1373             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
1374             const AnimationList* t = style->transitions();
1375             if (t) {
1376                 for (size_t i = 0; i < t->size(); ++i) {
1377                     int prop = t->animation(i)->property();
1378                     RefPtr<CSSValue> propertyValue;
1379                     if (prop == cAnimateNone)
1380                         propertyValue = CSSPrimitiveValue::createIdentifier(CSSValueNone);
1381                     else if (prop == cAnimateAll)
1382                         propertyValue = CSSPrimitiveValue::createIdentifier(CSSValueAll);
1383                     else
1384                         propertyValue = CSSPrimitiveValue::create(getPropertyName(static_cast<CSSPropertyID>(prop)), CSSPrimitiveValue::CSS_STRING);
1385                     list->append(propertyValue);
1386                 }
1387             } else
1388                 list->append(CSSPrimitiveValue::createIdentifier(CSSValueAll));
1389             return list.release();
1390         }
1391         case CSSPropertyWebkitTransitionTimingFunction:
1392             return getTimingFunctionValue(style->transitions());
1393         case CSSPropertyPointerEvents:
1394             return CSSPrimitiveValue::create(style->pointerEvents());
1395         case CSSPropertyWebkitColorCorrection:
1396             return CSSPrimitiveValue::create(style->colorSpace());
1397
1398         /* Shorthand properties, currently not supported see bug 13658*/
1399         case CSSPropertyBackground:
1400         case CSSPropertyBorder:
1401         case CSSPropertyBorderBottom:
1402         case CSSPropertyBorderColor:
1403         case CSSPropertyBorderLeft:
1404         case CSSPropertyBorderRadius:
1405         case CSSPropertyBorderRight:
1406         case CSSPropertyBorderStyle:
1407         case CSSPropertyBorderTop:
1408         case CSSPropertyBorderWidth:
1409         case CSSPropertyFont:
1410         case CSSPropertyListStyle:
1411         case CSSPropertyMargin:
1412         case CSSPropertyPadding:
1413             break;
1414
1415         /* Unimplemented CSS 3 properties (including CSS3 shorthand properties) */
1416         case CSSPropertyTextLineThrough:
1417         case CSSPropertyTextLineThroughColor:
1418         case CSSPropertyTextLineThroughMode:
1419         case CSSPropertyTextLineThroughStyle:
1420         case CSSPropertyTextLineThroughWidth:
1421         case CSSPropertyTextOverline:
1422         case CSSPropertyTextOverlineColor:
1423         case CSSPropertyTextOverlineMode:
1424         case CSSPropertyTextOverlineStyle:
1425         case CSSPropertyTextOverlineWidth:
1426         case CSSPropertyTextUnderline:
1427         case CSSPropertyTextUnderlineColor:
1428         case CSSPropertyTextUnderlineMode:
1429         case CSSPropertyTextUnderlineStyle:
1430         case CSSPropertyTextUnderlineWidth:
1431             break;
1432
1433         /* Unimplemented @font-face properties */
1434         case CSSPropertyFontStretch:
1435         case CSSPropertySrc:
1436         case CSSPropertyUnicodeRange:
1437             break;
1438
1439         /* Other unimplemented properties */
1440         case CSSPropertyBackgroundRepeatX:
1441         case CSSPropertyBackgroundRepeatY:
1442         case CSSPropertyContent: // FIXME: needs implementation, bug 23668
1443         case CSSPropertyCounterIncrement:
1444         case CSSPropertyCounterReset:
1445         case CSSPropertyOutline: // FIXME: needs implementation
1446         case CSSPropertyOutlineOffset: // FIXME: needs implementation
1447         case CSSPropertyPage: // for @page
1448         case CSSPropertyQuotes: // FIXME: needs implementation
1449         case CSSPropertySize: // for @page
1450             break;
1451
1452         /* Unimplemented -webkit- properties */
1453         case CSSPropertyWebkitAnimation:
1454         case CSSPropertyWebkitBorderRadius:
1455         case CSSPropertyWebkitColumns:
1456         case CSSPropertyWebkitColumnRule:
1457         case CSSPropertyWebkitMarginCollapse:
1458         case CSSPropertyWebkitMarginStart:
1459         case CSSPropertyWebkitMarquee:
1460         case CSSPropertyWebkitMarqueeSpeed:
1461         case CSSPropertyWebkitMask:
1462         case CSSPropertyWebkitMaskRepeatX:
1463         case CSSPropertyWebkitMaskRepeatY:
1464         case CSSPropertyWebkitPaddingStart:
1465         case CSSPropertyWebkitPerspectiveOriginX:
1466         case CSSPropertyWebkitPerspectiveOriginY:
1467         case CSSPropertyWebkitTextStroke:
1468         case CSSPropertyWebkitTransformOriginX:
1469         case CSSPropertyWebkitTransformOriginY:
1470         case CSSPropertyWebkitTransformOriginZ:
1471         case CSSPropertyWebkitTransition:
1472         case CSSPropertyWebkitVariableDeclarationBlock:
1473             break;
1474 #if ENABLE(SVG)
1475         // FIXME: This default case ruins the point of using an enum for
1476         // properties -- it prevents us from getting a warning when we
1477         // forget to list a property above.
1478         default:
1479             return getSVGPropertyCSSValue(propertyID, DoNotUpdateLayout);
1480 #endif
1481     }
1482
1483     logUnimplementedPropertyID(propertyID);
1484     return 0;
1485 }
1486
1487 String CSSComputedStyleDeclaration::getPropertyValue(int propertyID) const
1488 {
1489     RefPtr<CSSValue> value = getPropertyCSSValue(propertyID);
1490     if (value)
1491         return value->cssText();
1492     return "";
1493 }
1494
1495 bool CSSComputedStyleDeclaration::getPropertyPriority(int /*propertyID*/) const
1496 {
1497     // All computed styles have a priority of false (not "important").
1498     return false;
1499 }
1500
1501 String CSSComputedStyleDeclaration::removeProperty(int /*propertyID*/, ExceptionCode& ec)
1502 {
1503     ec = NO_MODIFICATION_ALLOWED_ERR;
1504     return String();
1505 }
1506
1507 void CSSComputedStyleDeclaration::setProperty(int /*propertyID*/, const String& /*value*/, bool /*important*/, ExceptionCode& ec)
1508 {
1509     ec = NO_MODIFICATION_ALLOWED_ERR;
1510 }
1511
1512 unsigned CSSComputedStyleDeclaration::virtualLength() const
1513 {
1514     Node* node = m_node.get();
1515     if (!node)
1516         return 0;
1517
1518     RenderStyle* style = node->computedStyle(m_pseudoElementSpecifier);
1519     if (!style)
1520         return 0;
1521
1522     return numComputedProperties;
1523 }
1524
1525 String CSSComputedStyleDeclaration::item(unsigned i) const
1526 {
1527     if (i >= length())
1528         return "";
1529
1530     return getPropertyName(static_cast<CSSPropertyID>(computedProperties[i]));
1531 }
1532
1533 bool CSSComputedStyleDeclaration::cssPropertyMatches(const CSSProperty* property) const
1534 {
1535     if (property->id() == CSSPropertyFontSize && property->value()->isPrimitiveValue() && m_node) {
1536         m_node->document()->updateLayoutIgnorePendingStylesheets();
1537         RenderStyle* style = m_node->computedStyle(m_pseudoElementSpecifier);
1538         if (style && style->fontDescription().keywordSize()) {
1539             int sizeValue = cssIdentifierForFontSizeKeyword(style->fontDescription().keywordSize());
1540             CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(property->value());
1541             if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_IDENT && primitiveValue->getIdent() == sizeValue)
1542                 return true;
1543         }
1544     }
1545
1546     return CSSStyleDeclaration::cssPropertyMatches(property);
1547 }
1548
1549 PassRefPtr<CSSMutableStyleDeclaration> CSSComputedStyleDeclaration::copy() const
1550 {
1551     return copyPropertiesInSet(computedProperties, numComputedProperties);
1552 }
1553
1554 PassRefPtr<CSSMutableStyleDeclaration> CSSComputedStyleDeclaration::makeMutable()
1555 {
1556     return copy();
1557 }
1558
1559 } // namespace WebCore