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