fix logic
[personal-kdelibs.git] / khtml / html / html_blockimpl.cpp
blob1021e1bd207b5683605a4fa7c9555f1e0ff79cc3
1 /**
2 * This file is part of the DOM implementation for KDE.
4 * Copyright (C) 1999-2003 Lars Knoll (knoll@kde.org)
5 * (C) 1999 Antti Koivisto (koivisto@kde.org)
6 * (C) 2003 Apple Computer, Inc.
7 * (C) 2004 Allan Sandfeld Jensen (kde@carewolf.com)
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Library General Public License for more details.
19 * You should have received a copy of the GNU Library General Public License
20 * along with this library; see the file COPYING.LIB. If not, write to
21 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 * Boston, MA 02110-1301, USA.
25 // -------------------------------------------------------------------------
26 //#define DEBUG
27 #include "html_blockimpl.h"
28 #include "html_documentimpl.h"
29 #include "css/cssstyleselector.h"
31 #include "css/cssproperties.h"
32 #include "css/cssvalues.h"
33 #include "misc/htmlhashes.h"
35 #include <kdebug.h>
37 using namespace khtml;
38 using namespace DOM;
40 void HTMLDivElementImpl::parseAttribute(AttributeImpl *attr)
42 switch(attr->id())
44 case ATTR_ALIGN:
46 DOMString v = attr->value().lower();
47 if ( strcmp( v, "middle" ) == 0 || strcmp( v, "center" ) == 0 )
48 addCSSProperty(CSS_PROP_TEXT_ALIGN, CSS_VAL__KHTML_CENTER);
49 else if (strcmp(v, "left") == 0)
50 addCSSProperty(CSS_PROP_TEXT_ALIGN, CSS_VAL__KHTML_LEFT);
51 else if (strcmp(v, "right") == 0)
52 addCSSProperty(CSS_PROP_TEXT_ALIGN, CSS_VAL__KHTML_RIGHT);
53 else
54 addCSSProperty(CSS_PROP_TEXT_ALIGN, v);
55 break;
57 default:
58 HTMLElementImpl::parseAttribute(attr);
62 // -------------------------------------------------------------------------
64 NodeImpl::Id HTMLHRElementImpl::id() const
66 return ID_HR;
69 void HTMLHRElementImpl::parseAttribute(AttributeImpl *attr)
71 switch( attr->id() )
73 case ATTR_ALIGN: {
74 if (strcasecmp(attr->value(), "left") == 0) {
75 addCSSProperty(CSS_PROP_MARGIN_LEFT, "0");
76 addCSSProperty(CSS_PROP_MARGIN_RIGHT, CSS_VAL_AUTO);
78 else if (strcasecmp(attr->value(), "right") == 0) {
79 addCSSProperty(CSS_PROP_MARGIN_LEFT, CSS_VAL_AUTO);
80 addCSSProperty(CSS_PROP_MARGIN_RIGHT, "0");
82 else {
83 addCSSProperty(CSS_PROP_MARGIN_LEFT, CSS_VAL_AUTO);
84 addCSSProperty(CSS_PROP_MARGIN_RIGHT, CSS_VAL_AUTO);
86 break;
88 case ATTR_WIDTH:
90 if(!attr->val()) break;
91 // cheap hack to cause linebreaks
92 // khtmltests/html/strange_hr.html
93 bool ok;
94 int v = attr->val()->toInt(&ok);
95 if(ok && !v)
96 addCSSLength(CSS_PROP_WIDTH, "1");
97 else
98 addCSSLength(CSS_PROP_WIDTH, attr->value());
100 break;
101 default:
102 HTMLElementImpl::parseAttribute(attr);
106 // ### make sure we undo what we did during detach
107 void HTMLHRElementImpl::attach()
109 if (attributes(true /* readonly */)) {
110 // there are some attributes, lets check
111 DOMString color = getAttribute(ATTR_COLOR);
112 DOMStringImpl* si = getAttribute(ATTR_SIZE).implementation();
113 int _s = si ? si->toInt() : -1;
114 DOMString n("1");
115 if (!color.isNull()) {
116 addCSSProperty(CSS_PROP_BORDER_TOP_STYLE, CSS_VAL_SOLID);
117 addCSSProperty(CSS_PROP_BORDER_RIGHT_STYLE, CSS_VAL_SOLID);
118 addCSSProperty(CSS_PROP_BORDER_BOTTOM_STYLE, CSS_VAL_SOLID);
119 addCSSProperty(CSS_PROP_BORDER_LEFT_STYLE, CSS_VAL_SOLID);
120 addCSSProperty(CSS_PROP_BORDER_TOP_WIDTH, DOMString("0"));
121 addCSSLength(CSS_PROP_BORDER_BOTTOM_WIDTH, DOMString(si));
122 addHTMLColor(CSS_PROP_BORDER_COLOR, color);
124 else {
125 if (_s > 1 && getAttribute(ATTR_NOSHADE).isNull()) {
126 addCSSProperty(CSS_PROP_BORDER_BOTTOM_WIDTH, n);
127 addCSSProperty(CSS_PROP_BORDER_TOP_WIDTH, n);
128 addCSSProperty(CSS_PROP_BORDER_LEFT_WIDTH, n);
129 addCSSProperty(CSS_PROP_BORDER_RIGHT_WIDTH, n);
130 addCSSLength(CSS_PROP_HEIGHT, DOMString(QString::number(_s-2)));
132 else if (_s >= 0) {
133 addCSSProperty(CSS_PROP_BORDER_TOP_WIDTH, DOMString(QString::number(_s)));
134 addCSSProperty(CSS_PROP_BORDER_BOTTOM_WIDTH, DOMString("0"));
137 if (_s == 0)
138 addCSSProperty(CSS_PROP_MARGIN_BOTTOM, n);
141 HTMLElementImpl::attach();
144 // -------------------------------------------------------------------------
146 long HTMLPreElementImpl::width() const
148 // ###
149 return 0;
152 void HTMLPreElementImpl::setWidth( long /*w*/ )
154 // ###
157 // -------------------------------------------------------------------------
159 // WinIE uses 60ms as the minimum delay by default.
160 const int defaultMinimumDelay = 60;
162 HTMLMarqueeElementImpl::HTMLMarqueeElementImpl(DocumentImpl *doc)
163 : HTMLElementImpl(doc),
164 m_minimumDelay(defaultMinimumDelay)
168 NodeImpl::Id HTMLMarqueeElementImpl::id() const
170 return ID_MARQUEE;
173 void HTMLMarqueeElementImpl::parseAttribute(AttributeImpl *attr)
175 switch(attr->id())
177 case ATTR_WIDTH:
178 if (!attr->value().isEmpty())
179 addCSSLength(CSS_PROP_WIDTH, attr->value());
180 else
181 removeCSSProperty(CSS_PROP_WIDTH);
182 break;
183 case ATTR_HEIGHT:
184 if (!attr->value().isEmpty())
185 addCSSLength(CSS_PROP_HEIGHT, attr->value());
186 else
187 removeCSSProperty(CSS_PROP_HEIGHT);
188 break;
189 case ATTR_BGCOLOR:
190 if (!attr->value().isEmpty())
191 addHTMLColor(CSS_PROP_BACKGROUND_COLOR, attr->value());
192 else
193 removeCSSProperty(CSS_PROP_BACKGROUND_COLOR);
194 break;
195 case ATTR_VSPACE:
196 if (!attr->value().isEmpty()) {
197 addCSSLength(CSS_PROP_MARGIN_TOP, attr->value());
198 addCSSLength(CSS_PROP_MARGIN_BOTTOM, attr->value());
200 else {
201 removeCSSProperty(CSS_PROP_MARGIN_TOP);
202 removeCSSProperty(CSS_PROP_MARGIN_BOTTOM);
204 break;
205 case ATTR_HSPACE:
206 if (!attr->value().isEmpty()) {
207 addCSSLength(CSS_PROP_MARGIN_LEFT, attr->value());
208 addCSSLength(CSS_PROP_MARGIN_RIGHT, attr->value());
210 else {
211 removeCSSProperty(CSS_PROP_MARGIN_LEFT);
212 removeCSSProperty(CSS_PROP_MARGIN_RIGHT);
214 break;
215 case ATTR_SCROLLAMOUNT:
216 if (!attr->value().isEmpty())
217 addCSSLength(CSS_PROP__KHTML_MARQUEE_INCREMENT, attr->value());
218 else
219 removeCSSProperty(CSS_PROP__KHTML_MARQUEE_INCREMENT);
220 break;
221 case ATTR_SCROLLDELAY:
222 if (!attr->value().isEmpty())
223 addCSSLength(CSS_PROP__KHTML_MARQUEE_SPEED, attr->value(), true);
224 else
225 removeCSSProperty(CSS_PROP__KHTML_MARQUEE_SPEED);
226 break;
227 case ATTR_LOOP:
228 if (!attr->value().isEmpty()) {
229 if (attr->value() == "-1" || strcasecmp(attr->value(), "infinite") == 0)
230 addCSSProperty(CSS_PROP__KHTML_MARQUEE_REPETITION, CSS_VAL_INFINITE);
231 else
232 addCSSLength(CSS_PROP__KHTML_MARQUEE_REPETITION, attr->value().lower(), true);
234 else
235 removeCSSProperty(CSS_PROP__KHTML_MARQUEE_REPETITION);
236 break;
237 case ATTR_BEHAVIOR:
238 if (!attr->value().isEmpty())
239 addCSSProperty(CSS_PROP__KHTML_MARQUEE_STYLE, attr->value().lower());
240 else
241 removeCSSProperty(CSS_PROP__KHTML_MARQUEE_STYLE);
242 break;
243 case ATTR_DIRECTION:
244 if (!attr->value().isEmpty())
245 addCSSProperty(CSS_PROP__KHTML_MARQUEE_DIRECTION, attr->value().lower());
246 else
247 removeCSSProperty(CSS_PROP__KHTML_MARQUEE_DIRECTION);
248 break;
249 case ATTR_TRUESPEED:
250 m_minimumDelay = attr->val() ? 0 : defaultMinimumDelay;
251 break;
252 default:
253 HTMLElementImpl::parseAttribute(attr);
257 // ------------------------------------------------------------------------
259 HTMLLayerElementImpl::HTMLLayerElementImpl(DocumentImpl *doc, ushort _tagid)
260 : HTMLDivElementImpl( doc, _tagid )
262 transparent = fixed = false;
265 void HTMLLayerElementImpl::parseAttribute(AttributeImpl *attr)
267 // Layers are evil
268 // They are mainly implemented here to correctly parse the hidden attribute
269 switch(attr->id()) {
270 case ATTR_LEFT:
271 addCSSProperty(CSS_PROP_LEFT, attr->value());
272 break;
273 case ATTR_TOP:
274 addCSSProperty(CSS_PROP_TOP, attr->value());
275 break;
276 case ATTR_PAGEX:
277 if (!transparent && !fixed) {
278 addCSSProperty(CSS_PROP_POSITION, CSS_VAL_FIXED);
279 fixed = true;
281 addCSSProperty(CSS_PROP_LEFT, attr->value());
282 break;
283 case ATTR_PAGEY:
284 if (!transparent && !fixed) {
285 addCSSProperty(CSS_PROP_POSITION, CSS_VAL_FIXED);
286 fixed = true;
288 addCSSProperty(CSS_PROP_TOP, attr->value());
289 break;
290 case ATTR_WIDTH:
291 if (!attr->value().isEmpty())
292 addCSSLength(CSS_PROP_WIDTH, attr->value());
293 else
294 removeCSSProperty(CSS_PROP_WIDTH);
295 break;
296 case ATTR_HEIGHT:
297 if (!attr->value().isEmpty())
298 addCSSLength(CSS_PROP_HEIGHT, attr->value());
299 else
300 removeCSSProperty(CSS_PROP_HEIGHT);
301 break;
302 case ATTR_BGCOLOR:
303 if (!attr->value().isEmpty())
304 addHTMLColor(CSS_PROP_BACKGROUND_COLOR, attr->value());
305 else
306 removeCSSProperty(CSS_PROP_BACKGROUND_COLOR);
307 break;
308 case ATTR_Z_INDEX:
309 if (!attr->value().isEmpty())
310 addCSSProperty(CSS_PROP_Z_INDEX, attr->value());
311 else
312 removeCSSProperty(CSS_PROP_Z_INDEX);
313 break;
314 case ATTR_VISIBILITY:
315 if (attr->value().lower() == "show")
316 addCSSProperty(CSS_PROP_VISIBILITY, CSS_VAL_VISIBLE);
317 else if (attr->value().lower() == "hide")
318 addCSSProperty(CSS_PROP_VISIBILITY, CSS_VAL_HIDDEN);
319 else if (attr->value().lower() == "inherit")
320 addCSSProperty(CSS_PROP_VISIBILITY, CSS_VAL_INHERIT);
321 break;
322 case ATTR_NAME:
323 if (id() == ID_LAYER && inDocument() && m_name != attr->value()) {
324 document()->underDocNamedCache().remove(m_name.string(), this);
325 document()->underDocNamedCache().add (attr->value().string(), this);
327 //fallthrough
328 default:
329 HTMLElementImpl::parseAttribute(attr);
333 void HTMLLayerElementImpl::removedFromDocument()
335 if (id() == ID_LAYER)
336 document()->underDocNamedCache().remove(m_name.string(), this);
337 HTMLDivElementImpl::removedFromDocument();
340 void HTMLLayerElementImpl::insertedIntoDocument()
342 if (id() == ID_LAYER)
343 document()->underDocNamedCache().add(m_name.string(), this);
344 HTMLDivElementImpl::insertedIntoDocument();
347 void HTMLLayerElementImpl::removeId(const QString& id)
349 document()->underDocNamedCache().remove(id, this);
350 HTMLDivElementImpl::removeId(id);
353 void HTMLLayerElementImpl::addId (const QString& id)
355 document()->underDocNamedCache().add(id, this);
356 HTMLDivElementImpl::addId(id);
361 NodeImpl *HTMLLayerElementImpl::addChild(NodeImpl *child)
363 NodeImpl *retval = HTMLDivElementImpl::addChild(child);
364 // When someone adds standard layers, we make sure not to interfere
365 if (retval && retval->id() == ID_DIV) {
366 if (!transparent)
367 addCSSProperty(CSS_PROP_POSITION, CSS_VAL_STATIC);
368 transparent = true;
370 return retval;