More dashboard region work.
[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     // Make sure our layout is up to date before we allow a query on these attributes.
217     DocumentImpl* docimpl = node()->getDocument();
218     if (docimpl)
219         docimpl->updateLayout();
220
221     if (!m_renderer)
222         return 0;
223     RenderStyle *style = m_renderer->style();
224     if (!style)
225         return 0;
226
227     switch(propertyID)
228     {
229     case CSS_PROP_BACKGROUND_COLOR:
230         return new CSSPrimitiveValueImpl(style->backgroundColor().rgb());
231     case CSS_PROP_BACKGROUND_IMAGE:
232         if (style->backgroundImage())
233             return new CSSPrimitiveValueImpl(style->backgroundImage()->url(),
234                                              CSSPrimitiveValue::CSS_URI);
235         return 0;
236     case CSS_PROP_BACKGROUND_REPEAT:
237         switch (style->backgroundRepeat()) {
238             case khtml::REPEAT:
239                 return new CSSPrimitiveValueImpl(CSS_VAL_REPEAT);
240             case khtml::REPEAT_X:
241                 return new CSSPrimitiveValueImpl(CSS_VAL_REPEAT_X);
242             case khtml::REPEAT_Y:
243                 return new CSSPrimitiveValueImpl(CSS_VAL_REPEAT_Y);
244             case khtml::NO_REPEAT:
245                 return new CSSPrimitiveValueImpl(CSS_VAL_NO_REPEAT);
246         }
247         ASSERT_NOT_REACHED();
248         return 0;
249     case CSS_PROP_BACKGROUND_ATTACHMENT:
250         if (style->backgroundAttachment())
251             return new CSSPrimitiveValueImpl(CSS_VAL_SCROLL);
252         else
253             return new CSSPrimitiveValueImpl(CSS_VAL_FIXED);
254     case CSS_PROP_BACKGROUND_POSITION:
255     {
256         DOMString string;
257         Length length(style->backgroundXPosition());
258         if (length.isPercent())
259             string = numberAsString(length.length()) + "%";
260         else
261             string = numberAsString(length.minWidth(m_renderer->contentWidth()));
262         string += " ";
263         length = style->backgroundYPosition();
264         if (length.isPercent())
265             string += numberAsString(length.length()) + "%";
266         else
267             string += numberAsString(length.minWidth(m_renderer->contentWidth()));
268         return new CSSPrimitiveValueImpl(string, CSSPrimitiveValue::CSS_STRING);
269     }
270     case CSS_PROP_BACKGROUND_POSITION_X:
271         return valueForLength(style->backgroundXPosition());
272     case CSS_PROP_BACKGROUND_POSITION_Y:
273         return valueForLength(style->backgroundYPosition());
274 #ifndef KHTML_NO_XBL
275     case CSS_PROP__KHTML_BINDING:
276         // FIXME: unimplemented
277         break;
278 #endif
279     case CSS_PROP_BORDER_COLLAPSE:
280         if (style->borderCollapse())
281             return new CSSPrimitiveValueImpl(CSS_VAL_COLLAPSE);
282         else
283             return new CSSPrimitiveValueImpl(CSS_VAL_SEPARATE);
284     case CSS_PROP_BORDER_SPACING:
285     {
286         QString string(numberAsString(style->horizontalBorderSpacing()) + 
287             "px " + 
288             numberAsString(style->verticalBorderSpacing()) +
289             "px");
290         return new CSSPrimitiveValueImpl(string, CSSPrimitiveValue::CSS_STRING);
291     }
292     case CSS_PROP__KHTML_BORDER_HORIZONTAL_SPACING:
293         return new CSSPrimitiveValueImpl(style->horizontalBorderSpacing(), CSSPrimitiveValue::CSS_PX);
294     case CSS_PROP__KHTML_BORDER_VERTICAL_SPACING:
295         return new CSSPrimitiveValueImpl(style->verticalBorderSpacing(), CSSPrimitiveValue::CSS_PX);
296     case CSS_PROP_BORDER_TOP_COLOR:
297         return new CSSPrimitiveValueImpl(style->borderLeftColor().rgb());
298     case CSS_PROP_BORDER_RIGHT_COLOR:
299         return new CSSPrimitiveValueImpl(style->borderRightColor().rgb());
300     case CSS_PROP_BORDER_BOTTOM_COLOR:
301         return new CSSPrimitiveValueImpl(style->borderBottomColor().rgb());
302     case CSS_PROP_BORDER_LEFT_COLOR:
303         return new CSSPrimitiveValueImpl(style->borderLeftColor().rgb());
304     case CSS_PROP_BORDER_TOP_STYLE:
305         return valueForBorderStyle(style->borderTopStyle());
306     case CSS_PROP_BORDER_RIGHT_STYLE:
307         return valueForBorderStyle(style->borderRightStyle());
308     case CSS_PROP_BORDER_BOTTOM_STYLE:
309         return valueForBorderStyle(style->borderBottomStyle());
310     case CSS_PROP_BORDER_LEFT_STYLE:
311         return valueForBorderStyle(style->borderLeftStyle());
312     case CSS_PROP_BORDER_TOP_WIDTH:
313         return new CSSPrimitiveValueImpl(style->borderTopWidth(), CSSPrimitiveValue::CSS_PX);
314     case CSS_PROP_BORDER_RIGHT_WIDTH:
315         return new CSSPrimitiveValueImpl(style->borderRightWidth(), CSSPrimitiveValue::CSS_PX);
316     case CSS_PROP_BORDER_BOTTOM_WIDTH:
317         return new CSSPrimitiveValueImpl(style->borderBottomWidth(), CSSPrimitiveValue::CSS_PX);
318     case CSS_PROP_BORDER_LEFT_WIDTH:
319         return new CSSPrimitiveValueImpl(style->borderLeftWidth(), CSSPrimitiveValue::CSS_PX);
320     case CSS_PROP_BOTTOM:
321         return getPositionOffsetValue(CSS_PROP_BOTTOM);
322     case CSS_PROP__KHTML_BOX_ALIGN:
323         // FIXME: unimplemented
324         break;
325     case CSS_PROP__KHTML_BOX_DIRECTION:
326         // FIXME: unimplemented
327         break;
328     case CSS_PROP__KHTML_BOX_FLEX:
329         // FIXME: unimplemented
330         break;
331     case CSS_PROP__KHTML_BOX_FLEX_GROUP:
332         // FIXME: unimplemented
333         break;
334     case CSS_PROP__KHTML_BOX_LINES:
335         // FIXME: unimplemented
336         break;
337     case CSS_PROP__KHTML_BOX_ORDINAL_GROUP:
338         // FIXME: unimplemented
339         break;
340     case CSS_PROP__KHTML_BOX_ORIENT:
341         // FIXME: unimplemented
342         break;
343     case CSS_PROP__KHTML_BOX_PACK:
344         // FIXME: unimplemented
345         break;
346     case CSS_PROP_CAPTION_SIDE:
347         // FIXME: unimplemented
348         break;
349     case CSS_PROP_CLEAR:
350         // FIXME: unimplemented
351         break;
352     case CSS_PROP_CLIP:
353         // FIXME: unimplemented
354         break;
355     case CSS_PROP_COLOR:
356         return new CSSPrimitiveValueImpl(style->color().rgb());
357     case CSS_PROP_CONTENT:
358         // FIXME: unimplemented
359         break;
360     case CSS_PROP_COUNTER_INCREMENT:
361         // FIXME: unimplemented
362         break;
363     case CSS_PROP_COUNTER_RESET:
364         // FIXME: unimplemented
365         break;
366     case CSS_PROP_CURSOR:
367         // FIXME: unimplemented
368         break;
369     case CSS_PROP_DIRECTION:
370         // FIXME: unimplemented
371         break;
372     case CSS_PROP_DISPLAY:
373         switch (style->display()) {
374             case khtml::INLINE:
375                 return new CSSPrimitiveValueImpl(CSS_VAL_INLINE);
376             case khtml::BLOCK:
377                 return new CSSPrimitiveValueImpl(CSS_VAL_BLOCK);
378             case khtml::LIST_ITEM:
379                 return new CSSPrimitiveValueImpl(CSS_VAL_LIST_ITEM);
380             case khtml::RUN_IN:
381                 return new CSSPrimitiveValueImpl(CSS_VAL_RUN_IN);
382             case khtml::COMPACT:
383                 return new CSSPrimitiveValueImpl(CSS_VAL_COMPACT);
384             case khtml::INLINE_BLOCK:
385                 return new CSSPrimitiveValueImpl(CSS_VAL_INLINE_BLOCK);
386             case khtml::TABLE:
387                 return new CSSPrimitiveValueImpl(CSS_VAL_TABLE);
388             case khtml::INLINE_TABLE:
389                 return new CSSPrimitiveValueImpl(CSS_VAL_INLINE_TABLE);
390             case khtml::TABLE_ROW_GROUP:
391                 return new CSSPrimitiveValueImpl(CSS_VAL_TABLE_ROW_GROUP);
392             case khtml::TABLE_HEADER_GROUP:
393                 return new CSSPrimitiveValueImpl(CSS_VAL_TABLE_HEADER_GROUP);
394             case khtml::TABLE_FOOTER_GROUP:
395                 return new CSSPrimitiveValueImpl(CSS_VAL_TABLE_FOOTER_GROUP);
396             case khtml::TABLE_ROW:
397                 return new CSSPrimitiveValueImpl(CSS_VAL_TABLE_ROW);
398             case khtml::TABLE_COLUMN_GROUP:
399                 return new CSSPrimitiveValueImpl(CSS_VAL_TABLE_COLUMN_GROUP);
400             case khtml::TABLE_COLUMN:
401                 return new CSSPrimitiveValueImpl(CSS_VAL_TABLE_COLUMN);
402             case khtml::TABLE_CELL:
403                 return new CSSPrimitiveValueImpl(CSS_VAL_TABLE_CELL);
404             case khtml::TABLE_CAPTION:
405                 return new CSSPrimitiveValueImpl(CSS_VAL_TABLE_CAPTION);
406             case khtml::BOX:
407                 return new CSSPrimitiveValueImpl(CSS_VAL__KHTML_BOX);
408             case khtml::INLINE_BOX:
409                 return new CSSPrimitiveValueImpl(CSS_VAL__KHTML_INLINE_BOX);
410             case khtml::NONE:
411                 return new CSSPrimitiveValueImpl(CSS_VAL_NONE);
412         }
413         ASSERT_NOT_REACHED();
414         return 0;
415     case CSS_PROP_EMPTY_CELLS:
416         // FIXME: unimplemented
417         break;
418     case CSS_PROP_FLOAT:
419         switch (style->floating()) {
420             case khtml::FNONE:
421                 return new CSSPrimitiveValueImpl(CSS_VAL_NONE);
422             case khtml::FLEFT:
423                 return new CSSPrimitiveValueImpl(CSS_VAL_LEFT);
424             case khtml::FRIGHT:
425                 return new CSSPrimitiveValueImpl(CSS_VAL_RIGHT);
426         }
427         ASSERT_NOT_REACHED();
428         return 0;
429     case CSS_PROP_FONT_FAMILY:
430     {
431         FontDef def = style->htmlFont().getFontDef();
432         return new CSSPrimitiveValueImpl(def.firstFamily().family().domString(), CSSPrimitiveValue::CSS_STRING);
433     }
434     case CSS_PROP_FONT_SIZE:
435     {
436         FontDef def = style->htmlFont().getFontDef();
437         return new CSSPrimitiveValueImpl(def.specifiedSize, CSSPrimitiveValue::CSS_PX);
438     }
439     case CSS_PROP_FONT_SIZE_ADJUST:
440         // FIXME: unimplemented
441         break;
442     case CSS_PROP_FONT_STRETCH:
443         // FIXME: unimplemented
444         break;
445     case CSS_PROP_FONT_STYLE:
446     {
447         // FIXME: handle oblique?
448         FontDef def = style->htmlFont().getFontDef();
449         if (def.italic)
450             return new CSSPrimitiveValueImpl(CSS_VAL_ITALIC);
451         else
452             return new CSSPrimitiveValueImpl(CSS_VAL_NORMAL);
453     }
454     case CSS_PROP_FONT_VARIANT:
455     {
456         FontDef def = style->htmlFont().getFontDef();
457         if (def.smallCaps)
458             return new CSSPrimitiveValueImpl(CSS_VAL_SMALL_CAPS);
459         else
460             return new CSSPrimitiveValueImpl(CSS_VAL_NORMAL);
461     }
462     case CSS_PROP_FONT_WEIGHT:
463     {
464         // FIXME: this does not reflect the full range of weights
465         // that can be expressed with CSS
466         FontDef def = style->htmlFont().getFontDef();
467         if (def.weight == QFont::Bold)
468             return new CSSPrimitiveValueImpl(CSS_VAL_BOLD);
469         else
470             return new CSSPrimitiveValueImpl(CSS_VAL_NORMAL);
471     }
472     case CSS_PROP_HEIGHT:
473         return new CSSPrimitiveValueImpl(m_renderer->contentHeight(), CSSPrimitiveValue::CSS_PX);
474     case CSS_PROP_LEFT:
475         return getPositionOffsetValue(CSS_PROP_LEFT);
476     case CSS_PROP_LETTER_SPACING:
477         if (style->letterSpacing() == 0)
478             return new CSSPrimitiveValueImpl(CSS_VAL_NORMAL);
479         return new CSSPrimitiveValueImpl(style->letterSpacing(), CSSPrimitiveValue::CSS_PX);
480     case CSS_PROP_LINE_HEIGHT: {
481         Length length(style->lineHeight());
482         if (length.isPercent()) {
483             float computedSize = style->htmlFont().getFontDef().computedSize;
484             return new CSSPrimitiveValueImpl((int)(length.length() * computedSize) / 100, CSSPrimitiveValue::CSS_PX);
485         }
486         else {
487             return new CSSPrimitiveValueImpl(length.length(), CSSPrimitiveValue::CSS_PX);
488         }
489     }
490     case CSS_PROP_LIST_STYLE_IMAGE:
491         // FIXME: unimplemented
492         break;
493     case CSS_PROP_LIST_STYLE_POSITION:
494         // FIXME: unimplemented
495         break;
496     case CSS_PROP_LIST_STYLE_TYPE:
497         // FIXME: unimplemented
498         break;
499     case CSS_PROP_MARGIN_TOP:
500         return valueForLength(style->marginTop());
501     case CSS_PROP_MARGIN_RIGHT:
502         return valueForLength(style->marginRight());
503     case CSS_PROP_MARGIN_BOTTOM:
504         return valueForLength(style->marginBottom());
505     case CSS_PROP_MARGIN_LEFT:
506         return valueForLength(style->marginLeft());
507     case CSS_PROP__KHTML_MARQUEE:
508         // FIXME: unimplemented
509         break;
510     case CSS_PROP__KHTML_MARQUEE_DIRECTION:
511         // FIXME: unimplemented
512         break;
513     case CSS_PROP__KHTML_MARQUEE_INCREMENT:
514         return valueForLength(style->marqueeIncrement());
515     case CSS_PROP__KHTML_MARQUEE_REPETITION:
516         // FIXME: unimplemented
517         break;
518     case CSS_PROP__KHTML_MARQUEE_SPEED:
519         // FIXME: unimplemented
520         break;
521     case CSS_PROP__KHTML_MARQUEE_STYLE:
522         // FIXME: unimplemented
523         break;
524     case CSS_PROP__KHTML_USER_MODIFY:
525         // FIXME: unimplemented
526         break;
527     case CSS_PROP_MAX_HEIGHT:
528         return valueForLength(style->maxHeight());
529     case CSS_PROP_MAX_WIDTH:
530         return valueForLength(style->maxWidth());
531     case CSS_PROP_MIN_HEIGHT:
532         return valueForLength(style->minHeight());
533     case CSS_PROP_MIN_WIDTH:
534         return valueForLength(style->minWidth());
535     case CSS_PROP_OPACITY:
536         // FIXME: unimplemented
537         break;
538     case CSS_PROP_ORPHANS:
539         // FIXME: unimplemented
540         break;
541         // FIXME: unimplemented
542         break;
543     case CSS_PROP_OUTLINE_COLOR:
544         // FIXME: unimplemented
545         break;
546     case CSS_PROP_OUTLINE_OFFSET:
547         // FIXME: unimplemented
548         break;
549     case CSS_PROP_OUTLINE_STYLE:
550         // FIXME: unimplemented
551         break;
552     case CSS_PROP_OUTLINE_WIDTH:
553         // FIXME: unimplemented
554         break;
555     case CSS_PROP_OVERFLOW:
556         switch (style->overflow()) {
557             case khtml::OVISIBLE:
558                 return new CSSPrimitiveValueImpl(CSS_VAL_VISIBLE);
559             case khtml::OHIDDEN:
560                 return new CSSPrimitiveValueImpl(CSS_VAL_HIDDEN);
561             case khtml::OSCROLL:
562                 return new CSSPrimitiveValueImpl(CSS_VAL_SCROLL);
563             case khtml::OAUTO:
564                 return new CSSPrimitiveValueImpl(CSS_VAL_AUTO);
565             case khtml::OMARQUEE:
566                 return new CSSPrimitiveValueImpl(CSS_VAL_MARQUEE);
567             case khtml::OOVERLAY:
568                 return new CSSPrimitiveValueImpl(CSS_VAL_OVERLAY);
569         }
570         ASSERT_NOT_REACHED();
571         return 0;
572     case CSS_PROP_PADDING_TOP:
573         return valueForLength(style->paddingTop());
574     case CSS_PROP_PADDING_RIGHT:
575         return valueForLength(style->paddingRight());
576     case CSS_PROP_PADDING_BOTTOM:
577         return valueForLength(style->paddingBottom());
578     case CSS_PROP_PADDING_LEFT:
579         return valueForLength(style->paddingLeft());
580     case CSS_PROP_PAGE:
581         // FIXME: unimplemented
582         break;
583     case CSS_PROP_PAGE_BREAK_AFTER:
584         // FIXME: unimplemented
585         break;
586     case CSS_PROP_PAGE_BREAK_BEFORE:
587         // FIXME: unimplemented
588         break;
589     case CSS_PROP_PAGE_BREAK_INSIDE:
590         // FIXME: unimplemented
591         break;
592     case CSS_PROP_POSITION:
593         // FIXME: unimplemented
594         break;
595     case CSS_PROP_QUOTES:
596         // FIXME: unimplemented
597         break;
598     case CSS_PROP_RIGHT:
599         return getPositionOffsetValue(CSS_PROP_RIGHT);
600     case CSS_PROP_SIZE:
601         // FIXME: unimplemented
602         break;
603     case CSS_PROP_TABLE_LAYOUT:
604         // FIXME: unimplemented
605         break;
606     case CSS_PROP_TEXT_ALIGN:
607         return valueForTextAlign(style->textAlign());
608     case CSS_PROP_TEXT_DECORATION:
609     {
610         QString string;
611         if (style->textDecoration() & khtml::UNDERLINE)
612             string += "underline";
613         if (style->textDecoration() & khtml::OVERLINE) {
614             if (string.length() > 0)
615                 string += " ";
616             string += "overline";
617         }
618         if (style->textDecoration() & khtml::LINE_THROUGH) {
619             if (string.length() > 0)
620                 string += " ";
621             string += "line-through";
622         }
623         if (style->textDecoration() & khtml::BLINK) {
624             if (string.length() > 0)
625                 string += " ";
626             string += "blink";
627         }
628         if (string.length() == 0)
629             return new CSSPrimitiveValueImpl(CSS_VAL_NONE);
630         return new CSSPrimitiveValueImpl(string, CSSPrimitiveValue::CSS_STRING);
631     }
632     case CSS_PROP_TEXT_INDENT:
633         return valueForLength(style->textIndent());
634     case CSS_PROP_TEXT_SHADOW:
635         return valueForShadow(style->textShadow());
636     case CSS_PROP_TEXT_TRANSFORM:
637         switch (style->textTransform()) {
638             case khtml::CAPITALIZE:
639                 return new CSSPrimitiveValueImpl(CSS_VAL_CAPITALIZE);
640             case khtml::UPPERCASE:
641                 return new CSSPrimitiveValueImpl(CSS_VAL_UPPERCASE);
642             case khtml::LOWERCASE:
643                 return new CSSPrimitiveValueImpl(CSS_VAL_LOWERCASE);
644             case khtml::TTNONE:
645                 return new CSSPrimitiveValueImpl(CSS_VAL_NONE);
646         }
647         ASSERT_NOT_REACHED();
648         return 0;
649     case CSS_PROP_TOP:
650         return getPositionOffsetValue(CSS_PROP_TOP);
651     case CSS_PROP_UNICODE_BIDI:
652         // FIXME: unimplemented
653         break;
654     case CSS_PROP_VERTICAL_ALIGN:
655         switch (style->verticalAlign()) {
656             case khtml::BASELINE:
657                 return new CSSPrimitiveValueImpl(CSS_VAL_BASELINE);
658             case khtml::MIDDLE:
659                 return new CSSPrimitiveValueImpl(CSS_VAL_MIDDLE);
660             case khtml::SUB:
661                 return new CSSPrimitiveValueImpl(CSS_VAL_SUB);
662             case khtml::SUPER:
663                 return new CSSPrimitiveValueImpl(CSS_VAL_SUPER);
664             case khtml::TEXT_TOP:
665                 return new CSSPrimitiveValueImpl(CSS_VAL_TEXT_TOP);
666             case khtml::TEXT_BOTTOM:
667                 return new CSSPrimitiveValueImpl(CSS_VAL_TEXT_BOTTOM);
668             case khtml::TOP:
669                 return new CSSPrimitiveValueImpl(CSS_VAL_TOP);
670             case khtml::BOTTOM:
671                 return new CSSPrimitiveValueImpl(CSS_VAL_BOTTOM);
672             case khtml::BASELINE_MIDDLE:
673                 return new CSSPrimitiveValueImpl(CSS_VAL__KHTML_BASELINE_MIDDLE);
674             case khtml::LENGTH:
675                 return valueForLength(style->verticalAlignLength());
676         }
677         ASSERT_NOT_REACHED();
678         return 0;
679     case CSS_PROP_VISIBILITY:
680         switch (style->visibility()) {
681             case khtml::VISIBLE:
682                 return new CSSPrimitiveValueImpl(CSS_VAL_VISIBLE);
683             case khtml::HIDDEN:
684                 return new CSSPrimitiveValueImpl(CSS_VAL_HIDDEN);
685             case khtml::COLLAPSE:
686                 return new CSSPrimitiveValueImpl(CSS_VAL_COLLAPSE);
687         }
688         ASSERT_NOT_REACHED();
689         return 0;
690     case CSS_PROP_WHITE_SPACE:
691         switch (style->whiteSpace()) {
692             case khtml::NORMAL:
693                 return new CSSPrimitiveValueImpl(CSS_VAL_NORMAL);
694             case khtml::PRE:
695                 return new CSSPrimitiveValueImpl(CSS_VAL_PRE);
696             case khtml::NOWRAP:
697                 return new CSSPrimitiveValueImpl(CSS_VAL_NOWRAP);
698             case khtml::KHTML_NOWRAP:
699                 return new CSSPrimitiveValueImpl(CSS_VAL__KHTML_NOWRAP);
700         }
701         ASSERT_NOT_REACHED();
702         return 0;
703     case CSS_PROP_WIDOWS:
704         // FIXME: unimplemented
705         break;
706     case CSS_PROP_WIDTH:
707         return new CSSPrimitiveValueImpl(m_renderer->contentWidth(), CSSPrimitiveValue::CSS_PX);
708     case CSS_PROP_WORD_SPACING:
709         return new CSSPrimitiveValueImpl(style->wordSpacing(), CSSPrimitiveValue::CSS_PX);
710     case CSS_PROP_Z_INDEX:
711         // FIXME: unimplemented
712         break;
713     case CSS_PROP_BACKGROUND:
714         // FIXME: unimplemented
715         break;
716     case CSS_PROP_BORDER:
717         // FIXME: unimplemented
718         break;
719     case CSS_PROP_BORDER_COLOR:
720         // FIXME: unimplemented
721         break;
722     case CSS_PROP_BORDER_STYLE:
723         // FIXME: unimplemented
724         break;
725     case CSS_PROP_BORDER_TOP:
726         // FIXME: unimplemented
727         break;
728     case CSS_PROP_BORDER_RIGHT:
729         // FIXME: unimplemented
730         break;
731     case CSS_PROP_BORDER_BOTTOM:
732         // FIXME: unimplemented
733         break;
734     case CSS_PROP_BORDER_LEFT:
735         // FIXME: unimplemented
736         break;
737     case CSS_PROP_BORDER_WIDTH:
738         // FIXME: unimplemented
739         break;
740     case CSS_PROP_FONT:
741         // FIXME: unimplemented
742         break;
743     case CSS_PROP_LIST_STYLE:
744         // FIXME: unimplemented
745         break;
746     case CSS_PROP_MARGIN:
747         // FIXME: unimplemented
748         break;
749     case CSS_PROP_OUTLINE:
750         // FIXME: unimplemented
751         break;
752     case CSS_PROP_PADDING:
753         // FIXME: unimplemented
754         break;
755 #if !APPLE_CHANGES
756     case CSS_PROP_SCROLLBAR_FACE_COLOR:
757         // FIXME: unimplemented
758         break;
759     case CSS_PROP_SCROLLBAR_SHADOW_COLOR:
760         // FIXME: unimplemented
761         break;
762     case CSS_PROP_SCROLLBAR_HIGHLIGHT_COLOR:
763         // FIXME: unimplemented
764         break;
765     case CSS_PROP_SCROLLBAR_3DLIGHT_COLOR:
766         // FIXME: unimplemented
767         break;
768     case CSS_PROP_SCROLLBAR_DARKSHADOW_COLOR:
769         // FIXME: unimplemented
770         break;
771     case CSS_PROP_SCROLLBAR_TRACK_COLOR:
772         // FIXME: unimplemented
773         break;
774     case CSS_PROP_SCROLLBAR_ARROW_COLOR:
775         // FIXME: unimplemented
776         break;
777 #endif
778     case CSS_PROP__KHTML_FLOW_MODE:
779         // FIXME: unimplemented
780         break;
781 #if APPLE_CHANGES
782         case CSS_PROP__APPLE_DASHBOARD_REGION: {
783             QValueList<StyleDashboardRegion> regions = style->dashboardRegions();
784             uint i, count = regions.count();
785             DashboardRegionImpl *firstRegion = new DashboardRegionImpl(), *region;
786             region = firstRegion;
787             for (i = 0; i < count; i++) {
788                 StyleDashboardRegion styleRegion = regions[i];
789                 region->m_label = styleRegion.label;
790                 LengthBox offset = styleRegion.offset;
791                 region->setTop (new CSSPrimitiveValueImpl(offset.top.value, CSSPrimitiveValue::CSS_PX));
792                 region->setRight (new CSSPrimitiveValueImpl(offset.right.value, CSSPrimitiveValue::CSS_PX));
793                 region->setBottom (new CSSPrimitiveValueImpl(offset.bottom.value, CSSPrimitiveValue::CSS_PX));
794                 region->setLeft (new CSSPrimitiveValueImpl(offset.left.value, CSSPrimitiveValue::CSS_PX));
795                 region->m_isRectangle = (styleRegion.type == StyleDashboardRegion::Rectangle); 
796                 region->m_isCircle = (styleRegion.type == StyleDashboardRegion::Circle);
797                 if (i != count-1) {
798                     DashboardRegionImpl *newRegion = new DashboardRegionImpl();
799                     region->setNext (newRegion);
800                     region = newRegion;
801                 }
802             }
803             return new CSSPrimitiveValueImpl(firstRegion);
804         }
805 #endif
806     }
807
808     ERROR("unimplemented propertyID: %d", propertyID);
809     return 0;
810 }
811
812 DOMString CSSComputedStyleDeclarationImpl::getPropertyValue(int propertyID) const
813 {
814     CSSValueImpl* value = getPropertyCSSValue(propertyID);
815     if (value)
816         return value->cssText();
817     return "";
818 }
819
820 bool CSSComputedStyleDeclarationImpl::getPropertyPriority(int) const
821 {
822     // This class does not support the notion of priority, since the object
823     // is a computed value.
824     return false;
825 }
826
827 DOMString CSSComputedStyleDeclarationImpl::removeProperty(int)
828 {
829     ASSERT_NOT_REACHED();
830     return DOMString();
831 }
832
833 bool CSSComputedStyleDeclarationImpl::setProperty(int, const DOMString &, bool)
834 {
835     ASSERT_NOT_REACHED();
836     return false;
837 }
838
839 void CSSComputedStyleDeclarationImpl::setProperty(int, int, bool)
840 {
841     ASSERT_NOT_REACHED();
842 }
843
844 void CSSComputedStyleDeclarationImpl::setLengthProperty(int, const DOMString&, bool, bool)
845 {
846     ASSERT_NOT_REACHED();
847 }
848
849 void CSSComputedStyleDeclarationImpl::setProperty(const DOMString &)
850 {
851     ASSERT_NOT_REACHED();
852 }
853
854 DOMString CSSComputedStyleDeclarationImpl::item(unsigned long) const
855 {
856     ERROR("unimplemented");
857     return DOMString();
858 }
859
860
861 CSSProperty CSSComputedStyleDeclarationImpl::property(int id) const
862 {
863     CSSProperty prop;
864     prop.m_id = id;
865     prop.m_bImportant = false;
866     prop.setValue(getPropertyCSSValue(id));
867     return prop;
868 }
869
870 CSSStyleDeclarationImpl *CSSComputedStyleDeclarationImpl::copyInheritableProperties() const
871 {
872     QPtrList<CSSProperty> *list = new QPtrList<CSSProperty>;
873     list->setAutoDelete(true);
874     for (unsigned i = 0; i < sizeof(InheritableProperties) / sizeof(InheritableProperties[0]); i++) {
875         CSSValueImpl *value = getPropertyCSSValue(InheritableProperties[i]);
876         if (value) {
877             CSSProperty *property = new CSSProperty;
878             property->m_id = InheritableProperties[i];
879             property->setValue(value);
880             list->append(property);
881         }
882     }
883     return new CSSStyleDeclarationImpl(0, list);
884 }
885
886 void CSSComputedStyleDeclarationImpl::diff(CSSStyleDeclarationImpl *style) const
887 {
888     if (!style)
889         return;
890
891     QValueList<int> properties;
892     for (QPtrListIterator<CSSProperty> it(*style->values()); it.current(); ++it) {
893         CSSProperty *property = it.current();
894         CSSValueImpl *value = getPropertyCSSValue(property->id());
895         if (value && value->cssText() == property->value()->cssText()) {
896             properties.append(property->id());
897         }
898     }
899     
900     for (QValueListIterator<int> it(properties.begin()); it != properties.end(); ++it)
901         style->removeProperty(*it);
902 }
903
904 } // namespace DOM