Reviewed by John
[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 #include "css_computedstyle.h"
23
24 #include "cssproperties.h"
25 #include "cssvalues.h"
26 #include "dom_atomicstring.h"
27 #include "dom_string.h"
28 #include "font.h"
29 #include "khtmllayout.h"
30 #include "loader.h"
31 #include "rendering/render_style.h"
32 #include "rendering/render_object.h"
33
34 #if APPLE_CHANGES
35 #import "KWQAssertions.h"
36 #import "KWQFontFamily.h"
37 #import "KWQLogging.h"
38 #endif
39
40 using khtml::EBorderStyle;
41 using khtml::ETextAlign;
42 using khtml::Font;
43 using khtml::FontDef;
44 using khtml::Length;
45 using khtml::LengthBox;
46 using khtml::RenderStyle;
47 using khtml::ShadowData;
48 using khtml::StyleDashboardRegion;
49
50 namespace DOM {
51
52 // This is the list of properties we want to copy in the copyInheritableProperties() function.
53 // It is the intersection of the list of inherited CSS properties and the
54 // properties for which we have a computed implementation in this file.
55 static const int InheritableProperties[] = {
56     CSS_PROP_BORDER_COLLAPSE,
57     CSS_PROP_BORDER_SPACING,
58     CSS_PROP_COLOR,
59     CSS_PROP_FONT_FAMILY,
60     CSS_PROP_FONT_SIZE,
61     CSS_PROP_FONT_STYLE,
62     CSS_PROP_FONT_VARIANT,
63     CSS_PROP_FONT_WEIGHT,
64     CSS_PROP_LETTER_SPACING,
65     CSS_PROP_LINE_HEIGHT,
66     CSS_PROP_TEXT_ALIGN,
67     CSS_PROP_TEXT_DECORATION, // this is not inheritable, yet we do want to consider it for typing style (name change needed? redesign?)
68     CSS_PROP_TEXT_INDENT,
69     CSS_PROP_TEXT_TRANSFORM,
70     CSS_PROP_WHITE_SPACE,
71     CSS_PROP_WORD_SPACING,
72 };
73
74 static CSSValueImpl* valueForLength(const Length &length)
75 {
76     switch (length.type) {
77         case khtml::Percent:
78             return new CSSPrimitiveValueImpl(length.length(), CSSPrimitiveValue::CSS_PERCENTAGE);
79         case khtml::Fixed:
80             return new CSSPrimitiveValueImpl(length.length(), CSSPrimitiveValue::CSS_PX);
81         default: // FIXME: Intrinsic and MinIntrinsic should probably return keywords.
82             return new CSSPrimitiveValueImpl(CSS_VAL_AUTO);
83     }
84 }
85
86 static CSSValueImpl *valueForBorderStyle(EBorderStyle style)
87 {
88     switch (style) {
89         case khtml::BNONE:
90             return new CSSPrimitiveValueImpl(CSS_VAL_NONE);
91         case khtml::BHIDDEN:
92             return new CSSPrimitiveValueImpl(CSS_VAL_HIDDEN);
93         case khtml::INSET:
94             return new CSSPrimitiveValueImpl(CSS_VAL_INSET);
95         case khtml::GROOVE:
96             return new CSSPrimitiveValueImpl(CSS_VAL_GROOVE);
97         case khtml::RIDGE:
98             return new CSSPrimitiveValueImpl(CSS_VAL_RIDGE);
99         case khtml::OUTSET:
100             return new CSSPrimitiveValueImpl(CSS_VAL_OUTSET);
101         case khtml::DOTTED:
102             return new CSSPrimitiveValueImpl(CSS_VAL_DOTTED);
103         case khtml::DASHED:
104             return new CSSPrimitiveValueImpl(CSS_VAL_DASHED);
105         case khtml::SOLID:
106             return new CSSPrimitiveValueImpl(CSS_VAL_SOLID);
107         case khtml::DOUBLE:
108             return new CSSPrimitiveValueImpl(CSS_VAL_DOUBLE);
109     }
110     ASSERT_NOT_REACHED();
111     return 0;
112 }
113
114 static CSSValueImpl *valueForTextAlign(ETextAlign align)
115 {
116     switch (align) {
117         case khtml::TAAUTO:
118             return new CSSPrimitiveValueImpl(CSS_VAL_AUTO);
119         case khtml::LEFT:
120             return new CSSPrimitiveValueImpl(CSS_VAL_LEFT);
121         case khtml::RIGHT:
122             return new CSSPrimitiveValueImpl(CSS_VAL_RIGHT);
123         case khtml::CENTER:
124             return new CSSPrimitiveValueImpl(CSS_VAL_CENTER);
125         case khtml::JUSTIFY:
126             return new CSSPrimitiveValueImpl(CSS_VAL_JUSTIFY);
127         case khtml::KHTML_LEFT:
128             return new CSSPrimitiveValueImpl(CSS_VAL__KHTML_LEFT);
129         case khtml::KHTML_RIGHT:
130             return new CSSPrimitiveValueImpl(CSS_VAL__KHTML_RIGHT);
131         case khtml::KHTML_CENTER:
132             return new CSSPrimitiveValueImpl(CSS_VAL__KHTML_CENTER);
133     }
134     ASSERT_NOT_REACHED();
135     return 0;
136 }
137
138 static CSSValueImpl* valueForShadow(const ShadowData *shadow)
139 {
140     if (!shadow)
141         return new CSSPrimitiveValueImpl(CSS_VAL_NONE);
142     CSSValueListImpl *list = new CSSValueListImpl;
143     for (const ShadowData *s = shadow; s; s = s->next) {
144         CSSPrimitiveValueImpl *x = new CSSPrimitiveValueImpl(s->x, CSSPrimitiveValue::CSS_PX);
145         CSSPrimitiveValueImpl *y = new CSSPrimitiveValueImpl(s->y, CSSPrimitiveValue::CSS_PX);
146         CSSPrimitiveValueImpl *blur = new CSSPrimitiveValueImpl(s->blur, CSSPrimitiveValue::CSS_PX);
147         CSSPrimitiveValueImpl *color = new CSSPrimitiveValueImpl(s->color.rgb());
148         list->append(new ShadowValueImpl(x, y, blur, color));
149     }
150     return list;
151 }
152
153 CSSValueImpl* CSSComputedStyleDeclarationImpl::getPositionOffsetValue(int propertyID) const
154 {
155     Length l;
156     switch (propertyID) {
157     case CSS_PROP_LEFT:
158         l = m_renderer->style()->left();
159         break;
160     case CSS_PROP_RIGHT:
161         l = m_renderer->style()->right();
162         break;
163     case CSS_PROP_TOP:
164         l = m_renderer->style()->top();
165         break;
166     case CSS_PROP_BOTTOM:
167         l = m_renderer->style()->bottom();
168         break;
169     default:
170         return 0;
171     }
172
173     if (m_renderer->isPositioned())
174         return valueForLength(l);
175     
176     if (m_renderer->isRelPositioned())
177         // FIXME: It's not enough to simply return "auto" values for one offset if the other side is defined.
178         // In other words if left is auto and right is not auto, then left's computed value is negative right.
179         // So we should get the opposite length unit and see if it is auto.
180         return valueForLength(l);
181     
182     return new CSSPrimitiveValueImpl(CSS_VAL_AUTO);
183 }
184
185 CSSComputedStyleDeclarationImpl::CSSComputedStyleDeclarationImpl(NodeImpl *n)
186     : CSSStyleDeclarationImpl(0)
187 {
188     setNode(n);
189     m_renderer = node()->renderer();
190 }
191
192 CSSComputedStyleDeclarationImpl::~CSSComputedStyleDeclarationImpl()
193 {
194 }
195
196 DOMString CSSComputedStyleDeclarationImpl::cssText() const
197 {
198     ERROR("unimplemented");
199     return DOMString();
200 }
201
202 void CSSComputedStyleDeclarationImpl::setCssText(const DOMString &)
203 {
204     ERROR("CSSComputedStyleDeclarationImpl is a read-only object");
205 }
206
207 // Display integers in integer format instead of "1.0".
208 static QString numberAsString(double n)
209 {
210     long i = static_cast<long>(n);
211     return i == n ? QString::number(i) : QString::number(n);
212 }
213
214 CSSValueImpl *CSSComputedStyleDeclarationImpl::getPropertyCSSValue(int propertyID) const
215 {
216     return getPropertyCSSValue(propertyID, UpdateLayout);
217 }
218
219 CSSValueImpl *CSSComputedStyleDeclarationImpl::getPropertyCSSValue(int propertyID, bool updateLayout) const
220 {
221     // Make sure our layout is up to date before we allow a query on these attributes.
222     DocumentImpl* docimpl = node()->getDocument();
223     if (docimpl && updateLayout)
224         docimpl->updateLayout();
225
226     if (!m_renderer)
227         return 0;
228     RenderStyle *style = m_renderer->style();
229     if (!style)
230         return 0;
231
232     switch(propertyID)
233     {
234     case CSS_PROP_BACKGROUND_COLOR:
235         return new CSSPrimitiveValueImpl(style->backgroundColor().rgb());
236     case CSS_PROP_BACKGROUND_IMAGE:
237         if (style->backgroundImage())
238             return new CSSPrimitiveValueImpl(style->backgroundImage()->url(),
239                                              CSSPrimitiveValue::CSS_URI);
240         return 0;
241     case CSS_PROP_BACKGROUND_REPEAT:
242         switch (style->backgroundRepeat()) {
243             case khtml::REPEAT:
244                 return new CSSPrimitiveValueImpl(CSS_VAL_REPEAT);
245             case khtml::REPEAT_X:
246                 return new CSSPrimitiveValueImpl(CSS_VAL_REPEAT_X);
247             case khtml::REPEAT_Y:
248                 return new CSSPrimitiveValueImpl(CSS_VAL_REPEAT_Y);
249             case khtml::NO_REPEAT:
250                 return new CSSPrimitiveValueImpl(CSS_VAL_NO_REPEAT);
251         }
252         ASSERT_NOT_REACHED();
253         return 0;
254     case CSS_PROP_BACKGROUND_ATTACHMENT:
255         if (style->backgroundAttachment())
256             return new CSSPrimitiveValueImpl(CSS_VAL_SCROLL);
257         else
258             return new CSSPrimitiveValueImpl(CSS_VAL_FIXED);
259     case CSS_PROP_BACKGROUND_POSITION:
260     {
261         DOMString string;
262         Length length(style->backgroundXPosition());
263         if (length.isPercent())
264             string = numberAsString(length.length()) + "%";
265         else
266             string = numberAsString(length.minWidth(m_renderer->contentWidth()));
267         string += " ";
268         length = style->backgroundYPosition();
269         if (length.isPercent())
270             string += numberAsString(length.length()) + "%";
271         else
272             string += numberAsString(length.minWidth(m_renderer->contentWidth()));
273         return new CSSPrimitiveValueImpl(string, CSSPrimitiveValue::CSS_STRING);
274     }
275     case CSS_PROP_BACKGROUND_POSITION_X:
276         return valueForLength(style->backgroundXPosition());
277     case CSS_PROP_BACKGROUND_POSITION_Y:
278         return valueForLength(style->backgroundYPosition());
279 #ifndef KHTML_NO_XBL
280     case CSS_PROP__KHTML_BINDING:
281         // FIXME: unimplemented
282         break;
283 #endif
284     case CSS_PROP_BORDER_COLLAPSE:
285         if (style->borderCollapse())
286             return new CSSPrimitiveValueImpl(CSS_VAL_COLLAPSE);
287         else
288             return new CSSPrimitiveValueImpl(CSS_VAL_SEPARATE);
289     case CSS_PROP_BORDER_SPACING:
290     {
291         QString string(numberAsString(style->horizontalBorderSpacing()) + 
292             "px " + 
293             numberAsString(style->verticalBorderSpacing()) +
294             "px");
295         return new CSSPrimitiveValueImpl(string, CSSPrimitiveValue::CSS_STRING);
296     }
297     case CSS_PROP__KHTML_BORDER_HORIZONTAL_SPACING:
298         return new CSSPrimitiveValueImpl(style->horizontalBorderSpacing(), CSSPrimitiveValue::CSS_PX);
299     case CSS_PROP__KHTML_BORDER_VERTICAL_SPACING:
300         return new CSSPrimitiveValueImpl(style->verticalBorderSpacing(), CSSPrimitiveValue::CSS_PX);
301     case CSS_PROP_BORDER_TOP_COLOR:
302         return new CSSPrimitiveValueImpl(style->borderLeftColor().rgb());
303     case CSS_PROP_BORDER_RIGHT_COLOR:
304         return new CSSPrimitiveValueImpl(style->borderRightColor().rgb());
305     case CSS_PROP_BORDER_BOTTOM_COLOR:
306         return new CSSPrimitiveValueImpl(style->borderBottomColor().rgb());
307     case CSS_PROP_BORDER_LEFT_COLOR:
308         return new CSSPrimitiveValueImpl(style->borderLeftColor().rgb());
309     case CSS_PROP_BORDER_TOP_STYLE:
310         return valueForBorderStyle(style->borderTopStyle());
311     case CSS_PROP_BORDER_RIGHT_STYLE:
312         return valueForBorderStyle(style->borderRightStyle());
313     case CSS_PROP_BORDER_BOTTOM_STYLE:
314         return valueForBorderStyle(style->borderBottomStyle());
315     case CSS_PROP_BORDER_LEFT_STYLE:
316         return valueForBorderStyle(style->borderLeftStyle());
317     case CSS_PROP_BORDER_TOP_WIDTH:
318         return new CSSPrimitiveValueImpl(style->borderTopWidth(), CSSPrimitiveValue::CSS_PX);
319     case CSS_PROP_BORDER_RIGHT_WIDTH:
320         return new CSSPrimitiveValueImpl(style->borderRightWidth(), CSSPrimitiveValue::CSS_PX);
321     case CSS_PROP_BORDER_BOTTOM_WIDTH:
322         return new CSSPrimitiveValueImpl(style->borderBottomWidth(), CSSPrimitiveValue::CSS_PX);
323     case CSS_PROP_BORDER_LEFT_WIDTH:
324         return new CSSPrimitiveValueImpl(style->borderLeftWidth(), CSSPrimitiveValue::CSS_PX);
325     case CSS_PROP_BOTTOM:
326         return getPositionOffsetValue(CSS_PROP_BOTTOM);
327     case CSS_PROP__KHTML_BOX_ALIGN:
328         // FIXME: unimplemented
329         break;
330     case CSS_PROP__KHTML_BOX_DIRECTION:
331         // FIXME: unimplemented
332         break;
333     case CSS_PROP__KHTML_BOX_FLEX:
334         // FIXME: unimplemented
335         break;
336     case CSS_PROP__KHTML_BOX_FLEX_GROUP:
337         // FIXME: unimplemented
338         break;
339     case CSS_PROP__KHTML_BOX_LINES:
340         // FIXME: unimplemented
341         break;
342     case CSS_PROP__KHTML_BOX_ORDINAL_GROUP:
343         // FIXME: unimplemented
344         break;
345     case CSS_PROP__KHTML_BOX_ORIENT:
346         // FIXME: unimplemented
347         break;
348     case CSS_PROP__KHTML_BOX_PACK:
349         // FIXME: unimplemented
350         break;
351     case CSS_PROP_CAPTION_SIDE:
352         // FIXME: unimplemented
353         break;
354     case CSS_PROP_CLEAR:
355         // FIXME: unimplemented
356         break;
357     case CSS_PROP_CLIP:
358         // FIXME: unimplemented
359         break;
360     case CSS_PROP_COLOR:
361         return new CSSPrimitiveValueImpl(style->color().rgb());
362     case CSS_PROP_CONTENT:
363         // FIXME: unimplemented
364         break;
365     case CSS_PROP_COUNTER_INCREMENT:
366         // FIXME: unimplemented
367         break;
368     case CSS_PROP_COUNTER_RESET:
369         // FIXME: unimplemented
370         break;
371     case CSS_PROP_CURSOR:
372         // FIXME: unimplemented
373         break;
374     case CSS_PROP_DIRECTION:
375         // FIXME: unimplemented
376         break;
377     case CSS_PROP_DISPLAY:
378         switch (style->display()) {
379             case khtml::INLINE:
380                 return new CSSPrimitiveValueImpl(CSS_VAL_INLINE);
381             case khtml::BLOCK:
382                 return new CSSPrimitiveValueImpl(CSS_VAL_BLOCK);
383             case khtml::LIST_ITEM:
384                 return new CSSPrimitiveValueImpl(CSS_VAL_LIST_ITEM);
385             case khtml::RUN_IN:
386                 return new CSSPrimitiveValueImpl(CSS_VAL_RUN_IN);
387             case khtml::COMPACT:
388                 return new CSSPrimitiveValueImpl(CSS_VAL_COMPACT);
389             case khtml::INLINE_BLOCK:
390                 return new CSSPrimitiveValueImpl(CSS_VAL_INLINE_BLOCK);
391             case khtml::TABLE:
392                 return new CSSPrimitiveValueImpl(CSS_VAL_TABLE);
393             case khtml::INLINE_TABLE:
394                 return new CSSPrimitiveValueImpl(CSS_VAL_INLINE_TABLE);
395             case khtml::TABLE_ROW_GROUP:
396                 return new CSSPrimitiveValueImpl(CSS_VAL_TABLE_ROW_GROUP);
397             case khtml::TABLE_HEADER_GROUP:
398                 return new CSSPrimitiveValueImpl(CSS_VAL_TABLE_HEADER_GROUP);
399             case khtml::TABLE_FOOTER_GROUP:
400                 return new CSSPrimitiveValueImpl(CSS_VAL_TABLE_FOOTER_GROUP);
401             case khtml::TABLE_ROW:
402                 return new CSSPrimitiveValueImpl(CSS_VAL_TABLE_ROW);
403             case khtml::TABLE_COLUMN_GROUP:
404                 return new CSSPrimitiveValueImpl(CSS_VAL_TABLE_COLUMN_GROUP);
405             case khtml::TABLE_COLUMN:
406                 return new CSSPrimitiveValueImpl(CSS_VAL_TABLE_COLUMN);
407             case khtml::TABLE_CELL:
408                 return new CSSPrimitiveValueImpl(CSS_VAL_TABLE_CELL);
409             case khtml::TABLE_CAPTION:
410                 return new CSSPrimitiveValueImpl(CSS_VAL_TABLE_CAPTION);
411             case khtml::BOX:
412                 return new CSSPrimitiveValueImpl(CSS_VAL__KHTML_BOX);
413             case khtml::INLINE_BOX:
414                 return new CSSPrimitiveValueImpl(CSS_VAL__KHTML_INLINE_BOX);
415             case khtml::NONE:
416                 return new CSSPrimitiveValueImpl(CSS_VAL_NONE);
417         }
418         ASSERT_NOT_REACHED();
419         return 0;
420     case CSS_PROP_EMPTY_CELLS:
421         switch (style->emptyCells()) {
422             case khtml::SHOW:
423                 return new CSSPrimitiveValueImpl(CSS_VAL_SHOW);
424             case khtml::HIDE:
425                 return new CSSPrimitiveValueImpl(CSS_VAL_HIDE);
426         }
427         ASSERT_NOT_REACHED();
428         return 0;
429     case CSS_PROP_FLOAT:
430         switch (style->floating()) {
431             case khtml::FNONE:
432                 return new CSSPrimitiveValueImpl(CSS_VAL_NONE);
433             case khtml::FLEFT:
434                 return new CSSPrimitiveValueImpl(CSS_VAL_LEFT);
435             case khtml::FRIGHT:
436                 return new CSSPrimitiveValueImpl(CSS_VAL_RIGHT);
437         }
438         ASSERT_NOT_REACHED();
439         return 0;
440     case CSS_PROP_FONT_FAMILY:
441     {
442         FontDef def = style->htmlFont().getFontDef();
443         return new CSSPrimitiveValueImpl(def.firstFamily().family().domString(), CSSPrimitiveValue::CSS_STRING);
444     }
445     case CSS_PROP_FONT_SIZE:
446     {
447         FontDef def = style->htmlFont().getFontDef();
448         return new CSSPrimitiveValueImpl(def.specifiedSize, CSSPrimitiveValue::CSS_PX);
449     }
450     case CSS_PROP_FONT_SIZE_ADJUST:
451         // FIXME: unimplemented
452         break;
453     case CSS_PROP_FONT_STRETCH:
454         // FIXME: unimplemented
455         break;
456     case CSS_PROP_FONT_STYLE:
457     {
458         // FIXME: handle oblique?
459         FontDef def = style->htmlFont().getFontDef();
460         if (def.italic)
461             return new CSSPrimitiveValueImpl(CSS_VAL_ITALIC);
462         else
463             return new CSSPrimitiveValueImpl(CSS_VAL_NORMAL);
464     }
465     case CSS_PROP_FONT_VARIANT:
466     {
467         FontDef def = style->htmlFont().getFontDef();
468         if (def.smallCaps)
469             return new CSSPrimitiveValueImpl(CSS_VAL_SMALL_CAPS);
470         else
471             return new CSSPrimitiveValueImpl(CSS_VAL_NORMAL);
472     }
473     case CSS_PROP_FONT_WEIGHT:
474     {
475         // FIXME: this does not reflect the full range of weights
476         // that can be expressed with CSS
477         FontDef def = style->htmlFont().getFontDef();
478         if (def.weight == QFont::Bold)
479             return new CSSPrimitiveValueImpl(CSS_VAL_BOLD);
480         else
481             return new CSSPrimitiveValueImpl(CSS_VAL_NORMAL);
482     }
483     case CSS_PROP_HEIGHT:
484         return new CSSPrimitiveValueImpl(m_renderer->contentHeight(), CSSPrimitiveValue::CSS_PX);
485     case CSS_PROP_LEFT:
486         return getPositionOffsetValue(CSS_PROP_LEFT);
487     case CSS_PROP_LETTER_SPACING:
488         if (style->letterSpacing() == 0)
489             return new CSSPrimitiveValueImpl(CSS_VAL_NORMAL);
490         return new CSSPrimitiveValueImpl(style->letterSpacing(), CSSPrimitiveValue::CSS_PX);
491     case CSS_PROP_LINE_HEIGHT: {
492         Length length(style->lineHeight());
493         if (length.isPercent()) {
494             float computedSize = style->htmlFont().getFontDef().computedSize;
495             return new CSSPrimitiveValueImpl((int)(length.length() * computedSize) / 100, CSSPrimitiveValue::CSS_PX);
496         }
497         else {
498             return new CSSPrimitiveValueImpl(length.length(), CSSPrimitiveValue::CSS_PX);
499         }
500     }
501     case CSS_PROP_LIST_STYLE_IMAGE:
502         // FIXME: unimplemented
503         break;
504     case CSS_PROP_LIST_STYLE_POSITION:
505         // FIXME: unimplemented
506         break;
507     case CSS_PROP_LIST_STYLE_TYPE:
508         // FIXME: unimplemented
509         break;
510     case CSS_PROP_MARGIN_TOP:
511         return valueForLength(style->marginTop());
512     case CSS_PROP_MARGIN_RIGHT:
513         return valueForLength(style->marginRight());
514     case CSS_PROP_MARGIN_BOTTOM:
515         return valueForLength(style->marginBottom());
516     case CSS_PROP_MARGIN_LEFT:
517         return valueForLength(style->marginLeft());
518     case CSS_PROP__KHTML_MARQUEE:
519         // FIXME: unimplemented
520         break;
521     case CSS_PROP__KHTML_MARQUEE_DIRECTION:
522         // FIXME: unimplemented
523         break;
524     case CSS_PROP__KHTML_MARQUEE_INCREMENT:
525         return valueForLength(style->marqueeIncrement());
526     case CSS_PROP__KHTML_MARQUEE_REPETITION:
527         // FIXME: unimplemented
528         break;
529     case CSS_PROP__KHTML_MARQUEE_SPEED:
530         // FIXME: unimplemented
531         break;
532     case CSS_PROP__KHTML_MARQUEE_STYLE:
533         // FIXME: unimplemented
534         break;
535     case CSS_PROP__KHTML_USER_MODIFY:
536         // FIXME: unimplemented
537         break;
538     case CSS_PROP_MAX_HEIGHT:
539         return valueForLength(style->maxHeight());
540     case CSS_PROP_MAX_WIDTH:
541         return valueForLength(style->maxWidth());
542     case CSS_PROP_MIN_HEIGHT:
543         return valueForLength(style->minHeight());
544     case CSS_PROP_MIN_WIDTH:
545         return valueForLength(style->minWidth());
546     case CSS_PROP_OPACITY:
547         // FIXME: unimplemented
548         break;
549     case CSS_PROP_ORPHANS:
550         // FIXME: unimplemented
551         break;
552         // FIXME: unimplemented
553         break;
554     case CSS_PROP_OUTLINE_COLOR:
555         // FIXME: unimplemented
556         break;
557     case CSS_PROP_OUTLINE_OFFSET:
558         // FIXME: unimplemented
559         break;
560     case CSS_PROP_OUTLINE_STYLE:
561         // FIXME: unimplemented
562         break;
563     case CSS_PROP_OUTLINE_WIDTH:
564         // FIXME: unimplemented
565         break;
566     case CSS_PROP_OVERFLOW:
567         switch (style->overflow()) {
568             case khtml::OVISIBLE:
569                 return new CSSPrimitiveValueImpl(CSS_VAL_VISIBLE);
570             case khtml::OHIDDEN:
571                 return new CSSPrimitiveValueImpl(CSS_VAL_HIDDEN);
572             case khtml::OSCROLL:
573                 return new CSSPrimitiveValueImpl(CSS_VAL_SCROLL);
574             case khtml::OAUTO:
575                 return new CSSPrimitiveValueImpl(CSS_VAL_AUTO);
576             case khtml::OMARQUEE:
577                 return new CSSPrimitiveValueImpl(CSS_VAL_MARQUEE);
578             case khtml::OOVERLAY:
579                 return new CSSPrimitiveValueImpl(CSS_VAL_OVERLAY);
580         }
581         ASSERT_NOT_REACHED();
582         return 0;
583     case CSS_PROP_PADDING_TOP:
584         return valueForLength(style->paddingTop());
585     case CSS_PROP_PADDING_RIGHT:
586         return valueForLength(style->paddingRight());
587     case CSS_PROP_PADDING_BOTTOM:
588         return valueForLength(style->paddingBottom());
589     case CSS_PROP_PADDING_LEFT:
590         return valueForLength(style->paddingLeft());
591     case CSS_PROP_PAGE:
592         // FIXME: unimplemented
593         break;
594     case CSS_PROP_PAGE_BREAK_AFTER:
595         // FIXME: unimplemented
596         break;
597     case CSS_PROP_PAGE_BREAK_BEFORE:
598         // FIXME: unimplemented
599         break;
600     case CSS_PROP_PAGE_BREAK_INSIDE:
601         // FIXME: unimplemented
602         break;
603     case CSS_PROP_POSITION:
604         // FIXME: unimplemented
605         break;
606     case CSS_PROP_QUOTES:
607         // FIXME: unimplemented
608         break;
609     case CSS_PROP_RIGHT:
610         return getPositionOffsetValue(CSS_PROP_RIGHT);
611     case CSS_PROP_SIZE:
612         // FIXME: unimplemented
613         break;
614     case CSS_PROP_TABLE_LAYOUT:
615         switch (style->tableLayout()) {
616             case khtml::TAUTO:
617                 return new CSSPrimitiveValueImpl(CSS_VAL_AUTO);
618             case khtml::TFIXED:
619                 return new CSSPrimitiveValueImpl(CSS_VAL_FIXED);
620         }
621         ASSERT_NOT_REACHED();
622         return 0;
623     case CSS_PROP_TEXT_ALIGN:
624         return valueForTextAlign(style->textAlign());
625     case CSS_PROP_TEXT_DECORATION:
626     {
627         QString string;
628         if (style->textDecoration() & khtml::UNDERLINE)
629             string += "underline";
630         if (style->textDecoration() & khtml::OVERLINE) {
631             if (string.length() > 0)
632                 string += " ";
633             string += "overline";
634         }
635         if (style->textDecoration() & khtml::LINE_THROUGH) {
636             if (string.length() > 0)
637                 string += " ";
638             string += "line-through";
639         }
640         if (style->textDecoration() & khtml::BLINK) {
641             if (string.length() > 0)
642                 string += " ";
643             string += "blink";
644         }
645         if (string.length() == 0)
646             return new CSSPrimitiveValueImpl(CSS_VAL_NONE);
647         return new CSSPrimitiveValueImpl(string, CSSPrimitiveValue::CSS_STRING);
648     }
649     case CSS_PROP_TEXT_INDENT:
650         return valueForLength(style->textIndent());
651     case CSS_PROP_TEXT_SHADOW:
652         return valueForShadow(style->textShadow());
653     case CSS_PROP_TEXT_TRANSFORM:
654         switch (style->textTransform()) {
655             case khtml::CAPITALIZE:
656                 return new CSSPrimitiveValueImpl(CSS_VAL_CAPITALIZE);
657             case khtml::UPPERCASE:
658                 return new CSSPrimitiveValueImpl(CSS_VAL_UPPERCASE);
659             case khtml::LOWERCASE:
660                 return new CSSPrimitiveValueImpl(CSS_VAL_LOWERCASE);
661             case khtml::TTNONE:
662                 return new CSSPrimitiveValueImpl(CSS_VAL_NONE);
663         }
664         ASSERT_NOT_REACHED();
665         return 0;
666     case CSS_PROP_TOP:
667         return getPositionOffsetValue(CSS_PROP_TOP);
668     case CSS_PROP_UNICODE_BIDI:
669         // FIXME: unimplemented
670         break;
671     case CSS_PROP_VERTICAL_ALIGN:
672         switch (style->verticalAlign()) {
673             case khtml::BASELINE:
674                 return new CSSPrimitiveValueImpl(CSS_VAL_BASELINE);
675             case khtml::MIDDLE:
676                 return new CSSPrimitiveValueImpl(CSS_VAL_MIDDLE);
677             case khtml::SUB:
678                 return new CSSPrimitiveValueImpl(CSS_VAL_SUB);
679             case khtml::SUPER:
680                 return new CSSPrimitiveValueImpl(CSS_VAL_SUPER);
681             case khtml::TEXT_TOP:
682                 return new CSSPrimitiveValueImpl(CSS_VAL_TEXT_TOP);
683             case khtml::TEXT_BOTTOM:
684                 return new CSSPrimitiveValueImpl(CSS_VAL_TEXT_BOTTOM);
685             case khtml::TOP:
686                 return new CSSPrimitiveValueImpl(CSS_VAL_TOP);
687             case khtml::BOTTOM:
688                 return new CSSPrimitiveValueImpl(CSS_VAL_BOTTOM);
689             case khtml::BASELINE_MIDDLE:
690                 return new CSSPrimitiveValueImpl(CSS_VAL__KHTML_BASELINE_MIDDLE);
691             case khtml::LENGTH:
692                 return valueForLength(style->verticalAlignLength());
693         }
694         ASSERT_NOT_REACHED();
695         return 0;
696     case CSS_PROP_VISIBILITY:
697         switch (style->visibility()) {
698             case khtml::VISIBLE:
699                 return new CSSPrimitiveValueImpl(CSS_VAL_VISIBLE);
700             case khtml::HIDDEN:
701                 return new CSSPrimitiveValueImpl(CSS_VAL_HIDDEN);
702             case khtml::COLLAPSE:
703                 return new CSSPrimitiveValueImpl(CSS_VAL_COLLAPSE);
704         }
705         ASSERT_NOT_REACHED();
706         return 0;
707     case CSS_PROP_WHITE_SPACE:
708         switch (style->whiteSpace()) {
709             case khtml::NORMAL:
710                 return new CSSPrimitiveValueImpl(CSS_VAL_NORMAL);
711             case khtml::PRE:
712                 return new CSSPrimitiveValueImpl(CSS_VAL_PRE);
713             case khtml::NOWRAP:
714                 return new CSSPrimitiveValueImpl(CSS_VAL_NOWRAP);
715             case khtml::KHTML_NOWRAP:
716                 return new CSSPrimitiveValueImpl(CSS_VAL__KHTML_NOWRAP);
717         }
718         ASSERT_NOT_REACHED();
719         return 0;
720     case CSS_PROP_WIDOWS:
721         // FIXME: unimplemented
722         break;
723     case CSS_PROP_WIDTH:
724         return new CSSPrimitiveValueImpl(m_renderer->contentWidth(), CSSPrimitiveValue::CSS_PX);
725     case CSS_PROP_WORD_SPACING:
726         return new CSSPrimitiveValueImpl(style->wordSpacing(), CSSPrimitiveValue::CSS_PX);
727     case CSS_PROP_WORD_WRAP:
728         switch (style->wordWrap()) {
729             case khtml::WBNORMAL:
730                 return new CSSPrimitiveValueImpl(CSS_VAL_NORMAL);
731             case khtml::BREAK_WORD:
732                 return new CSSPrimitiveValueImpl(CSS_VAL_BREAK_WORD);
733         }
734         ASSERT_NOT_REACHED();
735         return 0;
736     case CSS_PROP__KHTML_LINE_BREAK:
737         switch (style->khtmlLineBreak()) {
738             case khtml::LBNORMAL:
739                 return new CSSPrimitiveValueImpl(CSS_VAL_NORMAL);
740             case khtml::AFTER_WHITE_SPACE:
741                 return new CSSPrimitiveValueImpl(CSS_VAL_AFTER_WHITE_SPACE);
742         }
743         ASSERT_NOT_REACHED();
744         return 0;
745     case CSS_PROP__KHTML_NBSP_MODE:
746         switch (style->nbspMode()) {
747             case khtml::NBNORMAL:
748                 return new CSSPrimitiveValueImpl(CSS_VAL_NORMAL);
749             case khtml::SPACE:
750                 return new CSSPrimitiveValueImpl(CSS_VAL_SPACE);
751         }
752         ASSERT_NOT_REACHED();
753         return 0;
754     case CSS_PROP_Z_INDEX:
755         // FIXME: unimplemented
756         break;
757     case CSS_PROP_BACKGROUND:
758         // FIXME: unimplemented
759         break;
760     case CSS_PROP_BORDER:
761         // FIXME: unimplemented
762         break;
763     case CSS_PROP_BORDER_COLOR:
764         // FIXME: unimplemented
765         break;
766     case CSS_PROP_BORDER_STYLE:
767         // FIXME: unimplemented
768         break;
769     case CSS_PROP_BORDER_TOP:
770         // FIXME: unimplemented
771         break;
772     case CSS_PROP_BORDER_RIGHT:
773         // FIXME: unimplemented
774         break;
775     case CSS_PROP_BORDER_BOTTOM:
776         // FIXME: unimplemented
777         break;
778     case CSS_PROP_BORDER_LEFT:
779         // FIXME: unimplemented
780         break;
781     case CSS_PROP_BORDER_WIDTH:
782         // FIXME: unimplemented
783         break;
784     case CSS_PROP_FONT:
785         // FIXME: unimplemented
786         break;
787     case CSS_PROP_LIST_STYLE:
788         // FIXME: unimplemented
789         break;
790     case CSS_PROP_MARGIN:
791         // FIXME: unimplemented
792         break;
793     case CSS_PROP_OUTLINE:
794         // FIXME: unimplemented
795         break;
796     case CSS_PROP_PADDING:
797         // FIXME: unimplemented
798         break;
799 #if !APPLE_CHANGES
800     case CSS_PROP_SCROLLBAR_FACE_COLOR:
801         // FIXME: unimplemented
802         break;
803     case CSS_PROP_SCROLLBAR_SHADOW_COLOR:
804         // FIXME: unimplemented
805         break;
806     case CSS_PROP_SCROLLBAR_HIGHLIGHT_COLOR:
807         // FIXME: unimplemented
808         break;
809     case CSS_PROP_SCROLLBAR_3DLIGHT_COLOR:
810         // FIXME: unimplemented
811         break;
812     case CSS_PROP_SCROLLBAR_DARKSHADOW_COLOR:
813         // FIXME: unimplemented
814         break;
815     case CSS_PROP_SCROLLBAR_TRACK_COLOR:
816         // FIXME: unimplemented
817         break;
818     case CSS_PROP_SCROLLBAR_ARROW_COLOR:
819         // FIXME: unimplemented
820         break;
821 #endif
822     case CSS_PROP__KHTML_FLOW_MODE:
823         // FIXME: unimplemented
824         break;
825 #if APPLE_CHANGES
826         case CSS_PROP__APPLE_DASHBOARD_REGION: {
827             QValueList<StyleDashboardRegion> regions = style->dashboardRegions();
828             uint i, count = regions.count();
829             DashboardRegionImpl *firstRegion = new DashboardRegionImpl(), *region;
830             region = firstRegion;
831             
832             if (count == 1 && regions[0].type == StyleDashboardRegion::None)
833                 return new CSSPrimitiveValueImpl (CSS_VAL_NONE);
834                 
835             for (i = 0; i < count; i++) {
836                 StyleDashboardRegion styleRegion = regions[i];
837                 region->m_label = styleRegion.label;
838                 LengthBox offset = styleRegion.offset;
839                 region->setTop (new CSSPrimitiveValueImpl(offset.top.value, CSSPrimitiveValue::CSS_PX));
840                 region->setRight (new CSSPrimitiveValueImpl(offset.right.value, CSSPrimitiveValue::CSS_PX));
841                 region->setBottom (new CSSPrimitiveValueImpl(offset.bottom.value, CSSPrimitiveValue::CSS_PX));
842                 region->setLeft (new CSSPrimitiveValueImpl(offset.left.value, CSSPrimitiveValue::CSS_PX));
843                 region->m_isRectangle = (styleRegion.type == StyleDashboardRegion::Rectangle); 
844                 region->m_isCircle = (styleRegion.type == StyleDashboardRegion::Circle);
845                 if (i != count-1) {
846                     DashboardRegionImpl *newRegion = new DashboardRegionImpl();
847                     region->setNext (newRegion);
848                     region = newRegion;
849                 }
850             }
851             return new CSSPrimitiveValueImpl(firstRegion);
852         }
853 #endif
854     }
855
856     ERROR("unimplemented propertyID: %d", propertyID);
857     return 0;
858 }
859
860 DOMString CSSComputedStyleDeclarationImpl::getPropertyValue(int propertyID) const
861 {
862     CSSValueImpl* value = getPropertyCSSValue(propertyID);
863     if (value)
864         return value->cssText();
865     return "";
866 }
867
868 bool CSSComputedStyleDeclarationImpl::getPropertyPriority(int) const
869 {
870     // This class does not support the notion of priority, since the object
871     // is a computed value.
872     return false;
873 }
874
875 DOMString CSSComputedStyleDeclarationImpl::removeProperty(int)
876 {
877     ASSERT_NOT_REACHED();
878     return DOMString();
879 }
880
881 bool CSSComputedStyleDeclarationImpl::setProperty(int, const DOMString &, bool)
882 {
883     ASSERT_NOT_REACHED();
884     return false;
885 }
886
887 void CSSComputedStyleDeclarationImpl::setProperty(int, int, bool)
888 {
889     ASSERT_NOT_REACHED();
890 }
891
892 void CSSComputedStyleDeclarationImpl::setLengthProperty(int, const DOMString&, bool, bool)
893 {
894     ASSERT_NOT_REACHED();
895 }
896
897 void CSSComputedStyleDeclarationImpl::setProperty(const DOMString &)
898 {
899     ASSERT_NOT_REACHED();
900 }
901
902 DOMString CSSComputedStyleDeclarationImpl::item(unsigned long) const
903 {
904     ERROR("unimplemented");
905     return DOMString();
906 }
907
908
909 CSSProperty CSSComputedStyleDeclarationImpl::property(int id) const
910 {
911     CSSProperty prop;
912     prop.m_id = id;
913     prop.m_bImportant = false;
914     prop.setValue(getPropertyCSSValue(id));
915     return prop;
916 }
917
918 CSSStyleDeclarationImpl *CSSComputedStyleDeclarationImpl::copyInheritableProperties() const
919 {
920     return copyPropertiesInSet(InheritableProperties, sizeof(InheritableProperties) / sizeof(InheritableProperties[0]));
921 }
922
923 } // namespace DOM