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