c43aa5e7eb3d6a24b4714981ec45c6cd009e1c23
[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.value < 0)
494             return new CSSPrimitiveValueImpl(CSS_VAL_NORMAL);
495         if (length.isPercent()) {
496             float computedSize = style->htmlFont().getFontDef().computedSize;
497             return new CSSPrimitiveValueImpl((int)(length.length() * computedSize) / 100, CSSPrimitiveValue::CSS_PX);
498         }
499         else {
500             return new CSSPrimitiveValueImpl(length.length(), CSSPrimitiveValue::CSS_PX);
501         }
502     }
503     case CSS_PROP_LIST_STYLE_IMAGE:
504         // FIXME: unimplemented
505         break;
506     case CSS_PROP_LIST_STYLE_POSITION:
507         // FIXME: unimplemented
508         break;
509     case CSS_PROP_LIST_STYLE_TYPE:
510         // FIXME: unimplemented
511         break;
512     case CSS_PROP_MARGIN_TOP:
513         return valueForLength(style->marginTop());
514     case CSS_PROP_MARGIN_RIGHT:
515         return valueForLength(style->marginRight());
516     case CSS_PROP_MARGIN_BOTTOM:
517         return valueForLength(style->marginBottom());
518     case CSS_PROP_MARGIN_LEFT:
519         return valueForLength(style->marginLeft());
520     case CSS_PROP__KHTML_MARQUEE:
521         // FIXME: unimplemented
522         break;
523     case CSS_PROP__KHTML_MARQUEE_DIRECTION:
524         // FIXME: unimplemented
525         break;
526     case CSS_PROP__KHTML_MARQUEE_INCREMENT:
527         return valueForLength(style->marqueeIncrement());
528     case CSS_PROP__KHTML_MARQUEE_REPETITION:
529         // FIXME: unimplemented
530         break;
531     case CSS_PROP__KHTML_MARQUEE_SPEED:
532         // FIXME: unimplemented
533         break;
534     case CSS_PROP__KHTML_MARQUEE_STYLE:
535         // FIXME: unimplemented
536         break;
537     case CSS_PROP__KHTML_USER_MODIFY:
538         // FIXME: unimplemented
539         break;
540     case CSS_PROP_MAX_HEIGHT:
541         return valueForLength(style->maxHeight());
542     case CSS_PROP_MAX_WIDTH:
543         return valueForLength(style->maxWidth());
544     case CSS_PROP_MIN_HEIGHT:
545         return valueForLength(style->minHeight());
546     case CSS_PROP_MIN_WIDTH:
547         return valueForLength(style->minWidth());
548     case CSS_PROP_OPACITY:
549         // FIXME: unimplemented
550         break;
551     case CSS_PROP_ORPHANS:
552         // FIXME: unimplemented
553         break;
554         // FIXME: unimplemented
555         break;
556     case CSS_PROP_OUTLINE_COLOR:
557         // FIXME: unimplemented
558         break;
559     case CSS_PROP_OUTLINE_OFFSET:
560         // FIXME: unimplemented
561         break;
562     case CSS_PROP_OUTLINE_STYLE:
563         // FIXME: unimplemented
564         break;
565     case CSS_PROP_OUTLINE_WIDTH:
566         // FIXME: unimplemented
567         break;
568     case CSS_PROP_OVERFLOW:
569         switch (style->overflow()) {
570             case khtml::OVISIBLE:
571                 return new CSSPrimitiveValueImpl(CSS_VAL_VISIBLE);
572             case khtml::OHIDDEN:
573                 return new CSSPrimitiveValueImpl(CSS_VAL_HIDDEN);
574             case khtml::OSCROLL:
575                 return new CSSPrimitiveValueImpl(CSS_VAL_SCROLL);
576             case khtml::OAUTO:
577                 return new CSSPrimitiveValueImpl(CSS_VAL_AUTO);
578             case khtml::OMARQUEE:
579                 return new CSSPrimitiveValueImpl(CSS_VAL_MARQUEE);
580             case khtml::OOVERLAY:
581                 return new CSSPrimitiveValueImpl(CSS_VAL_OVERLAY);
582         }
583         ASSERT_NOT_REACHED();
584         return 0;
585     case CSS_PROP_PADDING_TOP:
586         return valueForLength(style->paddingTop());
587     case CSS_PROP_PADDING_RIGHT:
588         return valueForLength(style->paddingRight());
589     case CSS_PROP_PADDING_BOTTOM:
590         return valueForLength(style->paddingBottom());
591     case CSS_PROP_PADDING_LEFT:
592         return valueForLength(style->paddingLeft());
593     case CSS_PROP_PAGE:
594         // FIXME: unimplemented
595         break;
596     case CSS_PROP_PAGE_BREAK_AFTER:
597         // FIXME: unimplemented
598         break;
599     case CSS_PROP_PAGE_BREAK_BEFORE:
600         // FIXME: unimplemented
601         break;
602     case CSS_PROP_PAGE_BREAK_INSIDE:
603         // FIXME: unimplemented
604         break;
605     case CSS_PROP_POSITION:
606         // FIXME: unimplemented
607         break;
608     case CSS_PROP_QUOTES:
609         // FIXME: unimplemented
610         break;
611     case CSS_PROP_RIGHT:
612         return getPositionOffsetValue(CSS_PROP_RIGHT);
613     case CSS_PROP_SIZE:
614         // FIXME: unimplemented
615         break;
616     case CSS_PROP_TABLE_LAYOUT:
617         switch (style->tableLayout()) {
618             case khtml::TAUTO:
619                 return new CSSPrimitiveValueImpl(CSS_VAL_AUTO);
620             case khtml::TFIXED:
621                 return new CSSPrimitiveValueImpl(CSS_VAL_FIXED);
622         }
623         ASSERT_NOT_REACHED();
624         return 0;
625     case CSS_PROP_TEXT_ALIGN:
626         return valueForTextAlign(style->textAlign());
627     case CSS_PROP_TEXT_DECORATION:
628     {
629         QString string;
630         if (style->textDecoration() & khtml::UNDERLINE)
631             string += "underline";
632         if (style->textDecoration() & khtml::OVERLINE) {
633             if (string.length() > 0)
634                 string += " ";
635             string += "overline";
636         }
637         if (style->textDecoration() & khtml::LINE_THROUGH) {
638             if (string.length() > 0)
639                 string += " ";
640             string += "line-through";
641         }
642         if (style->textDecoration() & khtml::BLINK) {
643             if (string.length() > 0)
644                 string += " ";
645             string += "blink";
646         }
647         if (string.length() == 0)
648             return new CSSPrimitiveValueImpl(CSS_VAL_NONE);
649         return new CSSPrimitiveValueImpl(string, CSSPrimitiveValue::CSS_STRING);
650     }
651     case CSS_PROP_TEXT_INDENT:
652         return valueForLength(style->textIndent());
653     case CSS_PROP_TEXT_SHADOW:
654         return valueForShadow(style->textShadow());
655     case CSS_PROP_TEXT_TRANSFORM:
656         switch (style->textTransform()) {
657             case khtml::CAPITALIZE:
658                 return new CSSPrimitiveValueImpl(CSS_VAL_CAPITALIZE);
659             case khtml::UPPERCASE:
660                 return new CSSPrimitiveValueImpl(CSS_VAL_UPPERCASE);
661             case khtml::LOWERCASE:
662                 return new CSSPrimitiveValueImpl(CSS_VAL_LOWERCASE);
663             case khtml::TTNONE:
664                 return new CSSPrimitiveValueImpl(CSS_VAL_NONE);
665         }
666         ASSERT_NOT_REACHED();
667         return 0;
668     case CSS_PROP_TOP:
669         return getPositionOffsetValue(CSS_PROP_TOP);
670     case CSS_PROP_UNICODE_BIDI:
671         // FIXME: unimplemented
672         break;
673     case CSS_PROP_VERTICAL_ALIGN:
674         switch (style->verticalAlign()) {
675             case khtml::BASELINE:
676                 return new CSSPrimitiveValueImpl(CSS_VAL_BASELINE);
677             case khtml::MIDDLE:
678                 return new CSSPrimitiveValueImpl(CSS_VAL_MIDDLE);
679             case khtml::SUB:
680                 return new CSSPrimitiveValueImpl(CSS_VAL_SUB);
681             case khtml::SUPER:
682                 return new CSSPrimitiveValueImpl(CSS_VAL_SUPER);
683             case khtml::TEXT_TOP:
684                 return new CSSPrimitiveValueImpl(CSS_VAL_TEXT_TOP);
685             case khtml::TEXT_BOTTOM:
686                 return new CSSPrimitiveValueImpl(CSS_VAL_TEXT_BOTTOM);
687             case khtml::TOP:
688                 return new CSSPrimitiveValueImpl(CSS_VAL_TOP);
689             case khtml::BOTTOM:
690                 return new CSSPrimitiveValueImpl(CSS_VAL_BOTTOM);
691             case khtml::BASELINE_MIDDLE:
692                 return new CSSPrimitiveValueImpl(CSS_VAL__KHTML_BASELINE_MIDDLE);
693             case khtml::LENGTH:
694                 return valueForLength(style->verticalAlignLength());
695         }
696         ASSERT_NOT_REACHED();
697         return 0;
698     case CSS_PROP_VISIBILITY:
699         switch (style->visibility()) {
700             case khtml::VISIBLE:
701                 return new CSSPrimitiveValueImpl(CSS_VAL_VISIBLE);
702             case khtml::HIDDEN:
703                 return new CSSPrimitiveValueImpl(CSS_VAL_HIDDEN);
704             case khtml::COLLAPSE:
705                 return new CSSPrimitiveValueImpl(CSS_VAL_COLLAPSE);
706         }
707         ASSERT_NOT_REACHED();
708         return 0;
709     case CSS_PROP_WHITE_SPACE:
710         switch (style->whiteSpace()) {
711             case khtml::NORMAL:
712                 return new CSSPrimitiveValueImpl(CSS_VAL_NORMAL);
713             case khtml::PRE:
714                 return new CSSPrimitiveValueImpl(CSS_VAL_PRE);
715             case khtml::NOWRAP:
716                 return new CSSPrimitiveValueImpl(CSS_VAL_NOWRAP);
717             case khtml::KHTML_NOWRAP:
718                 return new CSSPrimitiveValueImpl(CSS_VAL__KHTML_NOWRAP);
719         }
720         ASSERT_NOT_REACHED();
721         return 0;
722     case CSS_PROP_WIDOWS:
723         // FIXME: unimplemented
724         break;
725     case CSS_PROP_WIDTH:
726         return new CSSPrimitiveValueImpl(m_renderer->contentWidth(), CSSPrimitiveValue::CSS_PX);
727     case CSS_PROP_WORD_SPACING:
728         return new CSSPrimitiveValueImpl(style->wordSpacing(), CSSPrimitiveValue::CSS_PX);
729     case CSS_PROP_WORD_WRAP:
730         switch (style->wordWrap()) {
731             case khtml::WBNORMAL:
732                 return new CSSPrimitiveValueImpl(CSS_VAL_NORMAL);
733             case khtml::BREAK_WORD:
734                 return new CSSPrimitiveValueImpl(CSS_VAL_BREAK_WORD);
735         }
736         ASSERT_NOT_REACHED();
737         return 0;
738     case CSS_PROP__KHTML_LINE_BREAK:
739         switch (style->khtmlLineBreak()) {
740             case khtml::LBNORMAL:
741                 return new CSSPrimitiveValueImpl(CSS_VAL_NORMAL);
742             case khtml::AFTER_WHITE_SPACE:
743                 return new CSSPrimitiveValueImpl(CSS_VAL_AFTER_WHITE_SPACE);
744         }
745         ASSERT_NOT_REACHED();
746         return 0;
747     case CSS_PROP__KHTML_NBSP_MODE:
748         switch (style->nbspMode()) {
749             case khtml::NBNORMAL:
750                 return new CSSPrimitiveValueImpl(CSS_VAL_NORMAL);
751             case khtml::SPACE:
752                 return new CSSPrimitiveValueImpl(CSS_VAL_SPACE);
753         }
754         ASSERT_NOT_REACHED();
755         return 0;
756     case CSS_PROP_Z_INDEX:
757         // FIXME: unimplemented
758         break;
759     case CSS_PROP_BACKGROUND:
760         // FIXME: unimplemented
761         break;
762     case CSS_PROP_BORDER:
763         // FIXME: unimplemented
764         break;
765     case CSS_PROP_BORDER_COLOR:
766         // FIXME: unimplemented
767         break;
768     case CSS_PROP_BORDER_STYLE:
769         // FIXME: unimplemented
770         break;
771     case CSS_PROP_BORDER_TOP:
772         // FIXME: unimplemented
773         break;
774     case CSS_PROP_BORDER_RIGHT:
775         // FIXME: unimplemented
776         break;
777     case CSS_PROP_BORDER_BOTTOM:
778         // FIXME: unimplemented
779         break;
780     case CSS_PROP_BORDER_LEFT:
781         // FIXME: unimplemented
782         break;
783     case CSS_PROP_BORDER_WIDTH:
784         // FIXME: unimplemented
785         break;
786     case CSS_PROP_FONT:
787         // FIXME: unimplemented
788         break;
789     case CSS_PROP_LIST_STYLE:
790         // FIXME: unimplemented
791         break;
792     case CSS_PROP_MARGIN:
793         // FIXME: unimplemented
794         break;
795     case CSS_PROP_OUTLINE:
796         // FIXME: unimplemented
797         break;
798     case CSS_PROP_PADDING:
799         // FIXME: unimplemented
800         break;
801 #if !APPLE_CHANGES
802     case CSS_PROP_SCROLLBAR_FACE_COLOR:
803         // FIXME: unimplemented
804         break;
805     case CSS_PROP_SCROLLBAR_SHADOW_COLOR:
806         // FIXME: unimplemented
807         break;
808     case CSS_PROP_SCROLLBAR_HIGHLIGHT_COLOR:
809         // FIXME: unimplemented
810         break;
811     case CSS_PROP_SCROLLBAR_3DLIGHT_COLOR:
812         // FIXME: unimplemented
813         break;
814     case CSS_PROP_SCROLLBAR_DARKSHADOW_COLOR:
815         // FIXME: unimplemented
816         break;
817     case CSS_PROP_SCROLLBAR_TRACK_COLOR:
818         // FIXME: unimplemented
819         break;
820     case CSS_PROP_SCROLLBAR_ARROW_COLOR:
821         // FIXME: unimplemented
822         break;
823 #endif
824     case CSS_PROP__KHTML_FLOW_MODE:
825         // FIXME: unimplemented
826         break;
827 #if APPLE_CHANGES
828         case CSS_PROP__APPLE_DASHBOARD_REGION: {
829             QValueList<StyleDashboardRegion> regions = style->dashboardRegions();
830             uint i, count = regions.count();
831             if (count == 1 && regions[0].type == StyleDashboardRegion::None)
832                 return new CSSPrimitiveValueImpl (CSS_VAL_NONE);
833                 
834             DashboardRegionImpl *firstRegion = new DashboardRegionImpl(), *region;
835             region = firstRegion;
836             for (i = 0; i < count; i++) {
837                 StyleDashboardRegion styleRegion = regions[i];
838                 region->m_label = styleRegion.label;
839                 LengthBox offset = styleRegion.offset;
840                 region->setTop (new CSSPrimitiveValueImpl(offset.top.value, CSSPrimitiveValue::CSS_PX));
841                 region->setRight (new CSSPrimitiveValueImpl(offset.right.value, CSSPrimitiveValue::CSS_PX));
842                 region->setBottom (new CSSPrimitiveValueImpl(offset.bottom.value, CSSPrimitiveValue::CSS_PX));
843                 region->setLeft (new CSSPrimitiveValueImpl(offset.left.value, CSSPrimitiveValue::CSS_PX));
844                 region->m_isRectangle = (styleRegion.type == StyleDashboardRegion::Rectangle); 
845                 region->m_isCircle = (styleRegion.type == StyleDashboardRegion::Circle);
846                 if (i != count-1) {
847                     DashboardRegionImpl *newRegion = new DashboardRegionImpl();
848                     region->setNext (newRegion);
849                     region = newRegion;
850                 }
851             }
852             return new CSSPrimitiveValueImpl(firstRegion);
853         }
854 #endif
855     }
856
857     ERROR("unimplemented propertyID: %d", propertyID);
858     return 0;
859 }
860
861 DOMString CSSComputedStyleDeclarationImpl::getPropertyValue(int propertyID) const
862 {
863     CSSValueImpl* value = getPropertyCSSValue(propertyID);
864     if (value) {
865         value->ref();
866         DOMString result = value->cssText();
867         value->deref();
868         return result;
869     }
870     return "";
871 }
872
873 bool CSSComputedStyleDeclarationImpl::getPropertyPriority(int) const
874 {
875     // This class does not support the notion of priority, since the object
876     // is a computed value.
877     return false;
878 }
879
880 DOMString CSSComputedStyleDeclarationImpl::removeProperty(int)
881 {
882     ASSERT_NOT_REACHED();
883     return DOMString();
884 }
885
886 bool CSSComputedStyleDeclarationImpl::setProperty(int, const DOMString &, bool)
887 {
888     ASSERT_NOT_REACHED();
889     return false;
890 }
891
892 void CSSComputedStyleDeclarationImpl::setProperty(int, int, bool)
893 {
894     ASSERT_NOT_REACHED();
895 }
896
897 void CSSComputedStyleDeclarationImpl::setLengthProperty(int, const DOMString&, bool, bool)
898 {
899     ASSERT_NOT_REACHED();
900 }
901
902 void CSSComputedStyleDeclarationImpl::setProperty(const DOMString &)
903 {
904     ASSERT_NOT_REACHED();
905 }
906
907 DOMString CSSComputedStyleDeclarationImpl::item(unsigned long) const
908 {
909     ERROR("unimplemented");
910     return DOMString();
911 }
912
913
914 CSSProperty CSSComputedStyleDeclarationImpl::property(int id) const
915 {
916     CSSProperty prop;
917     prop.m_id = id;
918     prop.m_bImportant = false;
919     prop.setValue(getPropertyCSSValue(id));
920     return prop;
921 }
922
923 CSSStyleDeclarationImpl *CSSComputedStyleDeclarationImpl::copyInheritableProperties() const
924 {
925     return copyPropertiesInSet(InheritableProperties, sizeof(InheritableProperties) / sizeof(InheritableProperties[0]));
926 }
927
928 } // namespace DOM