Reviewed by John
[WebKit-https.git] / WebCore / khtml / css / css_computedstyle.cpp
1 /**
2  * css_computedstyle.cpp
3  *
4  * Copyright (C)  2004  Zack Rusin <zack@kde.org>
5  * Copyright (C)  2004  Apple Computer, Inc.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20  * 02111-1307  USA
21  */
22 #include "css_computedstyle.h"
23
24 #include "cssproperties.h"
25 #include "dom_atomicstring.h"
26 #include "dom_string.h"
27 #include "font.h"
28 #include "khtmllayout.h"
29 #include "loader.h"
30 #include "rendering/render_style.h"
31 #include "rendering/render_object.h"
32
33 #if APPLE_CHANGES
34 #import "KWQAssertions.h"
35 #import "KWQFontFamily.h"
36 #import "KWQLogging.h"
37 #endif
38
39 using khtml::EBorderStyle;
40 using khtml::ETextAlign;
41 using khtml::Font;
42 using khtml::FontDef;
43 using khtml::Length;
44
45 namespace DOM {
46
47 // This is the list of properties we want to copy in the copyInheritableProperties() function.
48 // It is the intersection of the list of inherited CSS properties and the
49 // properties for which we have a computed implementation in this file.
50 static const int InheritableProperties[] = {
51     CSS_PROP_BORDER_COLLAPSE,
52     CSS_PROP_BORDER_SPACING,
53     CSS_PROP_COLOR,
54     CSS_PROP_FONT_FAMILY,
55     CSS_PROP_FONT_SIZE,
56     CSS_PROP_FONT_STYLE,
57     CSS_PROP_FONT_VARIANT,
58     CSS_PROP_FONT_WEIGHT,
59     CSS_PROP_LETTER_SPACING,
60     CSS_PROP_LINE_HEIGHT,
61     CSS_PROP_TEXT_ALIGN,
62     CSS_PROP_TEXT_INDENT,
63     CSS_PROP_WHITE_SPACE,
64     CSS_PROP_WORD_SPACING,
65 };
66
67 static CSSValueImpl *valueForLength(const Length &length, int max)
68 {
69     if (length.isPercent()) {
70         return new CSSPrimitiveValueImpl(length.length(), CSSPrimitiveValue::CSS_PERCENTAGE);
71     }
72     else {
73         return new CSSPrimitiveValueImpl(length.minWidth(max), CSSPrimitiveValue::CSS_PX);
74     }
75 }
76
77 static DOMString stringForBorderStyle(EBorderStyle style)
78 {
79     switch (style) {
80         case khtml::BNONE:
81             return "none";
82         case khtml::BHIDDEN:
83             return "hidden";
84         case khtml::INSET:
85             return "inset";
86         case khtml::GROOVE:
87             return "groove";
88         case khtml::RIDGE:
89             return "ridge";
90         case khtml::OUTSET:
91             return "outset";
92         case khtml::DOTTED:
93             return "dotted";
94         case khtml::DASHED:
95             return "dashed";
96         case khtml::SOLID:
97             return "solid";
98         case khtml::DOUBLE:
99             return "double";
100     }
101     ASSERT_NOT_REACHED();
102     return "";
103 }
104
105 static DOMString stringForTextAlign(ETextAlign align)
106 {
107     switch (align) {
108         case khtml::TAAUTO:
109             return "auto";
110         case khtml::LEFT:
111             return "left";
112         case khtml::RIGHT:
113             return "right";
114         case khtml::CENTER:
115             return "center";
116         case khtml::JUSTIFY:
117             return "justify";
118         case khtml::KHTML_LEFT:
119             return "-khtml-left";
120         case khtml::KHTML_RIGHT:
121             return "-khtml-right";
122         case khtml::KHTML_CENTER:
123             return "-khtml-center";
124     }
125     ASSERT_NOT_REACHED();
126     return "";
127 }
128
129 CSSComputedStyleDeclarationImpl::CSSComputedStyleDeclarationImpl(NodeImpl *n)
130     : CSSStyleDeclarationImpl(0)
131 {
132     setNode(n);
133     m_renderer = node()->renderer();
134 }
135
136 CSSComputedStyleDeclarationImpl::~CSSComputedStyleDeclarationImpl()
137 {
138 }
139
140 DOMString CSSComputedStyleDeclarationImpl::cssText() const
141 {
142     ERROR("unimplemented");
143     return DOMString();
144 }
145
146 void CSSComputedStyleDeclarationImpl::setCssText(const DOMString &)
147 {
148     ERROR("CSSComputedStyleDeclarationImpl is a read-only object");
149 }
150
151 CSSValueImpl *CSSComputedStyleDeclarationImpl::getPropertyCSSValue(int propertyID) const
152 {
153     // Make sure our layout is up to date before we allow a query on these attributes.
154     DocumentImpl* docimpl = node()->getDocument();
155     if (docimpl)
156         docimpl->updateLayout();
157
158     if (!m_renderer || !m_renderer->style())
159         return 0;
160
161     switch(propertyID)
162     {
163     case CSS_PROP_BACKGROUND_COLOR:
164         return new CSSPrimitiveValueImpl(m_renderer->style()->backgroundColor().rgb());
165     case CSS_PROP_BACKGROUND_IMAGE:
166         if (m_renderer->style()->backgroundImage())
167             return new CSSPrimitiveValueImpl(m_renderer->style()->backgroundImage()->url(), 
168                                              CSSPrimitiveValue::CSS_URI);
169         return 0;
170     case CSS_PROP_BACKGROUND_REPEAT:
171         switch (m_renderer->style()->backgroundRepeat()) {
172             case khtml::REPEAT:
173                 return new CSSPrimitiveValueImpl("repeat", CSSPrimitiveValue::CSS_STRING);
174             case khtml::REPEAT_X:
175                 return new CSSPrimitiveValueImpl("repeat-x", CSSPrimitiveValue::CSS_STRING);
176             case khtml::REPEAT_Y:
177                 return new CSSPrimitiveValueImpl("repeat-y", CSSPrimitiveValue::CSS_STRING);
178             case khtml::NO_REPEAT:
179                 return new CSSPrimitiveValueImpl("no-repeat", CSSPrimitiveValue::CSS_STRING);
180             default:
181                 ASSERT_NOT_REACHED();
182         }
183     case CSS_PROP_BACKGROUND_ATTACHMENT:
184         if (m_renderer->style()->backgroundAttachment())
185             return new CSSPrimitiveValueImpl("scroll", CSSPrimitiveValue::CSS_STRING);
186         else
187             return new CSSPrimitiveValueImpl("fixed", CSSPrimitiveValue::CSS_STRING);
188     case CSS_PROP_BACKGROUND_POSITION:
189     {
190         DOMString string;
191         Length length(m_renderer->style()->backgroundXPosition());
192         if (length.isPercent())
193             string = QString::number(length.length()) + "%";
194         else
195             string = QString::number(length.minWidth(m_renderer->contentWidth()));
196         string += " ";
197         length = m_renderer->style()->backgroundYPosition();
198         if (length.isPercent())
199             string += QString::number(length.length()) + "%";
200         else
201             string += QString::number(length.minWidth(m_renderer->contentWidth()));
202         return new CSSPrimitiveValueImpl(string, CSSPrimitiveValue::CSS_STRING);
203     }
204     case CSS_PROP_BACKGROUND_POSITION_X:
205         return valueForLength(m_renderer->style()->backgroundXPosition(), m_renderer->contentWidth());
206     case CSS_PROP_BACKGROUND_POSITION_Y:
207         return valueForLength(m_renderer->style()->backgroundYPosition(), m_renderer->contentHeight());
208 #ifndef KHTML_NO_XBL
209     case CSS_PROP__KHTML_BINDING:
210         // FIXME: unimplemented
211                 break;
212 #endif
213     case CSS_PROP_BORDER_COLLAPSE:
214         if (m_renderer->style()->borderCollapse())
215             return new CSSPrimitiveValueImpl("collapse", CSSPrimitiveValue::CSS_STRING);
216         else
217             return new CSSPrimitiveValueImpl("separate", CSSPrimitiveValue::CSS_STRING);
218     case CSS_PROP_BORDER_SPACING:
219     {
220         QString string(QString::number(m_renderer->style()->horizontalBorderSpacing()) + 
221             "px " + 
222             QString::number(m_renderer->style()->verticalBorderSpacing()) +
223             "px");
224         return new CSSPrimitiveValueImpl(string, CSSPrimitiveValue::CSS_STRING);
225     }
226     case CSS_PROP__KHTML_BORDER_HORIZONTAL_SPACING:
227         return new CSSPrimitiveValueImpl(m_renderer->style()->horizontalBorderSpacing(), CSSPrimitiveValue::CSS_PX);
228     case CSS_PROP__KHTML_BORDER_VERTICAL_SPACING:
229         return new CSSPrimitiveValueImpl(m_renderer->style()->verticalBorderSpacing(), CSSPrimitiveValue::CSS_PX);
230     case CSS_PROP_BORDER_TOP_COLOR:
231         return new CSSPrimitiveValueImpl(m_renderer->style()->borderLeftColor().rgb());
232     case CSS_PROP_BORDER_RIGHT_COLOR:
233         return new CSSPrimitiveValueImpl(m_renderer->style()->borderRightColor().rgb());
234     case CSS_PROP_BORDER_BOTTOM_COLOR:
235         return new CSSPrimitiveValueImpl(m_renderer->style()->borderBottomColor().rgb());
236     case CSS_PROP_BORDER_LEFT_COLOR:
237         return new CSSPrimitiveValueImpl(m_renderer->style()->borderLeftColor().rgb());
238     case CSS_PROP_BORDER_TOP_STYLE:
239         return new CSSPrimitiveValueImpl(stringForBorderStyle(m_renderer->style()->borderTopStyle()), CSSPrimitiveValue::CSS_STRING);
240     case CSS_PROP_BORDER_RIGHT_STYLE:
241         return new CSSPrimitiveValueImpl(stringForBorderStyle(m_renderer->style()->borderRightStyle()), CSSPrimitiveValue::CSS_STRING);
242     case CSS_PROP_BORDER_BOTTOM_STYLE:
243         return new CSSPrimitiveValueImpl(stringForBorderStyle(m_renderer->style()->borderBottomStyle()), CSSPrimitiveValue::CSS_STRING);
244     case CSS_PROP_BORDER_LEFT_STYLE:
245         return new CSSPrimitiveValueImpl(stringForBorderStyle(m_renderer->style()->borderLeftStyle()), CSSPrimitiveValue::CSS_STRING);
246     case CSS_PROP_BORDER_TOP_WIDTH:
247         return new CSSPrimitiveValueImpl(m_renderer->style()->borderTopWidth(), CSSPrimitiveValue::CSS_PX);
248     case CSS_PROP_BORDER_RIGHT_WIDTH:
249         return new CSSPrimitiveValueImpl(m_renderer->style()->borderRightWidth(), CSSPrimitiveValue::CSS_PX);
250     case CSS_PROP_BORDER_BOTTOM_WIDTH:
251         return new CSSPrimitiveValueImpl(m_renderer->style()->borderBottomWidth(), CSSPrimitiveValue::CSS_PX);
252     case CSS_PROP_BORDER_LEFT_WIDTH:
253         return new CSSPrimitiveValueImpl(m_renderer->style()->borderLeftWidth(), CSSPrimitiveValue::CSS_PX);
254     case CSS_PROP_BOTTOM:
255         // FIXME: unimplemented
256                 break;
257     case CSS_PROP__KHTML_BOX_ALIGN:
258         // FIXME: unimplemented
259                 break;
260     case CSS_PROP__KHTML_BOX_DIRECTION:
261         // FIXME: unimplemented
262                 break;
263     case CSS_PROP__KHTML_BOX_FLEX:
264         // FIXME: unimplemented
265                 break;
266     case CSS_PROP__KHTML_BOX_FLEX_GROUP:
267         // FIXME: unimplemented
268                 break;
269     case CSS_PROP__KHTML_BOX_LINES:
270         // FIXME: unimplemented
271                 break;
272     case CSS_PROP__KHTML_BOX_ORDINAL_GROUP:
273         // FIXME: unimplemented
274                 break;
275     case CSS_PROP__KHTML_BOX_ORIENT:
276         // FIXME: unimplemented
277                 break;
278     case CSS_PROP__KHTML_BOX_PACK:
279         // FIXME: unimplemented
280                 break;
281     case CSS_PROP_CAPTION_SIDE:
282         // FIXME: unimplemented
283                 break;
284     case CSS_PROP_CLEAR:
285         // FIXME: unimplemented
286                 break;
287     case CSS_PROP_CLIP:
288         // FIXME: unimplemented
289                 break;
290     case CSS_PROP_COLOR:
291         return new CSSPrimitiveValueImpl(m_renderer->style()->color().rgb());
292     case CSS_PROP_CONTENT:
293         // FIXME: unimplemented
294                 break;
295     case CSS_PROP_COUNTER_INCREMENT:
296         // FIXME: unimplemented
297                 break;
298     case CSS_PROP_COUNTER_RESET:
299         // FIXME: unimplemented
300                 break;
301     case CSS_PROP_CURSOR:
302         // FIXME: unimplemented
303                 break;
304     case CSS_PROP_DIRECTION:
305         // FIXME: unimplemented
306                 break;
307     case CSS_PROP_DISPLAY:
308         switch (m_renderer->style()->display()) {
309             case khtml::INLINE:
310                 return new CSSPrimitiveValueImpl("inline", CSSPrimitiveValue::CSS_STRING);
311             case khtml::BLOCK:
312                 return new CSSPrimitiveValueImpl("block", CSSPrimitiveValue::CSS_STRING);
313             case khtml::LIST_ITEM:
314                 return new CSSPrimitiveValueImpl("list-item", CSSPrimitiveValue::CSS_STRING);
315             case khtml::RUN_IN:
316                 return new CSSPrimitiveValueImpl("run-in", CSSPrimitiveValue::CSS_STRING);
317             case khtml::COMPACT:
318                 return new CSSPrimitiveValueImpl("compact", CSSPrimitiveValue::CSS_STRING);
319             case khtml::INLINE_BLOCK:
320                 return new CSSPrimitiveValueImpl("inline-block", CSSPrimitiveValue::CSS_STRING);
321             case khtml::TABLE:
322                 return new CSSPrimitiveValueImpl("table", CSSPrimitiveValue::CSS_STRING);
323             case khtml::INLINE_TABLE:
324                 return new CSSPrimitiveValueImpl("inline-table", CSSPrimitiveValue::CSS_STRING);
325             case khtml::TABLE_ROW_GROUP:
326                 return new CSSPrimitiveValueImpl("table-row-group", CSSPrimitiveValue::CSS_STRING);
327             case khtml::TABLE_HEADER_GROUP:
328                 return new CSSPrimitiveValueImpl("table-header-group", CSSPrimitiveValue::CSS_STRING);
329             case khtml::TABLE_FOOTER_GROUP:
330                 return new CSSPrimitiveValueImpl("table-footer-group", CSSPrimitiveValue::CSS_STRING);
331             case khtml::TABLE_ROW:
332                 return new CSSPrimitiveValueImpl("table-row", CSSPrimitiveValue::CSS_STRING);
333             case khtml::TABLE_COLUMN_GROUP:
334                 return new CSSPrimitiveValueImpl("table-column-group", CSSPrimitiveValue::CSS_STRING);
335             case khtml::TABLE_COLUMN:
336                 return new CSSPrimitiveValueImpl("table-column", CSSPrimitiveValue::CSS_STRING);
337             case khtml::TABLE_CELL:
338                 return new CSSPrimitiveValueImpl("table-cell", CSSPrimitiveValue::CSS_STRING);
339             case khtml::TABLE_CAPTION:
340                 return new CSSPrimitiveValueImpl("table-caption", CSSPrimitiveValue::CSS_STRING);
341             case khtml::BOX:
342                 return new CSSPrimitiveValueImpl("-khtml-box", CSSPrimitiveValue::CSS_STRING);
343             case khtml::INLINE_BOX:
344                 return new CSSPrimitiveValueImpl("-khtml-inline-box", CSSPrimitiveValue::CSS_STRING);
345             case khtml::NONE:
346                 return new CSSPrimitiveValueImpl("none", CSSPrimitiveValue::CSS_STRING);
347             default:
348                 ASSERT_NOT_REACHED();
349         }
350     case CSS_PROP_EMPTY_CELLS:
351         // FIXME: unimplemented
352                 break;
353     case CSS_PROP_FLOAT:
354     {
355         switch (m_renderer->style()->floating()) {
356             case khtml::FNONE:
357                 return new CSSPrimitiveValueImpl("none", CSSPrimitiveValue::CSS_STRING);
358             case khtml::FLEFT:
359                 return new CSSPrimitiveValueImpl("left", CSSPrimitiveValue::CSS_STRING);
360             case khtml::FRIGHT:
361                 return new CSSPrimitiveValueImpl("right", CSSPrimitiveValue::CSS_STRING);
362         }
363     }
364     case CSS_PROP_FONT_FAMILY:
365     {
366         FontDef def = m_renderer->style()->htmlFont().getFontDef();
367         return new CSSPrimitiveValueImpl(def.firstFamily().family().domString(), CSSPrimitiveValue::CSS_STRING);
368     }
369     case CSS_PROP_FONT_SIZE:
370     {
371         FontDef def = m_renderer->style()->htmlFont().getFontDef();
372         return new CSSPrimitiveValueImpl(def.specifiedSize, CSSPrimitiveValue::CSS_PX);
373     }
374     case CSS_PROP_FONT_SIZE_ADJUST:
375         // FIXME: unimplemented
376                 break;
377     case CSS_PROP_FONT_STRETCH:
378         // FIXME: unimplemented
379                 break;
380     case CSS_PROP_FONT_STYLE:
381     {
382         // FIXME: handle oblique
383         FontDef def = m_renderer->style()->htmlFont().getFontDef();
384         if (def.italic)
385             return new CSSPrimitiveValueImpl("italic", CSSPrimitiveValue::CSS_STRING);
386         else
387             return new CSSPrimitiveValueImpl("normal", CSSPrimitiveValue::CSS_STRING);
388     }
389     case CSS_PROP_FONT_VARIANT:
390     {
391         FontDef def = m_renderer->style()->htmlFont().getFontDef();
392         if (def.smallCaps)
393             return new CSSPrimitiveValueImpl("small-caps", CSSPrimitiveValue::CSS_STRING);
394         else
395             return new CSSPrimitiveValueImpl("normal", CSSPrimitiveValue::CSS_STRING);
396     }
397     case CSS_PROP_FONT_WEIGHT:
398     {
399         // FIXME: this does not reflect the full range of weights
400         // that can be expressed with CSS
401         FontDef def = m_renderer->style()->htmlFont().getFontDef();
402         if (def.weight == QFont::Bold)
403             return new CSSPrimitiveValueImpl("bold", CSSPrimitiveValue::CSS_STRING);
404         else
405             return new CSSPrimitiveValueImpl("normal", CSSPrimitiveValue::CSS_STRING);
406     }
407     case CSS_PROP_HEIGHT:
408         return new CSSPrimitiveValueImpl(m_renderer->contentHeight(), CSSPrimitiveValue::CSS_PX);
409     case CSS_PROP_LEFT:
410         // FIXME: unimplemented
411                 break;
412     case CSS_PROP_LETTER_SPACING:
413         if (m_renderer->style()->letterSpacing() == 0)
414             return new CSSPrimitiveValueImpl("normal", CSSPrimitiveValue::CSS_STRING);
415         return new CSSPrimitiveValueImpl(m_renderer->style()->letterSpacing(), CSSPrimitiveValue::CSS_PX);
416     case CSS_PROP_LINE_HEIGHT: {
417         Length length(m_renderer->style()->lineHeight());
418         if (length.isPercent()) {
419             float computedSize = m_renderer->style()->htmlFont().getFontDef().computedSize;
420             return new CSSPrimitiveValueImpl((int)(length.length() * computedSize) / 100, CSSPrimitiveValue::CSS_PX);
421         }
422         else {
423             return new CSSPrimitiveValueImpl(length.length(), CSSPrimitiveValue::CSS_PX);
424         }
425     }
426     case CSS_PROP_LIST_STYLE_IMAGE:
427         // FIXME: unimplemented
428                 break;
429     case CSS_PROP_LIST_STYLE_POSITION:
430         // FIXME: unimplemented
431                 break;
432     case CSS_PROP_LIST_STYLE_TYPE:
433         // FIXME: unimplemented
434                 break;
435     case CSS_PROP_MARGIN_TOP:
436         return valueForLength(m_renderer->style()->marginTop(), m_renderer->contentHeight());
437     case CSS_PROP_MARGIN_RIGHT:
438         return valueForLength(m_renderer->style()->marginRight(), m_renderer->contentWidth());
439     case CSS_PROP_MARGIN_BOTTOM:
440         return valueForLength(m_renderer->style()->marginBottom(), m_renderer->contentHeight());
441     case CSS_PROP_MARGIN_LEFT:
442         return valueForLength(m_renderer->style()->marginLeft(), m_renderer->contentWidth());
443     case CSS_PROP__KHTML_MARQUEE:
444         // FIXME: unimplemented
445                 break;
446     case CSS_PROP__KHTML_MARQUEE_DIRECTION:
447         // FIXME: unimplemented
448                 break;
449     case CSS_PROP__KHTML_MARQUEE_INCREMENT:
450         // FIXME: unimplemented
451                 break;
452     case CSS_PROP__KHTML_MARQUEE_REPETITION:
453         // FIXME: unimplemented
454                 break;
455     case CSS_PROP__KHTML_MARQUEE_SPEED:
456         // FIXME: unimplemented
457                 break;
458     case CSS_PROP__KHTML_MARQUEE_STYLE:
459         // FIXME: unimplemented
460                 break;
461     case CSS_PROP__KHTML_USER_MODIFY:
462         // FIXME: unimplemented
463                 break;
464     case CSS_PROP_MAX_HEIGHT:
465         // FIXME: unimplemented
466                 break;
467     case CSS_PROP_MAX_WIDTH:
468         // FIXME: unimplemented
469                 break;
470     case CSS_PROP_MIN_HEIGHT:
471         // FIXME: unimplemented
472                 break;
473     case CSS_PROP_MIN_WIDTH:
474         // FIXME: unimplemented
475                 break;
476     case CSS_PROP_OPACITY:
477         // FIXME: unimplemented
478                 break;
479     case CSS_PROP_ORPHANS:
480         // FIXME: unimplemented
481                 break;
482         // FIXME: unimplemented
483                 break;
484     case CSS_PROP_OUTLINE_COLOR:
485         // FIXME: unimplemented
486                 break;
487     case CSS_PROP_OUTLINE_OFFSET:
488         // FIXME: unimplemented
489                 break;
490     case CSS_PROP_OUTLINE_STYLE:
491         // FIXME: unimplemented
492                 break;
493     case CSS_PROP_OUTLINE_WIDTH:
494         // FIXME: unimplemented
495                 break;
496     case CSS_PROP_OVERFLOW:
497     {
498         switch (m_renderer->style()->overflow()) {
499             case khtml::OVISIBLE:
500                 return new CSSPrimitiveValueImpl("visible", CSSPrimitiveValue::CSS_STRING);
501             case khtml::OHIDDEN:
502                 return new CSSPrimitiveValueImpl("hidden", CSSPrimitiveValue::CSS_STRING);
503             case khtml::OSCROLL:
504                 return new CSSPrimitiveValueImpl("scroll", CSSPrimitiveValue::CSS_STRING);
505             case khtml::OAUTO:
506                 return new CSSPrimitiveValueImpl("auto", CSSPrimitiveValue::CSS_STRING);
507             case khtml::OMARQUEE:
508                 return new CSSPrimitiveValueImpl("marquee", CSSPrimitiveValue::CSS_STRING);
509             case khtml::OOVERLAY:
510                 return new CSSPrimitiveValueImpl("overlay", CSSPrimitiveValue::CSS_STRING);
511         }
512     }
513     case CSS_PROP_PADDING_TOP:
514         return valueForLength(m_renderer->style()->paddingTop(), m_renderer->contentHeight());
515     case CSS_PROP_PADDING_RIGHT:
516         return valueForLength(m_renderer->style()->paddingRight(), m_renderer->contentWidth());
517     case CSS_PROP_PADDING_BOTTOM:
518         return valueForLength(m_renderer->style()->paddingBottom(), m_renderer->contentHeight());
519     case CSS_PROP_PADDING_LEFT:
520         return valueForLength(m_renderer->style()->paddingLeft(), m_renderer->contentWidth());
521     case CSS_PROP_PAGE:
522         // FIXME: unimplemented
523                 break;
524     case CSS_PROP_PAGE_BREAK_AFTER:
525         // FIXME: unimplemented
526                 break;
527     case CSS_PROP_PAGE_BREAK_BEFORE:
528         // FIXME: unimplemented
529                 break;
530     case CSS_PROP_PAGE_BREAK_INSIDE:
531         // FIXME: unimplemented
532                 break;
533     case CSS_PROP_POSITION:
534         // FIXME: unimplemented
535                 break;
536     case CSS_PROP_QUOTES:
537         // FIXME: unimplemented
538                 break;
539     case CSS_PROP_RIGHT:
540         // FIXME: unimplemented
541                 break;
542     case CSS_PROP_SIZE:
543         // FIXME: unimplemented
544                 break;
545     case CSS_PROP_TABLE_LAYOUT:
546         // FIXME: unimplemented
547                 break;
548     case CSS_PROP_TEXT_ALIGN:
549         return new CSSPrimitiveValueImpl(stringForTextAlign(m_renderer->style()->textAlign()), CSSPrimitiveValue::CSS_STRING);
550     case CSS_PROP_TEXT_DECORATION:
551     {
552         QString string;
553         if (m_renderer->style()->textDecoration() & khtml::UNDERLINE)
554             string += "underline";
555         if (m_renderer->style()->textDecoration() & khtml::OVERLINE) {
556             if (string.length() > 0)
557                 string += " ";
558             string += "overline";
559         }
560         if (m_renderer->style()->textDecoration() & khtml::LINE_THROUGH) {
561             if (string.length() > 0)
562                 string += " ";
563             string += "line-through";
564         }
565         if (m_renderer->style()->textDecoration() & khtml::BLINK) {
566             if (string.length() > 0)
567                 string += " ";
568             string += "blink";
569         }
570         if (string.length() == 0)
571             string = "none";
572         return new CSSPrimitiveValueImpl(string, CSSPrimitiveValue::CSS_STRING);
573     }
574     case CSS_PROP_TEXT_DECORATION_COLOR:
575         // FIXME: unimplemented
576                 break;
577     case CSS_PROP_TEXT_INDENT:
578         return valueForLength(m_renderer->style()->textIndent(), m_renderer->contentWidth());
579     case CSS_PROP_TEXT_SHADOW:
580         // FIXME: unimplemented
581                 break;
582     case CSS_PROP_TEXT_TRANSFORM:
583         // FIXME: unimplemented
584                 break;
585     case CSS_PROP_TOP:
586         // FIXME: unimplemented
587                 break;
588     case CSS_PROP_UNICODE_BIDI:
589         // FIXME: unimplemented
590                 break;
591     case CSS_PROP_VERTICAL_ALIGN:
592     {
593         switch (m_renderer->style()->verticalAlign()) {
594             case khtml::BASELINE:
595                 return new CSSPrimitiveValueImpl("baseline", CSSPrimitiveValue::CSS_STRING);
596             case khtml::MIDDLE:
597                 return new CSSPrimitiveValueImpl("middle", CSSPrimitiveValue::CSS_STRING);
598             case khtml::SUB:
599                 return new CSSPrimitiveValueImpl("sub", CSSPrimitiveValue::CSS_STRING);
600             case khtml::SUPER:
601                 return new CSSPrimitiveValueImpl("super", CSSPrimitiveValue::CSS_STRING);
602             case khtml::TEXT_TOP:
603                 return new CSSPrimitiveValueImpl("text-top", CSSPrimitiveValue::CSS_STRING);
604             case khtml::TEXT_BOTTOM:
605                 return new CSSPrimitiveValueImpl("text-bottom", CSSPrimitiveValue::CSS_STRING);
606             case khtml::TOP:
607                 return new CSSPrimitiveValueImpl("top", CSSPrimitiveValue::CSS_STRING);
608             case khtml::BOTTOM:
609                 return new CSSPrimitiveValueImpl("bottom", CSSPrimitiveValue::CSS_STRING);
610             case khtml::BASELINE_MIDDLE:
611                 return new CSSPrimitiveValueImpl("baseline-middle", CSSPrimitiveValue::CSS_STRING);
612             case khtml::LENGTH:
613                 return valueForLength(m_renderer->style()->verticalAlignLength(), m_renderer->contentWidth());
614         }
615     }
616     case CSS_PROP_VISIBILITY:
617         // FIXME: unimplemented
618                 break;
619     case CSS_PROP_WHITE_SPACE:
620     {
621         switch (m_renderer->style()->whiteSpace()) {
622             case khtml::NORMAL:
623                 return new CSSPrimitiveValueImpl("normal", CSSPrimitiveValue::CSS_STRING);
624             case khtml::PRE:
625                 return new CSSPrimitiveValueImpl("pre", CSSPrimitiveValue::CSS_STRING);
626             case khtml::NOWRAP:
627                 return new CSSPrimitiveValueImpl("nowrap", CSSPrimitiveValue::CSS_STRING);
628             case khtml::KHTML_NOWRAP:
629                 return new CSSPrimitiveValueImpl("-khtml-nowrap", CSSPrimitiveValue::CSS_STRING);
630         }
631     }
632     case CSS_PROP_WIDOWS:
633         // FIXME: unimplemented
634                 break;
635     case CSS_PROP_WIDTH:
636         return new CSSPrimitiveValueImpl(m_renderer->contentWidth(), CSSPrimitiveValue::CSS_PX);
637     case CSS_PROP_WORD_SPACING:
638         return new CSSPrimitiveValueImpl(m_renderer->style()->wordSpacing(), CSSPrimitiveValue::CSS_PX);
639     case CSS_PROP_Z_INDEX:
640         // FIXME: unimplemented
641                 break;
642     case CSS_PROP_BACKGROUND:
643         // FIXME: unimplemented
644                 break;
645     case CSS_PROP_BORDER:
646         // FIXME: unimplemented
647                 break;
648     case CSS_PROP_BORDER_COLOR:
649         // FIXME: unimplemented
650                 break;
651     case CSS_PROP_BORDER_STYLE:
652         // FIXME: unimplemented
653                 break;
654     case CSS_PROP_BORDER_TOP:
655         // FIXME: unimplemented
656                 break;
657     case CSS_PROP_BORDER_RIGHT:
658         // FIXME: unimplemented
659                 break;
660     case CSS_PROP_BORDER_BOTTOM:
661         // FIXME: unimplemented
662                 break;
663     case CSS_PROP_BORDER_LEFT:
664         // FIXME: unimplemented
665                 break;
666     case CSS_PROP_BORDER_WIDTH:
667         // FIXME: unimplemented
668                 break;
669     case CSS_PROP_FONT:
670         // FIXME: unimplemented
671                 break;
672     case CSS_PROP_LIST_STYLE:
673         // FIXME: unimplemented
674                 break;
675     case CSS_PROP_MARGIN:
676         // FIXME: unimplemented
677                 break;
678     case CSS_PROP_OUTLINE:
679         // FIXME: unimplemented
680                 break;
681     case CSS_PROP_PADDING:
682         // FIXME: unimplemented
683                 break;
684 #if !APPLE_CHANGES
685     case CSS_PROP_SCROLLBAR_FACE_COLOR:
686         // FIXME: unimplemented
687                 break;
688     case CSS_PROP_SCROLLBAR_SHADOW_COLOR:
689         // FIXME: unimplemented
690                 break;
691     case CSS_PROP_SCROLLBAR_HIGHLIGHT_COLOR:
692         // FIXME: unimplemented
693                 break;
694     case CSS_PROP_SCROLLBAR_3DLIGHT_COLOR:
695         // FIXME: unimplemented
696                 break;
697     case CSS_PROP_SCROLLBAR_DARKSHADOW_COLOR:
698         // FIXME: unimplemented
699                 break;
700     case CSS_PROP_SCROLLBAR_TRACK_COLOR:
701         // FIXME: unimplemented
702                 break;
703     case CSS_PROP_SCROLLBAR_ARROW_COLOR:
704         // FIXME: unimplemented
705                 break;
706 #endif
707     case CSS_PROP__KHTML_FLOW_MODE:
708         // FIXME: unimplemented
709                 break;
710     default:
711         break;
712     }
713     ERROR("unimplemented propertyID: %d", propertyID);
714     return 0;
715 }
716
717 DOMString CSSComputedStyleDeclarationImpl::getPropertyValue(int propertyID) const
718 {
719     CSSValueImpl* value = getPropertyCSSValue(propertyID);
720     if (value)
721         return value->cssText();
722     return "";
723 }
724
725 bool CSSComputedStyleDeclarationImpl::getPropertyPriority(int) const
726 {
727     // This class does not support the notion of priority, since the object
728     // is a computed value.
729     return false;
730 }
731
732 DOMString CSSComputedStyleDeclarationImpl::removeProperty(int)
733 {
734     ASSERT_NOT_REACHED();
735     return DOMString();
736 }
737
738 bool CSSComputedStyleDeclarationImpl::setProperty(int, const DOMString &, bool)
739 {
740     ASSERT_NOT_REACHED();
741     return false;
742 }
743
744 void CSSComputedStyleDeclarationImpl::setProperty(int, int, bool)
745 {
746     ASSERT_NOT_REACHED();
747 }
748
749 void CSSComputedStyleDeclarationImpl::setLengthProperty(int, const DOMString&, bool, bool)
750 {
751     ASSERT_NOT_REACHED();
752 }
753
754 void CSSComputedStyleDeclarationImpl::setProperty(const DOMString &)
755 {
756     ASSERT_NOT_REACHED();
757 }
758
759 DOMString CSSComputedStyleDeclarationImpl::item(unsigned long) const
760 {
761     ERROR("unimplemented");
762     return DOMString();
763 }
764
765
766 CSSProperty CSSComputedStyleDeclarationImpl::property(int id) const
767 {
768     CSSProperty prop;
769     prop.m_id = id;
770     prop.m_bImportant = false;
771     prop.setValue(getPropertyCSSValue(id));
772     return prop;
773 }
774
775 CSSStyleDeclarationImpl *CSSComputedStyleDeclarationImpl::copyInheritableProperties() const
776 {
777     QPtrList<CSSProperty> *list = new QPtrList<CSSProperty>;
778     list->setAutoDelete(true);
779     for (unsigned i = 0; i < sizeof(InheritableProperties) / sizeof(InheritableProperties[0]); i++) {
780         CSSValueImpl *value = getPropertyCSSValue(InheritableProperties[i]);
781         if (value) {
782             CSSProperty *property = new CSSProperty;
783             property->m_id = InheritableProperties[i];
784             property->setValue(value);
785             list->append(property);
786         }
787     }
788     return new CSSStyleDeclarationImpl(0, list);
789 }
790
791 void CSSComputedStyleDeclarationImpl::diff(CSSStyleDeclarationImpl *style) const
792 {
793     if (!style)
794         return;
795
796     QValueList<int> properties;
797     for (QPtrListIterator<CSSProperty> it(*style->values()); it.current(); ++it) {
798         CSSProperty *property = it.current();
799         CSSValueImpl *value = getPropertyCSSValue(property->id());
800         if (value && value->cssText() == property->value()->cssText()) {
801             properties.append(property->id());
802         }
803     }
804     
805     for (QValueListIterator<int> it(properties.begin()); it != properties.end(); ++it)
806         style->removeProperty(*it);
807 }
808
809 } // namespace DOM