File indexing completed on 2024-05-05 16:10:08
0001 /** 0002 * This file is part of the DOM implementation for KDE. 0003 * 0004 * Copyright (C) 1999-2003 Lars Knoll (knoll@kde.org) 0005 * (C) 1999 Antti Koivisto (koivisto@kde.org) 0006 * (C) 2003 Apple Computer, Inc. 0007 * (C) 2004 Allan Sandfeld Jensen (kde@carewolf.com) 0008 * 0009 * This library is free software; you can redistribute it and/or 0010 * modify it under the terms of the GNU Library General Public 0011 * License as published by the Free Software Foundation; either 0012 * version 2 of the License, or (at your option) any later version. 0013 * 0014 * This library is distributed in the hope that it will be useful, 0015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0017 * Library General Public License for more details. 0018 * 0019 * You should have received a copy of the GNU Library General Public License 0020 * along with this library; see the file COPYING.LIB. If not, write to 0021 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0022 * Boston, MA 02110-1301, USA. 0023 * 0024 */ 0025 // ------------------------------------------------------------------------- 0026 //#define DEBUG 0027 #include "html_blockimpl.h" 0028 #include "html_documentimpl.h" 0029 #include "css/cssstyleselector.h" 0030 0031 #include "css/cssproperties.h" 0032 #include "css/cssvalues.h" 0033 0034 using namespace khtml; 0035 using namespace DOM; 0036 0037 void HTMLDivElementImpl::parseAttribute(AttributeImpl *attr) 0038 { 0039 switch (attr->id()) { 0040 case ATTR_ALIGN: { 0041 DOMString v = attr->value().lower(); 0042 if (strcmp(v, "middle") == 0 || strcmp(v, "center") == 0) { 0043 addCSSProperty(CSS_PROP_TEXT_ALIGN, CSS_VAL__KHTML_CENTER); 0044 } else if (strcmp(v, "left") == 0) { 0045 addCSSProperty(CSS_PROP_TEXT_ALIGN, CSS_VAL__KHTML_LEFT); 0046 } else if (strcmp(v, "right") == 0) { 0047 addCSSProperty(CSS_PROP_TEXT_ALIGN, CSS_VAL__KHTML_RIGHT); 0048 } else { 0049 addCSSProperty(CSS_PROP_TEXT_ALIGN, v); 0050 } 0051 break; 0052 } 0053 default: 0054 HTMLElementImpl::parseAttribute(attr); 0055 } 0056 } 0057 0058 // ------------------------------------------------------------------------- 0059 0060 NodeImpl::Id HTMLHRElementImpl::id() const 0061 { 0062 return ID_HR; 0063 } 0064 0065 void HTMLHRElementImpl::parseAttribute(AttributeImpl *attr) 0066 { 0067 switch (attr->id()) { 0068 case ATTR_ALIGN: { 0069 if (strcasecmp(attr->value(), "left") == 0) { 0070 addCSSProperty(CSS_PROP_MARGIN_LEFT, "0"); 0071 addCSSProperty(CSS_PROP_MARGIN_RIGHT, CSS_VAL_AUTO); 0072 } else if (strcasecmp(attr->value(), "right") == 0) { 0073 addCSSProperty(CSS_PROP_MARGIN_LEFT, CSS_VAL_AUTO); 0074 addCSSProperty(CSS_PROP_MARGIN_RIGHT, "0"); 0075 } else { 0076 addCSSProperty(CSS_PROP_MARGIN_LEFT, CSS_VAL_AUTO); 0077 addCSSProperty(CSS_PROP_MARGIN_RIGHT, CSS_VAL_AUTO); 0078 } 0079 break; 0080 } 0081 case ATTR_WIDTH: { 0082 if (!attr->val()) { 0083 break; 0084 } 0085 // cheap hack to cause linebreaks 0086 // khtmltests/html/strange_hr.html 0087 bool ok; 0088 int v = attr->val()->toInt(&ok); 0089 if (ok && !v) { 0090 addCSSLength(CSS_PROP_WIDTH, "1"); 0091 } else { 0092 addCSSLength(CSS_PROP_WIDTH, attr->value()); 0093 } 0094 } 0095 break; 0096 default: 0097 HTMLElementImpl::parseAttribute(attr); 0098 } 0099 } 0100 0101 // ### make sure we undo what we did during detach 0102 void HTMLHRElementImpl::attach() 0103 { 0104 if (attributes(true /* readonly */)) { 0105 // there are some attributes, lets check 0106 DOMString color = getAttribute(ATTR_COLOR); 0107 DOMStringImpl *si = getAttribute(ATTR_SIZE).implementation(); 0108 int _s = si ? si->toInt() : -1; 0109 DOMString n("1"); 0110 if (!color.isNull()) { 0111 addCSSProperty(CSS_PROP_BORDER_TOP_STYLE, CSS_VAL_SOLID); 0112 addCSSProperty(CSS_PROP_BORDER_RIGHT_STYLE, CSS_VAL_SOLID); 0113 addCSSProperty(CSS_PROP_BORDER_BOTTOM_STYLE, CSS_VAL_SOLID); 0114 addCSSProperty(CSS_PROP_BORDER_LEFT_STYLE, CSS_VAL_SOLID); 0115 addCSSProperty(CSS_PROP_BORDER_TOP_WIDTH, DOMString("0")); 0116 addCSSLength(CSS_PROP_BORDER_BOTTOM_WIDTH, DOMString(si)); 0117 addHTMLColor(CSS_PROP_BORDER_COLOR, color); 0118 } else { 0119 if (_s > 1 && getAttribute(ATTR_NOSHADE).isNull()) { 0120 addCSSProperty(CSS_PROP_BORDER_BOTTOM_WIDTH, n); 0121 addCSSProperty(CSS_PROP_BORDER_TOP_WIDTH, n); 0122 addCSSProperty(CSS_PROP_BORDER_LEFT_WIDTH, n); 0123 addCSSProperty(CSS_PROP_BORDER_RIGHT_WIDTH, n); 0124 addCSSLength(CSS_PROP_HEIGHT, DOMString(QString::number(_s - 2))); 0125 } else if (_s >= 0) { 0126 addCSSProperty(CSS_PROP_BORDER_TOP_WIDTH, DOMString(QString::number(_s))); 0127 addCSSProperty(CSS_PROP_BORDER_BOTTOM_WIDTH, DOMString("0")); 0128 } 0129 } 0130 if (_s == 0) { 0131 addCSSProperty(CSS_PROP_MARGIN_BOTTOM, n); 0132 } 0133 } 0134 0135 HTMLElementImpl::attach(); 0136 } 0137 0138 // ------------------------------------------------------------------------- 0139 0140 long HTMLPreElementImpl::width() const 0141 { 0142 // ### 0143 return 0; 0144 } 0145 0146 void HTMLPreElementImpl::setWidth(long /*w*/) 0147 { 0148 // ### 0149 } 0150 0151 // ------------------------------------------------------------------------- 0152 0153 // WinIE uses 60ms as the minimum delay by default. 0154 const int defaultMinimumDelay = 60; 0155 0156 HTMLMarqueeElementImpl::HTMLMarqueeElementImpl(DocumentImpl *doc) 0157 : HTMLElementImpl(doc), 0158 m_minimumDelay(defaultMinimumDelay) 0159 { 0160 } 0161 0162 NodeImpl::Id HTMLMarqueeElementImpl::id() const 0163 { 0164 return ID_MARQUEE; 0165 } 0166 0167 void HTMLMarqueeElementImpl::parseAttribute(AttributeImpl *attr) 0168 { 0169 switch (attr->id()) { 0170 case ATTR_WIDTH: 0171 if (!attr->value().isEmpty()) { 0172 addCSSLength(CSS_PROP_WIDTH, attr->value()); 0173 } else { 0174 removeCSSProperty(CSS_PROP_WIDTH); 0175 } 0176 break; 0177 case ATTR_HEIGHT: 0178 if (!attr->value().isEmpty()) { 0179 addCSSLength(CSS_PROP_HEIGHT, attr->value()); 0180 } else { 0181 removeCSSProperty(CSS_PROP_HEIGHT); 0182 } 0183 break; 0184 case ATTR_BGCOLOR: 0185 if (!attr->value().isEmpty()) { 0186 addHTMLColor(CSS_PROP_BACKGROUND_COLOR, attr->value()); 0187 } else { 0188 removeCSSProperty(CSS_PROP_BACKGROUND_COLOR); 0189 } 0190 break; 0191 case ATTR_VSPACE: 0192 if (!attr->value().isEmpty()) { 0193 addCSSLength(CSS_PROP_MARGIN_TOP, attr->value()); 0194 addCSSLength(CSS_PROP_MARGIN_BOTTOM, attr->value()); 0195 } else { 0196 removeCSSProperty(CSS_PROP_MARGIN_TOP); 0197 removeCSSProperty(CSS_PROP_MARGIN_BOTTOM); 0198 } 0199 break; 0200 case ATTR_HSPACE: 0201 if (!attr->value().isEmpty()) { 0202 addCSSLength(CSS_PROP_MARGIN_LEFT, attr->value()); 0203 addCSSLength(CSS_PROP_MARGIN_RIGHT, attr->value()); 0204 } else { 0205 removeCSSProperty(CSS_PROP_MARGIN_LEFT); 0206 removeCSSProperty(CSS_PROP_MARGIN_RIGHT); 0207 } 0208 break; 0209 case ATTR_SCROLLAMOUNT: 0210 if (!attr->value().isEmpty()) { 0211 addCSSLength(CSS_PROP__KHTML_MARQUEE_INCREMENT, attr->value()); 0212 } else { 0213 removeCSSProperty(CSS_PROP__KHTML_MARQUEE_INCREMENT); 0214 } 0215 break; 0216 case ATTR_SCROLLDELAY: 0217 if (!attr->value().isEmpty()) { 0218 addCSSLength(CSS_PROP__KHTML_MARQUEE_SPEED, attr->value(), true); 0219 } else { 0220 removeCSSProperty(CSS_PROP__KHTML_MARQUEE_SPEED); 0221 } 0222 break; 0223 case ATTR_LOOP: 0224 if (!attr->value().isEmpty()) { 0225 if (attr->value() == "-1" || strcasecmp(attr->value(), "infinite") == 0) { 0226 addCSSProperty(CSS_PROP__KHTML_MARQUEE_REPETITION, CSS_VAL_INFINITE); 0227 } else { 0228 addCSSLength(CSS_PROP__KHTML_MARQUEE_REPETITION, attr->value().lower(), true); 0229 } 0230 } else { 0231 removeCSSProperty(CSS_PROP__KHTML_MARQUEE_REPETITION); 0232 } 0233 break; 0234 case ATTR_BEHAVIOR: 0235 if (!attr->value().isEmpty()) { 0236 addCSSProperty(CSS_PROP__KHTML_MARQUEE_STYLE, attr->value().lower()); 0237 } else { 0238 removeCSSProperty(CSS_PROP__KHTML_MARQUEE_STYLE); 0239 } 0240 break; 0241 case ATTR_DIRECTION: 0242 if (!attr->value().isEmpty()) { 0243 addCSSProperty(CSS_PROP__KHTML_MARQUEE_DIRECTION, attr->value().lower()); 0244 } else { 0245 removeCSSProperty(CSS_PROP__KHTML_MARQUEE_DIRECTION); 0246 } 0247 break; 0248 case ATTR_TRUESPEED: 0249 m_minimumDelay = attr->val() ? 0 : defaultMinimumDelay; 0250 break; 0251 default: 0252 HTMLElementImpl::parseAttribute(attr); 0253 } 0254 } 0255 0256 // ------------------------------------------------------------------------ 0257 0258 HTMLLayerElementImpl::HTMLLayerElementImpl(DocumentImpl *doc, ushort _tagid) 0259 : HTMLDivElementImpl(doc, _tagid) 0260 { 0261 transparent = fixed = false; 0262 } 0263 0264 void HTMLLayerElementImpl::parseAttribute(AttributeImpl *attr) 0265 { 0266 // Layers are evil 0267 // They are mainly implemented here to correctly parse the hidden attribute 0268 switch (attr->id()) { 0269 case ATTR_LEFT: 0270 addCSSProperty(CSS_PROP_LEFT, attr->value()); 0271 break; 0272 case ATTR_TOP: 0273 addCSSProperty(CSS_PROP_TOP, attr->value()); 0274 break; 0275 case ATTR_PAGEX: 0276 if (!transparent && !fixed) { 0277 addCSSProperty(CSS_PROP_POSITION, CSS_VAL_FIXED); 0278 fixed = true; 0279 } 0280 addCSSProperty(CSS_PROP_LEFT, attr->value()); 0281 break; 0282 case ATTR_PAGEY: 0283 if (!transparent && !fixed) { 0284 addCSSProperty(CSS_PROP_POSITION, CSS_VAL_FIXED); 0285 fixed = true; 0286 } 0287 addCSSProperty(CSS_PROP_TOP, attr->value()); 0288 break; 0289 case ATTR_WIDTH: 0290 if (!attr->value().isEmpty()) { 0291 addCSSLength(CSS_PROP_WIDTH, attr->value()); 0292 } else { 0293 removeCSSProperty(CSS_PROP_WIDTH); 0294 } 0295 break; 0296 case ATTR_HEIGHT: 0297 if (!attr->value().isEmpty()) { 0298 addCSSLength(CSS_PROP_HEIGHT, attr->value()); 0299 } else { 0300 removeCSSProperty(CSS_PROP_HEIGHT); 0301 } 0302 break; 0303 case ATTR_BGCOLOR: 0304 if (!attr->value().isEmpty()) { 0305 addHTMLColor(CSS_PROP_BACKGROUND_COLOR, attr->value()); 0306 } else { 0307 removeCSSProperty(CSS_PROP_BACKGROUND_COLOR); 0308 } 0309 break; 0310 case ATTR_Z_INDEX: 0311 if (!attr->value().isEmpty()) { 0312 addCSSProperty(CSS_PROP_Z_INDEX, attr->value()); 0313 } else { 0314 removeCSSProperty(CSS_PROP_Z_INDEX); 0315 } 0316 break; 0317 case ATTR_VISIBILITY: 0318 if (attr->value().lower() == "show") { 0319 addCSSProperty(CSS_PROP_VISIBILITY, CSS_VAL_VISIBLE); 0320 } else if (attr->value().lower() == "hide") { 0321 addCSSProperty(CSS_PROP_VISIBILITY, CSS_VAL_HIDDEN); 0322 } else if (attr->value().lower() == "inherit") { 0323 addCSSProperty(CSS_PROP_VISIBILITY, CSS_VAL_INHERIT); 0324 } 0325 break; 0326 case ATTR_NAME: 0327 if (id() == ID_LAYER && inDocument() && m_name != attr->value()) { 0328 document()->underDocNamedCache().remove(m_name, this); 0329 document()->underDocNamedCache().add(attr->value(), this); 0330 } 0331 //fallthrough 0332 default: 0333 HTMLElementImpl::parseAttribute(attr); 0334 } 0335 } 0336 0337 void HTMLLayerElementImpl::removedFromDocument() 0338 { 0339 if (id() == ID_LAYER) { 0340 document()->underDocNamedCache().remove(m_name, this); 0341 } 0342 HTMLDivElementImpl::removedFromDocument(); 0343 } 0344 0345 void HTMLLayerElementImpl::insertedIntoDocument() 0346 { 0347 if (id() == ID_LAYER) { 0348 document()->underDocNamedCache().add(m_name, this); 0349 } 0350 HTMLDivElementImpl::insertedIntoDocument(); 0351 } 0352 0353 void HTMLLayerElementImpl::removeId(const DOMString &id) 0354 { 0355 document()->underDocNamedCache().remove(id, this); 0356 HTMLDivElementImpl::removeId(id); 0357 } 0358 0359 void HTMLLayerElementImpl::addId(const DOMString &id) 0360 { 0361 document()->underDocNamedCache().add(id, this); 0362 HTMLDivElementImpl::addId(id); 0363 } 0364 0365 NodeImpl *HTMLLayerElementImpl::addChild(NodeImpl *child) 0366 { 0367 NodeImpl *retval = HTMLDivElementImpl::addChild(child); 0368 // When someone adds standard layers, we make sure not to interfere 0369 if (retval && retval->id() == ID_DIV) { 0370 if (!transparent) { 0371 addCSSProperty(CSS_PROP_POSITION, CSS_VAL_STATIC); 0372 } 0373 transparent = true; 0374 } 0375 return retval; 0376 }