d4e82486c180b984cb0a61d5b6d643b2f0b637ea
[WebKit-https.git] / WebCore / css / CSSComputedStyleDeclaration.cpp
1 /**
2  * CSSComputedStyleDeclaration.cpp
3  *
4  * Copyright (C) 2004 Zack Rusin <zack@kde.org>
5  * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20  * 02111-1307  USA
21  */
22
23 #include "config.h"
24 #include "CSSComputedStyleDeclaration.h"
25
26 #include "CachedImage.h"
27 #include "DashboardRegion.h"
28 #include "Document.h"
29 #include "ExceptionCode.h"
30 #include "CSSMutableStyleDeclaration.h"
31 #include "CSSPrimitiveValue.h"
32 #include "CSSPropertyNames.h"
33 #include "CSSValueKeywords.h"
34 #include "CSSValueList.h"
35 #include "Pair.h"
36 #include "RenderObject.h"
37 #include "ShadowValue.h"
38
39 extern WebCore::String getPropertyName(unsigned short id);
40
41 namespace WebCore {
42
43 // List of all properties we know how to compute, omitting shorthands.
44 static const int computedProperties[] = {
45     CSS_PROP_BACKGROUND_COLOR,
46     CSS_PROP_BACKGROUND_IMAGE,
47     CSS_PROP__WEBKIT_BACKGROUND_SIZE,
48     CSS_PROP_BACKGROUND_REPEAT,
49     CSS_PROP__WEBKIT_BACKGROUND_COMPOSITE,
50     CSS_PROP_BACKGROUND_ATTACHMENT,
51     CSS_PROP__WEBKIT_BACKGROUND_CLIP,
52     CSS_PROP__WEBKIT_BACKGROUND_ORIGIN,
53     CSS_PROP_BACKGROUND_POSITION_X,
54     CSS_PROP_BACKGROUND_POSITION_Y,
55     CSS_PROP_BORDER_COLLAPSE,
56     CSS_PROP__WEBKIT_BORDER_HORIZONTAL_SPACING,
57     CSS_PROP__WEBKIT_BORDER_VERTICAL_SPACING,
58     CSS_PROP_BORDER_TOP_COLOR,
59     CSS_PROP_BORDER_RIGHT_COLOR,
60     CSS_PROP_BORDER_BOTTOM_COLOR,
61     CSS_PROP_BORDER_LEFT_COLOR,
62     CSS_PROP_BORDER_TOP_STYLE,
63     CSS_PROP_BORDER_RIGHT_STYLE,
64     CSS_PROP_BORDER_BOTTOM_STYLE,
65     CSS_PROP_BORDER_LEFT_STYLE,
66     CSS_PROP_BORDER_TOP_WIDTH,
67     CSS_PROP_BORDER_RIGHT_WIDTH,
68     CSS_PROP_BORDER_BOTTOM_WIDTH,
69     CSS_PROP_BORDER_LEFT_WIDTH,
70     CSS_PROP_BOTTOM,
71     CSS_PROP__WEBKIT_BOX_ALIGN,
72     CSS_PROP__WEBKIT_BOX_DIRECTION,
73     CSS_PROP__WEBKIT_BOX_FLEX,
74     CSS_PROP__WEBKIT_BOX_FLEX_GROUP,
75     CSS_PROP__WEBKIT_BOX_LINES,
76     CSS_PROP__WEBKIT_BOX_ORDINAL_GROUP,
77     CSS_PROP__WEBKIT_BOX_ORIENT,
78     CSS_PROP__WEBKIT_BOX_PACK,
79     CSS_PROP_CAPTION_SIDE,
80     CSS_PROP_CLEAR,
81     CSS_PROP_COLOR,
82     CSS_PROP_CURSOR,
83 #if PLATFORM(MAC)
84     CSS_PROP__WEBKIT_DASHBOARD_REGION,
85 #endif
86     CSS_PROP_DIRECTION,
87     CSS_PROP_DISPLAY,
88     CSS_PROP_EMPTY_CELLS,
89     CSS_PROP_FLOAT,
90     CSS_PROP_FONT_FAMILY,
91     CSS_PROP_FONT_SIZE,
92     CSS_PROP_FONT_STYLE,
93     CSS_PROP_FONT_VARIANT,
94     CSS_PROP_FONT_WEIGHT,
95     CSS_PROP_HEIGHT,
96     CSS_PROP__WEBKIT_HIGHLIGHT,
97     CSS_PROP_LEFT,
98     CSS_PROP_LETTER_SPACING,
99     CSS_PROP__WEBKIT_LINE_BREAK,
100     CSS_PROP__WEBKIT_LINE_CLAMP,
101     CSS_PROP_LINE_HEIGHT,
102     CSS_PROP_LIST_STYLE_IMAGE,
103     CSS_PROP_LIST_STYLE_POSITION,
104     CSS_PROP_LIST_STYLE_TYPE,
105     CSS_PROP_MARGIN_TOP,
106     CSS_PROP_MARGIN_RIGHT,
107     CSS_PROP_MARGIN_BOTTOM,
108     CSS_PROP_MARGIN_LEFT,
109     CSS_PROP__WEBKIT_MARQUEE_DIRECTION,
110     CSS_PROP__WEBKIT_MARQUEE_INCREMENT,
111     CSS_PROP__WEBKIT_MARQUEE_REPETITION,
112     CSS_PROP__WEBKIT_MARQUEE_STYLE,
113     CSS_PROP_MAX_HEIGHT,
114     CSS_PROP_MAX_WIDTH,
115     CSS_PROP_MIN_HEIGHT,
116     CSS_PROP_MIN_WIDTH,
117     CSS_PROP__WEBKIT_NBSP_MODE,
118     CSS_PROP_OPACITY,
119     CSS_PROP_ORPHANS,
120     CSS_PROP_OUTLINE_STYLE,
121     CSS_PROP_OVERFLOW_X,
122     CSS_PROP_OVERFLOW_Y,
123     CSS_PROP_PADDING_TOP,
124     CSS_PROP_PADDING_RIGHT,
125     CSS_PROP_PADDING_BOTTOM,
126     CSS_PROP_PADDING_LEFT,
127     CSS_PROP_PAGE_BREAK_AFTER,
128     CSS_PROP_PAGE_BREAK_BEFORE,
129     CSS_PROP_PAGE_BREAK_INSIDE,
130     CSS_PROP_POSITION,
131     CSS_PROP_RESIZE,
132     CSS_PROP_RIGHT,
133     CSS_PROP_TABLE_LAYOUT,
134     CSS_PROP_TEXT_ALIGN,
135     CSS_PROP_TEXT_DECORATION,
136     CSS_PROP__WEBKIT_TEXT_DECORATIONS_IN_EFFECT,
137     CSS_PROP_TEXT_INDENT,
138     CSS_PROP_TEXT_SHADOW,
139     CSS_PROP__WEBKIT_TEXT_SECURITY,
140     CSS_PROP_TEXT_TRANSFORM,
141     CSS_PROP_TOP,
142     CSS_PROP_UNICODE_BIDI,
143     CSS_PROP__WEBKIT_USER_MODIFY,
144     CSS_PROP_VERTICAL_ALIGN,
145     CSS_PROP_VISIBILITY,
146     CSS_PROP_WHITE_SPACE,
147     CSS_PROP_WIDOWS,
148     CSS_PROP_WIDTH,
149     CSS_PROP_WORD_SPACING,
150     CSS_PROP_WORD_WRAP,
151     CSS_PROP_Z_INDEX,
152 };
153
154 const unsigned numComputedProperties = sizeof(computedProperties) / sizeof(computedProperties[0]);
155
156 static CSSValue* valueForLength(const Length& length)
157 {
158     switch (length.type()) {
159         case Auto:
160             return new CSSPrimitiveValue(CSS_VAL_AUTO);
161         case WebCore::Fixed:
162             return new CSSPrimitiveValue(length.value(), CSSPrimitiveValue::CSS_PX);
163         case Intrinsic:
164             return new CSSPrimitiveValue(CSS_VAL_INTRINSIC);
165         case MinIntrinsic:
166             return new CSSPrimitiveValue(CSS_VAL_MIN_INTRINSIC);
167         case Percent:
168             return new CSSPrimitiveValue(length.value(), CSSPrimitiveValue::CSS_PERCENTAGE);
169         case Relative:
170         case Static:
171             // Should never be reached.
172             break;
173     }
174     // Should never be reached, but if we do, just return "auto".
175     return new CSSPrimitiveValue(CSS_VAL_AUTO);
176 }
177
178 // Handles special value for "none".
179 static CSSValue* valueForMaxLength(const Length& length)
180 {
181     if (length.isFixed() && length.value() == undefinedLength)
182         return new CSSPrimitiveValue(CSS_VAL_NONE);
183     return valueForLength(length);
184 }
185
186 static CSSValue *valueForBorderStyle(EBorderStyle style)
187 {
188     switch (style) {
189         case BNONE:
190             return new CSSPrimitiveValue(CSS_VAL_NONE);
191         case BHIDDEN:
192             return new CSSPrimitiveValue(CSS_VAL_HIDDEN);
193         case INSET:
194             return new CSSPrimitiveValue(CSS_VAL_INSET);
195         case GROOVE:
196             return new CSSPrimitiveValue(CSS_VAL_GROOVE);
197         case RIDGE:
198             return new CSSPrimitiveValue(CSS_VAL_RIDGE);
199         case OUTSET:
200             return new CSSPrimitiveValue(CSS_VAL_OUTSET);
201         case DOTTED:
202             return new CSSPrimitiveValue(CSS_VAL_DOTTED);
203         case DASHED:
204             return new CSSPrimitiveValue(CSS_VAL_DASHED);
205         case SOLID:
206             return new CSSPrimitiveValue(CSS_VAL_SOLID);
207         case DOUBLE:
208             return new CSSPrimitiveValue(CSS_VAL_DOUBLE);
209     }
210     ASSERT_NOT_REACHED();
211     return 0;
212 }
213
214 static CSSValue *valueForTextAlign(ETextAlign align)
215 {
216     switch (align) {
217         case TAAUTO:
218             return new CSSPrimitiveValue(CSS_VAL_AUTO);
219         case LEFT:
220             return new CSSPrimitiveValue(CSS_VAL_LEFT);
221         case RIGHT:
222             return new CSSPrimitiveValue(CSS_VAL_RIGHT);
223         case CENTER:
224             return new CSSPrimitiveValue(CSS_VAL_CENTER);
225         case JUSTIFY:
226             return new CSSPrimitiveValue(CSS_VAL_JUSTIFY);
227         case KHTML_LEFT:
228             return new CSSPrimitiveValue(CSS_VAL__WEBKIT_LEFT);
229         case KHTML_RIGHT:
230             return new CSSPrimitiveValue(CSS_VAL__WEBKIT_RIGHT);
231         case KHTML_CENTER:
232             return new CSSPrimitiveValue(CSS_VAL__WEBKIT_CENTER);
233     }
234     ASSERT_NOT_REACHED();
235     return 0;
236 }
237
238 static CSSValue* valueForShadow(const ShadowData* shadow)
239 {
240     if (!shadow)
241         return new CSSPrimitiveValue(CSS_VAL_NONE);
242     CSSValueList* list = new CSSValueList;
243     for (const ShadowData* s = shadow; s; s = s->next) {
244         CSSPrimitiveValue* x = new CSSPrimitiveValue(s->x, CSSPrimitiveValue::CSS_PX);
245         CSSPrimitiveValue* y = new CSSPrimitiveValue(s->y, CSSPrimitiveValue::CSS_PX);
246         CSSPrimitiveValue* blur = new CSSPrimitiveValue(s->blur, CSSPrimitiveValue::CSS_PX);
247         CSSPrimitiveValue* color = new CSSPrimitiveValue(s->color.rgb());
248         list->append(new ShadowValue(x, y, blur, color));
249     }
250     return list;
251 }
252
253 static CSSValue *getPositionOffsetValue(RenderObject *renderer, int propertyID)
254 {
255     if (!renderer)
256         return 0;
257
258     RenderStyle *style = renderer->style();
259     if (!style)
260         return 0;
261
262     Length l;
263     switch (propertyID) {
264     case CSS_PROP_LEFT:
265         l = style->left();
266         break;
267     case CSS_PROP_RIGHT:
268         l = style->right();
269         break;
270     case CSS_PROP_TOP:
271         l = style->top();
272         break;
273     case CSS_PROP_BOTTOM:
274         l = style->bottom();
275         break;
276     default:
277         return 0;
278     }
279
280     if (renderer->isPositioned())
281         return valueForLength(l);
282     
283     if (renderer->isRelPositioned())
284         // FIXME: It's not enough to simply return "auto" values for one offset if the other side is defined.
285         // In other words if left is auto and right is not auto, then left's computed value is negative right.
286         // So we should get the opposite length unit and see if it is auto.
287         return valueForLength(l);
288     
289     return new CSSPrimitiveValue(CSS_VAL_AUTO);
290 }
291
292 CSSComputedStyleDeclaration::CSSComputedStyleDeclaration(PassRefPtr<Node> n)
293     : m_node(n)
294 {
295 }
296
297 CSSComputedStyleDeclaration::~CSSComputedStyleDeclaration()
298 {
299 }
300
301 String CSSComputedStyleDeclaration::cssText() const
302 {
303     String result("");
304     
305     for (unsigned i = 0; i < numComputedProperties; i++) {
306         if (i != 0)
307             result += " ";
308         result += getPropertyName(computedProperties[i]);
309         result += ": ";
310         result += getPropertyValue(computedProperties[i]);
311         result += ";";
312     }
313     
314     return result;
315 }
316
317 void CSSComputedStyleDeclaration::setCssText(const String&, ExceptionCode& ec)
318 {
319     ec = NO_MODIFICATION_ALLOWED_ERR;
320 }
321
322 // Display integers in integer format instead of "1.0".
323 static String numberAsString(double n)
324 {
325     long i = static_cast<long>(n);
326     return i == n ? String::number(i) : String::number(n);
327 }
328
329 PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int propertyID) const
330 {
331     return getPropertyCSSValue(propertyID, UpdateLayout);
332 }
333
334 CSSPrimitiveValue* primitiveValueFromLength(Length length, RenderObject* renderer, RenderStyle* style)
335 {
336     String string;
337     if (length.isPercent())
338         string = numberAsString(length.value()) + "%";
339     else if (length.isFixed())
340         string = numberAsString(length.calcMinValue(0));
341     else if (length.isAuto())
342         string = "auto";
343     return new CSSPrimitiveValue(string, CSSPrimitiveValue::CSS_STRING);
344 }
345
346 PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int propertyID, EUpdateLayout updateLayout) const
347 {
348     Node* node = m_node.get();
349     if (!node)
350         return 0;
351
352     // Make sure our layout is up to date before we allow a query on these attributes.
353     if (updateLayout)
354         node->document()->updateLayout();
355
356     // FIXME: This should work even if we do not have a renderer.
357     RenderObject* renderer = node->renderer();
358     if (!renderer)
359         return 0;
360     RenderStyle* style = renderer->style();
361     if (!style)
362         return 0;
363
364     switch (propertyID)
365     {
366     case CSS_PROP_BACKGROUND_COLOR:
367         return new CSSPrimitiveValue(style->backgroundColor().rgb());
368     case CSS_PROP_BACKGROUND_IMAGE:
369         if (style->backgroundImage())
370             return new CSSPrimitiveValue(style->backgroundImage()->url(), CSSPrimitiveValue::CSS_URI);
371         return new CSSPrimitiveValue(CSS_VAL_NONE);
372     case CSS_PROP__WEBKIT_BACKGROUND_SIZE: {
373         Length widthLength = style->backgroundSize().width;
374         Length heightLength = style->backgroundSize().height;
375         CSSPrimitiveValue* bgWidth = primitiveValueFromLength(widthLength, renderer, style);
376         CSSPrimitiveValue* bgHeight = primitiveValueFromLength(heightLength, renderer, style);
377         Pair* pair = new Pair(bgWidth, bgHeight);
378         return new CSSPrimitiveValue(pair);
379     }
380     case CSS_PROP_BACKGROUND_REPEAT:
381         switch (style->backgroundRepeat()) {
382             case REPEAT:
383                 return new CSSPrimitiveValue(CSS_VAL_REPEAT);
384             case REPEAT_X:
385                 return new CSSPrimitiveValue(CSS_VAL_REPEAT_X);
386             case REPEAT_Y:
387                 return new CSSPrimitiveValue(CSS_VAL_REPEAT_Y);
388             case NO_REPEAT:
389                 return new CSSPrimitiveValue(CSS_VAL_NO_REPEAT);
390         }
391         ASSERT_NOT_REACHED();
392         return 0;
393     case CSS_PROP__WEBKIT_BACKGROUND_COMPOSITE:
394         switch (style->backgroundComposite()) {
395             case CompositeClear:
396                 return new CSSPrimitiveValue(CSS_VAL_CLEAR);
397             case CompositeCopy:
398                 return new CSSPrimitiveValue(CSS_VAL_COPY);
399             case CompositeSourceOver:
400                 return new CSSPrimitiveValue(CSS_VAL_SOURCE_OVER);
401             case CompositeSourceIn:
402                 return new CSSPrimitiveValue(CSS_VAL_SOURCE_IN);
403             case CompositeSourceOut:
404                 return new CSSPrimitiveValue(CSS_VAL_SOURCE_OUT);
405             case CompositeSourceAtop:
406                 return new CSSPrimitiveValue(CSS_VAL_SOURCE_ATOP);
407             case CompositeDestinationOver:
408                 return new CSSPrimitiveValue(CSS_VAL_DESTINATION_OVER);
409             case CompositeDestinationIn:
410                 return new CSSPrimitiveValue(CSS_VAL_DESTINATION_IN);
411             case CompositeDestinationOut:
412                 return new CSSPrimitiveValue(CSS_VAL_DESTINATION_OUT);
413             case CompositeDestinationAtop:
414                 return new CSSPrimitiveValue(CSS_VAL_DESTINATION_ATOP);
415             case CompositeXOR:
416                 return new CSSPrimitiveValue(CSS_VAL_XOR);
417             case CompositePlusDarker:
418                 return new CSSPrimitiveValue(CSS_VAL_PLUS_DARKER);
419             case CompositeHighlight:
420                 return new CSSPrimitiveValue(CSS_VAL_HIGHLIGHT);
421             case CompositePlusLighter:
422                 return new CSSPrimitiveValue(CSS_VAL_PLUS_LIGHTER);
423         }
424         ASSERT_NOT_REACHED();
425         return 0;
426     case CSS_PROP_BACKGROUND_ATTACHMENT:
427         if (style->backgroundAttachment())
428             return new CSSPrimitiveValue(CSS_VAL_SCROLL);
429         return new CSSPrimitiveValue(CSS_VAL_FIXED);
430     case CSS_PROP__WEBKIT_BACKGROUND_CLIP:
431     case CSS_PROP__WEBKIT_BACKGROUND_ORIGIN: {
432         EBackgroundBox box = (propertyID == CSS_PROP__WEBKIT_BACKGROUND_CLIP ? style->backgroundClip() : style->backgroundOrigin());
433         if (box == BGBORDER)
434             return new CSSPrimitiveValue(CSS_VAL_BORDER);
435         if (box == BGPADDING)
436             return new CSSPrimitiveValue(CSS_VAL_PADDING);
437         return new CSSPrimitiveValue(CSS_VAL_CONTENT);
438     }
439     case CSS_PROP_BACKGROUND_POSITION:
440     {
441         String string;
442         Length length(style->backgroundXPosition());
443         if (length.isPercent())
444             string = numberAsString(length.value()) + "%";
445         else
446             string = numberAsString(length.calcMinValue(renderer->contentWidth()));
447         string += " ";
448         length = style->backgroundYPosition();
449         if (length.isPercent())
450             string += numberAsString(length.value()) + "%";
451         else
452             string += numberAsString(length.calcMinValue(renderer->contentWidth()));
453         return new CSSPrimitiveValue(string, CSSPrimitiveValue::CSS_STRING);
454     }
455     case CSS_PROP_BACKGROUND_POSITION_X:
456         return valueForLength(style->backgroundXPosition());
457     case CSS_PROP_BACKGROUND_POSITION_Y:
458         return valueForLength(style->backgroundYPosition());
459 #ifdef XBL_SUPPORT
460     case CSS_PROP__WEBKIT_BINDING:
461         // FIXME: unimplemented
462         break;
463 #endif
464     case CSS_PROP_BORDER_COLLAPSE:
465         if (style->borderCollapse())
466             return new CSSPrimitiveValue(CSS_VAL_COLLAPSE);
467         else
468             return new CSSPrimitiveValue(CSS_VAL_SEPARATE);
469     case CSS_PROP_BORDER_SPACING:
470     {
471         String string(numberAsString(style->horizontalBorderSpacing()) + "px " + numberAsString(style->verticalBorderSpacing()) + "px");
472         return new CSSPrimitiveValue(string, CSSPrimitiveValue::CSS_STRING);
473     }
474     case CSS_PROP__WEBKIT_BORDER_HORIZONTAL_SPACING:
475         return new CSSPrimitiveValue(style->horizontalBorderSpacing(), CSSPrimitiveValue::CSS_PX);
476     case CSS_PROP__WEBKIT_BORDER_VERTICAL_SPACING:
477         return new CSSPrimitiveValue(style->verticalBorderSpacing(), CSSPrimitiveValue::CSS_PX);
478     case CSS_PROP_BORDER_TOP_COLOR:
479         return new CSSPrimitiveValue(style->borderLeftColor().rgb());
480     case CSS_PROP_BORDER_RIGHT_COLOR:
481         return new CSSPrimitiveValue(style->borderRightColor().rgb());
482     case CSS_PROP_BORDER_BOTTOM_COLOR:
483         return new CSSPrimitiveValue(style->borderBottomColor().rgb());
484     case CSS_PROP_BORDER_LEFT_COLOR:
485         return new CSSPrimitiveValue(style->borderLeftColor().rgb());
486     case CSS_PROP_BORDER_TOP_STYLE:
487         return valueForBorderStyle(style->borderTopStyle());
488     case CSS_PROP_BORDER_RIGHT_STYLE:
489         return valueForBorderStyle(style->borderRightStyle());
490     case CSS_PROP_BORDER_BOTTOM_STYLE:
491         return valueForBorderStyle(style->borderBottomStyle());
492     case CSS_PROP_BORDER_LEFT_STYLE:
493         return valueForBorderStyle(style->borderLeftStyle());
494     case CSS_PROP_BORDER_TOP_WIDTH:
495         return new CSSPrimitiveValue(style->borderTopWidth(), CSSPrimitiveValue::CSS_PX);
496     case CSS_PROP_BORDER_RIGHT_WIDTH:
497         return new CSSPrimitiveValue(style->borderRightWidth(), CSSPrimitiveValue::CSS_PX);
498     case CSS_PROP_BORDER_BOTTOM_WIDTH:
499         return new CSSPrimitiveValue(style->borderBottomWidth(), CSSPrimitiveValue::CSS_PX);
500     case CSS_PROP_BORDER_LEFT_WIDTH:
501         return new CSSPrimitiveValue(style->borderLeftWidth(), CSSPrimitiveValue::CSS_PX);
502     case CSS_PROP_BOTTOM:
503         return getPositionOffsetValue(renderer, CSS_PROP_BOTTOM);
504     case CSS_PROP__WEBKIT_BOX_ALIGN:
505         switch (style->boxAlign()) {
506             case BSTRETCH:
507                 return new CSSPrimitiveValue(CSS_VAL_STRETCH);
508             case BSTART:
509                 return new CSSPrimitiveValue(CSS_VAL_START);
510             case BCENTER:
511                 return new CSSPrimitiveValue(CSS_VAL_CENTER);
512             case BEND:
513                 return new CSSPrimitiveValue(CSS_VAL_END);
514             case BBASELINE:
515                 return new CSSPrimitiveValue(CSS_VAL_BASELINE);
516             case BJUSTIFY:
517                 break; // not allowed
518         }
519         ASSERT_NOT_REACHED();
520         return 0;
521     case CSS_PROP__WEBKIT_BOX_DIRECTION:
522         switch (style->boxDirection()) {
523             case BNORMAL:
524                 return new CSSPrimitiveValue(CSS_VAL_NORMAL);
525             case BREVERSE:
526                 return new CSSPrimitiveValue(CSS_VAL_REVERSE);
527         }
528         ASSERT_NOT_REACHED();
529         return 0;
530     case CSS_PROP__WEBKIT_BOX_FLEX:
531         return new CSSPrimitiveValue(style->boxFlex(), CSSPrimitiveValue::CSS_NUMBER);
532     case CSS_PROP__WEBKIT_BOX_FLEX_GROUP:
533         return new CSSPrimitiveValue(style->boxFlexGroup(), CSSPrimitiveValue::CSS_NUMBER);
534     case CSS_PROP__WEBKIT_BOX_LINES:
535         switch (style->boxLines()) {
536             case SINGLE:
537                 return new CSSPrimitiveValue(CSS_VAL_SINGLE);
538             case MULTIPLE:
539                 return new CSSPrimitiveValue(CSS_VAL_MULTIPLE);
540         }
541         ASSERT_NOT_REACHED();
542         return 0;
543     case CSS_PROP__WEBKIT_BOX_ORDINAL_GROUP:
544         return new CSSPrimitiveValue(style->boxOrdinalGroup(), CSSPrimitiveValue::CSS_NUMBER);
545     case CSS_PROP__WEBKIT_BOX_ORIENT:
546         switch (style->boxOrient()) {
547             case HORIZONTAL:
548                 return new CSSPrimitiveValue(CSS_VAL_HORIZONTAL);
549             case VERTICAL:
550                 return new CSSPrimitiveValue(CSS_VAL_VERTICAL);
551         }
552         ASSERT_NOT_REACHED();
553         return 0;
554     case CSS_PROP__WEBKIT_BOX_PACK:
555         switch (style->boxPack()) {
556             case BSTART:
557                 return new CSSPrimitiveValue(CSS_VAL_START);
558             case BEND:
559                 return new CSSPrimitiveValue(CSS_VAL_END);
560             case BCENTER:
561                 return new CSSPrimitiveValue(CSS_VAL_CENTER);
562             case BJUSTIFY:
563                 return new CSSPrimitiveValue(CSS_VAL_JUSTIFY);
564             case BSTRETCH:
565             case BBASELINE:
566                 break; // not allowed
567         }
568         ASSERT_NOT_REACHED();
569         return 0;
570     case CSS_PROP_CAPTION_SIDE:
571         switch (style->captionSide()) {
572             case CAPLEFT:
573                 return new CSSPrimitiveValue(CSS_VAL_LEFT);
574             case CAPRIGHT:
575                 return new CSSPrimitiveValue(CSS_VAL_RIGHT);
576             case CAPTOP:
577                 return new CSSPrimitiveValue(CSS_VAL_TOP);
578             case CAPBOTTOM:
579                 return new CSSPrimitiveValue(CSS_VAL_BOTTOM);
580         }
581         ASSERT_NOT_REACHED();
582         return 0;
583     case CSS_PROP_CLEAR:
584         switch (style->clear()) {
585             case CNONE:
586                 return new CSSPrimitiveValue(CSS_VAL_NONE);
587             case CLEFT:
588                 return new CSSPrimitiveValue(CSS_VAL_LEFT);
589             case CRIGHT:
590                 return new CSSPrimitiveValue(CSS_VAL_RIGHT);
591             case CBOTH:
592                 return new CSSPrimitiveValue(CSS_VAL_BOTH);
593         }
594         ASSERT_NOT_REACHED();
595         return 0;
596     case CSS_PROP_CLIP:
597         // FIXME: unimplemented
598         break;
599     case CSS_PROP_COLOR:
600         return new CSSPrimitiveValue(style->color().rgb());
601     case CSS_PROP_CONTENT:
602         // FIXME: unimplemented
603         break;
604     case CSS_PROP_COUNTER_INCREMENT:
605         return style->counterIncrementValueList();
606     case CSS_PROP_COUNTER_RESET:
607         return style->counterResetValueList();
608     case CSS_PROP_CURSOR: {
609         CSSValueList* list = 0;
610         CSSValue* value = 0;
611         CursorList* cursors = style->cursors();
612         if (cursors && cursors->size() > 0) {
613             list = new CSSValueList;
614             for (unsigned i = 0; i < cursors->size(); ++i)
615                 list->append(new CSSPrimitiveValue((*cursors)[i].cursorImage->url(), CSSPrimitiveValue::CSS_URI));
616         }
617         switch (style->cursor()) {
618             case CURSOR_AUTO:
619                 value = new CSSPrimitiveValue(CSS_VAL_AUTO);
620                 break;
621             case CURSOR_CROSS:
622                 value = new CSSPrimitiveValue(CSS_VAL_CROSSHAIR);
623                 break;
624             case CURSOR_DEFAULT:
625                 value = new CSSPrimitiveValue(CSS_VAL_DEFAULT);
626                 break;
627             case CURSOR_POINTER:
628                 value = new CSSPrimitiveValue(CSS_VAL_POINTER);
629                 break;
630             case CURSOR_MOVE:
631                 value = new CSSPrimitiveValue(CSS_VAL_MOVE);
632                 break;
633             case CURSOR_E_RESIZE:
634                 value = new CSSPrimitiveValue(CSS_VAL_E_RESIZE);
635                 break;
636             case CURSOR_NE_RESIZE:
637                 value = new CSSPrimitiveValue(CSS_VAL_NE_RESIZE);
638                 break;
639             case CURSOR_NW_RESIZE:
640                 value = new CSSPrimitiveValue(CSS_VAL_NW_RESIZE);
641                 break;
642             case CURSOR_N_RESIZE:
643                 value = new CSSPrimitiveValue(CSS_VAL_N_RESIZE);
644                 break;
645             case CURSOR_SE_RESIZE:
646                 value = new CSSPrimitiveValue(CSS_VAL_SE_RESIZE);
647                 break;
648             case CURSOR_SW_RESIZE:
649                 value = new CSSPrimitiveValue(CSS_VAL_SW_RESIZE);
650                 break;
651             case CURSOR_S_RESIZE:
652                 value = new CSSPrimitiveValue(CSS_VAL_S_RESIZE);
653                 break;
654             case CURSOR_W_RESIZE:
655                 value = new CSSPrimitiveValue(CSS_VAL_W_RESIZE);
656                 break;
657             case CURSOR_EW_RESIZE:
658                 value = new CSSPrimitiveValue(CSS_VAL_EW_RESIZE);
659                 break;
660             case CURSOR_NS_RESIZE:
661                 value = new CSSPrimitiveValue(CSS_VAL_NS_RESIZE);
662                 break;
663             case CURSOR_NESW_RESIZE:
664                 value = new CSSPrimitiveValue(CSS_VAL_NESW_RESIZE);
665                 break;
666             case CURSOR_NWSE_RESIZE:
667                 value = new CSSPrimitiveValue(CSS_VAL_NWSE_RESIZE);
668                 break;
669             case CURSOR_COL_RESIZE:
670                 value = new CSSPrimitiveValue(CSS_VAL_COL_RESIZE);
671                 break;
672             case CURSOR_ROW_RESIZE:
673                 value = new CSSPrimitiveValue(CSS_VAL_ROW_RESIZE);
674                 break;
675             case CURSOR_TEXT:
676                 value = new CSSPrimitiveValue(CSS_VAL_TEXT);
677                 break;
678             case CURSOR_WAIT:
679                 value = new CSSPrimitiveValue(CSS_VAL_WAIT);
680                 break;
681             case CURSOR_HELP:
682                 value = new CSSPrimitiveValue(CSS_VAL_HELP);
683             case CURSOR_ALL_SCROLL:
684                 value = new CSSPrimitiveValue(CSS_VAL_ALL_SCROLL);
685                 break;
686         }
687         ASSERT(value);
688         if (list) {
689             list->append(value);
690             return list;
691         }
692         return value;
693     }
694     case CSS_PROP_DIRECTION:
695         switch (style->direction()) {
696             case LTR:
697                 return new CSSPrimitiveValue(CSS_VAL_LTR);
698             case RTL:
699                 return new CSSPrimitiveValue(CSS_VAL_RTL);
700         }
701         ASSERT_NOT_REACHED();
702         return 0;
703     case CSS_PROP_DISPLAY:
704         switch (style->display()) {
705             case INLINE:
706                 return new CSSPrimitiveValue(CSS_VAL_INLINE);
707             case BLOCK:
708                 return new CSSPrimitiveValue(CSS_VAL_BLOCK);
709             case LIST_ITEM:
710                 return new CSSPrimitiveValue(CSS_VAL_LIST_ITEM);
711             case RUN_IN:
712                 return new CSSPrimitiveValue(CSS_VAL_RUN_IN);
713             case COMPACT:
714                 return new CSSPrimitiveValue(CSS_VAL_COMPACT);
715             case INLINE_BLOCK:
716                 return new CSSPrimitiveValue(CSS_VAL_INLINE_BLOCK);
717             case TABLE:
718                 return new CSSPrimitiveValue(CSS_VAL_TABLE);
719             case INLINE_TABLE:
720                 return new CSSPrimitiveValue(CSS_VAL_INLINE_TABLE);
721             case TABLE_ROW_GROUP:
722                 return new CSSPrimitiveValue(CSS_VAL_TABLE_ROW_GROUP);
723             case TABLE_HEADER_GROUP:
724                 return new CSSPrimitiveValue(CSS_VAL_TABLE_HEADER_GROUP);
725             case TABLE_FOOTER_GROUP:
726                 return new CSSPrimitiveValue(CSS_VAL_TABLE_FOOTER_GROUP);
727             case TABLE_ROW:
728                 return new CSSPrimitiveValue(CSS_VAL_TABLE_ROW);
729             case TABLE_COLUMN_GROUP:
730                 return new CSSPrimitiveValue(CSS_VAL_TABLE_COLUMN_GROUP);
731             case TABLE_COLUMN:
732                 return new CSSPrimitiveValue(CSS_VAL_TABLE_COLUMN);
733             case TABLE_CELL:
734                 return new CSSPrimitiveValue(CSS_VAL_TABLE_CELL);
735             case TABLE_CAPTION:
736                 return new CSSPrimitiveValue(CSS_VAL_TABLE_CAPTION);
737             case BOX:
738                 return new CSSPrimitiveValue(CSS_VAL__WEBKIT_BOX);
739             case INLINE_BOX:
740                 return new CSSPrimitiveValue(CSS_VAL__WEBKIT_INLINE_BOX);
741             case NONE:
742                 return new CSSPrimitiveValue(CSS_VAL_NONE);
743         }
744         ASSERT_NOT_REACHED();
745         return 0;
746     case CSS_PROP_EMPTY_CELLS:
747         switch (style->emptyCells()) {
748             case SHOW:
749                 return new CSSPrimitiveValue(CSS_VAL_SHOW);
750             case HIDE:
751                 return new CSSPrimitiveValue(CSS_VAL_HIDE);
752         }
753         ASSERT_NOT_REACHED();
754         return 0;
755     case CSS_PROP_FLOAT:
756         switch (style->floating()) {
757             case FNONE:
758                 return new CSSPrimitiveValue(CSS_VAL_NONE);
759             case FLEFT:
760                 return new CSSPrimitiveValue(CSS_VAL_LEFT);
761             case FRIGHT:
762                 return new CSSPrimitiveValue(CSS_VAL_RIGHT);
763         }
764         ASSERT_NOT_REACHED();
765         return 0;
766     case CSS_PROP_FONT_FAMILY:
767     {
768         // FIXME: This only returns the first family.
769         const FontDescription& desc = style->fontDescription();
770         return new CSSPrimitiveValue(desc.family().family().domString(), CSSPrimitiveValue::CSS_STRING);
771     }
772     case CSS_PROP_FONT_SIZE:
773     {
774         FontDescription desc = style->fontDescription();
775         return new CSSPrimitiveValue(desc.computedPixelSize(), CSSPrimitiveValue::CSS_PX);
776     }
777     case CSS_PROP_FONT_STRETCH:
778         // FIXME: unimplemented
779         break;
780     case CSS_PROP_FONT_STYLE:
781     {
782         // FIXME: handle oblique?
783         const FontDescription& desc = style->fontDescription();
784         if (desc.italic())
785             return new CSSPrimitiveValue(CSS_VAL_ITALIC);
786         else
787             return new CSSPrimitiveValue(CSS_VAL_NORMAL);
788     }
789     case CSS_PROP_FONT_VARIANT:
790     {
791         const FontDescription& desc = style->fontDescription();
792         if (desc.smallCaps())
793             return new CSSPrimitiveValue(CSS_VAL_SMALL_CAPS);
794         else
795             return new CSSPrimitiveValue(CSS_VAL_NORMAL);
796     }
797     case CSS_PROP_FONT_WEIGHT:
798     {
799         // FIXME: this does not reflect the full range of weights
800         // that can be expressed with CSS
801         const FontDescription& desc = style->fontDescription();
802         if (desc.weight() == cBoldWeight)
803             return new CSSPrimitiveValue(CSS_VAL_BOLD);
804         else
805             return new CSSPrimitiveValue(CSS_VAL_NORMAL);
806     }
807     case CSS_PROP_HEIGHT:
808         return new CSSPrimitiveValue(renderer->contentHeight(), CSSPrimitiveValue::CSS_PX);
809     case CSS_PROP__WEBKIT_HIGHLIGHT: {
810         if (style->highlight() == nullAtom)
811             return new CSSPrimitiveValue(CSS_VAL_NONE);
812         else
813             return new CSSPrimitiveValue(style->highlight(), CSSPrimitiveValue::CSS_STRING);
814     }
815     case CSS_PROP_LEFT:
816         return getPositionOffsetValue(renderer, CSS_PROP_LEFT);
817     case CSS_PROP_LETTER_SPACING:
818         if (style->letterSpacing() == 0)
819             return new CSSPrimitiveValue(CSS_VAL_NORMAL);
820         return new CSSPrimitiveValue(style->letterSpacing(), CSSPrimitiveValue::CSS_PX);
821     case CSS_PROP__WEBKIT_LINE_CLAMP:
822         if (style->lineClamp() == -1)
823             return new CSSPrimitiveValue(CSS_VAL_NONE);
824         return new CSSPrimitiveValue(style->lineClamp(), CSSPrimitiveValue::CSS_PERCENTAGE);
825     case CSS_PROP_LINE_HEIGHT: {
826         Length length(style->lineHeight());
827         if (length.value() < 0)
828             return new CSSPrimitiveValue(CSS_VAL_NORMAL);
829         if (length.isPercent()) {
830             // This is imperfect, because it doesn't include the zoom factor and the real computation
831             // for how high to be in pixels does include things like minimum font size and the zoom factor.
832             // On the other hand, since font-size doesn't include the zoom factor, we really can't do
833             // that here either.
834             float fontSize = style->fontDescription().specifiedSize();
835             return new CSSPrimitiveValue((int)(length.value() * fontSize) / 100, CSSPrimitiveValue::CSS_PX);
836         }
837         else {
838             return new CSSPrimitiveValue(length.value(), CSSPrimitiveValue::CSS_PX);
839         }
840     }
841     case CSS_PROP_LIST_STYLE_IMAGE:
842         if (style->listStyleImage())
843             return new CSSPrimitiveValue(style->listStyleImage()->url(), CSSPrimitiveValue::CSS_URI);
844         return new CSSPrimitiveValue(CSS_VAL_NONE);
845     case CSS_PROP_LIST_STYLE_POSITION:
846         switch (style->listStylePosition()) {
847             case OUTSIDE:
848                 return new CSSPrimitiveValue(CSS_VAL_OUTSIDE);
849             case INSIDE:
850                 return new CSSPrimitiveValue(CSS_VAL_INSIDE);
851         }
852         ASSERT_NOT_REACHED();
853         return 0;
854     case CSS_PROP_LIST_STYLE_TYPE:
855         switch (style->listStyleType()) {
856             case LNONE:
857                 return new CSSPrimitiveValue(CSS_VAL_NONE);
858             case DISC:
859                 return new CSSPrimitiveValue(CSS_VAL_DISC);
860             case CIRCLE:
861                 return new CSSPrimitiveValue(CSS_VAL_CIRCLE);
862             case SQUARE:
863                 return new CSSPrimitiveValue(CSS_VAL_SQUARE);
864             case LDECIMAL:
865                 return new CSSPrimitiveValue(CSS_VAL_DECIMAL);
866             case DECIMAL_LEADING_ZERO:
867                 return new CSSPrimitiveValue(CSS_VAL_DECIMAL_LEADING_ZERO);
868             case LOWER_ROMAN:
869                 return new CSSPrimitiveValue(CSS_VAL_LOWER_ROMAN);
870             case UPPER_ROMAN:
871                 return new CSSPrimitiveValue(CSS_VAL_UPPER_ROMAN);
872             case LOWER_GREEK:
873                 return new CSSPrimitiveValue(CSS_VAL_LOWER_GREEK);
874             case LOWER_ALPHA:
875                 return new CSSPrimitiveValue(CSS_VAL_LOWER_ALPHA);
876             case LOWER_LATIN:
877                 return new CSSPrimitiveValue(CSS_VAL_LOWER_LATIN);
878             case UPPER_ALPHA:
879                 return new CSSPrimitiveValue(CSS_VAL_UPPER_ALPHA);
880             case UPPER_LATIN:
881                 return new CSSPrimitiveValue(CSS_VAL_UPPER_LATIN);
882             case HEBREW:
883                 return new CSSPrimitiveValue(CSS_VAL_HEBREW);
884             case ARMENIAN:
885                 return new CSSPrimitiveValue(CSS_VAL_ARMENIAN);
886             case GEORGIAN:
887                 return new CSSPrimitiveValue(CSS_VAL_GEORGIAN);
888             case CJK_IDEOGRAPHIC:
889                 return new CSSPrimitiveValue(CSS_VAL_CJK_IDEOGRAPHIC);
890             case HIRAGANA:
891                 return new CSSPrimitiveValue(CSS_VAL_HIRAGANA);
892             case KATAKANA:
893                 return new CSSPrimitiveValue(CSS_VAL_KATAKANA);
894             case HIRAGANA_IROHA:
895                 return new CSSPrimitiveValue(CSS_VAL_HIRAGANA_IROHA);
896             case KATAKANA_IROHA:
897                 return new CSSPrimitiveValue(CSS_VAL_KATAKANA_IROHA);
898         }
899         ASSERT_NOT_REACHED();
900         return 0;
901     case CSS_PROP_MARGIN_TOP:
902         // FIXME: Supposed to return the percentage if percentage was specified.
903         return new CSSPrimitiveValue(renderer->marginTop(), CSSPrimitiveValue::CSS_PX);
904     case CSS_PROP_MARGIN_RIGHT:
905         // FIXME: Supposed to return the percentage if percentage was specified.
906         return new CSSPrimitiveValue(renderer->marginRight(), CSSPrimitiveValue::CSS_PX);
907     case CSS_PROP_MARGIN_BOTTOM:
908         // FIXME: Supposed to return the percentage if percentage was specified.
909         return new CSSPrimitiveValue(renderer->marginBottom(), CSSPrimitiveValue::CSS_PX);
910     case CSS_PROP_MARGIN_LEFT:
911         // FIXME: Supposed to return the percentage if percentage was specified.
912         return new CSSPrimitiveValue(renderer->marginLeft(), CSSPrimitiveValue::CSS_PX);
913     case CSS_PROP__WEBKIT_MARQUEE:
914         // FIXME: unimplemented
915         break;
916     case CSS_PROP__WEBKIT_MARQUEE_DIRECTION:
917         switch (style->marqueeDirection()) {
918             case MFORWARD:
919                 return new CSSPrimitiveValue(CSS_VAL_FORWARDS);
920             case MBACKWARD:
921                 return new CSSPrimitiveValue(CSS_VAL_BACKWARDS);
922             case MAUTO:
923                 return new CSSPrimitiveValue(CSS_VAL_AUTO);
924             case MUP:
925                 return new CSSPrimitiveValue(CSS_VAL_UP);
926             case MDOWN:
927                 return new CSSPrimitiveValue(CSS_VAL_DOWN);
928             case MLEFT:
929                 return new CSSPrimitiveValue(CSS_VAL_LEFT);
930             case MRIGHT:
931                 return new CSSPrimitiveValue(CSS_VAL_RIGHT);
932         }
933         ASSERT_NOT_REACHED();
934         return 0;
935     case CSS_PROP__WEBKIT_MARQUEE_INCREMENT:
936         return valueForLength(style->marqueeIncrement());
937     case CSS_PROP__WEBKIT_MARQUEE_REPETITION:
938         if (style->marqueeLoopCount() < 0)
939             return new CSSPrimitiveValue(CSS_VAL_INFINITE);
940         return new CSSPrimitiveValue(style->marqueeLoopCount(), CSSPrimitiveValue::CSS_NUMBER);
941     case CSS_PROP__WEBKIT_MARQUEE_SPEED:
942         // FIXME: unimplemented
943         break;
944     case CSS_PROP__WEBKIT_MARQUEE_STYLE:
945         switch (style->marqueeBehavior()) {
946             case MNONE:
947                 return new CSSPrimitiveValue(CSS_VAL_NONE);
948             case MSCROLL:
949                 return new CSSPrimitiveValue(CSS_VAL_SCROLL);
950             case MSLIDE:
951                 return new CSSPrimitiveValue(CSS_VAL_SLIDE);
952             case MALTERNATE:
953                 return new CSSPrimitiveValue(CSS_VAL_ALTERNATE);
954             case MUNFURL:
955                 return new CSSPrimitiveValue(CSS_VAL_UNFURL);
956         }
957         ASSERT_NOT_REACHED();
958         return 0;
959     case CSS_PROP__WEBKIT_USER_MODIFY:
960         switch (style->userModify()) {
961             case READ_ONLY:
962                 return new CSSPrimitiveValue(CSS_VAL_READ_ONLY);
963             case READ_WRITE:
964                 return new CSSPrimitiveValue(CSS_VAL_READ_WRITE);
965             case READ_WRITE_PLAINTEXT_ONLY:
966                 return new CSSPrimitiveValue(CSS_VAL_READ_WRITE_PLAINTEXT_ONLY);
967         }
968         ASSERT_NOT_REACHED();
969         return 0;
970     case CSS_PROP_MAX_HEIGHT:
971         return valueForMaxLength(style->maxHeight());
972     case CSS_PROP_MAX_WIDTH:
973         return valueForMaxLength(style->maxWidth());
974     case CSS_PROP_MIN_HEIGHT:
975         return valueForLength(style->minHeight());
976     case CSS_PROP_MIN_WIDTH:
977         return valueForLength(style->minWidth());
978     case CSS_PROP_OPACITY:
979         return new CSSPrimitiveValue(style->opacity(), CSSPrimitiveValue::CSS_NUMBER);
980     case CSS_PROP_ORPHANS:
981         return new CSSPrimitiveValue(style->orphans(), CSSPrimitiveValue::CSS_NUMBER);
982     case CSS_PROP_OUTLINE_COLOR:
983         // FIXME: unimplemented
984         break;
985     case CSS_PROP_OUTLINE_OFFSET:
986         // FIXME: unimplemented
987         break;
988     case CSS_PROP_OUTLINE_STYLE:
989         if (style->outlineStyleIsAuto())
990             return new CSSPrimitiveValue(CSS_VAL_AUTO);
991         return valueForBorderStyle(style->outlineStyle());
992     case CSS_PROP_OUTLINE_WIDTH:
993         // FIXME: unimplemented
994         break;
995     case CSS_PROP_OVERFLOW:
996     case CSS_PROP_OVERFLOW_X:
997     case CSS_PROP_OVERFLOW_Y:
998         EOverflow overflow;
999         switch (propertyID) {
1000             case CSS_PROP_OVERFLOW_X:
1001                 overflow = style->overflowX();
1002                 break;
1003             case CSS_PROP_OVERFLOW_Y:
1004                 overflow = style->overflowY();
1005                 break;
1006             default:
1007                 overflow = max(style->overflowX(), style->overflowY());
1008         }
1009         switch (overflow) {
1010             case OVISIBLE:
1011                 return new CSSPrimitiveValue(CSS_VAL_VISIBLE);
1012             case OHIDDEN:
1013                 return new CSSPrimitiveValue(CSS_VAL_HIDDEN);
1014             case OSCROLL:
1015                 return new CSSPrimitiveValue(CSS_VAL_SCROLL);
1016             case OAUTO:
1017                 return new CSSPrimitiveValue(CSS_VAL_AUTO);
1018             case OMARQUEE:
1019                 return new CSSPrimitiveValue(CSS_VAL__WEBKIT_MARQUEE);
1020             case OOVERLAY:
1021                 return new CSSPrimitiveValue(CSS_VAL_OVERLAY);
1022         }
1023         ASSERT_NOT_REACHED();
1024         return 0;
1025     case CSS_PROP_PADDING_TOP:
1026         return new CSSPrimitiveValue(renderer->paddingTop(), CSSPrimitiveValue::CSS_PX);
1027     case CSS_PROP_PADDING_RIGHT:
1028         return new CSSPrimitiveValue(renderer->paddingRight(), CSSPrimitiveValue::CSS_PX);
1029     case CSS_PROP_PADDING_BOTTOM:
1030         return new CSSPrimitiveValue(renderer->paddingBottom(), CSSPrimitiveValue::CSS_PX);
1031     case CSS_PROP_PADDING_LEFT:
1032         return new CSSPrimitiveValue(renderer->paddingLeft(), CSSPrimitiveValue::CSS_PX);
1033     case CSS_PROP_PAGE:
1034         // FIXME: unimplemented
1035         break;
1036     case CSS_PROP_PAGE_BREAK_AFTER:
1037         switch (style->pageBreakAfter()) {
1038             case PBAUTO:
1039                 return new CSSPrimitiveValue(CSS_VAL_AUTO);
1040             case PBALWAYS:
1041                 return new CSSPrimitiveValue(CSS_VAL_ALWAYS);
1042             case PBAVOID:
1043                 return new CSSPrimitiveValue(CSS_VAL_AVOID);
1044         }
1045         ASSERT_NOT_REACHED();
1046         return 0;
1047     case CSS_PROP_PAGE_BREAK_BEFORE:
1048         switch (style->pageBreakBefore()) {
1049             case PBAUTO:
1050                 return new CSSPrimitiveValue(CSS_VAL_AUTO);
1051             case PBALWAYS:
1052                 return new CSSPrimitiveValue(CSS_VAL_ALWAYS);
1053             case PBAVOID:
1054                 return new CSSPrimitiveValue(CSS_VAL_AVOID);
1055         }
1056         ASSERT_NOT_REACHED();
1057         return 0;
1058     case CSS_PROP_PAGE_BREAK_INSIDE:
1059         switch (style->pageBreakInside()) {
1060             case PBAUTO:
1061                 return new CSSPrimitiveValue(CSS_VAL_AUTO);
1062             case PBAVOID:
1063                 return new CSSPrimitiveValue(CSS_VAL_AVOID);
1064             case PBALWAYS:
1065                 break; // not allowed
1066         }
1067         ASSERT_NOT_REACHED();
1068         return 0;
1069     case CSS_PROP_POSITION:
1070         switch (style->position()) {
1071             case StaticPosition:
1072                 return new CSSPrimitiveValue(CSS_VAL_STATIC);
1073             case RelativePosition:
1074                 return new CSSPrimitiveValue(CSS_VAL_RELATIVE);
1075             case AbsolutePosition:
1076                 return new CSSPrimitiveValue(CSS_VAL_ABSOLUTE);
1077             case FixedPosition:
1078                 return new CSSPrimitiveValue(CSS_VAL_FIXED);
1079         }
1080         ASSERT_NOT_REACHED();
1081         return 0;
1082     case CSS_PROP_QUOTES:
1083         // FIXME: unimplemented
1084         break;
1085     case CSS_PROP_RIGHT:
1086         return getPositionOffsetValue(renderer, CSS_PROP_RIGHT);
1087     case CSS_PROP_SIZE:
1088         // FIXME: unimplemented
1089         break;
1090     case CSS_PROP_TABLE_LAYOUT:
1091         switch (style->tableLayout()) {
1092             case TAUTO:
1093                 return new CSSPrimitiveValue(CSS_VAL_AUTO);
1094             case TFIXED:
1095                 return new CSSPrimitiveValue(CSS_VAL_FIXED);
1096         }
1097         ASSERT_NOT_REACHED();
1098         return 0;
1099     case CSS_PROP_TEXT_ALIGN:
1100         return valueForTextAlign(style->textAlign());
1101     case CSS_PROP_TEXT_DECORATION:
1102     {
1103         String string;
1104         if (style->textDecoration() & UNDERLINE)
1105             string += "underline";
1106         if (style->textDecoration() & OVERLINE) {
1107             if (string.length() > 0)
1108                 string += " ";
1109             string += "overline";
1110         }
1111         if (style->textDecoration() & LINE_THROUGH) {
1112             if (string.length() > 0)
1113                 string += " ";
1114             string += "line-through";
1115         }
1116         if (style->textDecoration() & BLINK) {
1117             if (string.length() > 0)
1118                 string += " ";
1119             string += "blink";
1120         }
1121         if (string.length() == 0)
1122             return new CSSPrimitiveValue(CSS_VAL_NONE);
1123         return new CSSPrimitiveValue(string, CSSPrimitiveValue::CSS_STRING);
1124     }
1125     case CSS_PROP__WEBKIT_TEXT_DECORATIONS_IN_EFFECT:
1126     {
1127         String string;
1128         if (style->textDecorationsInEffect() & UNDERLINE)
1129             string += "underline";
1130         if (style->textDecorationsInEffect() & OVERLINE) {
1131             if (string.length() > 0)
1132                 string += " ";
1133             string += "overline";
1134         }
1135         if (style->textDecorationsInEffect() & LINE_THROUGH) {
1136             if (string.length() > 0)
1137                 string += " ";
1138             string += "line-through";
1139         }
1140         if (style->textDecorationsInEffect() & BLINK) {
1141             if (string.length() > 0)
1142                 string += " ";
1143             string += "blink";
1144         }
1145         if (string.length() == 0)
1146             return new CSSPrimitiveValue(CSS_VAL_NONE);
1147         return new CSSPrimitiveValue(string, CSSPrimitiveValue::CSS_STRING);
1148     }
1149     case CSS_PROP_TEXT_INDENT:
1150         return valueForLength(style->textIndent());
1151     case CSS_PROP_TEXT_SHADOW:
1152         return valueForShadow(style->textShadow());
1153     case CSS_PROP__WEBKIT_TEXT_SECURITY:
1154     {
1155         switch (style->textSecurity()) {
1156             case TSNONE:
1157                 return new CSSPrimitiveValue(CSS_VAL_NONE);
1158             case TSDISC:
1159                 return new CSSPrimitiveValue(CSS_VAL_DISC);
1160             case TSCIRCLE:
1161                 return new CSSPrimitiveValue(CSS_VAL_CIRCLE);
1162             case TSSQUARE:
1163                 return new CSSPrimitiveValue(CSS_VAL_SQUARE);
1164         }
1165         ASSERT_NOT_REACHED();
1166         return 0;
1167     }
1168     case CSS_PROP__WEBKIT_TEXT_SIZE_ADJUST:
1169         if (style->textSizeAdjust()) 
1170             return new CSSPrimitiveValue(CSS_VAL_AUTO);
1171         else
1172             return new CSSPrimitiveValue(CSS_VAL_NONE);
1173     case CSS_PROP_TEXT_TRANSFORM:
1174         switch (style->textTransform()) {
1175             case CAPITALIZE:
1176                 return new CSSPrimitiveValue(CSS_VAL_CAPITALIZE);
1177             case UPPERCASE:
1178                 return new CSSPrimitiveValue(CSS_VAL_UPPERCASE);
1179             case LOWERCASE:
1180                 return new CSSPrimitiveValue(CSS_VAL_LOWERCASE);
1181             case TTNONE:
1182                 return new CSSPrimitiveValue(CSS_VAL_NONE);
1183         }
1184         ASSERT_NOT_REACHED();
1185         return 0;
1186     case CSS_PROP_TOP:
1187         return getPositionOffsetValue(renderer, CSS_PROP_TOP);
1188     case CSS_PROP_UNICODE_BIDI:
1189         switch (style->unicodeBidi()) {
1190             case UBNormal:
1191                 return new CSSPrimitiveValue(CSS_VAL_NORMAL);
1192             case Embed:
1193                 return new CSSPrimitiveValue(CSS_VAL_EMBED);
1194             case Override:
1195                 return new CSSPrimitiveValue(CSS_VAL_BIDI_OVERRIDE);
1196         }
1197         ASSERT_NOT_REACHED();
1198         return 0;
1199     case CSS_PROP_VERTICAL_ALIGN:
1200         switch (style->verticalAlign()) {
1201             case BASELINE:
1202                 return new CSSPrimitiveValue(CSS_VAL_BASELINE);
1203             case MIDDLE:
1204                 return new CSSPrimitiveValue(CSS_VAL_MIDDLE);
1205             case SUB:
1206                 return new CSSPrimitiveValue(CSS_VAL_SUB);
1207             case SUPER:
1208                 return new CSSPrimitiveValue(CSS_VAL_SUPER);
1209             case TEXT_TOP:
1210                 return new CSSPrimitiveValue(CSS_VAL_TEXT_TOP);
1211             case TEXT_BOTTOM:
1212                 return new CSSPrimitiveValue(CSS_VAL_TEXT_BOTTOM);
1213             case TOP:
1214                 return new CSSPrimitiveValue(CSS_VAL_TOP);
1215             case BOTTOM:
1216                 return new CSSPrimitiveValue(CSS_VAL_BOTTOM);
1217             case BASELINE_MIDDLE:
1218                 return new CSSPrimitiveValue(CSS_VAL__WEBKIT_BASELINE_MIDDLE);
1219             case LENGTH:
1220                 return valueForLength(style->verticalAlignLength());
1221         }
1222         ASSERT_NOT_REACHED();
1223         return 0;
1224     case CSS_PROP_VISIBILITY:
1225         switch (style->visibility()) {
1226             case VISIBLE:
1227                 return new CSSPrimitiveValue(CSS_VAL_VISIBLE);
1228             case HIDDEN:
1229                 return new CSSPrimitiveValue(CSS_VAL_HIDDEN);
1230             case COLLAPSE:
1231                 return new CSSPrimitiveValue(CSS_VAL_COLLAPSE);
1232         }
1233         ASSERT_NOT_REACHED();
1234         return 0;
1235     case CSS_PROP_WHITE_SPACE:
1236         switch (style->whiteSpace()) {
1237             case NORMAL:
1238                 return new CSSPrimitiveValue(CSS_VAL_NORMAL);
1239             case PRE:
1240                 return new CSSPrimitiveValue(CSS_VAL_PRE);
1241             case PRE_WRAP:
1242                 return new CSSPrimitiveValue(CSS_VAL_PRE_WRAP);
1243             case PRE_LINE:
1244                 return new CSSPrimitiveValue(CSS_VAL_PRE_LINE);
1245             case NOWRAP:
1246                 return new CSSPrimitiveValue(CSS_VAL_NOWRAP);
1247             case KHTML_NOWRAP:
1248                 return new CSSPrimitiveValue(CSS_VAL__WEBKIT_NOWRAP);
1249         }
1250         ASSERT_NOT_REACHED();
1251         return 0;
1252     case CSS_PROP_WIDOWS:
1253         return new CSSPrimitiveValue(style->widows(), CSSPrimitiveValue::CSS_NUMBER);
1254     case CSS_PROP_WIDTH:
1255         return new CSSPrimitiveValue(renderer->contentWidth(), CSSPrimitiveValue::CSS_PX);
1256     case CSS_PROP_WORD_SPACING:
1257         return new CSSPrimitiveValue(style->wordSpacing(), CSSPrimitiveValue::CSS_PX);
1258     case CSS_PROP_WORD_WRAP:
1259         switch (style->wordWrap()) {
1260             case WBNORMAL:
1261                 return new CSSPrimitiveValue(CSS_VAL_NORMAL);
1262             case BREAK_WORD:
1263                 return new CSSPrimitiveValue(CSS_VAL_BREAK_WORD);
1264         }
1265         ASSERT_NOT_REACHED();
1266         return 0;
1267     case CSS_PROP__WEBKIT_LINE_BREAK:
1268         switch (style->khtmlLineBreak()) {
1269             case LBNORMAL:
1270                 return new CSSPrimitiveValue(CSS_VAL_NORMAL);
1271             case AFTER_WHITE_SPACE:
1272                 return new CSSPrimitiveValue(CSS_VAL_AFTER_WHITE_SPACE);
1273         }
1274         ASSERT_NOT_REACHED();
1275         return 0;
1276     case CSS_PROP__WEBKIT_NBSP_MODE:
1277         switch (style->nbspMode()) {
1278             case NBNORMAL:
1279                 return new CSSPrimitiveValue(CSS_VAL_NORMAL);
1280             case SPACE:
1281                 return new CSSPrimitiveValue(CSS_VAL_SPACE);
1282         }
1283         ASSERT_NOT_REACHED();
1284         return 0;
1285     case CSS_PROP__WEBKIT_MATCH_NEAREST_MAIL_BLOCKQUOTE_COLOR:
1286         switch (style->matchNearestMailBlockquoteColor()) {
1287             case BCNORMAL:
1288                 return new CSSPrimitiveValue(CSS_VAL_NORMAL);
1289             case MATCH:
1290                 return new CSSPrimitiveValue(CSS_VAL_MATCH);
1291         }
1292         ASSERT_NOT_REACHED();
1293         return 0;
1294     case CSS_PROP_RESIZE:
1295         switch (style->resize()) {
1296             case RESIZE_BOTH:
1297                 return new CSSPrimitiveValue(CSS_VAL_BOTH);
1298             case RESIZE_HORIZONTAL:
1299                 return new CSSPrimitiveValue(CSS_VAL_HORIZONTAL);
1300             case RESIZE_VERTICAL:
1301                 return new CSSPrimitiveValue(CSS_VAL_VERTICAL);
1302             case RESIZE_NONE:
1303             default:
1304                 return new CSSPrimitiveValue(CSS_VAL_NONE);
1305         }
1306     case CSS_PROP_Z_INDEX:
1307         if (style->hasAutoZIndex())
1308             return new CSSPrimitiveValue(CSS_VAL_NORMAL);
1309         return new CSSPrimitiveValue(style->zIndex(), CSSPrimitiveValue::CSS_NUMBER);
1310     case CSS_PROP_BACKGROUND:
1311         // FIXME: unimplemented
1312         break;
1313     case CSS_PROP_BORDER:
1314         // FIXME: unimplemented
1315         break;
1316     case CSS_PROP_BORDER_COLOR:
1317         // FIXME: unimplemented
1318         break;
1319     case CSS_PROP_BORDER_STYLE:
1320         // FIXME: unimplemented
1321         break;
1322     case CSS_PROP_BORDER_TOP:
1323         // FIXME: unimplemented
1324         break;
1325     case CSS_PROP_BORDER_RIGHT:
1326         // FIXME: unimplemented
1327         break;
1328     case CSS_PROP_BORDER_BOTTOM:
1329         // FIXME: unimplemented
1330         break;
1331     case CSS_PROP_BORDER_LEFT:
1332         // FIXME: unimplemented
1333         break;
1334     case CSS_PROP_BORDER_WIDTH:
1335         // FIXME: unimplemented
1336         break;
1337     case CSS_PROP_FONT:
1338         // FIXME: unimplemented
1339         break;
1340     case CSS_PROP_LIST_STYLE:
1341         // FIXME: unimplemented
1342         break;
1343     case CSS_PROP_MARGIN:
1344         // FIXME: unimplemented
1345         break;
1346     case CSS_PROP_OUTLINE:
1347         // FIXME: unimplemented
1348         break;
1349     case CSS_PROP_PADDING:
1350         // FIXME: unimplemented
1351         break;
1352 #if PLATFORM(MAC)
1353         case CSS_PROP__WEBKIT_DASHBOARD_REGION: {
1354             const Vector<StyleDashboardRegion>& regions = style->dashboardRegions();
1355             unsigned count = regions.size();
1356             if (count == 1 && regions[0].type == StyleDashboardRegion::None)
1357                 return new CSSPrimitiveValue(CSS_VAL_NONE);
1358             
1359             RefPtr<DashboardRegion> firstRegion;
1360             DashboardRegion* previousRegion = 0;
1361             for (unsigned i = 0; i < count; i++) {
1362                 RefPtr<DashboardRegion> region = new DashboardRegion;
1363                 StyleDashboardRegion styleRegion = regions[i];
1364
1365                 region->m_label = styleRegion.label;
1366                 LengthBox offset = styleRegion.offset;
1367                 region->setTop(new CSSPrimitiveValue(offset.top.value(), CSSPrimitiveValue::CSS_PX));
1368                 region->setRight(new CSSPrimitiveValue(offset.right.value(), CSSPrimitiveValue::CSS_PX));
1369                 region->setBottom(new CSSPrimitiveValue(offset.bottom.value(), CSSPrimitiveValue::CSS_PX));
1370                 region->setLeft(new CSSPrimitiveValue(offset.left.value(), CSSPrimitiveValue::CSS_PX));
1371                 region->m_isRectangle = (styleRegion.type == StyleDashboardRegion::Rectangle); 
1372                 region->m_isCircle = (styleRegion.type == StyleDashboardRegion::Circle);
1373
1374                 if (previousRegion)
1375                     previousRegion->m_next = region;
1376                 else
1377                     firstRegion = region;
1378                 previousRegion = region.get();
1379             }
1380             return new CSSPrimitiveValue(firstRegion.release());
1381         }
1382 #endif
1383     }
1384
1385     LOG_ERROR("unimplemented propertyID: %d", propertyID);
1386     return 0;
1387 }
1388
1389 String CSSComputedStyleDeclaration::getPropertyValue(int propertyID) const
1390 {
1391     RefPtr<CSSValue> value = getPropertyCSSValue(propertyID);
1392     if (value)
1393         return value->cssText();
1394     return "";
1395 }
1396
1397 bool CSSComputedStyleDeclaration::getPropertyPriority(int) const
1398 {
1399     // All computed styles have a priority of false (not "important").
1400     return false;
1401 }
1402
1403 String CSSComputedStyleDeclaration::removeProperty(int, ExceptionCode& ec)
1404 {
1405     ec = NO_MODIFICATION_ALLOWED_ERR;
1406     return String();
1407 }
1408
1409 void CSSComputedStyleDeclaration::setProperty(int, const String&, bool, ExceptionCode& ec)
1410 {
1411     ec = NO_MODIFICATION_ALLOWED_ERR;
1412 }
1413
1414 unsigned CSSComputedStyleDeclaration::length() const
1415 {
1416     Node* node = m_node.get();
1417     if (!node)
1418         return 0;
1419     RenderObject* renderer = node->renderer();
1420     if (!renderer)
1421         return 0;
1422     RenderStyle* style = renderer->style();
1423     if (!style)
1424         return 0;
1425     return numComputedProperties;
1426 }
1427
1428 String CSSComputedStyleDeclaration::item(unsigned i) const
1429 {
1430     if (i >= length())
1431         return String();
1432     
1433     return getPropertyName(computedProperties[i]);
1434 }
1435
1436 // This is the list of properties we want to copy in the copyInheritableProperties() function.
1437 // It is the intersection of the list of inherited CSS properties and the
1438 // properties for which we have a computed implementation in this file.
1439 const int inheritableProperties[] = {
1440     CSS_PROP_BORDER_COLLAPSE,
1441     CSS_PROP__WEBKIT_BORDER_HORIZONTAL_SPACING,
1442     CSS_PROP__WEBKIT_BORDER_VERTICAL_SPACING,
1443     CSS_PROP_COLOR,
1444     CSS_PROP_FONT_FAMILY,
1445     CSS_PROP_FONT_SIZE,
1446     CSS_PROP_FONT_STYLE,
1447     CSS_PROP_FONT_VARIANT,
1448     CSS_PROP_FONT_WEIGHT,
1449     CSS_PROP_LETTER_SPACING,
1450     CSS_PROP_LINE_HEIGHT,
1451     CSS_PROP_TEXT_ALIGN,
1452     CSS_PROP__WEBKIT_TEXT_DECORATIONS_IN_EFFECT,
1453     CSS_PROP_TEXT_INDENT,
1454     CSS_PROP__WEBKIT_TEXT_SIZE_ADJUST,
1455     CSS_PROP_TEXT_TRANSFORM,
1456     CSS_PROP_ORPHANS,
1457     CSS_PROP_WHITE_SPACE,
1458     CSS_PROP_WIDOWS,
1459     CSS_PROP_WORD_SPACING,
1460 };
1461
1462 const unsigned numInheritableProperties = sizeof(inheritableProperties) / sizeof(inheritableProperties[0]);
1463
1464 PassRefPtr<CSSMutableStyleDeclaration> CSSComputedStyleDeclaration::copyInheritableProperties() const
1465 {
1466     return copyPropertiesInSet(inheritableProperties, numInheritableProperties);
1467 }
1468
1469 PassRefPtr<CSSMutableStyleDeclaration> CSSComputedStyleDeclaration::copy() const
1470 {
1471     return copyPropertiesInSet(computedProperties, numComputedProperties);
1472 }
1473
1474 PassRefPtr<CSSMutableStyleDeclaration> CSSComputedStyleDeclaration::makeMutable()
1475 {
1476     return copy();
1477 }
1478
1479 } // namespace WebCore