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