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