2006-11-01 David Kilzer <ddkilzer@kilzer.net>
[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                 break;
684             case CURSOR_ALL_SCROLL:
685                 value = new CSSPrimitiveValue(CSS_VAL_ALL_SCROLL);
686                 break;
687         }
688         ASSERT(value);
689         if (list) {
690             list->append(value);
691             return list;
692         }
693         return value;
694     }
695     case CSS_PROP_DIRECTION:
696         switch (style->direction()) {
697             case LTR:
698                 return new CSSPrimitiveValue(CSS_VAL_LTR);
699             case RTL:
700                 return new CSSPrimitiveValue(CSS_VAL_RTL);
701         }
702         ASSERT_NOT_REACHED();
703         return 0;
704     case CSS_PROP_DISPLAY:
705         switch (style->display()) {
706             case INLINE:
707                 return new CSSPrimitiveValue(CSS_VAL_INLINE);
708             case BLOCK:
709                 return new CSSPrimitiveValue(CSS_VAL_BLOCK);
710             case LIST_ITEM:
711                 return new CSSPrimitiveValue(CSS_VAL_LIST_ITEM);
712             case RUN_IN:
713                 return new CSSPrimitiveValue(CSS_VAL_RUN_IN);
714             case COMPACT:
715                 return new CSSPrimitiveValue(CSS_VAL_COMPACT);
716             case INLINE_BLOCK:
717                 return new CSSPrimitiveValue(CSS_VAL_INLINE_BLOCK);
718             case TABLE:
719                 return new CSSPrimitiveValue(CSS_VAL_TABLE);
720             case INLINE_TABLE:
721                 return new CSSPrimitiveValue(CSS_VAL_INLINE_TABLE);
722             case TABLE_ROW_GROUP:
723                 return new CSSPrimitiveValue(CSS_VAL_TABLE_ROW_GROUP);
724             case TABLE_HEADER_GROUP:
725                 return new CSSPrimitiveValue(CSS_VAL_TABLE_HEADER_GROUP);
726             case TABLE_FOOTER_GROUP:
727                 return new CSSPrimitiveValue(CSS_VAL_TABLE_FOOTER_GROUP);
728             case TABLE_ROW:
729                 return new CSSPrimitiveValue(CSS_VAL_TABLE_ROW);
730             case TABLE_COLUMN_GROUP:
731                 return new CSSPrimitiveValue(CSS_VAL_TABLE_COLUMN_GROUP);
732             case TABLE_COLUMN:
733                 return new CSSPrimitiveValue(CSS_VAL_TABLE_COLUMN);
734             case TABLE_CELL:
735                 return new CSSPrimitiveValue(CSS_VAL_TABLE_CELL);
736             case TABLE_CAPTION:
737                 return new CSSPrimitiveValue(CSS_VAL_TABLE_CAPTION);
738             case BOX:
739                 return new CSSPrimitiveValue(CSS_VAL__WEBKIT_BOX);
740             case INLINE_BOX:
741                 return new CSSPrimitiveValue(CSS_VAL__WEBKIT_INLINE_BOX);
742             case NONE:
743                 return new CSSPrimitiveValue(CSS_VAL_NONE);
744         }
745         ASSERT_NOT_REACHED();
746         return 0;
747     case CSS_PROP_EMPTY_CELLS:
748         switch (style->emptyCells()) {
749             case SHOW:
750                 return new CSSPrimitiveValue(CSS_VAL_SHOW);
751             case HIDE:
752                 return new CSSPrimitiveValue(CSS_VAL_HIDE);
753         }
754         ASSERT_NOT_REACHED();
755         return 0;
756     case CSS_PROP_FLOAT:
757         switch (style->floating()) {
758             case FNONE:
759                 return new CSSPrimitiveValue(CSS_VAL_NONE);
760             case FLEFT:
761                 return new CSSPrimitiveValue(CSS_VAL_LEFT);
762             case FRIGHT:
763                 return new CSSPrimitiveValue(CSS_VAL_RIGHT);
764         }
765         ASSERT_NOT_REACHED();
766         return 0;
767     case CSS_PROP_FONT_FAMILY:
768     {
769         // FIXME: This only returns the first family.
770         const FontDescription& desc = style->fontDescription();
771         return new CSSPrimitiveValue(desc.family().family().domString(), CSSPrimitiveValue::CSS_STRING);
772     }
773     case CSS_PROP_FONT_SIZE:
774     {
775         FontDescription desc = style->fontDescription();
776         return new CSSPrimitiveValue(desc.computedPixelSize(), CSSPrimitiveValue::CSS_PX);
777     }
778     case CSS_PROP_FONT_STRETCH:
779         // FIXME: unimplemented
780         break;
781     case CSS_PROP_FONT_STYLE:
782     {
783         // FIXME: handle oblique?
784         const FontDescription& desc = style->fontDescription();
785         if (desc.italic())
786             return new CSSPrimitiveValue(CSS_VAL_ITALIC);
787         else
788             return new CSSPrimitiveValue(CSS_VAL_NORMAL);
789     }
790     case CSS_PROP_FONT_VARIANT:
791     {
792         const FontDescription& desc = style->fontDescription();
793         if (desc.smallCaps())
794             return new CSSPrimitiveValue(CSS_VAL_SMALL_CAPS);
795         else
796             return new CSSPrimitiveValue(CSS_VAL_NORMAL);
797     }
798     case CSS_PROP_FONT_WEIGHT:
799     {
800         // FIXME: this does not reflect the full range of weights
801         // that can be expressed with CSS
802         const FontDescription& desc = style->fontDescription();
803         if (desc.weight() == cBoldWeight)
804             return new CSSPrimitiveValue(CSS_VAL_BOLD);
805         else
806             return new CSSPrimitiveValue(CSS_VAL_NORMAL);
807     }
808     case CSS_PROP_HEIGHT:
809         return new CSSPrimitiveValue(renderer->contentHeight(), CSSPrimitiveValue::CSS_PX);
810     case CSS_PROP__WEBKIT_HIGHLIGHT: {
811         if (style->highlight() == nullAtom)
812             return new CSSPrimitiveValue(CSS_VAL_NONE);
813         else
814             return new CSSPrimitiveValue(style->highlight(), CSSPrimitiveValue::CSS_STRING);
815     }
816     case CSS_PROP_LEFT:
817         return getPositionOffsetValue(renderer, CSS_PROP_LEFT);
818     case CSS_PROP_LETTER_SPACING:
819         if (style->letterSpacing() == 0)
820             return new CSSPrimitiveValue(CSS_VAL_NORMAL);
821         return new CSSPrimitiveValue(style->letterSpacing(), CSSPrimitiveValue::CSS_PX);
822     case CSS_PROP__WEBKIT_LINE_CLAMP:
823         if (style->lineClamp() == -1)
824             return new CSSPrimitiveValue(CSS_VAL_NONE);
825         return new CSSPrimitiveValue(style->lineClamp(), CSSPrimitiveValue::CSS_PERCENTAGE);
826     case CSS_PROP_LINE_HEIGHT: {
827         Length length(style->lineHeight());
828         if (length.value() < 0)
829             return new CSSPrimitiveValue(CSS_VAL_NORMAL);
830         if (length.isPercent()) {
831             // This is imperfect, because it doesn't include the zoom factor and the real computation
832             // for how high to be in pixels does include things like minimum font size and the zoom factor.
833             // On the other hand, since font-size doesn't include the zoom factor, we really can't do
834             // that here either.
835             float fontSize = style->fontDescription().specifiedSize();
836             return new CSSPrimitiveValue((int)(length.value() * fontSize) / 100, CSSPrimitiveValue::CSS_PX);
837         }
838         else {
839             return new CSSPrimitiveValue(length.value(), CSSPrimitiveValue::CSS_PX);
840         }
841     }
842     case CSS_PROP_LIST_STYLE_IMAGE:
843         if (style->listStyleImage())
844             return new CSSPrimitiveValue(style->listStyleImage()->url(), CSSPrimitiveValue::CSS_URI);
845         return new CSSPrimitiveValue(CSS_VAL_NONE);
846     case CSS_PROP_LIST_STYLE_POSITION:
847         switch (style->listStylePosition()) {
848             case OUTSIDE:
849                 return new CSSPrimitiveValue(CSS_VAL_OUTSIDE);
850             case INSIDE:
851                 return new CSSPrimitiveValue(CSS_VAL_INSIDE);
852         }
853         ASSERT_NOT_REACHED();
854         return 0;
855     case CSS_PROP_LIST_STYLE_TYPE:
856         switch (style->listStyleType()) {
857             case LNONE:
858                 return new CSSPrimitiveValue(CSS_VAL_NONE);
859             case DISC:
860                 return new CSSPrimitiveValue(CSS_VAL_DISC);
861             case CIRCLE:
862                 return new CSSPrimitiveValue(CSS_VAL_CIRCLE);
863             case SQUARE:
864                 return new CSSPrimitiveValue(CSS_VAL_SQUARE);
865             case LDECIMAL:
866                 return new CSSPrimitiveValue(CSS_VAL_DECIMAL);
867             case DECIMAL_LEADING_ZERO:
868                 return new CSSPrimitiveValue(CSS_VAL_DECIMAL_LEADING_ZERO);
869             case LOWER_ROMAN:
870                 return new CSSPrimitiveValue(CSS_VAL_LOWER_ROMAN);
871             case UPPER_ROMAN:
872                 return new CSSPrimitiveValue(CSS_VAL_UPPER_ROMAN);
873             case LOWER_GREEK:
874                 return new CSSPrimitiveValue(CSS_VAL_LOWER_GREEK);
875             case LOWER_ALPHA:
876                 return new CSSPrimitiveValue(CSS_VAL_LOWER_ALPHA);
877             case LOWER_LATIN:
878                 return new CSSPrimitiveValue(CSS_VAL_LOWER_LATIN);
879             case UPPER_ALPHA:
880                 return new CSSPrimitiveValue(CSS_VAL_UPPER_ALPHA);
881             case UPPER_LATIN:
882                 return new CSSPrimitiveValue(CSS_VAL_UPPER_LATIN);
883             case HEBREW:
884                 return new CSSPrimitiveValue(CSS_VAL_HEBREW);
885             case ARMENIAN:
886                 return new CSSPrimitiveValue(CSS_VAL_ARMENIAN);
887             case GEORGIAN:
888                 return new CSSPrimitiveValue(CSS_VAL_GEORGIAN);
889             case CJK_IDEOGRAPHIC:
890                 return new CSSPrimitiveValue(CSS_VAL_CJK_IDEOGRAPHIC);
891             case HIRAGANA:
892                 return new CSSPrimitiveValue(CSS_VAL_HIRAGANA);
893             case KATAKANA:
894                 return new CSSPrimitiveValue(CSS_VAL_KATAKANA);
895             case HIRAGANA_IROHA:
896                 return new CSSPrimitiveValue(CSS_VAL_HIRAGANA_IROHA);
897             case KATAKANA_IROHA:
898                 return new CSSPrimitiveValue(CSS_VAL_KATAKANA_IROHA);
899         }
900         ASSERT_NOT_REACHED();
901         return 0;
902     case CSS_PROP_MARGIN_TOP:
903         // FIXME: Supposed to return the percentage if percentage was specified.
904         return new CSSPrimitiveValue(renderer->marginTop(), CSSPrimitiveValue::CSS_PX);
905     case CSS_PROP_MARGIN_RIGHT:
906         // FIXME: Supposed to return the percentage if percentage was specified.
907         return new CSSPrimitiveValue(renderer->marginRight(), CSSPrimitiveValue::CSS_PX);
908     case CSS_PROP_MARGIN_BOTTOM:
909         // FIXME: Supposed to return the percentage if percentage was specified.
910         return new CSSPrimitiveValue(renderer->marginBottom(), CSSPrimitiveValue::CSS_PX);
911     case CSS_PROP_MARGIN_LEFT:
912         // FIXME: Supposed to return the percentage if percentage was specified.
913         return new CSSPrimitiveValue(renderer->marginLeft(), CSSPrimitiveValue::CSS_PX);
914     case CSS_PROP__WEBKIT_MARQUEE:
915         // FIXME: unimplemented
916         break;
917     case CSS_PROP__WEBKIT_MARQUEE_DIRECTION:
918         switch (style->marqueeDirection()) {
919             case MFORWARD:
920                 return new CSSPrimitiveValue(CSS_VAL_FORWARDS);
921             case MBACKWARD:
922                 return new CSSPrimitiveValue(CSS_VAL_BACKWARDS);
923             case MAUTO:
924                 return new CSSPrimitiveValue(CSS_VAL_AUTO);
925             case MUP:
926                 return new CSSPrimitiveValue(CSS_VAL_UP);
927             case MDOWN:
928                 return new CSSPrimitiveValue(CSS_VAL_DOWN);
929             case MLEFT:
930                 return new CSSPrimitiveValue(CSS_VAL_LEFT);
931             case MRIGHT:
932                 return new CSSPrimitiveValue(CSS_VAL_RIGHT);
933         }
934         ASSERT_NOT_REACHED();
935         return 0;
936     case CSS_PROP__WEBKIT_MARQUEE_INCREMENT:
937         return valueForLength(style->marqueeIncrement());
938     case CSS_PROP__WEBKIT_MARQUEE_REPETITION:
939         if (style->marqueeLoopCount() < 0)
940             return new CSSPrimitiveValue(CSS_VAL_INFINITE);
941         return new CSSPrimitiveValue(style->marqueeLoopCount(), CSSPrimitiveValue::CSS_NUMBER);
942     case CSS_PROP__WEBKIT_MARQUEE_SPEED:
943         // FIXME: unimplemented
944         break;
945     case CSS_PROP__WEBKIT_MARQUEE_STYLE:
946         switch (style->marqueeBehavior()) {
947             case MNONE:
948                 return new CSSPrimitiveValue(CSS_VAL_NONE);
949             case MSCROLL:
950                 return new CSSPrimitiveValue(CSS_VAL_SCROLL);
951             case MSLIDE:
952                 return new CSSPrimitiveValue(CSS_VAL_SLIDE);
953             case MALTERNATE:
954                 return new CSSPrimitiveValue(CSS_VAL_ALTERNATE);
955             case MUNFURL:
956                 return new CSSPrimitiveValue(CSS_VAL_UNFURL);
957         }
958         ASSERT_NOT_REACHED();
959         return 0;
960     case CSS_PROP__WEBKIT_USER_MODIFY:
961         switch (style->userModify()) {
962             case READ_ONLY:
963                 return new CSSPrimitiveValue(CSS_VAL_READ_ONLY);
964             case READ_WRITE:
965                 return new CSSPrimitiveValue(CSS_VAL_READ_WRITE);
966             case READ_WRITE_PLAINTEXT_ONLY:
967                 return new CSSPrimitiveValue(CSS_VAL_READ_WRITE_PLAINTEXT_ONLY);
968         }
969         ASSERT_NOT_REACHED();
970         return 0;
971     case CSS_PROP_MAX_HEIGHT:
972         return valueForMaxLength(style->maxHeight());
973     case CSS_PROP_MAX_WIDTH:
974         return valueForMaxLength(style->maxWidth());
975     case CSS_PROP_MIN_HEIGHT:
976         return valueForLength(style->minHeight());
977     case CSS_PROP_MIN_WIDTH:
978         return valueForLength(style->minWidth());
979     case CSS_PROP_OPACITY:
980         return new CSSPrimitiveValue(style->opacity(), CSSPrimitiveValue::CSS_NUMBER);
981     case CSS_PROP_ORPHANS:
982         return new CSSPrimitiveValue(style->orphans(), CSSPrimitiveValue::CSS_NUMBER);
983     case CSS_PROP_OUTLINE_COLOR:
984         // FIXME: unimplemented
985         break;
986     case CSS_PROP_OUTLINE_OFFSET:
987         // FIXME: unimplemented
988         break;
989     case CSS_PROP_OUTLINE_STYLE:
990         if (style->outlineStyleIsAuto())
991             return new CSSPrimitiveValue(CSS_VAL_AUTO);
992         return valueForBorderStyle(style->outlineStyle());
993     case CSS_PROP_OUTLINE_WIDTH:
994         // FIXME: unimplemented
995         break;
996     case CSS_PROP_OVERFLOW:
997     case CSS_PROP_OVERFLOW_X:
998     case CSS_PROP_OVERFLOW_Y:
999         EOverflow overflow;
1000         switch (propertyID) {
1001             case CSS_PROP_OVERFLOW_X:
1002                 overflow = style->overflowX();
1003                 break;
1004             case CSS_PROP_OVERFLOW_Y:
1005                 overflow = style->overflowY();
1006                 break;
1007             default:
1008                 overflow = max(style->overflowX(), style->overflowY());
1009         }
1010         switch (overflow) {
1011             case OVISIBLE:
1012                 return new CSSPrimitiveValue(CSS_VAL_VISIBLE);
1013             case OHIDDEN:
1014                 return new CSSPrimitiveValue(CSS_VAL_HIDDEN);
1015             case OSCROLL:
1016                 return new CSSPrimitiveValue(CSS_VAL_SCROLL);
1017             case OAUTO:
1018                 return new CSSPrimitiveValue(CSS_VAL_AUTO);
1019             case OMARQUEE:
1020                 return new CSSPrimitiveValue(CSS_VAL__WEBKIT_MARQUEE);
1021             case OOVERLAY:
1022                 return new CSSPrimitiveValue(CSS_VAL_OVERLAY);
1023         }
1024         ASSERT_NOT_REACHED();
1025         return 0;
1026     case CSS_PROP_PADDING_TOP:
1027         return new CSSPrimitiveValue(renderer->paddingTop(), CSSPrimitiveValue::CSS_PX);
1028     case CSS_PROP_PADDING_RIGHT:
1029         return new CSSPrimitiveValue(renderer->paddingRight(), CSSPrimitiveValue::CSS_PX);
1030     case CSS_PROP_PADDING_BOTTOM:
1031         return new CSSPrimitiveValue(renderer->paddingBottom(), CSSPrimitiveValue::CSS_PX);
1032     case CSS_PROP_PADDING_LEFT:
1033         return new CSSPrimitiveValue(renderer->paddingLeft(), CSSPrimitiveValue::CSS_PX);
1034     case CSS_PROP_PAGE:
1035         // FIXME: unimplemented
1036         break;
1037     case CSS_PROP_PAGE_BREAK_AFTER:
1038         switch (style->pageBreakAfter()) {
1039             case PBAUTO:
1040                 return new CSSPrimitiveValue(CSS_VAL_AUTO);
1041             case PBALWAYS:
1042                 return new CSSPrimitiveValue(CSS_VAL_ALWAYS);
1043             case PBAVOID:
1044                 return new CSSPrimitiveValue(CSS_VAL_AVOID);
1045         }
1046         ASSERT_NOT_REACHED();
1047         return 0;
1048     case CSS_PROP_PAGE_BREAK_BEFORE:
1049         switch (style->pageBreakBefore()) {
1050             case PBAUTO:
1051                 return new CSSPrimitiveValue(CSS_VAL_AUTO);
1052             case PBALWAYS:
1053                 return new CSSPrimitiveValue(CSS_VAL_ALWAYS);
1054             case PBAVOID:
1055                 return new CSSPrimitiveValue(CSS_VAL_AVOID);
1056         }
1057         ASSERT_NOT_REACHED();
1058         return 0;
1059     case CSS_PROP_PAGE_BREAK_INSIDE:
1060         switch (style->pageBreakInside()) {
1061             case PBAUTO:
1062                 return new CSSPrimitiveValue(CSS_VAL_AUTO);
1063             case PBAVOID:
1064                 return new CSSPrimitiveValue(CSS_VAL_AVOID);
1065             case PBALWAYS:
1066                 break; // not allowed
1067         }
1068         ASSERT_NOT_REACHED();
1069         return 0;
1070     case CSS_PROP_POSITION:
1071         switch (style->position()) {
1072             case StaticPosition:
1073                 return new CSSPrimitiveValue(CSS_VAL_STATIC);
1074             case RelativePosition:
1075                 return new CSSPrimitiveValue(CSS_VAL_RELATIVE);
1076             case AbsolutePosition:
1077                 return new CSSPrimitiveValue(CSS_VAL_ABSOLUTE);
1078             case FixedPosition:
1079                 return new CSSPrimitiveValue(CSS_VAL_FIXED);
1080         }
1081         ASSERT_NOT_REACHED();
1082         return 0;
1083     case CSS_PROP_QUOTES:
1084         // FIXME: unimplemented
1085         break;
1086     case CSS_PROP_RIGHT:
1087         return getPositionOffsetValue(renderer, CSS_PROP_RIGHT);
1088     case CSS_PROP_SIZE:
1089         // FIXME: unimplemented
1090         break;
1091     case CSS_PROP_TABLE_LAYOUT:
1092         switch (style->tableLayout()) {
1093             case TAUTO:
1094                 return new CSSPrimitiveValue(CSS_VAL_AUTO);
1095             case TFIXED:
1096                 return new CSSPrimitiveValue(CSS_VAL_FIXED);
1097         }
1098         ASSERT_NOT_REACHED();
1099         return 0;
1100     case CSS_PROP_TEXT_ALIGN:
1101         return valueForTextAlign(style->textAlign());
1102     case CSS_PROP_TEXT_DECORATION:
1103     {
1104         String string;
1105         if (style->textDecoration() & UNDERLINE)
1106             string += "underline";
1107         if (style->textDecoration() & OVERLINE) {
1108             if (string.length() > 0)
1109                 string += " ";
1110             string += "overline";
1111         }
1112         if (style->textDecoration() & LINE_THROUGH) {
1113             if (string.length() > 0)
1114                 string += " ";
1115             string += "line-through";
1116         }
1117         if (style->textDecoration() & BLINK) {
1118             if (string.length() > 0)
1119                 string += " ";
1120             string += "blink";
1121         }
1122         if (string.length() == 0)
1123             return new CSSPrimitiveValue(CSS_VAL_NONE);
1124         return new CSSPrimitiveValue(string, CSSPrimitiveValue::CSS_STRING);
1125     }
1126     case CSS_PROP__WEBKIT_TEXT_DECORATIONS_IN_EFFECT:
1127     {
1128         String string;
1129         if (style->textDecorationsInEffect() & UNDERLINE)
1130             string += "underline";
1131         if (style->textDecorationsInEffect() & OVERLINE) {
1132             if (string.length() > 0)
1133                 string += " ";
1134             string += "overline";
1135         }
1136         if (style->textDecorationsInEffect() & LINE_THROUGH) {
1137             if (string.length() > 0)
1138                 string += " ";
1139             string += "line-through";
1140         }
1141         if (style->textDecorationsInEffect() & BLINK) {
1142             if (string.length() > 0)
1143                 string += " ";
1144             string += "blink";
1145         }
1146         if (string.length() == 0)
1147             return new CSSPrimitiveValue(CSS_VAL_NONE);
1148         return new CSSPrimitiveValue(string, CSSPrimitiveValue::CSS_STRING);
1149     }
1150     case CSS_PROP_TEXT_INDENT:
1151         return valueForLength(style->textIndent());
1152     case CSS_PROP_TEXT_SHADOW:
1153         return valueForShadow(style->textShadow());
1154     case CSS_PROP__WEBKIT_TEXT_SECURITY:
1155     {
1156         switch (style->textSecurity()) {
1157             case TSNONE:
1158                 return new CSSPrimitiveValue(CSS_VAL_NONE);
1159             case TSDISC:
1160                 return new CSSPrimitiveValue(CSS_VAL_DISC);
1161             case TSCIRCLE:
1162                 return new CSSPrimitiveValue(CSS_VAL_CIRCLE);
1163             case TSSQUARE:
1164                 return new CSSPrimitiveValue(CSS_VAL_SQUARE);
1165         }
1166         ASSERT_NOT_REACHED();
1167         return 0;
1168     }
1169     case CSS_PROP__WEBKIT_TEXT_SIZE_ADJUST:
1170         if (style->textSizeAdjust()) 
1171             return new CSSPrimitiveValue(CSS_VAL_AUTO);
1172         else
1173             return new CSSPrimitiveValue(CSS_VAL_NONE);
1174     case CSS_PROP_TEXT_TRANSFORM:
1175         switch (style->textTransform()) {
1176             case CAPITALIZE:
1177                 return new CSSPrimitiveValue(CSS_VAL_CAPITALIZE);
1178             case UPPERCASE:
1179                 return new CSSPrimitiveValue(CSS_VAL_UPPERCASE);
1180             case LOWERCASE:
1181                 return new CSSPrimitiveValue(CSS_VAL_LOWERCASE);
1182             case TTNONE:
1183                 return new CSSPrimitiveValue(CSS_VAL_NONE);
1184         }
1185         ASSERT_NOT_REACHED();
1186         return 0;
1187     case CSS_PROP_TOP:
1188         return getPositionOffsetValue(renderer, CSS_PROP_TOP);
1189     case CSS_PROP_UNICODE_BIDI:
1190         switch (style->unicodeBidi()) {
1191             case UBNormal:
1192                 return new CSSPrimitiveValue(CSS_VAL_NORMAL);
1193             case Embed:
1194                 return new CSSPrimitiveValue(CSS_VAL_EMBED);
1195             case Override:
1196                 return new CSSPrimitiveValue(CSS_VAL_BIDI_OVERRIDE);
1197         }
1198         ASSERT_NOT_REACHED();
1199         return 0;
1200     case CSS_PROP_VERTICAL_ALIGN:
1201         switch (style->verticalAlign()) {
1202             case BASELINE:
1203                 return new CSSPrimitiveValue(CSS_VAL_BASELINE);
1204             case MIDDLE:
1205                 return new CSSPrimitiveValue(CSS_VAL_MIDDLE);
1206             case SUB:
1207                 return new CSSPrimitiveValue(CSS_VAL_SUB);
1208             case SUPER:
1209                 return new CSSPrimitiveValue(CSS_VAL_SUPER);
1210             case TEXT_TOP:
1211                 return new CSSPrimitiveValue(CSS_VAL_TEXT_TOP);
1212             case TEXT_BOTTOM:
1213                 return new CSSPrimitiveValue(CSS_VAL_TEXT_BOTTOM);
1214             case TOP:
1215                 return new CSSPrimitiveValue(CSS_VAL_TOP);
1216             case BOTTOM:
1217                 return new CSSPrimitiveValue(CSS_VAL_BOTTOM);
1218             case BASELINE_MIDDLE:
1219                 return new CSSPrimitiveValue(CSS_VAL__WEBKIT_BASELINE_MIDDLE);
1220             case LENGTH:
1221                 return valueForLength(style->verticalAlignLength());
1222         }
1223         ASSERT_NOT_REACHED();
1224         return 0;
1225     case CSS_PROP_VISIBILITY:
1226         switch (style->visibility()) {
1227             case VISIBLE:
1228                 return new CSSPrimitiveValue(CSS_VAL_VISIBLE);
1229             case HIDDEN:
1230                 return new CSSPrimitiveValue(CSS_VAL_HIDDEN);
1231             case COLLAPSE:
1232                 return new CSSPrimitiveValue(CSS_VAL_COLLAPSE);
1233         }
1234         ASSERT_NOT_REACHED();
1235         return 0;
1236     case CSS_PROP_WHITE_SPACE:
1237         switch (style->whiteSpace()) {
1238             case NORMAL:
1239                 return new CSSPrimitiveValue(CSS_VAL_NORMAL);
1240             case PRE:
1241                 return new CSSPrimitiveValue(CSS_VAL_PRE);
1242             case PRE_WRAP:
1243                 return new CSSPrimitiveValue(CSS_VAL_PRE_WRAP);
1244             case PRE_LINE:
1245                 return new CSSPrimitiveValue(CSS_VAL_PRE_LINE);
1246             case NOWRAP:
1247                 return new CSSPrimitiveValue(CSS_VAL_NOWRAP);
1248             case KHTML_NOWRAP:
1249                 return new CSSPrimitiveValue(CSS_VAL__WEBKIT_NOWRAP);
1250         }
1251         ASSERT_NOT_REACHED();
1252         return 0;
1253     case CSS_PROP_WIDOWS:
1254         return new CSSPrimitiveValue(style->widows(), CSSPrimitiveValue::CSS_NUMBER);
1255     case CSS_PROP_WIDTH:
1256         return new CSSPrimitiveValue(renderer->contentWidth(), CSSPrimitiveValue::CSS_PX);
1257     case CSS_PROP_WORD_SPACING:
1258         return new CSSPrimitiveValue(style->wordSpacing(), CSSPrimitiveValue::CSS_PX);
1259     case CSS_PROP_WORD_WRAP:
1260         switch (style->wordWrap()) {
1261             case WBNORMAL:
1262                 return new CSSPrimitiveValue(CSS_VAL_NORMAL);
1263             case BREAK_WORD:
1264                 return new CSSPrimitiveValue(CSS_VAL_BREAK_WORD);
1265         }
1266         ASSERT_NOT_REACHED();
1267         return 0;
1268     case CSS_PROP__WEBKIT_LINE_BREAK:
1269         switch (style->khtmlLineBreak()) {
1270             case LBNORMAL:
1271                 return new CSSPrimitiveValue(CSS_VAL_NORMAL);
1272             case AFTER_WHITE_SPACE:
1273                 return new CSSPrimitiveValue(CSS_VAL_AFTER_WHITE_SPACE);
1274         }
1275         ASSERT_NOT_REACHED();
1276         return 0;
1277     case CSS_PROP__WEBKIT_NBSP_MODE:
1278         switch (style->nbspMode()) {
1279             case NBNORMAL:
1280                 return new CSSPrimitiveValue(CSS_VAL_NORMAL);
1281             case SPACE:
1282                 return new CSSPrimitiveValue(CSS_VAL_SPACE);
1283         }
1284         ASSERT_NOT_REACHED();
1285         return 0;
1286     case CSS_PROP__WEBKIT_MATCH_NEAREST_MAIL_BLOCKQUOTE_COLOR:
1287         switch (style->matchNearestMailBlockquoteColor()) {
1288             case BCNORMAL:
1289                 return new CSSPrimitiveValue(CSS_VAL_NORMAL);
1290             case MATCH:
1291                 return new CSSPrimitiveValue(CSS_VAL_MATCH);
1292         }
1293         ASSERT_NOT_REACHED();
1294         return 0;
1295     case CSS_PROP_RESIZE:
1296         switch (style->resize()) {
1297             case RESIZE_BOTH:
1298                 return new CSSPrimitiveValue(CSS_VAL_BOTH);
1299             case RESIZE_HORIZONTAL:
1300                 return new CSSPrimitiveValue(CSS_VAL_HORIZONTAL);
1301             case RESIZE_VERTICAL:
1302                 return new CSSPrimitiveValue(CSS_VAL_VERTICAL);
1303             case RESIZE_NONE:
1304             default:
1305                 return new CSSPrimitiveValue(CSS_VAL_NONE);
1306         }
1307     case CSS_PROP_Z_INDEX:
1308         if (style->hasAutoZIndex())
1309             return new CSSPrimitiveValue(CSS_VAL_NORMAL);
1310         return new CSSPrimitiveValue(style->zIndex(), CSSPrimitiveValue::CSS_NUMBER);
1311     case CSS_PROP_BACKGROUND:
1312         // FIXME: unimplemented
1313         break;
1314     case CSS_PROP_BORDER:
1315         // FIXME: unimplemented
1316         break;
1317     case CSS_PROP_BORDER_COLOR:
1318         // FIXME: unimplemented
1319         break;
1320     case CSS_PROP_BORDER_STYLE:
1321         // FIXME: unimplemented
1322         break;
1323     case CSS_PROP_BORDER_TOP:
1324         // FIXME: unimplemented
1325         break;
1326     case CSS_PROP_BORDER_RIGHT:
1327         // FIXME: unimplemented
1328         break;
1329     case CSS_PROP_BORDER_BOTTOM:
1330         // FIXME: unimplemented
1331         break;
1332     case CSS_PROP_BORDER_LEFT:
1333         // FIXME: unimplemented
1334         break;
1335     case CSS_PROP_BORDER_WIDTH:
1336         // FIXME: unimplemented
1337         break;
1338     case CSS_PROP_FONT:
1339         // FIXME: unimplemented
1340         break;
1341     case CSS_PROP_LIST_STYLE:
1342         // FIXME: unimplemented
1343         break;
1344     case CSS_PROP_MARGIN:
1345         // FIXME: unimplemented
1346         break;
1347     case CSS_PROP_OUTLINE:
1348         // FIXME: unimplemented
1349         break;
1350     case CSS_PROP_PADDING:
1351         // FIXME: unimplemented
1352         break;
1353 #if PLATFORM(MAC)
1354         case CSS_PROP__WEBKIT_DASHBOARD_REGION: {
1355             const Vector<StyleDashboardRegion>& regions = style->dashboardRegions();
1356             unsigned count = regions.size();
1357             if (count == 1 && regions[0].type == StyleDashboardRegion::None)
1358                 return new CSSPrimitiveValue(CSS_VAL_NONE);
1359             
1360             RefPtr<DashboardRegion> firstRegion;
1361             DashboardRegion* previousRegion = 0;
1362             for (unsigned i = 0; i < count; i++) {
1363                 RefPtr<DashboardRegion> region = new DashboardRegion;
1364                 StyleDashboardRegion styleRegion = regions[i];
1365
1366                 region->m_label = styleRegion.label;
1367                 LengthBox offset = styleRegion.offset;
1368                 region->setTop(new CSSPrimitiveValue(offset.top.value(), CSSPrimitiveValue::CSS_PX));
1369                 region->setRight(new CSSPrimitiveValue(offset.right.value(), CSSPrimitiveValue::CSS_PX));
1370                 region->setBottom(new CSSPrimitiveValue(offset.bottom.value(), CSSPrimitiveValue::CSS_PX));
1371                 region->setLeft(new CSSPrimitiveValue(offset.left.value(), CSSPrimitiveValue::CSS_PX));
1372                 region->m_isRectangle = (styleRegion.type == StyleDashboardRegion::Rectangle); 
1373                 region->m_isCircle = (styleRegion.type == StyleDashboardRegion::Circle);
1374
1375                 if (previousRegion)
1376                     previousRegion->m_next = region;
1377                 else
1378                     firstRegion = region;
1379                 previousRegion = region.get();
1380             }
1381             return new CSSPrimitiveValue(firstRegion.release());
1382         }
1383 #endif
1384     }
1385
1386     LOG_ERROR("unimplemented propertyID: %d", propertyID);
1387     return 0;
1388 }
1389
1390 String CSSComputedStyleDeclaration::getPropertyValue(int propertyID) const
1391 {
1392     RefPtr<CSSValue> value = getPropertyCSSValue(propertyID);
1393     if (value)
1394         return value->cssText();
1395     return "";
1396 }
1397
1398 bool CSSComputedStyleDeclaration::getPropertyPriority(int) const
1399 {
1400     // All computed styles have a priority of false (not "important").
1401     return false;
1402 }
1403
1404 String CSSComputedStyleDeclaration::removeProperty(int, ExceptionCode& ec)
1405 {
1406     ec = NO_MODIFICATION_ALLOWED_ERR;
1407     return String();
1408 }
1409
1410 void CSSComputedStyleDeclaration::setProperty(int, const String&, bool, ExceptionCode& ec)
1411 {
1412     ec = NO_MODIFICATION_ALLOWED_ERR;
1413 }
1414
1415 unsigned CSSComputedStyleDeclaration::length() const
1416 {
1417     Node* node = m_node.get();
1418     if (!node)
1419         return 0;
1420     RenderObject* renderer = node->renderer();
1421     if (!renderer)
1422         return 0;
1423     RenderStyle* style = renderer->style();
1424     if (!style)
1425         return 0;
1426     return numComputedProperties;
1427 }
1428
1429 String CSSComputedStyleDeclaration::item(unsigned i) const
1430 {
1431     if (i >= length())
1432         return String();
1433     
1434     return getPropertyName(computedProperties[i]);
1435 }
1436
1437 // This is the list of properties we want to copy in the copyInheritableProperties() function.
1438 // It is the intersection of the list of inherited CSS properties and the
1439 // properties for which we have a computed implementation in this file.
1440 const int inheritableProperties[] = {
1441     CSS_PROP_BORDER_COLLAPSE,
1442     CSS_PROP__WEBKIT_BORDER_HORIZONTAL_SPACING,
1443     CSS_PROP__WEBKIT_BORDER_VERTICAL_SPACING,
1444     CSS_PROP_COLOR,
1445     CSS_PROP_FONT_FAMILY,
1446     CSS_PROP_FONT_SIZE,
1447     CSS_PROP_FONT_STYLE,
1448     CSS_PROP_FONT_VARIANT,
1449     CSS_PROP_FONT_WEIGHT,
1450     CSS_PROP_LETTER_SPACING,
1451     CSS_PROP_LINE_HEIGHT,
1452     CSS_PROP_TEXT_ALIGN,
1453     CSS_PROP__WEBKIT_TEXT_DECORATIONS_IN_EFFECT,
1454     CSS_PROP_TEXT_INDENT,
1455     CSS_PROP__WEBKIT_TEXT_SIZE_ADJUST,
1456     CSS_PROP_TEXT_TRANSFORM,
1457     CSS_PROP_ORPHANS,
1458     CSS_PROP_WHITE_SPACE,
1459     CSS_PROP_WIDOWS,
1460     CSS_PROP_WORD_SPACING,
1461 };
1462
1463 const unsigned numInheritableProperties = sizeof(inheritableProperties) / sizeof(inheritableProperties[0]);
1464
1465 PassRefPtr<CSSMutableStyleDeclaration> CSSComputedStyleDeclaration::copyInheritableProperties() const
1466 {
1467     return copyPropertiesInSet(inheritableProperties, numInheritableProperties);
1468 }
1469
1470 PassRefPtr<CSSMutableStyleDeclaration> CSSComputedStyleDeclaration::copy() const
1471 {
1472     return copyPropertiesInSet(computedProperties, numComputedProperties);
1473 }
1474
1475 PassRefPtr<CSSMutableStyleDeclaration> CSSComputedStyleDeclaration::makeMutable()
1476 {
1477     return copy();
1478 }
1479
1480 } // namespace WebCore