/** * This file is part of the DOM implementation for KDE. * * Copyright (C) 1999-2003 Lars Knoll (knoll@kde.org) * (C) 1999 Antti Koivisto (koivisto@kde.org) * (C) 2003 Apple Computer, Inc. * (C) 2004 Allan Sandfeld Jensen (kde@carewolf.com) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ // ------------------------------------------------------------------------- //#define DEBUG #include "html_blockimpl.h" #include "html_documentimpl.h" #include "css/cssstyleselector.h" #include "css/cssproperties.h" #include "css/cssvalues.h" #include "misc/htmlhashes.h" #include <kdebug.h> using namespace tdehtml; using namespace DOM; void HTMLDivElementImpl::parseAttribute(AttributeImpl *attr) { switch(attr->id()) { case ATTR_ALIGN: { DOMString v = attr->value().lower(); if ( strcmp( v, "middle" ) == 0 || strcmp( v, "center" ) == 0 ) addCSSProperty(CSS_PROP_TEXT_ALIGN, CSS_VAL__TDEHTML_CENTER); else if (strcmp(v, "left") == 0) addCSSProperty(CSS_PROP_TEXT_ALIGN, CSS_VAL__TDEHTML_LEFT); else if (strcmp(v, "right") == 0) addCSSProperty(CSS_PROP_TEXT_ALIGN, CSS_VAL__TDEHTML_RIGHT); else addCSSProperty(CSS_PROP_TEXT_ALIGN, v); break; } default: HTMLElementImpl::parseAttribute(attr); } } // ------------------------------------------------------------------------- NodeImpl::Id HTMLHRElementImpl::id() const { return ID_HR; } void HTMLHRElementImpl::parseAttribute(AttributeImpl *attr) { switch( attr->id() ) { case ATTR_ALIGN: { if (strcasecmp(attr->value(), "left") == 0) { addCSSProperty(CSS_PROP_MARGIN_LEFT, "0"); addCSSProperty(CSS_PROP_MARGIN_RIGHT, CSS_VAL_AUTO); } else if (strcasecmp(attr->value(), "right") == 0) { addCSSProperty(CSS_PROP_MARGIN_LEFT, CSS_VAL_AUTO); addCSSProperty(CSS_PROP_MARGIN_RIGHT, "0"); } else { addCSSProperty(CSS_PROP_MARGIN_LEFT, CSS_VAL_AUTO); addCSSProperty(CSS_PROP_MARGIN_RIGHT, CSS_VAL_AUTO); } break; } case ATTR_WIDTH: { if(!attr->val()) break; // cheap hack to cause linebreaks // tdehtmltests/html/strange_hr.html bool ok; int v = attr->val()->toInt(&ok); if(ok && !v) addCSSLength(CSS_PROP_WIDTH, "1"); else addCSSLength(CSS_PROP_WIDTH, attr->value()); } break; default: HTMLElementImpl::parseAttribute(attr); } } // ### make sure we undo what we did during detach void HTMLHRElementImpl::attach() { if (attributes(true /* readonly */)) { // there are some attributes, lets check DOMString color = getAttribute(ATTR_COLOR); DOMStringImpl* si = getAttribute(ATTR_SIZE).implementation(); int _s = si ? si->toInt() : -1; DOMString n("1"); if (!color.isNull()) { addCSSProperty(CSS_PROP_BORDER_TOP_STYLE, CSS_VAL_SOLID); addCSSProperty(CSS_PROP_BORDER_RIGHT_STYLE, CSS_VAL_SOLID); addCSSProperty(CSS_PROP_BORDER_BOTTOM_STYLE, CSS_VAL_SOLID); addCSSProperty(CSS_PROP_BORDER_LEFT_STYLE, CSS_VAL_SOLID); addCSSProperty(CSS_PROP_BORDER_TOP_WIDTH, DOMString("0")); addCSSLength(CSS_PROP_BORDER_BOTTOM_WIDTH, DOMString(si)); addHTMLColor(CSS_PROP_BORDER_COLOR, color); } else { if (_s > 1 && getAttribute(ATTR_NOSHADE).isNull()) { addCSSProperty(CSS_PROP_BORDER_BOTTOM_WIDTH, n); addCSSProperty(CSS_PROP_BORDER_TOP_WIDTH, n); addCSSProperty(CSS_PROP_BORDER_LEFT_WIDTH, n); addCSSProperty(CSS_PROP_BORDER_RIGHT_WIDTH, n); addCSSLength(CSS_PROP_HEIGHT, DOMString(TQString::number(_s-2))); } else if (_s >= 0) { addCSSProperty(CSS_PROP_BORDER_TOP_WIDTH, DOMString(TQString::number(_s))); addCSSProperty(CSS_PROP_BORDER_BOTTOM_WIDTH, DOMString("0")); } } if (_s == 0) addCSSProperty(CSS_PROP_MARGIN_BOTTOM, n); } HTMLElementImpl::attach(); } // ------------------------------------------------------------------------- long HTMLPreElementImpl::width() const { // ### return 0; } void HTMLPreElementImpl::setWidth( long /*w*/ ) { // ### } // ------------------------------------------------------------------------- // WinIE uses 60ms as the minimum delay by default. const int defaultMinimumDelay = 60; HTMLMarqueeElementImpl::HTMLMarqueeElementImpl(DocumentImpl *doc) : HTMLElementImpl(doc), m_minimumDelay(defaultMinimumDelay) { } NodeImpl::Id HTMLMarqueeElementImpl::id() const { return ID_MARQUEE; } void HTMLMarqueeElementImpl::parseAttribute(AttributeImpl *attr) { switch(attr->id()) { case ATTR_WIDTH: if (!attr->value().isEmpty()) addCSSLength(CSS_PROP_WIDTH, attr->value()); else removeCSSProperty(CSS_PROP_WIDTH); break; case ATTR_HEIGHT: if (!attr->value().isEmpty()) addCSSLength(CSS_PROP_HEIGHT, attr->value()); else removeCSSProperty(CSS_PROP_HEIGHT); break; case ATTR_BGCOLOR: if (!attr->value().isEmpty()) addHTMLColor(CSS_PROP_BACKGROUND_COLOR, attr->value()); else removeCSSProperty(CSS_PROP_BACKGROUND_COLOR); break; case ATTR_VSPACE: if (!attr->value().isEmpty()) { addCSSLength(CSS_PROP_MARGIN_TOP, attr->value()); addCSSLength(CSS_PROP_MARGIN_BOTTOM, attr->value()); } else { removeCSSProperty(CSS_PROP_MARGIN_TOP); removeCSSProperty(CSS_PROP_MARGIN_BOTTOM); } break; case ATTR_HSPACE: if (!attr->value().isEmpty()) { addCSSLength(CSS_PROP_MARGIN_LEFT, attr->value()); addCSSLength(CSS_PROP_MARGIN_RIGHT, attr->value()); } else { removeCSSProperty(CSS_PROP_MARGIN_LEFT); removeCSSProperty(CSS_PROP_MARGIN_RIGHT); } break; case ATTR_SCROLLAMOUNT: if (!attr->value().isEmpty()) addCSSLength(CSS_PROP__TDEHTML_MARQUEE_INCREMENT, attr->value()); else removeCSSProperty(CSS_PROP__TDEHTML_MARQUEE_INCREMENT); break; case ATTR_SCROLLDELAY: if (!attr->value().isEmpty()) addCSSLength(CSS_PROP__TDEHTML_MARQUEE_SPEED, attr->value(), true); else removeCSSProperty(CSS_PROP__TDEHTML_MARQUEE_SPEED); break; case ATTR_LOOP: if (!attr->value().isEmpty()) { if (attr->value() == "-1" || strcasecmp(attr->value(), "infinite") == 0) addCSSProperty(CSS_PROP__TDEHTML_MARQUEE_REPETITION, CSS_VAL_INFINITE); else addCSSLength(CSS_PROP__TDEHTML_MARQUEE_REPETITION, attr->value().lower(), true); } else removeCSSProperty(CSS_PROP__TDEHTML_MARQUEE_REPETITION); break; case ATTR_BEHAVIOR: if (!attr->value().isEmpty()) addCSSProperty(CSS_PROP__TDEHTML_MARQUEE_STYLE, attr->value().lower()); else removeCSSProperty(CSS_PROP__TDEHTML_MARQUEE_STYLE); break; case ATTR_DIRECTION: if (!attr->value().isEmpty()) addCSSProperty(CSS_PROP__TDEHTML_MARQUEE_DIRECTION, attr->value().lower()); else removeCSSProperty(CSS_PROP__TDEHTML_MARQUEE_DIRECTION); break; case ATTR_TRUESPEED: m_minimumDelay = attr->val() ? 0 : defaultMinimumDelay; break; default: HTMLElementImpl::parseAttribute(attr); } } // ------------------------------------------------------------------------ HTMLLayerElementImpl::HTMLLayerElementImpl(DocumentImpl *doc, ushort _tagid) : HTMLDivElementImpl( doc, _tagid ) { transparent = fixed = false; } void HTMLLayerElementImpl::parseAttribute(AttributeImpl *attr) { // Layers are evil // They are mainly implemented here to correctly parse the hidden attribute switch(attr->id()) { case ATTR_LEFT: addCSSProperty(CSS_PROP_LEFT, attr->value()); break; case ATTR_TOP: addCSSProperty(CSS_PROP_TOP, attr->value()); break; case ATTR_PAGEX: if (!transparent && !fixed) { addCSSProperty(CSS_PROP_POSITION, CSS_VAL_FIXED); fixed = true; } addCSSProperty(CSS_PROP_LEFT, attr->value()); break; case ATTR_PAGEY: if (!transparent && !fixed) { addCSSProperty(CSS_PROP_POSITION, CSS_VAL_FIXED); fixed = true; } addCSSProperty(CSS_PROP_TOP, attr->value()); break; case ATTR_WIDTH: if (!attr->value().isEmpty()) addCSSLength(CSS_PROP_WIDTH, attr->value()); else removeCSSProperty(CSS_PROP_WIDTH); break; case ATTR_HEIGHT: if (!attr->value().isEmpty()) addCSSLength(CSS_PROP_HEIGHT, attr->value()); else removeCSSProperty(CSS_PROP_HEIGHT); break; case ATTR_BGCOLOR: if (!attr->value().isEmpty()) addHTMLColor(CSS_PROP_BACKGROUND_COLOR, attr->value()); else removeCSSProperty(CSS_PROP_BACKGROUND_COLOR); break; case ATTR_Z_INDEX: if (!attr->value().isEmpty()) addCSSProperty(CSS_PROP_Z_INDEX, attr->value()); else removeCSSProperty(CSS_PROP_Z_INDEX); break; case ATTR_VISIBILITY: if (attr->value().lower() == "show") addCSSProperty(CSS_PROP_VISIBILITY, CSS_VAL_VISIBLE); else if (attr->value().lower() == "hide") addCSSProperty(CSS_PROP_VISIBILITY, CSS_VAL_HIDDEN); else if (attr->value().lower() == "inherit") addCSSProperty(CSS_PROP_VISIBILITY, CSS_VAL_INHERIT); break; case ATTR_NAME: if (id() == ID_LAYER && inDocument() && m_name != attr->value()) { getDocument()->underDocNamedCache().remove(m_name.string(), this); getDocument()->underDocNamedCache().add (attr->value().string(), this); } //fallthrough default: HTMLElementImpl::parseAttribute(attr); } } void HTMLLayerElementImpl::removedFromDocument() { if (id() == ID_LAYER) getDocument()->underDocNamedCache().remove(m_name.string(), this); HTMLDivElementImpl::removedFromDocument(); } void HTMLLayerElementImpl::insertedIntoDocument() { if (id() == ID_LAYER) getDocument()->underDocNamedCache().add(m_name.string(), this); HTMLDivElementImpl::insertedIntoDocument(); } void HTMLLayerElementImpl::removeId(const TQString& id) { getDocument()->underDocNamedCache().remove(id, this); HTMLDivElementImpl::removeId(id); } void HTMLLayerElementImpl::addId (const TQString& id) { getDocument()->underDocNamedCache().add(id, this); HTMLDivElementImpl::addId(id); } NodeImpl *HTMLLayerElementImpl::addChild(NodeImpl *child) { NodeImpl *retval = HTMLDivElementImpl::addChild(child); // When someone adds standard layers, we make sure not to interfere if (retval && retval->id() == ID_DIV) { if (!transparent) addCSSProperty(CSS_PROP_POSITION, CSS_VAL_STATIC); transparent = true; } return retval; }