You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
372 lines
12 KiB
372 lines
12 KiB
/**
|
|
* 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 khtml;
|
|
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__KHTML_CENTER);
|
|
else if (strcmp(v, "left") == 0)
|
|
addCSSProperty(CSS_PROP_TEXT_ALIGN, CSS_VAL__KHTML_LEFT);
|
|
else if (strcmp(v, "right") == 0)
|
|
addCSSProperty(CSS_PROP_TEXT_ALIGN, CSS_VAL__KHTML_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
|
|
// khtmltests/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__KHTML_MARQUEE_INCREMENT, attr->value());
|
|
else
|
|
removeCSSProperty(CSS_PROP__KHTML_MARQUEE_INCREMENT);
|
|
break;
|
|
case ATTR_SCROLLDELAY:
|
|
if (!attr->value().isEmpty())
|
|
addCSSLength(CSS_PROP__KHTML_MARQUEE_SPEED, attr->value(), true);
|
|
else
|
|
removeCSSProperty(CSS_PROP__KHTML_MARQUEE_SPEED);
|
|
break;
|
|
case ATTR_LOOP:
|
|
if (!attr->value().isEmpty()) {
|
|
if (attr->value() == "-1" || strcasecmp(attr->value(), "infinite") == 0)
|
|
addCSSProperty(CSS_PROP__KHTML_MARQUEE_REPETITION, CSS_VAL_INFINITE);
|
|
else
|
|
addCSSLength(CSS_PROP__KHTML_MARQUEE_REPETITION, attr->value().lower(), true);
|
|
}
|
|
else
|
|
removeCSSProperty(CSS_PROP__KHTML_MARQUEE_REPETITION);
|
|
break;
|
|
case ATTR_BEHAVIOR:
|
|
if (!attr->value().isEmpty())
|
|
addCSSProperty(CSS_PROP__KHTML_MARQUEE_STYLE, attr->value().lower());
|
|
else
|
|
removeCSSProperty(CSS_PROP__KHTML_MARQUEE_STYLE);
|
|
break;
|
|
case ATTR_DIRECTION:
|
|
if (!attr->value().isEmpty())
|
|
addCSSProperty(CSS_PROP__KHTML_MARQUEE_DIRECTION, attr->value().lower());
|
|
else
|
|
removeCSSProperty(CSS_PROP__KHTML_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;
|
|
}
|