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