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