789925eca60cff886e5100ce7f601ac4b5292e84
[WebKit-https.git] / WebCore / khtml / css / css_computedstyle.cpp
1 /**
2  * css_computedstyle.cpp
3  *
4  * Copyright (C)  2004  Zack Rusin <zack@kde.org>
5  * Copyright (C) 2004 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 "css_computedstyle.h"
24
25 #include "cssproperties.h"
26 #include "cssvalues.h"
27 #include "dom_atomicstring.h"
28 #include "dom_exception.h"
29 #include "dom_string.h"
30 #include "font.h"
31 #include "khtmllayout.h"
32 #include "loader.h"
33 #include "rendering/render_style.h"
34 #include "rendering/render_object.h"
35
36 #if APPLE_CHANGES
37 #import "KWQAssertions.h"
38 #import "KWQFontFamily.h"
39 #import "KWQLogging.h"
40 #endif
41
42 using khtml::EBorderStyle;
43 using khtml::ETextAlign;
44 using khtml::Font;
45 using khtml::FontDef;
46 using khtml::Length;
47 using khtml::LengthBox;
48 using khtml::RenderObject;
49 using khtml::RenderStyle;
50 using khtml::ShadowData;
51 using khtml::StyleDashboardRegion;
52
53 namespace DOM {
54
55 // List of all properties we know how to compute, omitting shorthands.
56 static const int computedProperties[] = {
57     CSS_PROP_BACKGROUND_COLOR,
58     CSS_PROP_BACKGROUND_IMAGE,
59     CSS_PROP_BACKGROUND_REPEAT,
60     CSS_PROP_BACKGROUND_ATTACHMENT,
61     CSS_PROP_BACKGROUND_POSITION,
62     CSS_PROP_BACKGROUND_POSITION_X,
63     CSS_PROP_BACKGROUND_POSITION_Y,
64     CSS_PROP_BORDER_COLLAPSE,
65     CSS_PROP_BORDER_SPACING,
66     CSS_PROP__KHTML_BORDER_HORIZONTAL_SPACING,
67     CSS_PROP__KHTML_BORDER_VERTICAL_SPACING,
68     CSS_PROP_BORDER_TOP_COLOR,
69     CSS_PROP_BORDER_RIGHT_COLOR,
70     CSS_PROP_BORDER_BOTTOM_COLOR,
71     CSS_PROP_BORDER_LEFT_COLOR,
72     CSS_PROP_BORDER_TOP_STYLE,
73     CSS_PROP_BORDER_RIGHT_STYLE,
74     CSS_PROP_BORDER_BOTTOM_STYLE,
75     CSS_PROP_BORDER_LEFT_STYLE,
76     CSS_PROP_BORDER_TOP_WIDTH,
77     CSS_PROP_BORDER_RIGHT_WIDTH,
78     CSS_PROP_BORDER_BOTTOM_WIDTH,
79     CSS_PROP_BORDER_LEFT_WIDTH,
80     CSS_PROP_BOTTOM,
81     CSS_PROP__KHTML_BOX_ALIGN,
82     CSS_PROP__KHTML_BOX_DIRECTION,
83     CSS_PROP__KHTML_BOX_FLEX,
84     CSS_PROP__KHTML_BOX_FLEX_GROUP,
85     CSS_PROP__KHTML_BOX_LINES,
86     CSS_PROP__KHTML_BOX_ORDINAL_GROUP,
87     CSS_PROP__KHTML_BOX_ORIENT,
88     CSS_PROP__KHTML_BOX_PACK,
89     CSS_PROP_CAPTION_SIDE,
90     CSS_PROP_CLEAR,
91     CSS_PROP_COLOR,
92     CSS_PROP_CURSOR,
93     CSS_PROP__APPLE_DASHBOARD_REGION,
94     CSS_PROP_DIRECTION,
95     CSS_PROP_DISPLAY,
96     CSS_PROP_EMPTY_CELLS,
97     CSS_PROP_FLOAT,
98     CSS_PROP_FONT_FAMILY,
99     CSS_PROP_FONT_SIZE,
100     CSS_PROP_FONT_STYLE,
101     CSS_PROP_FONT_VARIANT,
102     CSS_PROP_FONT_WEIGHT,
103     CSS_PROP_HEIGHT,
104     CSS_PROP_LEFT,
105     CSS_PROP_LETTER_SPACING,
106     CSS_PROP__KHTML_LINE_BREAK,
107     CSS_PROP__APPLE_LINE_CLAMP,
108     CSS_PROP_LINE_HEIGHT,
109     CSS_PROP_LIST_STYLE_IMAGE,
110     CSS_PROP_LIST_STYLE_POSITION,
111     CSS_PROP_LIST_STYLE_TYPE,
112     CSS_PROP_MARGIN_TOP,
113     CSS_PROP_MARGIN_RIGHT,
114     CSS_PROP_MARGIN_BOTTOM,
115     CSS_PROP_MARGIN_LEFT,
116     CSS_PROP__KHTML_MARQUEE_DIRECTION,
117     CSS_PROP__KHTML_MARQUEE_INCREMENT,
118     CSS_PROP__KHTML_MARQUEE_REPETITION,
119     CSS_PROP__KHTML_MARQUEE_STYLE,
120     CSS_PROP_MAX_HEIGHT,
121     CSS_PROP_MAX_WIDTH,
122     CSS_PROP_MIN_HEIGHT,
123     CSS_PROP_MIN_WIDTH,
124     CSS_PROP__KHTML_NBSP_MODE,
125     CSS_PROP_OPACITY,
126     CSS_PROP_ORPHANS,
127     CSS_PROP_OUTLINE_STYLE,
128     CSS_PROP_OVERFLOW,
129     CSS_PROP_PADDING_TOP,
130     CSS_PROP_PADDING_RIGHT,
131     CSS_PROP_PADDING_BOTTOM,
132     CSS_PROP_PADDING_LEFT,
133     CSS_PROP_PAGE_BREAK_AFTER,
134     CSS_PROP_PAGE_BREAK_BEFORE,
135     CSS_PROP_PAGE_BREAK_INSIDE,
136     CSS_PROP_POSITION,
137     CSS_PROP_RIGHT,
138     CSS_PROP_TABLE_LAYOUT,
139     CSS_PROP_TEXT_ALIGN,
140     CSS_PROP_TEXT_DECORATION,
141     CSS_PROP__KHTML_TEXT_DECORATIONS_IN_EFFECT,
142     CSS_PROP_TEXT_INDENT,
143     CSS_PROP_TEXT_SHADOW,
144     CSS_PROP_TEXT_TRANSFORM,
145     CSS_PROP_TOP,
146     CSS_PROP_UNICODE_BIDI,
147     CSS_PROP__KHTML_USER_MODIFY,
148     CSS_PROP_VERTICAL_ALIGN,
149     CSS_PROP_VISIBILITY,
150     CSS_PROP_WHITE_SPACE,
151     CSS_PROP_WIDOWS,
152     CSS_PROP_WIDTH,
153     CSS_PROP_WORD_SPACING,
154     CSS_PROP_WORD_WRAP,
155     CSS_PROP_Z_INDEX,
156 };
157
158 const unsigned numComputedProperties = sizeof(computedProperties) / sizeof(computedProperties[0]);
159
160 // This is the list of properties we want to copy in the copyInheritableProperties() function.
161 // It is the intersection of the list of inherited CSS properties and the
162 // properties for which we have a computed implementation in this file.
163 static const int inheritableProperties[] = {
164     CSS_PROP_BORDER_COLLAPSE,
165     CSS_PROP_BORDER_SPACING,
166     CSS_PROP_COLOR,
167     CSS_PROP_FONT_FAMILY,
168     CSS_PROP_FONT_SIZE,
169     CSS_PROP_FONT_STYLE,
170     CSS_PROP_FONT_VARIANT,
171     CSS_PROP_FONT_WEIGHT,
172     CSS_PROP_LETTER_SPACING,
173     CSS_PROP_LINE_HEIGHT,
174     CSS_PROP_TEXT_ALIGN,
175     CSS_PROP__KHTML_TEXT_DECORATIONS_IN_EFFECT,
176     CSS_PROP_TEXT_INDENT,
177     CSS_PROP__APPLE_TEXT_SIZE_ADJUST,
178     CSS_PROP_TEXT_TRANSFORM,
179     CSS_PROP_ORPHANS,
180     CSS_PROP_WHITE_SPACE,
181     CSS_PROP_WIDOWS,
182     CSS_PROP_WORD_SPACING,
183 };
184
185 const unsigned numInheritableProperties = sizeof(inheritableProperties) / sizeof(inheritableProperties[0]);
186
187 static CSSValueImpl* valueForLength(const Length &length)
188 {
189     switch (length.type) {
190         case khtml::Percent:
191             return new CSSPrimitiveValueImpl(length.length(), CSSPrimitiveValue::CSS_PERCENTAGE);
192         case khtml::Fixed:
193             return new CSSPrimitiveValueImpl(length.length(), CSSPrimitiveValue::CSS_PX);
194         default: // FIXME: Intrinsic and MinIntrinsic should probably return keywords.
195             return new CSSPrimitiveValueImpl(CSS_VAL_AUTO);
196     }
197 }
198
199 static CSSValueImpl *valueForBorderStyle(EBorderStyle style)
200 {
201     switch (style) {
202         case khtml::BNONE:
203             return new CSSPrimitiveValueImpl(CSS_VAL_NONE);
204         case khtml::BHIDDEN:
205             return new CSSPrimitiveValueImpl(CSS_VAL_HIDDEN);
206         case khtml::INSET:
207             return new CSSPrimitiveValueImpl(CSS_VAL_INSET);
208         case khtml::GROOVE:
209             return new CSSPrimitiveValueImpl(CSS_VAL_GROOVE);
210         case khtml::RIDGE:
211             return new CSSPrimitiveValueImpl(CSS_VAL_RIDGE);
212         case khtml::OUTSET:
213             return new CSSPrimitiveValueImpl(CSS_VAL_OUTSET);
214         case khtml::DOTTED:
215             return new CSSPrimitiveValueImpl(CSS_VAL_DOTTED);
216         case khtml::DASHED:
217             return new CSSPrimitiveValueImpl(CSS_VAL_DASHED);
218         case khtml::SOLID:
219             return new CSSPrimitiveValueImpl(CSS_VAL_SOLID);
220         case khtml::DOUBLE:
221             return new CSSPrimitiveValueImpl(CSS_VAL_DOUBLE);
222     }
223     ASSERT_NOT_REACHED();
224     return 0;
225 }
226
227 static CSSValueImpl *valueForTextAlign(ETextAlign align)
228 {
229     switch (align) {
230         case khtml::TAAUTO:
231             return new CSSPrimitiveValueImpl(CSS_VAL_AUTO);
232         case khtml::LEFT:
233             return new CSSPrimitiveValueImpl(CSS_VAL_LEFT);
234         case khtml::RIGHT:
235             return new CSSPrimitiveValueImpl(CSS_VAL_RIGHT);
236         case khtml::CENTER:
237             return new CSSPrimitiveValueImpl(CSS_VAL_CENTER);
238         case khtml::JUSTIFY:
239             return new CSSPrimitiveValueImpl(CSS_VAL_JUSTIFY);
240         case khtml::KHTML_LEFT:
241             return new CSSPrimitiveValueImpl(CSS_VAL__KHTML_LEFT);
242         case khtml::KHTML_RIGHT:
243             return new CSSPrimitiveValueImpl(CSS_VAL__KHTML_RIGHT);
244         case khtml::KHTML_CENTER:
245             return new CSSPrimitiveValueImpl(CSS_VAL__KHTML_CENTER);
246     }
247     ASSERT_NOT_REACHED();
248     return 0;
249 }
250
251 static CSSValueImpl* valueForShadow(const ShadowData *shadow)
252 {
253     if (!shadow)
254         return new CSSPrimitiveValueImpl(CSS_VAL_NONE);
255     CSSValueListImpl *list = new CSSValueListImpl;
256     for (const ShadowData *s = shadow; s; s = s->next) {
257         CSSPrimitiveValueImpl *x = new CSSPrimitiveValueImpl(s->x, CSSPrimitiveValue::CSS_PX);
258         CSSPrimitiveValueImpl *y = new CSSPrimitiveValueImpl(s->y, CSSPrimitiveValue::CSS_PX);
259         CSSPrimitiveValueImpl *blur = new CSSPrimitiveValueImpl(s->blur, CSSPrimitiveValue::CSS_PX);
260         CSSPrimitiveValueImpl *color = new CSSPrimitiveValueImpl(s->color.rgb());
261         list->append(new ShadowValueImpl(x, y, blur, color));
262     }
263     return list;
264 }
265
266 static CSSValueImpl *getPositionOffsetValue(RenderObject *renderer, int propertyID)
267 {
268     if (!renderer)
269         return 0;
270
271     RenderStyle *style = renderer->style();
272     if (!style)
273         return 0;
274
275     Length l;
276     switch (propertyID) {
277     case CSS_PROP_LEFT:
278         l = style->left();
279         break;
280     case CSS_PROP_RIGHT:
281         l = style->right();
282         break;
283     case CSS_PROP_TOP:
284         l = style->top();
285         break;
286     case CSS_PROP_BOTTOM:
287         l = style->bottom();
288         break;
289     default:
290         return 0;
291     }
292
293     if (renderer->isPositioned())
294         return valueForLength(l);
295     
296     if (renderer->isRelPositioned())
297         // FIXME: It's not enough to simply return "auto" values for one offset if the other side is defined.
298         // In other words if left is auto and right is not auto, then left's computed value is negative right.
299         // So we should get the opposite length unit and see if it is auto.
300         return valueForLength(l);
301     
302     return new CSSPrimitiveValueImpl(CSS_VAL_AUTO);
303 }
304
305 CSSComputedStyleDeclarationImpl::CSSComputedStyleDeclarationImpl(NodeImpl *n)
306     : m_node(n)
307 {
308 }
309
310 CSSComputedStyleDeclarationImpl::~CSSComputedStyleDeclarationImpl()
311 {
312 }
313
314 DOMString CSSComputedStyleDeclarationImpl::cssText() const
315 {
316     ERROR("unimplemented");
317     return DOMString();
318 }
319
320 void CSSComputedStyleDeclarationImpl::setCssText(const DOMString &, int &exceptionCode)
321 {
322     exceptionCode = DOMException::NO_MODIFICATION_ALLOWED_ERR;
323 }
324
325 // Display integers in integer format instead of "1.0".
326 static QString numberAsString(double n)
327 {
328     long i = static_cast<long>(n);
329     return i == n ? QString::number(i) : QString::number(n);
330 }
331
332 CSSValueImpl *CSSComputedStyleDeclarationImpl::getPropertyCSSValue(int propertyID) const
333 {
334     return getPropertyCSSValue(propertyID, UpdateLayout);
335 }
336
337 CSSValueImpl *CSSComputedStyleDeclarationImpl::getPropertyCSSValue(int propertyID, EUpdateLayout updateLayout) const
338 {
339     NodeImpl *node = m_node.handle();
340     if (!node)
341         return 0;
342
343     // Make sure our layout is up to date before we allow a query on these attributes.
344     DocumentImpl* docimpl = node->getDocument();
345     if (docimpl && updateLayout)
346         docimpl->updateLayout();
347
348     RenderObject *renderer = node->renderer();
349     if (!renderer)
350         return 0;
351     RenderStyle *style = renderer->style();
352     if (!style)
353         return 0;
354
355     switch (propertyID)
356     {
357     case CSS_PROP_BACKGROUND_COLOR:
358         return new CSSPrimitiveValueImpl(style->backgroundColor().rgb());
359     case CSS_PROP_BACKGROUND_IMAGE:
360         if (style->backgroundImage())
361             return new CSSPrimitiveValueImpl(style->backgroundImage()->url(), CSSPrimitiveValue::CSS_URI);
362         return new CSSPrimitiveValueImpl(CSS_VAL_NONE);
363     case CSS_PROP_BACKGROUND_REPEAT:
364         switch (style->backgroundRepeat()) {
365             case khtml::REPEAT:
366                 return new CSSPrimitiveValueImpl(CSS_VAL_REPEAT);
367             case khtml::REPEAT_X:
368                 return new CSSPrimitiveValueImpl(CSS_VAL_REPEAT_X);
369             case khtml::REPEAT_Y:
370                 return new CSSPrimitiveValueImpl(CSS_VAL_REPEAT_Y);
371             case khtml::NO_REPEAT:
372                 return new CSSPrimitiveValueImpl(CSS_VAL_NO_REPEAT);
373         }
374         ASSERT_NOT_REACHED();
375         return 0;
376     case CSS_PROP_BACKGROUND_ATTACHMENT:
377         if (style->backgroundAttachment())
378             return new CSSPrimitiveValueImpl(CSS_VAL_SCROLL);
379         else
380             return new CSSPrimitiveValueImpl(CSS_VAL_FIXED);
381     case CSS_PROP_BACKGROUND_POSITION:
382     {
383         DOMString string;
384         Length length(style->backgroundXPosition());
385         if (length.isPercent())
386             string = numberAsString(length.length()) + "%";
387         else
388             string = numberAsString(length.minWidth(renderer->contentWidth()));
389         string += " ";
390         length = style->backgroundYPosition();
391         if (length.isPercent())
392             string += numberAsString(length.length()) + "%";
393         else
394             string += numberAsString(length.minWidth(renderer->contentWidth()));
395         return new CSSPrimitiveValueImpl(string, CSSPrimitiveValue::CSS_STRING);
396     }
397     case CSS_PROP_BACKGROUND_POSITION_X:
398         return valueForLength(style->backgroundXPosition());
399     case CSS_PROP_BACKGROUND_POSITION_Y:
400         return valueForLength(style->backgroundYPosition());
401 #ifndef KHTML_NO_XBL
402     case CSS_PROP__KHTML_BINDING:
403         // FIXME: unimplemented
404         break;
405 #endif
406     case CSS_PROP_BORDER_COLLAPSE:
407         if (style->borderCollapse())
408             return new CSSPrimitiveValueImpl(CSS_VAL_COLLAPSE);
409         else
410             return new CSSPrimitiveValueImpl(CSS_VAL_SEPARATE);
411     case CSS_PROP_BORDER_SPACING:
412     {
413         QString string(numberAsString(style->horizontalBorderSpacing()) + 
414             "px " + 
415             numberAsString(style->verticalBorderSpacing()) +
416             "px");
417         return new CSSPrimitiveValueImpl(string, CSSPrimitiveValue::CSS_STRING);
418     }
419     case CSS_PROP__KHTML_BORDER_HORIZONTAL_SPACING:
420         return new CSSPrimitiveValueImpl(style->horizontalBorderSpacing(), CSSPrimitiveValue::CSS_PX);
421     case CSS_PROP__KHTML_BORDER_VERTICAL_SPACING:
422         return new CSSPrimitiveValueImpl(style->verticalBorderSpacing(), CSSPrimitiveValue::CSS_PX);
423     case CSS_PROP_BORDER_TOP_COLOR:
424         return new CSSPrimitiveValueImpl(style->borderLeftColor().rgb());
425     case CSS_PROP_BORDER_RIGHT_COLOR:
426         return new CSSPrimitiveValueImpl(style->borderRightColor().rgb());
427     case CSS_PROP_BORDER_BOTTOM_COLOR:
428         return new CSSPrimitiveValueImpl(style->borderBottomColor().rgb());
429     case CSS_PROP_BORDER_LEFT_COLOR:
430         return new CSSPrimitiveValueImpl(style->borderLeftColor().rgb());
431     case CSS_PROP_BORDER_TOP_STYLE:
432         return valueForBorderStyle(style->borderTopStyle());
433     case CSS_PROP_BORDER_RIGHT_STYLE:
434         return valueForBorderStyle(style->borderRightStyle());
435     case CSS_PROP_BORDER_BOTTOM_STYLE:
436         return valueForBorderStyle(style->borderBottomStyle());
437     case CSS_PROP_BORDER_LEFT_STYLE:
438         return valueForBorderStyle(style->borderLeftStyle());
439     case CSS_PROP_BORDER_TOP_WIDTH:
440         return new CSSPrimitiveValueImpl(style->borderTopWidth(), CSSPrimitiveValue::CSS_PX);
441     case CSS_PROP_BORDER_RIGHT_WIDTH:
442         return new CSSPrimitiveValueImpl(style->borderRightWidth(), CSSPrimitiveValue::CSS_PX);
443     case CSS_PROP_BORDER_BOTTOM_WIDTH:
444         return new CSSPrimitiveValueImpl(style->borderBottomWidth(), CSSPrimitiveValue::CSS_PX);
445     case CSS_PROP_BORDER_LEFT_WIDTH:
446         return new CSSPrimitiveValueImpl(style->borderLeftWidth(), CSSPrimitiveValue::CSS_PX);
447     case CSS_PROP_BOTTOM:
448         return getPositionOffsetValue(renderer, CSS_PROP_BOTTOM);
449     case CSS_PROP__KHTML_BOX_ALIGN:
450         switch (style->boxAlign()) {
451             case khtml::BSTRETCH:
452                 return new CSSPrimitiveValueImpl(CSS_VAL_STRETCH);
453             case khtml::BSTART:
454                 return new CSSPrimitiveValueImpl(CSS_VAL_START);
455             case khtml::BCENTER:
456                 return new CSSPrimitiveValueImpl(CSS_VAL_CENTER);
457             case khtml::BEND:
458                 return new CSSPrimitiveValueImpl(CSS_VAL_END);
459             case khtml::BBASELINE:
460                 return new CSSPrimitiveValueImpl(CSS_VAL_BASELINE);
461             case khtml::BJUSTIFY:
462                 break; // not allowed
463         }
464         ASSERT_NOT_REACHED();
465         return 0;
466     case CSS_PROP__KHTML_BOX_DIRECTION:
467         switch (style->boxDirection()) {
468             case khtml::BNORMAL:
469                 return new CSSPrimitiveValueImpl(CSS_VAL_NORMAL);
470             case khtml::BREVERSE:
471                 return new CSSPrimitiveValueImpl(CSS_VAL_REVERSE);
472         }
473         ASSERT_NOT_REACHED();
474         return 0;
475     case CSS_PROP__KHTML_BOX_FLEX:
476         return new CSSPrimitiveValueImpl(style->boxFlex(), CSSPrimitiveValue::CSS_NUMBER);
477     case CSS_PROP__KHTML_BOX_FLEX_GROUP:
478         return new CSSPrimitiveValueImpl(style->boxFlexGroup(), CSSPrimitiveValue::CSS_NUMBER);
479     case CSS_PROP__KHTML_BOX_LINES:
480         switch (style->boxLines()) {
481             case khtml::SINGLE:
482                 return new CSSPrimitiveValueImpl(CSS_VAL_SINGLE);
483             case khtml::MULTIPLE:
484                 return new CSSPrimitiveValueImpl(CSS_VAL_MULTIPLE);
485         }
486         ASSERT_NOT_REACHED();
487         return 0;
488     case CSS_PROP__KHTML_BOX_ORDINAL_GROUP:
489         return new CSSPrimitiveValueImpl(style->boxOrdinalGroup(), CSSPrimitiveValue::CSS_NUMBER);
490     case CSS_PROP__KHTML_BOX_ORIENT:
491         switch (style->boxOrient()) {
492             case khtml::HORIZONTAL:
493                 return new CSSPrimitiveValueImpl(CSS_VAL_HORIZONTAL);
494             case khtml::VERTICAL:
495                 return new CSSPrimitiveValueImpl(CSS_VAL_VERTICAL);
496         }
497         ASSERT_NOT_REACHED();
498         return 0;
499     case CSS_PROP__KHTML_BOX_PACK:
500         switch (style->boxPack()) {
501             case khtml::BSTART:
502                 return new CSSPrimitiveValueImpl(CSS_VAL_START);
503             case khtml::BEND:
504                 return new CSSPrimitiveValueImpl(CSS_VAL_END);
505             case khtml::BCENTER:
506                 return new CSSPrimitiveValueImpl(CSS_VAL_CENTER);
507             case khtml::BJUSTIFY:
508                 return new CSSPrimitiveValueImpl(CSS_VAL_JUSTIFY);
509             case khtml::BSTRETCH:
510             case khtml::BBASELINE:
511                 break; // not allowed
512         }
513         ASSERT_NOT_REACHED();
514         return 0;
515     case CSS_PROP_CAPTION_SIDE:
516         switch (style->captionSide()) {
517             case khtml::CAPLEFT:
518                 return new CSSPrimitiveValueImpl(CSS_VAL_LEFT);
519             case khtml::CAPRIGHT:
520                 return new CSSPrimitiveValueImpl(CSS_VAL_RIGHT);
521             case khtml::CAPTOP:
522                 return new CSSPrimitiveValueImpl(CSS_VAL_TOP);
523             case khtml::CAPBOTTOM:
524                 return new CSSPrimitiveValueImpl(CSS_VAL_BOTTOM);
525         }
526         ASSERT_NOT_REACHED();
527         return 0;
528     case CSS_PROP_CLEAR:
529         switch (style->clear()) {
530             case khtml::CNONE:
531                 return new CSSPrimitiveValueImpl(CSS_VAL_NONE);
532             case khtml::CLEFT:
533                 return new CSSPrimitiveValueImpl(CSS_VAL_LEFT);
534             case khtml::CRIGHT:
535                 return new CSSPrimitiveValueImpl(CSS_VAL_RIGHT);
536             case khtml::CBOTH:
537                 return new CSSPrimitiveValueImpl(CSS_VAL_BOTH);
538         }
539         ASSERT_NOT_REACHED();
540         return 0;
541     case CSS_PROP_CLIP:
542         // FIXME: unimplemented
543         break;
544     case CSS_PROP_COLOR:
545         return new CSSPrimitiveValueImpl(style->color().rgb());
546     case CSS_PROP_CONTENT:
547         // FIXME: unimplemented
548         break;
549     case CSS_PROP_COUNTER_INCREMENT:
550         // FIXME: unimplemented
551         break;
552     case CSS_PROP_COUNTER_RESET:
553         // FIXME: unimplemented
554         break;
555     case CSS_PROP_CURSOR:
556         switch (style->cursor()) {
557             case khtml::CURSOR_AUTO:
558                 return new CSSPrimitiveValueImpl(CSS_VAL_AUTO);
559             case khtml::CURSOR_CROSS:
560                 return new CSSPrimitiveValueImpl(CSS_VAL_CROSSHAIR);
561             case khtml::CURSOR_DEFAULT:
562                 return new CSSPrimitiveValueImpl(CSS_VAL_DEFAULT);
563             case khtml::CURSOR_POINTER:
564                 return new CSSPrimitiveValueImpl(CSS_VAL_POINTER);
565             case khtml::CURSOR_MOVE:
566                 return new CSSPrimitiveValueImpl(CSS_VAL_MOVE);
567             case khtml::CURSOR_E_RESIZE:
568                 return new CSSPrimitiveValueImpl(CSS_VAL_E_RESIZE);
569             case khtml::CURSOR_NE_RESIZE:
570                 return new CSSPrimitiveValueImpl(CSS_VAL_NE_RESIZE);
571             case khtml::CURSOR_NW_RESIZE:
572                 return new CSSPrimitiveValueImpl(CSS_VAL_NW_RESIZE);
573             case khtml::CURSOR_N_RESIZE:
574                 return new CSSPrimitiveValueImpl(CSS_VAL_N_RESIZE);
575             case khtml::CURSOR_SE_RESIZE:
576                 return new CSSPrimitiveValueImpl(CSS_VAL_SE_RESIZE);
577             case khtml::CURSOR_SW_RESIZE:
578                 return new CSSPrimitiveValueImpl(CSS_VAL_SW_RESIZE);
579             case khtml::CURSOR_S_RESIZE:
580                 return new CSSPrimitiveValueImpl(CSS_VAL_S_RESIZE);
581             case khtml::CURSOR_W_RESIZE:
582                 return new CSSPrimitiveValueImpl(CSS_VAL_W_RESIZE);
583             case khtml::CURSOR_TEXT:
584                 return new CSSPrimitiveValueImpl(CSS_VAL_TEXT);
585             case khtml::CURSOR_WAIT:
586                 return new CSSPrimitiveValueImpl(CSS_VAL_WAIT);
587             case khtml::CURSOR_HELP:
588                 return new CSSPrimitiveValueImpl(CSS_VAL_HELP);
589         }
590         ASSERT_NOT_REACHED();
591         return 0;
592     case CSS_PROP_DIRECTION:
593         switch (style->direction()) {
594             case khtml::LTR:
595                 return new CSSPrimitiveValueImpl(CSS_VAL_LTR);
596             case khtml::RTL:
597                 return new CSSPrimitiveValueImpl(CSS_VAL_RTL);
598         }
599         ASSERT_NOT_REACHED();
600         return 0;
601     case CSS_PROP_DISPLAY:
602         switch (style->display()) {
603             case khtml::INLINE:
604                 return new CSSPrimitiveValueImpl(CSS_VAL_INLINE);
605             case khtml::BLOCK:
606                 return new CSSPrimitiveValueImpl(CSS_VAL_BLOCK);
607             case khtml::LIST_ITEM:
608                 return new CSSPrimitiveValueImpl(CSS_VAL_LIST_ITEM);
609             case khtml::RUN_IN:
610                 return new CSSPrimitiveValueImpl(CSS_VAL_RUN_IN);
611             case khtml::COMPACT:
612                 return new CSSPrimitiveValueImpl(CSS_VAL_COMPACT);
613             case khtml::INLINE_BLOCK:
614                 return new CSSPrimitiveValueImpl(CSS_VAL_INLINE_BLOCK);
615             case khtml::TABLE:
616                 return new CSSPrimitiveValueImpl(CSS_VAL_TABLE);
617             case khtml::INLINE_TABLE:
618                 return new CSSPrimitiveValueImpl(CSS_VAL_INLINE_TABLE);
619             case khtml::TABLE_ROW_GROUP:
620                 return new CSSPrimitiveValueImpl(CSS_VAL_TABLE_ROW_GROUP);
621             case khtml::TABLE_HEADER_GROUP:
622                 return new CSSPrimitiveValueImpl(CSS_VAL_TABLE_HEADER_GROUP);
623             case khtml::TABLE_FOOTER_GROUP:
624                 return new CSSPrimitiveValueImpl(CSS_VAL_TABLE_FOOTER_GROUP);
625             case khtml::TABLE_ROW:
626                 return new CSSPrimitiveValueImpl(CSS_VAL_TABLE_ROW);
627             case khtml::TABLE_COLUMN_GROUP:
628                 return new CSSPrimitiveValueImpl(CSS_VAL_TABLE_COLUMN_GROUP);
629             case khtml::TABLE_COLUMN:
630                 return new CSSPrimitiveValueImpl(CSS_VAL_TABLE_COLUMN);
631             case khtml::TABLE_CELL:
632                 return new CSSPrimitiveValueImpl(CSS_VAL_TABLE_CELL);
633             case khtml::TABLE_CAPTION:
634                 return new CSSPrimitiveValueImpl(CSS_VAL_TABLE_CAPTION);
635             case khtml::BOX:
636                 return new CSSPrimitiveValueImpl(CSS_VAL__KHTML_BOX);
637             case khtml::INLINE_BOX:
638                 return new CSSPrimitiveValueImpl(CSS_VAL__KHTML_INLINE_BOX);
639             case khtml::NONE:
640                 return new CSSPrimitiveValueImpl(CSS_VAL_NONE);
641         }
642         ASSERT_NOT_REACHED();
643         return 0;
644     case CSS_PROP_EMPTY_CELLS:
645         switch (style->emptyCells()) {
646             case khtml::SHOW:
647                 return new CSSPrimitiveValueImpl(CSS_VAL_SHOW);
648             case khtml::HIDE:
649                 return new CSSPrimitiveValueImpl(CSS_VAL_HIDE);
650         }
651         ASSERT_NOT_REACHED();
652         return 0;
653     case CSS_PROP_FLOAT:
654         switch (style->floating()) {
655             case khtml::FNONE:
656                 return new CSSPrimitiveValueImpl(CSS_VAL_NONE);
657             case khtml::FLEFT:
658                 return new CSSPrimitiveValueImpl(CSS_VAL_LEFT);
659             case khtml::FRIGHT:
660                 return new CSSPrimitiveValueImpl(CSS_VAL_RIGHT);
661         }
662         ASSERT_NOT_REACHED();
663         return 0;
664     case CSS_PROP_FONT_FAMILY:
665     {
666         FontDef def = style->htmlFont().getFontDef();
667         return new CSSPrimitiveValueImpl(def.firstFamily().family().domString(), CSSPrimitiveValue::CSS_STRING);
668     }
669     case CSS_PROP_FONT_SIZE:
670     {
671         FontDef def = style->htmlFont().getFontDef();
672         return new CSSPrimitiveValueImpl(def.specifiedSize, CSSPrimitiveValue::CSS_PX);
673     }
674     case CSS_PROP_FONT_STRETCH:
675         // FIXME: unimplemented
676         break;
677     case CSS_PROP_FONT_STYLE:
678     {
679         // FIXME: handle oblique?
680         FontDef def = style->htmlFont().getFontDef();
681         if (def.italic)
682             return new CSSPrimitiveValueImpl(CSS_VAL_ITALIC);
683         else
684             return new CSSPrimitiveValueImpl(CSS_VAL_NORMAL);
685     }
686     case CSS_PROP_FONT_VARIANT:
687     {
688         FontDef def = style->htmlFont().getFontDef();
689         if (def.smallCaps)
690             return new CSSPrimitiveValueImpl(CSS_VAL_SMALL_CAPS);
691         else
692             return new CSSPrimitiveValueImpl(CSS_VAL_NORMAL);
693     }
694     case CSS_PROP_FONT_WEIGHT:
695     {
696         // FIXME: this does not reflect the full range of weights
697         // that can be expressed with CSS
698         FontDef def = style->htmlFont().getFontDef();
699         if (def.weight == QFont::Bold)
700             return new CSSPrimitiveValueImpl(CSS_VAL_BOLD);
701         else
702             return new CSSPrimitiveValueImpl(CSS_VAL_NORMAL);
703     }
704     case CSS_PROP_HEIGHT:
705         return new CSSPrimitiveValueImpl(renderer->contentHeight(), CSSPrimitiveValue::CSS_PX);
706     case CSS_PROP_LEFT:
707         return getPositionOffsetValue(renderer, CSS_PROP_LEFT);
708     case CSS_PROP_LETTER_SPACING:
709         if (style->letterSpacing() == 0)
710             return new CSSPrimitiveValueImpl(CSS_VAL_NORMAL);
711         return new CSSPrimitiveValueImpl(style->letterSpacing(), CSSPrimitiveValue::CSS_PX);
712     case CSS_PROP__APPLE_LINE_CLAMP:
713         return new CSSPrimitiveValueImpl(style->lineClamp(), CSSPrimitiveValue::CSS_PERCENTAGE);
714     case CSS_PROP_LINE_HEIGHT: {
715         Length length(style->lineHeight());
716         if (length.value < 0)
717             return new CSSPrimitiveValueImpl(CSS_VAL_NORMAL);
718         if (length.isPercent()) {
719             // This is imperfect, because it doesn't include the zoom factor and the real computation
720             // for how high to be in pixels does include things like minimum font size and the zoom factor.
721             // On the other hand, since font-size doesn't include the zoom factor, we really can't do
722             // that here either.
723             float fontSize = style->htmlFont().getFontDef().specifiedSize;
724             return new CSSPrimitiveValueImpl((int)(length.length() * fontSize) / 100, CSSPrimitiveValue::CSS_PX);
725         }
726         else {
727             return new CSSPrimitiveValueImpl(length.length(), CSSPrimitiveValue::CSS_PX);
728         }
729     }
730     case CSS_PROP_LIST_STYLE_IMAGE:
731         if (style->listStyleImage())
732             return new CSSPrimitiveValueImpl(style->listStyleImage()->url(), CSSPrimitiveValue::CSS_URI);
733         return new CSSPrimitiveValueImpl(CSS_VAL_NONE);
734     case CSS_PROP_LIST_STYLE_POSITION:
735         switch (style->listStylePosition()) {
736             case khtml::OUTSIDE:
737                 return new CSSPrimitiveValueImpl(CSS_VAL_OUTSIDE);
738             case khtml::INSIDE:
739                 return new CSSPrimitiveValueImpl(CSS_VAL_INSIDE);
740         }
741         ASSERT_NOT_REACHED();
742         return 0;
743     case CSS_PROP_LIST_STYLE_TYPE:
744         switch (style->listStyleType()) {
745             case khtml::LNONE:
746                 return new CSSPrimitiveValueImpl(CSS_VAL_NONE);
747             case khtml::DISC:
748                 return new CSSPrimitiveValueImpl(CSS_VAL_DISC);
749             case khtml::CIRCLE:
750                 return new CSSPrimitiveValueImpl(CSS_VAL_CIRCLE);
751             case khtml::SQUARE:
752                 return new CSSPrimitiveValueImpl(CSS_VAL_SQUARE);
753             case khtml::LDECIMAL:
754                 return new CSSPrimitiveValueImpl(CSS_VAL_DECIMAL);
755             case khtml::DECIMAL_LEADING_ZERO:
756                 return new CSSPrimitiveValueImpl(CSS_VAL_DECIMAL_LEADING_ZERO);
757             case khtml::LOWER_ROMAN:
758                 return new CSSPrimitiveValueImpl(CSS_VAL_LOWER_ROMAN);
759             case khtml::UPPER_ROMAN:
760                 return new CSSPrimitiveValueImpl(CSS_VAL_UPPER_ROMAN);
761             case khtml::LOWER_GREEK:
762                 return new CSSPrimitiveValueImpl(CSS_VAL_LOWER_GREEK);
763             case khtml::LOWER_ALPHA:
764                 return new CSSPrimitiveValueImpl(CSS_VAL_LOWER_ALPHA);
765             case khtml::LOWER_LATIN:
766                 return new CSSPrimitiveValueImpl(CSS_VAL_LOWER_LATIN);
767             case khtml::UPPER_ALPHA:
768                 return new CSSPrimitiveValueImpl(CSS_VAL_UPPER_ALPHA);
769             case khtml::UPPER_LATIN:
770                 return new CSSPrimitiveValueImpl(CSS_VAL_UPPER_LATIN);
771             case khtml::HEBREW:
772                 return new CSSPrimitiveValueImpl(CSS_VAL_HEBREW);
773             case khtml::ARMENIAN:
774                 return new CSSPrimitiveValueImpl(CSS_VAL_ARMENIAN);
775             case khtml::GEORGIAN:
776                 return new CSSPrimitiveValueImpl(CSS_VAL_GEORGIAN);
777             case khtml::CJK_IDEOGRAPHIC:
778                 return new CSSPrimitiveValueImpl(CSS_VAL_CJK_IDEOGRAPHIC);
779             case khtml::HIRAGANA:
780                 return new CSSPrimitiveValueImpl(CSS_VAL_HIRAGANA);
781             case khtml::KATAKANA:
782                 return new CSSPrimitiveValueImpl(CSS_VAL_KATAKANA);
783             case khtml::HIRAGANA_IROHA:
784                 return new CSSPrimitiveValueImpl(CSS_VAL_HIRAGANA_IROHA);
785             case khtml::KATAKANA_IROHA:
786                 return new CSSPrimitiveValueImpl(CSS_VAL_KATAKANA_IROHA);
787         }
788         ASSERT_NOT_REACHED();
789         return 0;
790     case CSS_PROP_MARGIN_TOP:
791         return valueForLength(style->marginTop());
792     case CSS_PROP_MARGIN_RIGHT:
793         return valueForLength(style->marginRight());
794     case CSS_PROP_MARGIN_BOTTOM:
795         return valueForLength(style->marginBottom());
796     case CSS_PROP_MARGIN_LEFT:
797         return valueForLength(style->marginLeft());
798     case CSS_PROP__KHTML_MARQUEE:
799         // FIXME: unimplemented
800         break;
801     case CSS_PROP__KHTML_MARQUEE_DIRECTION:
802         switch (style->marqueeDirection()) {
803             case khtml::MFORWARD:
804                 return new CSSPrimitiveValueImpl(CSS_VAL_FORWARDS);
805             case khtml::MBACKWARD:
806                 return new CSSPrimitiveValueImpl(CSS_VAL_BACKWARDS);
807             case khtml::MAUTO:
808                 return new CSSPrimitiveValueImpl(CSS_VAL_AUTO);
809             case khtml::MUP:
810                 return new CSSPrimitiveValueImpl(CSS_VAL_UP);
811             case khtml::MDOWN:
812                 return new CSSPrimitiveValueImpl(CSS_VAL_DOWN);
813             case khtml::MLEFT:
814                 return new CSSPrimitiveValueImpl(CSS_VAL_LEFT);
815             case khtml::MRIGHT:
816                 return new CSSPrimitiveValueImpl(CSS_VAL_RIGHT);
817         }
818         ASSERT_NOT_REACHED();
819         return 0;
820     case CSS_PROP__KHTML_MARQUEE_INCREMENT:
821         return valueForLength(style->marqueeIncrement());
822     case CSS_PROP__KHTML_MARQUEE_REPETITION:
823         if (style->marqueeLoopCount() < 0)
824             return new CSSPrimitiveValueImpl(CSS_VAL_INFINITE);
825         return new CSSPrimitiveValueImpl(style->marqueeLoopCount(), CSSPrimitiveValue::CSS_NUMBER);
826     case CSS_PROP__KHTML_MARQUEE_SPEED:
827         // FIXME: unimplemented
828         break;
829     case CSS_PROP__KHTML_MARQUEE_STYLE:
830         switch (style->marqueeBehavior()) {
831             case khtml::MNONE:
832                 return new CSSPrimitiveValueImpl(CSS_VAL_NONE);
833             case khtml::MSCROLL:
834                 return new CSSPrimitiveValueImpl(CSS_VAL_SCROLL);
835             case khtml::MSLIDE:
836                 return new CSSPrimitiveValueImpl(CSS_VAL_SLIDE);
837             case khtml::MALTERNATE:
838                 return new CSSPrimitiveValueImpl(CSS_VAL_ALTERNATE);
839             case khtml::MUNFURL:
840                 return new CSSPrimitiveValueImpl(CSS_VAL_UNFURL);
841         }
842         ASSERT_NOT_REACHED();
843         return 0;
844     case CSS_PROP__KHTML_USER_MODIFY:
845         switch (style->userModify()) {
846             case khtml::READ_ONLY:
847                 return new CSSPrimitiveValueImpl(CSS_VAL_READ_ONLY);
848             case khtml::READ_WRITE:
849                 return new CSSPrimitiveValueImpl(CSS_VAL_READ_WRITE);
850         }
851         ASSERT_NOT_REACHED();
852         return 0;
853     case CSS_PROP_MAX_HEIGHT:
854         return valueForLength(style->maxHeight());
855     case CSS_PROP_MAX_WIDTH:
856         return valueForLength(style->maxWidth());
857     case CSS_PROP_MIN_HEIGHT:
858         return valueForLength(style->minHeight());
859     case CSS_PROP_MIN_WIDTH:
860         return valueForLength(style->minWidth());
861     case CSS_PROP_OPACITY:
862         return new CSSPrimitiveValueImpl(style->opacity(), CSSPrimitiveValue::CSS_NUMBER);
863     case CSS_PROP_ORPHANS:
864         return new CSSPrimitiveValueImpl(style->orphans(), CSSPrimitiveValue::CSS_NUMBER);
865     case CSS_PROP_OUTLINE_COLOR:
866         // FIXME: unimplemented
867         break;
868     case CSS_PROP_OUTLINE_OFFSET:
869         // FIXME: unimplemented
870         break;
871     case CSS_PROP_OUTLINE_STYLE:
872         if (style->outlineStyleIsAuto())
873             return new CSSPrimitiveValueImpl(CSS_VAL_AUTO);
874         return valueForBorderStyle(style->outlineStyle());
875     case CSS_PROP_OUTLINE_WIDTH:
876         // FIXME: unimplemented
877         break;
878     case CSS_PROP_OVERFLOW:
879         switch (style->overflow()) {
880             case khtml::OVISIBLE:
881                 return new CSSPrimitiveValueImpl(CSS_VAL_VISIBLE);
882             case khtml::OHIDDEN:
883                 return new CSSPrimitiveValueImpl(CSS_VAL_HIDDEN);
884             case khtml::OSCROLL:
885                 return new CSSPrimitiveValueImpl(CSS_VAL_SCROLL);
886             case khtml::OAUTO:
887                 return new CSSPrimitiveValueImpl(CSS_VAL_AUTO);
888             case khtml::OMARQUEE:
889                 return new CSSPrimitiveValueImpl(CSS_VAL_MARQUEE);
890             case khtml::OOVERLAY:
891                 return new CSSPrimitiveValueImpl(CSS_VAL_OVERLAY);
892         }
893         ASSERT_NOT_REACHED();
894         return 0;
895     case CSS_PROP_PADDING_TOP:
896         return valueForLength(style->paddingTop());
897     case CSS_PROP_PADDING_RIGHT:
898         return valueForLength(style->paddingRight());
899     case CSS_PROP_PADDING_BOTTOM:
900         return valueForLength(style->paddingBottom());
901     case CSS_PROP_PADDING_LEFT:
902         return valueForLength(style->paddingLeft());
903     case CSS_PROP_PAGE:
904         // FIXME: unimplemented
905         break;
906     case CSS_PROP_PAGE_BREAK_AFTER:
907         switch (style->pageBreakAfter()) {
908             case khtml::PBAUTO:
909                 return new CSSPrimitiveValueImpl(CSS_VAL_AUTO);
910             case khtml::PBALWAYS:
911                 return new CSSPrimitiveValueImpl(CSS_VAL_ALWAYS);
912             case khtml::PBAVOID:
913                 return new CSSPrimitiveValueImpl(CSS_VAL_AVOID);
914         }
915         ASSERT_NOT_REACHED();
916         return 0;
917     case CSS_PROP_PAGE_BREAK_BEFORE:
918         switch (style->pageBreakBefore()) {
919             case khtml::PBAUTO:
920                 return new CSSPrimitiveValueImpl(CSS_VAL_AUTO);
921             case khtml::PBALWAYS:
922                 return new CSSPrimitiveValueImpl(CSS_VAL_ALWAYS);
923             case khtml::PBAVOID:
924                 return new CSSPrimitiveValueImpl(CSS_VAL_AVOID);
925         }
926         ASSERT_NOT_REACHED();
927         return 0;
928     case CSS_PROP_PAGE_BREAK_INSIDE:
929         switch (style->pageBreakInside()) {
930             case khtml::PBAUTO:
931                 return new CSSPrimitiveValueImpl(CSS_VAL_AUTO);
932             case khtml::PBAVOID:
933                 return new CSSPrimitiveValueImpl(CSS_VAL_AVOID);
934             case khtml::PBALWAYS:
935                 break; // not allowed
936         }
937         ASSERT_NOT_REACHED();
938         return 0;
939     case CSS_PROP_POSITION:
940         switch (style->position()) {
941             case khtml::STATIC:
942                 return new CSSPrimitiveValueImpl(CSS_VAL_STATIC);
943             case khtml::RELATIVE:
944                 return new CSSPrimitiveValueImpl(CSS_VAL_RELATIVE);
945             case khtml::ABSOLUTE:
946                 return new CSSPrimitiveValueImpl(CSS_VAL_ABSOLUTE);
947             case khtml::FIXED:
948                 return new CSSPrimitiveValueImpl(CSS_VAL_FIXED);
949         }
950         ASSERT_NOT_REACHED();
951         return 0;
952     case CSS_PROP_QUOTES:
953         // FIXME: unimplemented
954         break;
955     case CSS_PROP_RIGHT:
956         return getPositionOffsetValue(renderer, CSS_PROP_RIGHT);
957     case CSS_PROP_SIZE:
958         // FIXME: unimplemented
959         break;
960     case CSS_PROP_TABLE_LAYOUT:
961         switch (style->tableLayout()) {
962             case khtml::TAUTO:
963                 return new CSSPrimitiveValueImpl(CSS_VAL_AUTO);
964             case khtml::TFIXED:
965                 return new CSSPrimitiveValueImpl(CSS_VAL_FIXED);
966         }
967         ASSERT_NOT_REACHED();
968         return 0;
969     case CSS_PROP_TEXT_ALIGN:
970         return valueForTextAlign(style->textAlign());
971     case CSS_PROP_TEXT_DECORATION:
972     {
973         QString string;
974         if (style->textDecoration() & khtml::UNDERLINE)
975             string += "underline";
976         if (style->textDecoration() & khtml::OVERLINE) {
977             if (string.length() > 0)
978                 string += " ";
979             string += "overline";
980         }
981         if (style->textDecoration() & khtml::LINE_THROUGH) {
982             if (string.length() > 0)
983                 string += " ";
984             string += "line-through";
985         }
986         if (style->textDecoration() & khtml::BLINK) {
987             if (string.length() > 0)
988                 string += " ";
989             string += "blink";
990         }
991         if (string.length() == 0)
992             return new CSSPrimitiveValueImpl(CSS_VAL_NONE);
993         return new CSSPrimitiveValueImpl(string, CSSPrimitiveValue::CSS_STRING);
994     }
995     case CSS_PROP__KHTML_TEXT_DECORATIONS_IN_EFFECT:
996     {
997         QString string;
998         if (style->textDecorationsInEffect() & khtml::UNDERLINE)
999             string += "underline";
1000         if (style->textDecorationsInEffect() & khtml::OVERLINE) {
1001             if (string.length() > 0)
1002                 string += " ";
1003             string += "overline";
1004         }
1005         if (style->textDecorationsInEffect() & khtml::LINE_THROUGH) {
1006             if (string.length() > 0)
1007                 string += " ";
1008             string += "line-through";
1009         }
1010         if (style->textDecorationsInEffect() & khtml::BLINK) {
1011             if (string.length() > 0)
1012                 string += " ";
1013             string += "blink";
1014         }
1015         if (string.length() == 0)
1016             return new CSSPrimitiveValueImpl(CSS_VAL_NONE);
1017         return new CSSPrimitiveValueImpl(string, CSSPrimitiveValue::CSS_STRING);
1018     }
1019     case CSS_PROP_TEXT_INDENT:
1020         return valueForLength(style->textIndent());
1021     case CSS_PROP_TEXT_SHADOW:
1022         return valueForShadow(style->textShadow());
1023     case CSS_PROP__APPLE_TEXT_SIZE_ADJUST:
1024         if (style->textSizeAdjust()) 
1025             return new CSSPrimitiveValueImpl(CSS_VAL_AUTO);
1026         else
1027             return new CSSPrimitiveValueImpl(CSS_VAL_NONE);
1028     case CSS_PROP_TEXT_TRANSFORM:
1029         switch (style->textTransform()) {
1030             case khtml::CAPITALIZE:
1031                 return new CSSPrimitiveValueImpl(CSS_VAL_CAPITALIZE);
1032             case khtml::UPPERCASE:
1033                 return new CSSPrimitiveValueImpl(CSS_VAL_UPPERCASE);
1034             case khtml::LOWERCASE:
1035                 return new CSSPrimitiveValueImpl(CSS_VAL_LOWERCASE);
1036             case khtml::TTNONE:
1037                 return new CSSPrimitiveValueImpl(CSS_VAL_NONE);
1038         }
1039         ASSERT_NOT_REACHED();
1040         return 0;
1041     case CSS_PROP_TOP:
1042         return getPositionOffsetValue(renderer, CSS_PROP_TOP);
1043     case CSS_PROP_UNICODE_BIDI:
1044         switch (style->unicodeBidi()) {
1045             case khtml::UBNormal:
1046                 return new CSSPrimitiveValueImpl(CSS_VAL_NORMAL);
1047             case khtml::Embed:
1048                 return new CSSPrimitiveValueImpl(CSS_VAL_EMBED);
1049             case khtml::Override:
1050                 return new CSSPrimitiveValueImpl(CSS_VAL_BIDI_OVERRIDE);
1051         }
1052         ASSERT_NOT_REACHED();
1053         return 0;
1054     case CSS_PROP_VERTICAL_ALIGN:
1055         switch (style->verticalAlign()) {
1056             case khtml::BASELINE:
1057                 return new CSSPrimitiveValueImpl(CSS_VAL_BASELINE);
1058             case khtml::MIDDLE:
1059                 return new CSSPrimitiveValueImpl(CSS_VAL_MIDDLE);
1060             case khtml::SUB:
1061                 return new CSSPrimitiveValueImpl(CSS_VAL_SUB);
1062             case khtml::SUPER:
1063                 return new CSSPrimitiveValueImpl(CSS_VAL_SUPER);
1064             case khtml::TEXT_TOP:
1065                 return new CSSPrimitiveValueImpl(CSS_VAL_TEXT_TOP);
1066             case khtml::TEXT_BOTTOM:
1067                 return new CSSPrimitiveValueImpl(CSS_VAL_TEXT_BOTTOM);
1068             case khtml::TOP:
1069                 return new CSSPrimitiveValueImpl(CSS_VAL_TOP);
1070             case khtml::BOTTOM:
1071                 return new CSSPrimitiveValueImpl(CSS_VAL_BOTTOM);
1072             case khtml::BASELINE_MIDDLE:
1073                 return new CSSPrimitiveValueImpl(CSS_VAL__KHTML_BASELINE_MIDDLE);
1074             case khtml::LENGTH:
1075                 return valueForLength(style->verticalAlignLength());
1076         }
1077         ASSERT_NOT_REACHED();
1078         return 0;
1079     case CSS_PROP_VISIBILITY:
1080         switch (style->visibility()) {
1081             case khtml::VISIBLE:
1082                 return new CSSPrimitiveValueImpl(CSS_VAL_VISIBLE);
1083             case khtml::HIDDEN:
1084                 return new CSSPrimitiveValueImpl(CSS_VAL_HIDDEN);
1085             case khtml::COLLAPSE:
1086                 return new CSSPrimitiveValueImpl(CSS_VAL_COLLAPSE);
1087         }
1088         ASSERT_NOT_REACHED();
1089         return 0;
1090     case CSS_PROP_WHITE_SPACE:
1091         switch (style->whiteSpace()) {
1092             case khtml::NORMAL:
1093                 return new CSSPrimitiveValueImpl(CSS_VAL_NORMAL);
1094             case khtml::PRE:
1095                 return new CSSPrimitiveValueImpl(CSS_VAL_PRE);
1096             case khtml::NOWRAP:
1097                 return new CSSPrimitiveValueImpl(CSS_VAL_NOWRAP);
1098             case khtml::KHTML_NOWRAP:
1099                 return new CSSPrimitiveValueImpl(CSS_VAL__KHTML_NOWRAP);
1100         }
1101         ASSERT_NOT_REACHED();
1102         return 0;
1103     case CSS_PROP_WIDOWS:
1104         return new CSSPrimitiveValueImpl(style->widows(), CSSPrimitiveValue::CSS_NUMBER);
1105     case CSS_PROP_WIDTH:
1106         return new CSSPrimitiveValueImpl(renderer->contentWidth(), CSSPrimitiveValue::CSS_PX);
1107     case CSS_PROP_WORD_SPACING:
1108         return new CSSPrimitiveValueImpl(style->wordSpacing(), CSSPrimitiveValue::CSS_PX);
1109     case CSS_PROP_WORD_WRAP:
1110         switch (style->wordWrap()) {
1111             case khtml::WBNORMAL:
1112                 return new CSSPrimitiveValueImpl(CSS_VAL_NORMAL);
1113             case khtml::BREAK_WORD:
1114                 return new CSSPrimitiveValueImpl(CSS_VAL_BREAK_WORD);
1115         }
1116         ASSERT_NOT_REACHED();
1117         return 0;
1118     case CSS_PROP__KHTML_LINE_BREAK:
1119         switch (style->khtmlLineBreak()) {
1120             case khtml::LBNORMAL:
1121                 return new CSSPrimitiveValueImpl(CSS_VAL_NORMAL);
1122             case khtml::AFTER_WHITE_SPACE:
1123                 return new CSSPrimitiveValueImpl(CSS_VAL_AFTER_WHITE_SPACE);
1124         }
1125         ASSERT_NOT_REACHED();
1126         return 0;
1127     case CSS_PROP__KHTML_NBSP_MODE:
1128         switch (style->nbspMode()) {
1129             case khtml::NBNORMAL:
1130                 return new CSSPrimitiveValueImpl(CSS_VAL_NORMAL);
1131             case khtml::SPACE:
1132                 return new CSSPrimitiveValueImpl(CSS_VAL_SPACE);
1133         }
1134         ASSERT_NOT_REACHED();
1135         return 0;
1136     case CSS_PROP__KHTML_MATCH_NEAREST_MAIL_BLOCKQUOTE_COLOR:
1137         switch (style->matchNearestMailBlockquoteColor()) {
1138             case khtml::BCNORMAL:
1139                 return new CSSPrimitiveValueImpl(CSS_VAL_NORMAL);
1140             case khtml::MATCH:
1141                 return new CSSPrimitiveValueImpl(CSS_VAL_MATCH);
1142         }
1143         ASSERT_NOT_REACHED();
1144         return 0;
1145     case CSS_PROP_Z_INDEX:
1146         if (style->hasAutoZIndex())
1147             return new CSSPrimitiveValueImpl(CSS_VAL_NORMAL);
1148         return new CSSPrimitiveValueImpl(style->zIndex(), CSSPrimitiveValue::CSS_NUMBER);
1149     case CSS_PROP_BACKGROUND:
1150         // FIXME: unimplemented
1151         break;
1152     case CSS_PROP_BORDER:
1153         // FIXME: unimplemented
1154         break;
1155     case CSS_PROP_BORDER_COLOR:
1156         // FIXME: unimplemented
1157         break;
1158     case CSS_PROP_BORDER_STYLE:
1159         // FIXME: unimplemented
1160         break;
1161     case CSS_PROP_BORDER_TOP:
1162         // FIXME: unimplemented
1163         break;
1164     case CSS_PROP_BORDER_RIGHT:
1165         // FIXME: unimplemented
1166         break;
1167     case CSS_PROP_BORDER_BOTTOM:
1168         // FIXME: unimplemented
1169         break;
1170     case CSS_PROP_BORDER_LEFT:
1171         // FIXME: unimplemented
1172         break;
1173     case CSS_PROP_BORDER_WIDTH:
1174         // FIXME: unimplemented
1175         break;
1176     case CSS_PROP_FONT:
1177         // FIXME: unimplemented
1178         break;
1179     case CSS_PROP_LIST_STYLE:
1180         // FIXME: unimplemented
1181         break;
1182     case CSS_PROP_MARGIN:
1183         // FIXME: unimplemented
1184         break;
1185     case CSS_PROP_OUTLINE:
1186         // FIXME: unimplemented
1187         break;
1188     case CSS_PROP_PADDING:
1189         // FIXME: unimplemented
1190         break;
1191 #if !APPLE_CHANGES
1192     case CSS_PROP_SCROLLBAR_FACE_COLOR:
1193         // FIXME: unimplemented
1194         break;
1195     case CSS_PROP_SCROLLBAR_SHADOW_COLOR:
1196         // FIXME: unimplemented
1197         break;
1198     case CSS_PROP_SCROLLBAR_HIGHLIGHT_COLOR:
1199         // FIXME: unimplemented
1200         break;
1201     case CSS_PROP_SCROLLBAR_3DLIGHT_COLOR:
1202         // FIXME: unimplemented
1203         break;
1204     case CSS_PROP_SCROLLBAR_DARKSHADOW_COLOR:
1205         // FIXME: unimplemented
1206         break;
1207     case CSS_PROP_SCROLLBAR_TRACK_COLOR:
1208         // FIXME: unimplemented
1209         break;
1210     case CSS_PROP_SCROLLBAR_ARROW_COLOR:
1211         // FIXME: unimplemented
1212         break;
1213 #endif
1214 #if APPLE_CHANGES
1215         case CSS_PROP__APPLE_DASHBOARD_REGION: {
1216             QValueList<StyleDashboardRegion> regions = style->dashboardRegions();
1217             uint i, count = regions.count();
1218             if (count == 1 && regions[0].type == StyleDashboardRegion::None)
1219                 return new CSSPrimitiveValueImpl (CSS_VAL_NONE);
1220                 
1221             DashboardRegionImpl *firstRegion = new DashboardRegionImpl(), *region;
1222             region = firstRegion;
1223             for (i = 0; i < count; i++) {
1224                 StyleDashboardRegion styleRegion = regions[i];
1225                 region->m_label = styleRegion.label;
1226                 LengthBox offset = styleRegion.offset;
1227                 region->setTop (new CSSPrimitiveValueImpl(offset.top.value, CSSPrimitiveValue::CSS_PX));
1228                 region->setRight (new CSSPrimitiveValueImpl(offset.right.value, CSSPrimitiveValue::CSS_PX));
1229                 region->setBottom (new CSSPrimitiveValueImpl(offset.bottom.value, CSSPrimitiveValue::CSS_PX));
1230                 region->setLeft (new CSSPrimitiveValueImpl(offset.left.value, CSSPrimitiveValue::CSS_PX));
1231                 region->m_isRectangle = (styleRegion.type == StyleDashboardRegion::Rectangle); 
1232                 region->m_isCircle = (styleRegion.type == StyleDashboardRegion::Circle);
1233                 if (i != count-1) {
1234                     DashboardRegionImpl *newRegion = new DashboardRegionImpl();
1235                     region->setNext (newRegion);
1236                     region = newRegion;
1237                 }
1238             }
1239             return new CSSPrimitiveValueImpl(firstRegion);
1240         }
1241 #endif
1242     }
1243
1244     ERROR("unimplemented propertyID: %d", propertyID);
1245     return 0;
1246 }
1247
1248 DOMString CSSComputedStyleDeclarationImpl::getPropertyValue(int propertyID) const
1249 {
1250     CSSValueImpl* value = getPropertyCSSValue(propertyID);
1251     if (value) {
1252         value->ref();
1253         DOMString result = value->cssText();
1254         value->deref();
1255         return result;
1256     }
1257     return "";
1258 }
1259
1260 bool CSSComputedStyleDeclarationImpl::getPropertyPriority(int) const
1261 {
1262     // All computed styles have a priority of false (not "important").
1263     return false;
1264 }
1265
1266 DOMString CSSComputedStyleDeclarationImpl::removeProperty(int, int &exceptionCode)
1267 {
1268     exceptionCode = DOMException::NO_MODIFICATION_ALLOWED_ERR;
1269     return DOMString();
1270 }
1271
1272 void CSSComputedStyleDeclarationImpl::setProperty(int, const DOMString &, bool, int &exceptionCode)
1273 {
1274     exceptionCode = DOMException::NO_MODIFICATION_ALLOWED_ERR;
1275 }
1276
1277 unsigned long CSSComputedStyleDeclarationImpl::length() const
1278 {
1279     return numComputedProperties;
1280 }
1281
1282 DOMString CSSComputedStyleDeclarationImpl::item(unsigned long i) const
1283 {
1284     if (i >= numComputedProperties)
1285         return DOMString();
1286     return getPropertyValue(computedProperties[i]);
1287 }
1288
1289 CSSMutableStyleDeclarationImpl *CSSComputedStyleDeclarationImpl::copyInheritableProperties() const
1290 {
1291     return copyPropertiesInSet(inheritableProperties, numInheritableProperties);
1292 }
1293
1294 CSSMutableStyleDeclarationImpl *CSSComputedStyleDeclarationImpl::copy() const
1295 {
1296     return copyPropertiesInSet(computedProperties, numComputedProperties);
1297 }
1298
1299 CSSMutableStyleDeclarationImpl *CSSComputedStyleDeclarationImpl::makeMutable()
1300 {
1301     return copy();
1302 }
1303
1304 } // namespace DOM