Commit 2c511d0c authored by Peter Kelly's avatar Peter Kelly

- Made HTMLBaseElementImpl, HTMLLinkElementImpl, HTMLStyleElementImpl

  and HTMLTitleElementImpl all update correctly when they're attributes
  are changed, child text nodes change or they are added/removed from
  the tree.
- Cleanups in html_formimpl.cpp

svn path=/trunk/kdelibs/; revision=129488
parent 7d8b68f5
......@@ -190,3 +190,12 @@ Things we discussed (in no particular order):
- minor things i forgot...
More things (pmk):
- Make sure all elements update properly when parsing attributes, basically
what is done in most of the init() methods. This also needs to take into
account what happens when you insert/remvoe elements, e.g. removing a title
element should clear the document's title, and then creating a new title
element again and changing the text should only update the doc's title when
it actually gets put in the tree.
......@@ -82,15 +82,7 @@ HTMLDocument::~HTMLDocument()
DOMString HTMLDocument::title() const
{
if(!impl) return DOMString();
NodeImpl *e = static_cast<HTMLDocumentImpl *>(impl)->findElement(ID_TITLE);
if(!e) return DOMString();
NodeImpl *t = e->firstChild();
if(!t) return DOMString();
// ### join all text nodes within <TITLE>
return static_cast<TextImpl *>(t)->data();
return static_cast<HTMLDocumentImpl *>(impl)->title();
}
void HTMLDocument::setTitle( const DOMString &/*value*/ )
......
......@@ -478,29 +478,17 @@ void HTMLFormElementImpl::removeFormElement(HTMLGenericFormElementImpl *e)
HTMLGenericFormElementImpl::HTMLGenericFormElementImpl(DocumentPtr *doc, HTMLFormElementImpl *f)
: HTMLElementImpl(doc)
{
clear();
m_form = f;
if (m_form)
m_form->registerFormElement(this);
}
HTMLGenericFormElementImpl::HTMLGenericFormElementImpl(DocumentPtr *doc)
: HTMLElementImpl(doc)
{
clear();
m_disabled = m_readOnly = false;
m_name = 0;
m_form = getForm();
if (f)
m_form = f;
else
m_form = getForm();
if (m_form)
m_form->registerFormElement(this);
}
void HTMLGenericFormElementImpl::clear()
{
m_disabled = m_readOnly = false;
m_name = 0;
}
HTMLGenericFormElementImpl::~HTMLGenericFormElementImpl()
{
if (m_form)
......@@ -669,15 +657,6 @@ HTMLButtonElementImpl::HTMLButtonElementImpl(DocumentPtr *doc, HTMLFormElementIm
m_activeSubmit = false;
}
HTMLButtonElementImpl::HTMLButtonElementImpl(DocumentPtr *doc)
: HTMLGenericFormElementImpl(doc)
{
m_clicked = false;
m_type = BUTTON;
m_dirty = true;
m_activeSubmit = false;
}
HTMLButtonElementImpl::~HTMLButtonElementImpl()
{
}
......@@ -758,11 +737,6 @@ HTMLFieldSetElementImpl::HTMLFieldSetElementImpl(DocumentPtr *doc, HTMLFormEleme
{
}
HTMLFieldSetElementImpl::HTMLFieldSetElementImpl(DocumentPtr *doc)
: HTMLGenericFormElementImpl(doc)
{
}
HTMLFieldSetElementImpl::~HTMLFieldSetElementImpl()
{
}
......@@ -774,22 +748,8 @@ NodeImpl::Id HTMLFieldSetElementImpl::id() const
// -------------------------------------------------------------------------
HTMLInputElementImpl::HTMLInputElementImpl(DocumentPtr *doc)
: HTMLGenericFormElementImpl(doc)
{
clear();
}
HTMLInputElementImpl::HTMLInputElementImpl(DocumentPtr *doc, HTMLFormElementImpl *f)
: HTMLGenericFormElementImpl(doc, f)
{
clear();
if ( f )
m_autocomplete = f->autoComplete();
}
void HTMLInputElementImpl::clear()
{
m_type = TEXT;
m_maxLen = -1;
......@@ -804,6 +764,9 @@ void HTMLInputElementImpl::clear()
xPos = 0;
yPos = 0;
if ( m_form )
m_autocomplete = f->autoComplete();
}
HTMLInputElementImpl::~HTMLInputElementImpl()
......@@ -1414,11 +1377,6 @@ HTMLLegendElementImpl::HTMLLegendElementImpl(DocumentPtr *doc, HTMLFormElementIm
{
}
HTMLLegendElementImpl::HTMLLegendElementImpl(DocumentPtr *doc)
: HTMLGenericFormElementImpl(doc)
{
}
HTMLLegendElementImpl::~HTMLLegendElementImpl()
{
}
......@@ -1430,15 +1388,6 @@ NodeImpl::Id HTMLLegendElementImpl::id() const
// -------------------------------------------------------------------------
HTMLSelectElementImpl::HTMLSelectElementImpl(DocumentPtr *doc)
: HTMLGenericFormElementImpl(doc)
{
m_multiple = false;
// 0 means invalid (i.e. not set)
m_size = 0;
m_minwidth = 0;
}
HTMLSelectElementImpl::HTMLSelectElementImpl(DocumentPtr *doc, HTMLFormElementImpl *f)
: HTMLGenericFormElementImpl(doc, f)
{
......@@ -1807,19 +1756,8 @@ void HTMLSelectElementImpl::notifyOptionSelected(HTMLOptionElementImpl *selected
// -------------------------------------------------------------------------
HTMLKeygenElementImpl::HTMLKeygenElementImpl(DocumentPtr* doc)
: HTMLSelectElementImpl(doc)
{
clear(doc);
}
HTMLKeygenElementImpl::HTMLKeygenElementImpl(DocumentPtr* doc, HTMLFormElementImpl* f)
: HTMLSelectElementImpl(doc, f)
{
clear(doc);
}
void HTMLKeygenElementImpl::clear(DocumentPtr* doc)
{
QStringList keys = KSSLKeyGen::supportedKeySizes();
for (QStringList::Iterator i = keys.begin(); i != keys.end(); ++i) {
......@@ -1829,7 +1767,6 @@ void HTMLKeygenElementImpl::clear(DocumentPtr* doc)
}
}
NodeImpl::Id HTMLKeygenElementImpl::id() const
{
return ID_KEYGEN;
......@@ -1874,11 +1811,6 @@ HTMLOptGroupElementImpl::HTMLOptGroupElementImpl(DocumentPtr *doc, HTMLFormEleme
{
}
HTMLOptGroupElementImpl::HTMLOptGroupElementImpl(DocumentPtr *doc)
: HTMLGenericFormElementImpl(doc)
{
}
HTMLOptGroupElementImpl::~HTMLOptGroupElementImpl()
{
}
......@@ -1950,12 +1882,6 @@ HTMLOptionElementImpl::HTMLOptionElementImpl(DocumentPtr *doc, HTMLFormElementIm
m_selected = false;
}
HTMLOptionElementImpl::HTMLOptionElementImpl(DocumentPtr *doc)
: HTMLGenericFormElementImpl(doc)
{
m_selected = false;
}
NodeImpl::Id HTMLOptionElementImpl::id() const
{
return ID_OPTION;
......@@ -2064,17 +1990,6 @@ void HTMLOptionElementImpl::setChanged( bool b )
// -------------------------------------------------------------------------
HTMLTextAreaElementImpl::HTMLTextAreaElementImpl(DocumentPtr *doc)
: HTMLGenericFormElementImpl(doc)
{
// DTD requires rows & cols be specified, but we will provide reasonable defaults
m_rows = 2;
m_cols = 20;
m_wrap = ta_Virtual;
m_dirtyvalue = true;
}
HTMLTextAreaElementImpl::HTMLTextAreaElementImpl(DocumentPtr *doc, HTMLFormElementImpl *f)
: HTMLGenericFormElementImpl(doc, f)
{
......@@ -2262,16 +2177,11 @@ bool HTMLTextAreaElementImpl::isEditable()
// -------------------------------------------------------------------------
HTMLIsIndexElementImpl::HTMLIsIndexElementImpl(DocumentPtr *doc)
: HTMLInputElementImpl(doc)
{
m_type = TEXT;
}
HTMLIsIndexElementImpl::HTMLIsIndexElementImpl(DocumentPtr *doc, HTMLFormElementImpl *f)
: HTMLInputElementImpl(doc, f)
{
m_type = TEXT;
setName("isindex");
}
HTMLIsIndexElementImpl::~HTMLIsIndexElementImpl()
......@@ -2288,7 +2198,7 @@ void HTMLIsIndexElementImpl::parseAttribute(AttrImpl* attr)
switch(attr->attrId)
{
case ATTR_PROMPT:
m_prompt = attr->value();
setValue(attr->value());
default:
// don't call HTMLInputElement::parseAttribute here, as it would
// accept attributes this element does not support
......@@ -2296,14 +2206,5 @@ void HTMLIsIndexElementImpl::parseAttribute(AttrImpl* attr)
}
}
void HTMLIsIndexElementImpl::init()
{
HTMLInputElementImpl::init();
setName("isindex");
// ### fix this, this is just a crude hack
setValue(m_prompt);
}
// -------------------------------------------------------------------------
......@@ -115,8 +115,7 @@ class HTMLGenericFormElementImpl : public HTMLElementImpl
friend class khtml::RenderFormElement;
public:
HTMLGenericFormElementImpl(DocumentPtr *doc);
HTMLGenericFormElementImpl(DocumentPtr *doc, HTMLFormElementImpl *f);
HTMLGenericFormElementImpl(DocumentPtr *doc, HTMLFormElementImpl *f = 0);
virtual ~HTMLGenericFormElementImpl();
HTMLFormElementImpl *form() { return m_form; }
......@@ -154,9 +153,6 @@ public:
virtual void defaultEventHandler(EventImpl *evt);
virtual bool isEditable();
private:
void clear();
protected:
HTMLFormElementImpl *getForm() const;
......@@ -170,8 +166,7 @@ protected:
class HTMLButtonElementImpl : public HTMLGenericFormElementImpl
{
public:
HTMLButtonElementImpl(DocumentPtr *doc);
HTMLButtonElementImpl(DocumentPtr *doc, HTMLFormElementImpl *f);
HTMLButtonElementImpl(DocumentPtr *doc, HTMLFormElementImpl *f = 0);
virtual ~HTMLButtonElementImpl();
......@@ -205,8 +200,7 @@ protected:
class HTMLFieldSetElementImpl : public HTMLGenericFormElementImpl
{
public:
HTMLFieldSetElementImpl(DocumentPtr *doc);
HTMLFieldSetElementImpl(DocumentPtr *doc, HTMLFormElementImpl *f);
HTMLFieldSetElementImpl(DocumentPtr *doc, HTMLFormElementImpl *f = 0);
virtual ~HTMLFieldSetElementImpl();
......@@ -234,8 +228,7 @@ public:
ISINDEX
};
HTMLInputElementImpl(DocumentPtr *doc);
HTMLInputElementImpl(DocumentPtr *doc, HTMLFormElementImpl *f);
HTMLInputElementImpl(DocumentPtr *doc, HTMLFormElementImpl *f = 0);
virtual ~HTMLInputElementImpl();
virtual Id id() const;
......@@ -305,9 +298,6 @@ protected:
bool m_haveType : 1;
bool m_activeSubmit : 1;
bool m_autocomplete : 1;
private:
void clear();
};
// -------------------------------------------------------------------------
......@@ -335,8 +325,7 @@ public:
class HTMLLegendElementImpl : public HTMLGenericFormElementImpl
{
public:
HTMLLegendElementImpl(DocumentPtr *doc);
HTMLLegendElementImpl(DocumentPtr *doc, HTMLFormElementImpl *f);
HTMLLegendElementImpl(DocumentPtr *doc, HTMLFormElementImpl *f = 0);
virtual ~HTMLLegendElementImpl();
virtual Id id() const;
......@@ -348,8 +337,7 @@ public:
class HTMLSelectElementImpl : public HTMLGenericFormElementImpl
{
public:
HTMLSelectElementImpl(DocumentPtr *doc);
HTMLSelectElementImpl(DocumentPtr *doc, HTMLFormElementImpl *f);
HTMLSelectElementImpl(DocumentPtr *doc, HTMLFormElementImpl *f = 0);
virtual Id id() const;
......@@ -412,8 +400,7 @@ protected:
class HTMLKeygenElementImpl : public HTMLSelectElementImpl
{
public:
HTMLKeygenElementImpl(DocumentPtr *doc);
HTMLKeygenElementImpl(DocumentPtr *doc, HTMLFormElementImpl *f);
HTMLKeygenElementImpl(DocumentPtr *doc, HTMLFormElementImpl *f = 0);
virtual Id id() const;
......@@ -428,8 +415,6 @@ public:
virtual void parseAttribute(AttrImpl *attr);
virtual bool encoding(const QTextCodec*, khtml::encodingList&, bool);
private:
void clear(DocumentPtr*);
};
// -------------------------------------------------------------------------
......@@ -437,8 +422,7 @@ private:
class HTMLOptGroupElementImpl : public HTMLGenericFormElementImpl
{
public:
HTMLOptGroupElementImpl(DocumentPtr *doc);
HTMLOptGroupElementImpl(DocumentPtr *doc, HTMLFormElementImpl *f);
HTMLOptGroupElementImpl(DocumentPtr *doc, HTMLFormElementImpl *f = 0);
virtual ~HTMLOptGroupElementImpl();
virtual Id id() const;
......@@ -462,8 +446,7 @@ class HTMLOptionElementImpl : public HTMLGenericFormElementImpl
friend class DOM::HTMLSelectElementImpl;
public:
HTMLOptionElementImpl(DocumentPtr *doc);
HTMLOptionElementImpl(DocumentPtr *doc, HTMLFormElementImpl *f);
HTMLOptionElementImpl(DocumentPtr *doc, HTMLFormElementImpl *f = 0);
virtual Id id() const;
......@@ -501,8 +484,7 @@ public:
ta_Physical
};
HTMLTextAreaElementImpl(DocumentPtr *doc);
HTMLTextAreaElementImpl(DocumentPtr *doc, HTMLFormElementImpl *f);
HTMLTextAreaElementImpl(DocumentPtr *doc, HTMLFormElementImpl *f = 0);
virtual Id id() const;
......@@ -549,18 +531,13 @@ protected:
class HTMLIsIndexElementImpl : public HTMLInputElementImpl
{
public:
HTMLIsIndexElementImpl(DocumentPtr *doc);
HTMLIsIndexElementImpl(DocumentPtr *doc, HTMLFormElementImpl *f);
HTMLIsIndexElementImpl(DocumentPtr *doc, HTMLFormElementImpl *f = 0);
~HTMLIsIndexElementImpl();
virtual Id id() const;
virtual void parseAttribute(AttrImpl *attr);
virtual void init();
protected:
DOMString m_prompt;
};
......
......@@ -38,7 +38,6 @@
#include "css/csshelper.h"
#include <kurl.h>
#include <kstringhandler.h>
#include <kdebug.h>
using namespace khtml;
......@@ -62,25 +61,46 @@ void HTMLBaseElementImpl::parseAttribute(AttrImpl *attr)
switch(attr->attrId)
{
case ATTR_HREF:
_href = khtml::parseURL(attr->value());
break;
m_href = khtml::parseURL(attr->value());
process();
break;
case ATTR_TARGET:
_target = attr->value();
break;
m_target = attr->value();
process();
break;
default:
HTMLElementImpl::parseAttribute(attr);
}
}
void HTMLBaseElementImpl::init()
void HTMLBaseElementImpl::insertedIntoDocument()
{
HTMLElementImpl::insertedIntoDocument();
process();
}
void HTMLBaseElementImpl::removedFromDocument()
{
HTMLElementImpl::removedFromDocument();
// Since the document doesn't have a base element...
// (This will break in the case of multiple base elements, but that's not valid anyway (?))
getDocument()->setBaseURL( QString::null );
getDocument()->setBaseTarget( QString::null );
}
void HTMLBaseElementImpl::process()
{
HTMLElementImpl::init();
if (!inDocument())
return;
if(!m_href.isEmpty())
getDocument()->setBaseURL( KURL( getDocument()->view()->part()->url(), m_href.string() ).url() );
if(!_href.isEmpty())
getDocument()->setBaseURL( KURL( getDocument()->view()->part()->url(), _href.string() ).url() );
if(!m_target.isEmpty())
getDocument()->setBaseTarget( m_target.string() );
if(!_target.isEmpty())
getDocument()->setBaseTarget( _target.string() );
// ### should changing a document's base URL dynamically automatically update all images, stylesheets etc?
}
// -------------------------------------------------------------------------
......@@ -104,52 +124,25 @@ NodeImpl::Id HTMLLinkElementImpl::id() const
return ID_LINK;
}
void HTMLLinkElementImpl::init()
{
HTMLElementImpl::init();
QString type = m_type.string().lower();
QString rel = m_rel.string().lower();
KHTMLPart* part = getDocument()->view() ? getDocument()->view()->part() : 0;
// IE extension: location of small icon for locationbar / bookmarks
if ( part && rel.contains("shortcut icon") && !m_url.isEmpty() && !part->parentPart())
part->browserExtension()->setIconURL( KURL(m_url.string()) );
if((type.contains("text/css") || rel == "stylesheet") && !rel.contains("alternate"))
{
// no need to load style sheets which aren't for the screen output
// ### there may be in some situations e.g. for an editor or script to manipulate
if( m_media.isNull() || m_media.contains("screen") || m_media.contains("all") || m_media.contains("print") )
{
m_loading = true;
DocumentImpl *doc = getDocument();
// we must have a doc->docLoader() !
QString chset = getAttribute( ATTR_CHARSET ).string();
m_cachedSheet = doc->docLoader()->requestStyleSheet(m_url, chset);
if(m_cachedSheet) m_cachedSheet->ref(this);
}
}
getDocument()->updateStyleSelector();
}
void HTMLLinkElementImpl::parseAttribute(AttrImpl *attr)
{
switch (attr->attrId)
{
case ATTR_REL:
m_rel = attr->value();
process();
break;
case ATTR_HREF:
m_url = getDocument()->completeURL( khtml::parseURL(attr->value()).string() );
process();
break;
case ATTR_TYPE:
m_type = attr->value();
process();
break;
case ATTR_MEDIA:
m_media = attr->value().string().lower();
process();
break;
case ATTR_DISABLED:
// ###
......@@ -159,12 +152,62 @@ void HTMLLinkElementImpl::parseAttribute(AttrImpl *attr)
}
}
void HTMLLinkElementImpl::process()
{
if (!inDocument())
return;
QString type = m_type.string().lower();
QString rel = m_rel.string().lower();
KHTMLPart* part = getDocument()->view() ? getDocument()->view()->part() : 0;
// IE extension: location of small icon for locationbar / bookmarks
if ( part && rel.contains("shortcut icon") && !m_url.isEmpty() && !part->parentPart())
part->browserExtension()->setIconURL( KURL(m_url.string()) );
// Stylesheet
if((type.contains("text/css") || rel == "stylesheet") && !rel.contains("alternate")) {
// no need to load style sheets which aren't for the screen output
// ### there may be in some situations e.g. for an editor or script to manipulate
if( m_media.isNull() || m_media.contains("screen") || m_media.contains("all") || m_media.contains("print") ) {
m_loading = true;
QString chset = getAttribute( ATTR_CHARSET ).string();
if (m_cachedSheet)
m_cachedSheet->deref(this);
m_cachedSheet = getDocument()->docLoader()->requestStyleSheet(m_url, chset);
if (m_cachedSheet)
m_cachedSheet->ref(this);
}
}
else if (m_sheet) {
// we no longer contain a stylesheet, e.g. perhaps rel or type was changed
m_sheet->deref();
m_sheet = 0;
getDocument()->updateStyleSelector();
}
}
void HTMLLinkElementImpl::insertedIntoDocument()
{
HTMLElementImpl::insertedIntoDocument();
process();
}
void HTMLLinkElementImpl::removedFromDocument()
{
HTMLElementImpl::removedFromDocument();
process();
}
void HTMLLinkElementImpl::setStyleSheet(const DOM::DOMString &url, const DOM::DOMString &sheetStr)
{
// kdDebug( 6030 ) << "HTMLLinkElement::setStyleSheet()" << endl;
// kdDebug( 6030 ) << "**** current medium: " << m_media << endl;
if( m_sheet ) return;
if (m_sheet)
m_sheet->deref();
m_sheet = new CSSStyleSheetImpl(this, url);
m_sheet->ref();
m_sheet->parseString(sheetStr);
......@@ -198,12 +241,10 @@ StyleSheetImpl *HTMLLinkElementImpl::sheet() const
return m_sheet;
}
// -------------------------------------------------------------------------
HTMLMetaElementImpl::HTMLMetaElementImpl(DocumentPtr *doc) : HTMLElementImpl(doc)
{
m_processed = false;
}
HTMLMetaElementImpl::~HTMLMetaElementImpl()
......@@ -221,13 +262,11 @@ void HTMLMetaElementImpl::parseAttribute(AttrImpl *attr)
{
case ATTR_HTTP_EQUIV:
m_equiv = attr->value();
m_processed = false;
checkProcess();
process();
break;
case ATTR_CONTENT:
m_content = attr->value();
m_processed = false;
checkProcess();
process();
break;
case ATTR_NAME:
break;
......@@ -238,23 +277,16 @@ void HTMLMetaElementImpl::parseAttribute(AttrImpl *attr)
void HTMLMetaElementImpl::insertedIntoDocument()
{
checkProcess();
HTMLElementImpl::insertedIntoDocument();
process();
}
void HTMLMetaElementImpl::checkProcess()
void HTMLMetaElementImpl::process()
{
if (!m_processed && !m_equiv.isNull