Commit 6a579e82 authored by Dirk Mueller's avatar Dirk Mueller

- Attribute handling cleanups and implemented full XML namespace support:

  - AttributeImpl is going to internally store the attribute id and
    value. saves 24 Bytes per attribute.
  - AttrImpl is allocated on demand for DOM compliance. inheriting
    from NodeBaseImpl now as it can have children (text and entityreference)
  - sharing name strings of unknown attributes for reduced memory consumption.
  There are still quite some FIXME's in the code though.
- NodeWParentImpl died as the only use (AttrImpl) got obsolete and
  was a wrong assumption anyway
- related code cleanups in DOM bindings. There is no point in adding
  1 line wrappers in xml/* if the method is completely unused and of
  no use inside khtml. moving the apropiate code directly in the DOM
  bindings.
- removed a lot of "virtual" specifications and made methods inline
  where apropiate. Now making EVERY method virtual is really a
  very, very bad idea. I did this cleanup already some time ago,
  not sure why they popped up again. there is NO point in making
  an accessor virtual that is never reimplement.
- ownerDocument() died in impl classes. using getDocument() everywhere.

result: 1260 less lines of code.

svn path=/trunk/kdelibs/; revision=129740
parent a1a2a52d
......@@ -251,14 +251,33 @@ ProcessingInstruction Document::createProcessingInstruction( const DOMString &ta
Attr Document::createAttribute( const DOMString &name )
{
if (impl) return ((DocumentImpl *)impl)->createAttribute( name );
return 0;
return createAttributeNS(DOMString(), name);
}
Attr Document::createAttributeNS( const DOMString &namespaceURI, const DOMString &qualifiedName )
{
if (impl) return ((DocumentImpl *)impl)->createAttributeNS( namespaceURI, qualifiedName );
return 0;
if (!impl) throw DOMException(DOMException::NOT_FOUND_ERR);
if (qualifiedName.isNull()) throw DOMException(DOMException::NAMESPACE_ERR);
DOMString localName(qualifiedName.copy());
DOMString prefix;
int colonpos;
if ((colonpos = qualifiedName.find(':')) >= 0) {
prefix = qualifiedName.copy();
prefix.truncate(colonpos);
localName.remove(0, colonpos+1);
}
// ### check correctness of parameters
NodeImpl::Id id = static_cast<DocumentImpl*>(impl)->attrId(namespaceURI.implementation(), localName.implementation(), false /* allocate */);
Attr r = static_cast<DocumentImpl*>(impl)->createAttribute(id);
int exceptioncode = 0;
if (r.handle() && prefix.implementation())
r.handle()->setPrefix(prefix.implementation(), exceptioncode);
if (exceptioncode)
throw DOMException(exceptioncode);
return r;
}
EntityReference Document::createEntityReference( const DOMString &name )
......@@ -421,11 +440,17 @@ DocumentFragment::DocumentFragment(DocumentFragmentImpl *i) : Node(i)
// ----------------------------------------------------------------------------
DocumentType::DocumentType() : Node()
DocumentType::DocumentType()
: Node()
{
}
DocumentType::DocumentType(const DocumentType &other) : Node(other)
DocumentType::DocumentType(const DocumentType &other)
: Node(other)
{
}
DocumentType::DocumentType(DocumentTypeImpl *impl) : Node(impl)
{
}
......@@ -499,8 +524,3 @@ DOMString DocumentType::internalSubset() const
return static_cast<DocumentTypeImpl*>(impl)->internalSubset();
}
DocumentType::DocumentType(DocumentTypeImpl *impl) : Node(impl)
{
}
......@@ -22,7 +22,7 @@
*/
#include "dom/dom_exception.h"
#include "xml/dom_docimpl.h"
#include "xml/dom_elementimpl.h"
using namespace DOM;
......@@ -64,10 +64,11 @@ Attr::~Attr()
DOMString Attr::name() const
{
if (impl) return ((AttrImpl *)impl)->name();
return DOMString();
if (!impl) throw DOMException(DOMException::NOT_FOUND_ERR);
return impl->getDocument()->attrName(impl->id());
}
bool Attr::specified() const
{
if (impl) return ((AttrImpl *)impl)->specified();
......@@ -76,14 +77,14 @@ bool Attr::specified() const
Element Attr::ownerElement() const
{
if (impl) return ((AttrImpl *)impl)->ownerElement();
return Element();
if (!impl) return 0;
return static_cast<AttrImpl*>(impl)->ownerElement();
}
DOMString Attr::value() const
{
if (impl) return ((AttrImpl *)impl)->value();
return DOMString();
if (!impl) throw DOMException(DOMException::NOT_FOUND_ERR);
return impl->nodeValue();
}
void Attr::setValue( const DOMString &newValue )
......@@ -134,73 +135,44 @@ Element::~Element()
DOMString Element::tagName() const
{
if (impl) return ((ElementImpl *)impl)->tagName();
return DOMString();
if (!impl) throw DOMException(DOMException::NOT_FOUND_ERR);
return static_cast<ElementImpl*>(impl)->tagName();
}
DOMString Element::getAttribute( const DOMString &name )
{
if (!impl)
return DOMString(); // ### throw exception
int exceptioncode = 0;
DOMString r = ((ElementImpl *)impl)->getAttribute(name, exceptioncode);
if ( exceptioncode )
throw DOMException( exceptioncode );
return r;
return getAttributeNS(DOMString(), name);
}
void Element::setAttribute( const DOMString &name, const DOMString &value )
{
if (!impl)
return;
int exceptioncode = 0;
((ElementImpl *)impl)->setAttribute(name, value, exceptioncode);
if ( exceptioncode )
throw DOMException( exceptioncode );
setAttributeNS(DOMString(), name, value);
}
void Element::removeAttribute( const DOMString &name )
{
if (!impl)
return; // ### throw exception
int exceptioncode = 0;
((ElementImpl *)impl)->removeAttribute(name, exceptioncode);
if ( exceptioncode )
throw DOMException( exceptioncode );
return removeAttributeNS(DOMString(), name);
}
Attr Element::getAttributeNode( const DOMString &name )
{
if (!impl)
return 0;
int exceptioncode = 0;
AttrImpl *r = ((ElementImpl *)impl)->getAttributeNode(name, exceptioncode);
if ( exceptioncode )
throw DOMException( exceptioncode );
return r;
return getAttributeNodeNS(DOMString(), name);
}
Attr Element::setAttributeNode( const Attr &newAttr )
{
int exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR;
Attr r = 0;
if (impl)
r = ((ElementImpl *)impl)->setAttributeNode((AttrImpl *)newAttr.impl, exceptioncode);
if ( exceptioncode )
throw DOMException( exceptioncode );
return r;
return setAttributeNodeNS(newAttr);
}
Attr Element::removeAttributeNode( const Attr &oldAttr )
{
int exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR;
Attr r = 0;
if (impl)
r = ((ElementImpl *)impl)->removeAttributeNode((AttrImpl *)oldAttr.impl, exceptioncode);
if (!impl || oldAttr.isNull() || oldAttr.ownerElement() != *this)
throw DOMException(DOMException::NOT_FOUND_ERR);
if (impl->getDocument() != oldAttr.handle()->getDocument())
throw DOMException(DOMException::WRONG_DOCUMENT_ERR);
int exceptioncode = 0;
Attr r = static_cast<ElementImpl*>(impl)->attributes(true)->removeNamedItem(oldAttr.handle()->id(), exceptioncode);
if ( exceptioncode )
throw DOMException( exceptioncode );
return r;
......@@ -224,37 +196,43 @@ NodeList Element::getElementsByTagNameNS( const DOMString &namespaceURI,
DOMString Element::getAttributeNS( const DOMString &namespaceURI,
const DOMString &localName)
{
if (!impl)
throw DOMException(DOMException::NOT_FOUND_ERR);
int exceptioncode = 0;
DOMString r = ((ElementImpl *)impl)->getAttributeNS(namespaceURI,localName,exceptioncode);
if ( exceptioncode )
throw DOMException( exceptioncode );
return r;
if (!impl) throw DOMException(DOMException::NOT_FOUND_ERR);
NodeImpl::Id id = impl->getDocument()->attrId(namespaceURI.implementation(),
localName.implementation(), true);
if (id == NodeImpl::IdIllegal) return DOMString();
return static_cast<ElementImpl*>(impl)->getAttribute(id);
}
void Element::setAttributeNS( const DOMString &namespaceURI,
const DOMString &qualifiedName,
const DOMString &value)
{
if (!impl)
throw DOMException(DOMException::NOT_FOUND_ERR);
if (!impl) throw DOMException(DOMException::NOT_FOUND_ERR);
int colonpos = qualifiedName.find(':');
DOMString localName = qualifiedName;
if (colonpos >= 0) {
localName.remove(0, colonpos+1);
// ### extract and set new prefix
}
NodeImpl::Id id = impl->getDocument()->attrId(namespaceURI.implementation(),
localName.implementation(), false /* allocate */);
int exceptioncode = 0;
((ElementImpl *)impl)->setAttributeNS(namespaceURI,qualifiedName,value,exceptioncode);
if ( exceptioncode )
throw DOMException( exceptioncode );
static_cast<ElementImpl*>(impl)->setAttribute(id, value.implementation(), exceptioncode);
if (exceptioncode)
throw DOMException(exceptioncode);
}
void Element::removeAttributeNS( const DOMString &namespaceURI,
const DOMString &localName )
{
if (!impl)
throw DOMException(DOMException::NOT_FOUND_ERR);
if (!impl) throw DOMException(DOMException::NOT_FOUND_ERR);
NodeImpl::Id id = impl->getDocument()->attrId(namespaceURI.implementation(),
localName.implementation(), true);
if (id == NodeImpl::IdIllegal) return DOMString();
int exceptioncode = 0;
((ElementImpl *)impl)->removeAttributeNS(namespaceURI,localName,exceptioncode);
((ElementImpl *)impl)->removeAttribute(id, exceptioncode);
if ( exceptioncode )
throw DOMException( exceptioncode );
}
......@@ -262,23 +240,28 @@ void Element::removeAttributeNS( const DOMString &namespaceURI,
Attr Element::getAttributeNodeNS( const DOMString &namespaceURI,
const DOMString &localName )
{
if (!impl)
throw DOMException(DOMException::NOT_FOUND_ERR);
if (!impl) throw DOMException(DOMException::NOT_FOUND_ERR);
NodeImpl::Id id = impl->getDocument()->attrId(namespaceURI.implementation(),
localName.implementation(), true);
if (id == NodeImpl::IdIllegal) return DOMString();
int exceptioncode = 0;
AttrImpl *r = ((ElementImpl *)impl)->getAttributeNodeNS(namespaceURI,localName,exceptioncode);
if ( exceptioncode )
throw DOMException( exceptioncode );
return r;
ElementImpl* e = static_cast<ElementImpl*>(impl);
if (!e->attributes()) return 0; // exception ?
return e->attributes()->getNamedItem(id);
}
Attr Element::setAttributeNodeNS( const Attr &newAttr )
{
if (!impl)
throw DOMException(DOMException::NOT_FOUND_ERR);
if (!impl || newAttr.isNull())
throw DOMException(DOMException::NOT_FOUND_ERR);
if (impl->getDocument() != newAttr.handle()->getDocument())
throw DOMException(DOMException::WRONG_DOCUMENT_ERR);
if (!newAttr.ownerElement().isNull())
throw DOMException(DOMException::INUSE_ATTRIBUTE_ERR);
int exceptioncode = 0;
AttrImpl *r = ((ElementImpl *)impl)->setAttributeNodeNS((AttrImpl*)newAttr.handle(),exceptioncode);
Attr r = static_cast<ElementImpl*>(impl)->attributes(false)->setNamedItem(newAttr.handle(), exceptioncode);
if ( exceptioncode )
throw DOMException( exceptioncode );
return r;
......@@ -287,38 +270,19 @@ Attr Element::setAttributeNodeNS( const Attr &newAttr )
bool Element::hasAttribute( const DOMString& name )
{
if (!impl)
return false; // ### throw exception
int exceptioncode = 0;
bool r = ((ElementImpl *)impl)->hasAttribute(name, exceptioncode);
if ( exceptioncode )
throw DOMException( exceptioncode );
return r;
return hasAttributeNS(DOMString(), name);
}
bool Element::hasAttributeNS( const DOMString &namespaceURI,
const DOMString &localName )
{
if (!impl)
throw DOMException(DOMException::NOT_FOUND_ERR);
int exceptioncode = 0;
bool r = ((ElementImpl *)impl)->hasAttributeNS(namespaceURI,localName,exceptioncode);
if ( exceptioncode )
throw DOMException( exceptioncode );
return r;
}
void Element::normalize()
{
if (!impl)
throw DOMException(DOMException::NOT_FOUND_ERR);
if (!impl || !static_cast<ElementImpl*>(impl)->attributes()) return false; // ### throw ?
NodeImpl::Id id = impl->getDocument()->attrId(namespaceURI.implementation(),
localName.implementation(), true);
if (id == NodeImpl::IdIllegal) return false;
int exceptioncode = 0;
((ElementImpl *)impl)->normalize(exceptioncode);
if (exceptioncode)
throw DOMException(exceptioncode);
if (!static_cast<ElementImpl*>(impl)->attributes(true /*readonly*/)) return false;
return static_cast<ElementImpl*>(impl)->attributes(true)->getAttributeItem(id) != 0;
}
bool Element::isHTMLElement() const
......@@ -333,4 +297,32 @@ CSSStyleDeclaration Element::style()
return 0;
}
bool Element::khtmlValidAttrName(const DOMString &/*name*/)
{
// ###
return true;
}
bool Element::khtmlValidPrefix(const DOMString &/*name*/)
{
// ###
return true;
}
bool Element::khtmlValidQualifiedName(const DOMString &/*name*/)
{
// ###
return true;
}
bool Element::khtmlMalformedQualifiedName(const DOMString &/*name*/)
{
// ###
return false;
}
bool Element::khtmlMalformedPrefix(const DOMString &/*name*/)
{
// ###
return false;
}
......@@ -205,7 +205,8 @@ class Element : public Node
{
friend class Document;
friend class HTMLDocument;
friend class AttrImpl;
// friend class AttrImpl;
friend class Attr;
public:
Element();
......@@ -343,8 +344,6 @@ public:
Attr removeAttributeNode ( const Attr &oldAttr );
/**
* No exceptions.
*
* Returns a <code> NodeList </code> of all descendant elements
* with a given tag name, in the order in which they would be
* encountered in a preorder traversal of the <code> Element
......@@ -360,8 +359,6 @@ public:
/**
* Introduced in DOM Level 2
* No exceptions.
*
* Returns a NodeList of all the descendant Elements with a given local
* name and namespace URI in the order in which they are encountered in a
* preorder traversal of this Element tree.
......@@ -378,7 +375,9 @@ public:
const DOMString &localName );
/**
* Introduced in DOM Level 2
* Introduced in DOM Level 2.
*
* No Exceptions.
*
* Retrieves an attribute value by local name and namespace URI. HTML-only
* DOM implementations do not need to implement this method.
......@@ -527,23 +526,6 @@ public:
bool hasAttributeNS ( const DOMString &namespaceURI,
const DOMString &localName );
/**
* Puts all <code> Text </code> nodes in the full depth of the
* sub-tree underneath this <code> Element </code> into a "normal"
* form where only markup (e.g., tags, comments, processing
* instructions, CDATA sections, and entity references) separates
* <code> Text </code> nodes, i.e., there are no adjacent <code>
* Text </code> nodes. This can be used to ensure that the DOM
* view of a document is the same as if it were saved and
* re-loaded, and is useful when operations (such as XPointer
* lookups) that depend on a particular document tree structure
* are to be used.
*
* @return
*
*/
void normalize ( );
/**
* Introduced in DOM Level 2
* This method is from the CSSStyleDeclaration interface
......@@ -558,8 +540,13 @@ public:
*/
bool isHTMLElement() const;
protected:
static bool khtmlValidAttrName(const DOMString &name);
static bool khtmlValidPrefix(const DOMString &name);
static bool khtmlValidQualifiedName(const DOMString &name);
static bool khtmlMalformedQualifiedName(const DOMString &name);
static bool khtmlMalformedPrefix(const DOMString &name);
protected:
Element(ElementImpl *_impl);
};
......
......@@ -32,8 +32,7 @@ DomShared::~DomShared()
bool DomShared::deleteMe()
{
if(_ref <= 0) return true;
return false;
return !_ref;
}
......@@ -23,18 +23,15 @@
#include "dom/dom_doc.h"
#include "dom/dom_exception.h"
#include "xml/dom_elementimpl.h"
#include "dom/dom2_events.h"
#include "xml/dom_docimpl.h"
#include "xml/dom_elementimpl.h"
#include "xml/dom2_eventsimpl.h"
#include <qrect.h>
using namespace DOM;
// ### eventually we should get these methods to throw NOT_FOUND_ERR
// when they are being used with a null node
//
// unfortunately this breaks a whole heap of stuff at the moment :(
NamedNodeMap::NamedNodeMap()
{
impl = 0;
......@@ -68,89 +65,54 @@ NamedNodeMap::~NamedNodeMap()
Node NamedNodeMap::getNamedItem( const DOMString &name ) const
{
if (!impl)
return 0; // ### enable throw DOMException(DOMException::NOT_FOUND_ERR);
int exceptioncode = 0;
NodeImpl *r = impl->getNamedItem(name,exceptioncode);
if (exceptioncode)
throw DOMException(exceptioncode);
return r;
return getNamedItemNS(DOMString(), name);
}
Node NamedNodeMap::setNamedItem( const Node &arg )
{
if (!impl)
return 0; // ### enable throw throw DOMException(DOMException::NOT_FOUND_ERR);
int exceptioncode = 0;
Node r = impl->setNamedItem(arg,exceptioncode);
if (exceptioncode)
throw DOMException(exceptioncode);
return r;
return setNamedItemNS(arg);
}
Node NamedNodeMap::removeNamedItem( const DOMString &name )
{
if (!impl)
return 0; // ### enable throw DOMException(DOMException::NOT_FOUND_ERR);
int exceptioncode = 0;
Node r = impl->removeNamedItem(name,exceptioncode);
if (exceptioncode)
throw DOMException(exceptioncode);
return r;
return removeNamedItemNS(DOMString(), name);
}
Node NamedNodeMap::item( unsigned long index ) const
{
if (!impl)
return 0; // ### enable throw DOMException(DOMException::NOT_FOUND_ERR);
if (!impl) return 0;
return impl->item(index);
}
Node NamedNodeMap::getNamedItemNS( const DOMString &namespaceURI, const DOMString &localName ) const
{
if (!impl)
throw DOMException(DOMException::NOT_FOUND_ERR);
int exceptioncode = 0;
NodeImpl *r = impl->getNamedItemNS(namespaceURI, localName, exceptioncode);
if (exceptioncode)
throw DOMException(exceptioncode);
return r;
if (!impl) return 0;
return impl->getNamedItem(impl->mapId(namespaceURI, localName, true));
}
Node NamedNodeMap::setNamedItemNS( const Node &arg )
{
if (!impl)
throw DOMException(DOMException::NOT_FOUND_ERR);
if (!impl) throw DOMException(DOMException::NOT_FOUND_ERR);
int exceptioncode = 0;
NodeImpl *r = impl->setNamedItemNS(arg.handle(), exceptioncode);
Node r = impl->setNamedItem(arg.impl, exceptioncode);
if (exceptioncode)
throw DOMException(exceptioncode);
throw DOMException(exceptioncode);
return r;
}
Node NamedNodeMap::removeNamedItemNS( const DOMString &namespaceURI, const DOMString &localName )
{
if (!impl)
throw DOMException(DOMException::NOT_FOUND_ERR);
if (!impl) throw DOMException(DOMException::NOT_FOUND_ERR);
int exceptioncode = 0;
NodeImpl *r = impl->removeNamedItemNS(namespaceURI, localName, exceptioncode);
Node r = impl->removeNamedItem(impl->mapId(namespaceURI, localName, true), exceptioncode);
if (exceptioncode)
throw DOMException(exceptioncode);
throw DOMException(exceptioncode);
return r;
}
unsigned long NamedNodeMap::length() const
{
if (!impl)
return 0; // ### enable throw DOMException(DOMException::NOT_FOUND_ERR);
if (!impl) return 0;
return impl->length();
}
......@@ -194,18 +156,12 @@ Node &Node::operator = (const Node &other)
bool Node::operator == (const Node &other)
{
if(impl == other.impl)
return true;
else
return false;
return (impl == other.impl);
}
bool Node::operator != (const Node &other)
{
if(impl != other.impl)
return true;