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