KHtml

html_blockimpl.cpp
1 /**
2  * This file is part of the DOM implementation for KDE.
3  *
4  * Copyright (C) 1999-2003 Lars Knoll ([email protected])
5  * (C) 1999 Antti Koivisto ([email protected])
6  * (C) 2003 Apple Computer, Inc.
7  * (C) 2004 Allan Sandfeld Jensen ([email protected])
8  *
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.
13  *
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.
18  *
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.
23  *
24  */
25 // -------------------------------------------------------------------------
26 //#define DEBUG
27 #include "html_blockimpl.h"
28 #include "html_documentimpl.h"
29 #include "css/cssstyleselector.h"
30 
31 #include "css/cssproperties.h"
32 #include "css/cssvalues.h"
33 
34 using namespace khtml;
35 using namespace DOM;
36 
37 void HTMLDivElementImpl::parseAttribute(AttributeImpl *attr)
38 {
39  switch (attr->id()) {
40  case ATTR_ALIGN: {
41  DOMString v = attr->value().lower();
42  if (strcmp(v, "middle") == 0 || strcmp(v, "center") == 0) {
43  addCSSProperty(CSS_PROP_TEXT_ALIGN, CSS_VAL__KHTML_CENTER);
44  } else if (strcmp(v, "left") == 0) {
45  addCSSProperty(CSS_PROP_TEXT_ALIGN, CSS_VAL__KHTML_LEFT);
46  } else if (strcmp(v, "right") == 0) {
47  addCSSProperty(CSS_PROP_TEXT_ALIGN, CSS_VAL__KHTML_RIGHT);
48  } else {
49  addCSSProperty(CSS_PROP_TEXT_ALIGN, v);
50  }
51  break;
52  }
53  default:
54  HTMLElementImpl::parseAttribute(attr);
55  }
56 }
57 
58 // -------------------------------------------------------------------------
59 
60 NodeImpl::Id HTMLHRElementImpl::id() const
61 {
62  return ID_HR;
63 }
64 
65 void HTMLHRElementImpl::parseAttribute(AttributeImpl *attr)
66 {
67  switch (attr->id()) {
68  case ATTR_ALIGN: {
69  if (strcasecmp(attr->value(), "left") == 0) {
70  addCSSProperty(CSS_PROP_MARGIN_LEFT, "0");
71  addCSSProperty(CSS_PROP_MARGIN_RIGHT, CSS_VAL_AUTO);
72  } else if (strcasecmp(attr->value(), "right") == 0) {
73  addCSSProperty(CSS_PROP_MARGIN_LEFT, CSS_VAL_AUTO);
74  addCSSProperty(CSS_PROP_MARGIN_RIGHT, "0");
75  } else {
76  addCSSProperty(CSS_PROP_MARGIN_LEFT, CSS_VAL_AUTO);
77  addCSSProperty(CSS_PROP_MARGIN_RIGHT, CSS_VAL_AUTO);
78  }
79  break;
80  }
81  case ATTR_WIDTH: {
82  if (!attr->val()) {
83  break;
84  }
85  // cheap hack to cause linebreaks
86  // khtmltests/html/strange_hr.html
87  bool ok;
88  int v = attr->val()->toInt(&ok);
89  if (ok && !v) {
90  addCSSLength(CSS_PROP_WIDTH, "1");
91  } else {
92  addCSSLength(CSS_PROP_WIDTH, attr->value());
93  }
94  }
95  break;
96  default:
97  HTMLElementImpl::parseAttribute(attr);
98  }
99 }
100 
101 // ### make sure we undo what we did during detach
102 void HTMLHRElementImpl::attach()
103 {
104  if (attributes(true /* readonly */)) {
105  // there are some attributes, lets check
106  DOMString color = getAttribute(ATTR_COLOR);
107  DOMStringImpl *si = getAttribute(ATTR_SIZE).implementation();
108  int _s = si ? si->toInt() : -1;
109  DOMString n("1");
110  if (!color.isNull()) {
111  addCSSProperty(CSS_PROP_BORDER_TOP_STYLE, CSS_VAL_SOLID);
112  addCSSProperty(CSS_PROP_BORDER_RIGHT_STYLE, CSS_VAL_SOLID);
113  addCSSProperty(CSS_PROP_BORDER_BOTTOM_STYLE, CSS_VAL_SOLID);
114  addCSSProperty(CSS_PROP_BORDER_LEFT_STYLE, CSS_VAL_SOLID);
115  addCSSProperty(CSS_PROP_BORDER_TOP_WIDTH, DOMString("0"));
116  addCSSLength(CSS_PROP_BORDER_BOTTOM_WIDTH, DOMString(si));
117  addHTMLColor(CSS_PROP_BORDER_COLOR, color);
118  } else {
119  if (_s > 1 && getAttribute(ATTR_NOSHADE).isNull()) {
120  addCSSProperty(CSS_PROP_BORDER_BOTTOM_WIDTH, n);
121  addCSSProperty(CSS_PROP_BORDER_TOP_WIDTH, n);
122  addCSSProperty(CSS_PROP_BORDER_LEFT_WIDTH, n);
123  addCSSProperty(CSS_PROP_BORDER_RIGHT_WIDTH, n);
124  addCSSLength(CSS_PROP_HEIGHT, DOMString(QString::number(_s - 2)));
125  } else if (_s >= 0) {
126  addCSSProperty(CSS_PROP_BORDER_TOP_WIDTH, DOMString(QString::number(_s)));
127  addCSSProperty(CSS_PROP_BORDER_BOTTOM_WIDTH, DOMString("0"));
128  }
129  }
130  if (_s == 0) {
131  addCSSProperty(CSS_PROP_MARGIN_BOTTOM, n);
132  }
133  }
134 
135  HTMLElementImpl::attach();
136 }
137 
138 // -------------------------------------------------------------------------
139 
140 long HTMLPreElementImpl::width() const
141 {
142  // ###
143  return 0;
144 }
145 
146 void HTMLPreElementImpl::setWidth(long /*w*/)
147 {
148  // ###
149 }
150 
151 // -------------------------------------------------------------------------
152 
153 // WinIE uses 60ms as the minimum delay by default.
154 const int defaultMinimumDelay = 60;
155 
156 HTMLMarqueeElementImpl::HTMLMarqueeElementImpl(DocumentImpl *doc)
157  : HTMLElementImpl(doc),
158  m_minimumDelay(defaultMinimumDelay)
159 {
160 }
161 
162 NodeImpl::Id HTMLMarqueeElementImpl::id() const
163 {
164  return ID_MARQUEE;
165 }
166 
167 void HTMLMarqueeElementImpl::parseAttribute(AttributeImpl *attr)
168 {
169  switch (attr->id()) {
170  case ATTR_WIDTH:
171  if (!attr->value().isEmpty()) {
172  addCSSLength(CSS_PROP_WIDTH, attr->value());
173  } else {
174  removeCSSProperty(CSS_PROP_WIDTH);
175  }
176  break;
177  case ATTR_HEIGHT:
178  if (!attr->value().isEmpty()) {
179  addCSSLength(CSS_PROP_HEIGHT, attr->value());
180  } else {
181  removeCSSProperty(CSS_PROP_HEIGHT);
182  }
183  break;
184  case ATTR_BGCOLOR:
185  if (!attr->value().isEmpty()) {
186  addHTMLColor(CSS_PROP_BACKGROUND_COLOR, attr->value());
187  } else {
188  removeCSSProperty(CSS_PROP_BACKGROUND_COLOR);
189  }
190  break;
191  case ATTR_VSPACE:
192  if (!attr->value().isEmpty()) {
193  addCSSLength(CSS_PROP_MARGIN_TOP, attr->value());
194  addCSSLength(CSS_PROP_MARGIN_BOTTOM, attr->value());
195  } else {
196  removeCSSProperty(CSS_PROP_MARGIN_TOP);
197  removeCSSProperty(CSS_PROP_MARGIN_BOTTOM);
198  }
199  break;
200  case ATTR_HSPACE:
201  if (!attr->value().isEmpty()) {
202  addCSSLength(CSS_PROP_MARGIN_LEFT, attr->value());
203  addCSSLength(CSS_PROP_MARGIN_RIGHT, attr->value());
204  } else {
205  removeCSSProperty(CSS_PROP_MARGIN_LEFT);
206  removeCSSProperty(CSS_PROP_MARGIN_RIGHT);
207  }
208  break;
209  case ATTR_SCROLLAMOUNT:
210  if (!attr->value().isEmpty()) {
211  addCSSLength(CSS_PROP__KHTML_MARQUEE_INCREMENT, attr->value());
212  } else {
213  removeCSSProperty(CSS_PROP__KHTML_MARQUEE_INCREMENT);
214  }
215  break;
216  case ATTR_SCROLLDELAY:
217  if (!attr->value().isEmpty()) {
218  addCSSLength(CSS_PROP__KHTML_MARQUEE_SPEED, attr->value(), true);
219  } else {
220  removeCSSProperty(CSS_PROP__KHTML_MARQUEE_SPEED);
221  }
222  break;
223  case ATTR_LOOP:
224  if (!attr->value().isEmpty()) {
225  if (attr->value() == "-1" || strcasecmp(attr->value(), "infinite") == 0) {
226  addCSSProperty(CSS_PROP__KHTML_MARQUEE_REPETITION, CSS_VAL_INFINITE);
227  } else {
228  addCSSLength(CSS_PROP__KHTML_MARQUEE_REPETITION, attr->value().lower(), true);
229  }
230  } else {
231  removeCSSProperty(CSS_PROP__KHTML_MARQUEE_REPETITION);
232  }
233  break;
234  case ATTR_BEHAVIOR:
235  if (!attr->value().isEmpty()) {
236  addCSSProperty(CSS_PROP__KHTML_MARQUEE_STYLE, attr->value().lower());
237  } else {
238  removeCSSProperty(CSS_PROP__KHTML_MARQUEE_STYLE);
239  }
240  break;
241  case ATTR_DIRECTION:
242  if (!attr->value().isEmpty()) {
243  addCSSProperty(CSS_PROP__KHTML_MARQUEE_DIRECTION, attr->value().lower());
244  } else {
245  removeCSSProperty(CSS_PROP__KHTML_MARQUEE_DIRECTION);
246  }
247  break;
248  case ATTR_TRUESPEED:
249  m_minimumDelay = attr->val() ? 0 : defaultMinimumDelay;
250  break;
251  default:
252  HTMLElementImpl::parseAttribute(attr);
253  }
254 }
255 
256 // ------------------------------------------------------------------------
257 
258 HTMLLayerElementImpl::HTMLLayerElementImpl(DocumentImpl *doc, ushort _tagid)
259  : HTMLDivElementImpl(doc, _tagid)
260 {
261  transparent = fixed = false;
262 }
263 
264 void HTMLLayerElementImpl::parseAttribute(AttributeImpl *attr)
265 {
266  // Layers are evil
267  // They are mainly implemented here to correctly parse the hidden attribute
268  switch (attr->id()) {
269  case ATTR_LEFT:
270  addCSSProperty(CSS_PROP_LEFT, attr->value());
271  break;
272  case ATTR_TOP:
273  addCSSProperty(CSS_PROP_TOP, attr->value());
274  break;
275  case ATTR_PAGEX:
276  if (!transparent && !fixed) {
277  addCSSProperty(CSS_PROP_POSITION, CSS_VAL_FIXED);
278  fixed = true;
279  }
280  addCSSProperty(CSS_PROP_LEFT, attr->value());
281  break;
282  case ATTR_PAGEY:
283  if (!transparent && !fixed) {
284  addCSSProperty(CSS_PROP_POSITION, CSS_VAL_FIXED);
285  fixed = true;
286  }
287  addCSSProperty(CSS_PROP_TOP, attr->value());
288  break;
289  case ATTR_WIDTH:
290  if (!attr->value().isEmpty()) {
291  addCSSLength(CSS_PROP_WIDTH, attr->value());
292  } else {
293  removeCSSProperty(CSS_PROP_WIDTH);
294  }
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  }
302  break;
303  case ATTR_BGCOLOR:
304  if (!attr->value().isEmpty()) {
305  addHTMLColor(CSS_PROP_BACKGROUND_COLOR, attr->value());
306  } else {
307  removeCSSProperty(CSS_PROP_BACKGROUND_COLOR);
308  }
309  break;
310  case ATTR_Z_INDEX:
311  if (!attr->value().isEmpty()) {
312  addCSSProperty(CSS_PROP_Z_INDEX, attr->value());
313  } else {
314  removeCSSProperty(CSS_PROP_Z_INDEX);
315  }
316  break;
317  case ATTR_VISIBILITY:
318  if (attr->value().lower() == "show") {
319  addCSSProperty(CSS_PROP_VISIBILITY, CSS_VAL_VISIBLE);
320  } else if (attr->value().lower() == "hide") {
321  addCSSProperty(CSS_PROP_VISIBILITY, CSS_VAL_HIDDEN);
322  } else if (attr->value().lower() == "inherit") {
323  addCSSProperty(CSS_PROP_VISIBILITY, CSS_VAL_INHERIT);
324  }
325  break;
326  case ATTR_NAME:
327  if (id() == ID_LAYER && inDocument() && m_name != attr->value()) {
328  document()->underDocNamedCache().remove(m_name, this);
329  document()->underDocNamedCache().add(attr->value(), this);
330  }
331  //fallthrough
332  default:
333  HTMLElementImpl::parseAttribute(attr);
334  }
335 }
336 
337 void HTMLLayerElementImpl::removedFromDocument()
338 {
339  if (id() == ID_LAYER) {
340  document()->underDocNamedCache().remove(m_name, this);
341  }
342  HTMLDivElementImpl::removedFromDocument();
343 }
344 
345 void HTMLLayerElementImpl::insertedIntoDocument()
346 {
347  if (id() == ID_LAYER) {
348  document()->underDocNamedCache().add(m_name, this);
349  }
350  HTMLDivElementImpl::insertedIntoDocument();
351 }
352 
353 void HTMLLayerElementImpl::removeId(const DOMString &id)
354 {
355  document()->underDocNamedCache().remove(id, this);
356  HTMLDivElementImpl::removeId(id);
357 }
358 
359 void HTMLLayerElementImpl::addId(const DOMString &id)
360 {
361  document()->underDocNamedCache().add(id, this);
362  HTMLDivElementImpl::addId(id);
363 }
364 
365 NodeImpl *HTMLLayerElementImpl::addChild(NodeImpl *child)
366 {
367  NodeImpl *retval = HTMLDivElementImpl::addChild(child);
368  // When someone adds standard layers, we make sure not to interfere
369  if (retval && retval->id() == ID_DIV) {
370  if (!transparent) {
371  addCSSProperty(CSS_PROP_POSITION, CSS_VAL_STATIC);
372  }
373  transparent = true;
374  }
375  return retval;
376 }
QTextStream & fixed(QTextStream &stream)
DOMString lower() const
Returns a lowercase version of the string.
Definition: dom_string.cpp:232
This file is part of the HTML rendering engine for KDE.
QString number(int n, int base)
This class implements the basic string we use in the DOM.
Definition: dom_string.h:44
This library provides a full-featured HTML parser and widget.
transparent
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Tue Oct 26 2021 22:48:01 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.