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