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