khtml Library API Documentation

dom_element.cpp

00001 
00024 #include "dom/dom_exception.h"
00025 #include "xml/dom_docimpl.h"
00026 #include "xml/dom_elementimpl.h"
00027 #include "html/html_formimpl.h"
00028 
00029 using namespace DOM;
00030 
00031 Attr::Attr() : Node()
00032 {
00033 }
00034 
00035 Attr::Attr(const Attr &other) : Node(other)
00036 {
00037 }
00038 
00039 Attr::Attr( AttrImpl *_impl )
00040 {
00041     impl= _impl;
00042     if (impl) impl->ref();
00043 }
00044 
00045 Attr &Attr::operator = (const Node &other)
00046 {
00047     NodeImpl* ohandle = other.handle();
00048     if ( impl != ohandle ) {
00049         if (!ohandle || !ohandle->isAttributeNode()) {
00050             if (impl) impl->deref();
00051             impl = 0;
00052         } else {
00053             Node::operator =(other);
00054         }
00055     }
00056     return *this;
00057 }
00058 
00059 Attr &Attr::operator = (const Attr &other)
00060 {
00061     Node::operator =(other);
00062     return *this;
00063 }
00064 
00065 Attr::~Attr()
00066 {
00067 }
00068 
00069 DOMString Attr::name() const
00070 {
00071     if (!impl) throw DOMException(DOMException::NOT_FOUND_ERR);
00072     return ((AttrImpl *)impl)->name();
00073 }
00074 
00075 bool Attr::specified() const
00076 {
00077   if (impl) return ((AttrImpl *)impl)->specified();
00078   return 0;
00079 }
00080 
00081 Element Attr::ownerElement() const
00082 {
00083   if (!impl) return 0;
00084   return static_cast<AttrImpl*>(impl)->ownerElement();
00085 }
00086 
00087 DOMString Attr::value() const
00088 {
00089     if (!impl) throw DOMException(DOMException::NOT_FOUND_ERR);
00090     return impl->nodeValue();
00091 }
00092 
00093 void Attr::setValue( const DOMString &newValue )
00094 {
00095   if (!impl)
00096     return;
00097 
00098   int exceptioncode = 0;
00099   ((AttrImpl *)impl)->setValue(newValue,exceptioncode);
00100   if (exceptioncode)
00101     throw DOMException(exceptioncode);
00102 }
00103 
00104 // ---------------------------------------------------------------------------
00105 
00106 Element::Element() : Node()
00107 {
00108 }
00109 
00110 Element::Element(const Element &other) : Node(other)
00111 {
00112 }
00113 
00114 Element::Element(ElementImpl *impl) : Node(impl)
00115 {
00116 }
00117 
00118 Element &Element::operator = (const Node &other)
00119 {
00120     NodeImpl* ohandle = other.handle();
00121     if ( impl != ohandle ) {
00122         if (!ohandle || !ohandle->isElementNode()) {
00123             if (impl) impl->deref();
00124             impl = 0;
00125     } else {
00126             Node::operator =(other);
00127     }
00128     }
00129     return *this;
00130 }
00131 
00132 Element &Element::operator = (const Element &other)
00133 {
00134     Node::operator =(other);
00135     return *this;
00136 }
00137 
00138 Element::~Element()
00139 {
00140 }
00141 
00142 DOMString Element::tagName() const
00143 {
00144     if (!impl) throw DOMException(DOMException::NOT_FOUND_ERR);
00145     return static_cast<ElementImpl*>(impl)->tagName();
00146 }
00147 
00148 DOMString Element::getAttribute( const DOMString &name )
00149 {
00150     // ### getAttribute() and getAttributeNS() are supposed to return the empty string if the attribute
00151     // does not exist. However, there are a number of places around khtml that expect a null string
00152     // for nonexistent attributes. These need to be changed to use hasAttribute() instead.
00153     if (!impl) throw DOMException(DOMException::NOT_FOUND_ERR);
00154     if (!name.implementation()) throw DOMException(DOMException::NOT_FOUND_ERR);
00155 
00156     NodeImpl::Id id = impl->getDocument()->getId(NodeImpl::AttributeId,name.implementation(),true,true);
00157     if (!id) return DOMString();
00158 
00159     ElementImpl* e = static_cast<ElementImpl*>(impl);
00160     return e->getAttribute(id, false, name);
00161 }
00162 
00163 void Element::setAttribute( const DOMString &name, const DOMString &value )
00164 {
00165     if (!impl) throw DOMException(DOMException::NOT_FOUND_ERR);
00166     int exceptioncode = 0;
00167     NodeImpl::Id id = impl->getDocument()->getId(NodeImpl::AttributeId, name.implementation(), false /* allocate */,
00168                                                  true, &exceptioncode);
00169 
00170     static_cast<ElementImpl*>(impl)->setAttribute(id, value, name, exceptioncode);
00171     if ( exceptioncode )
00172         throw DOMException( exceptioncode );
00173 }
00174 
00175 void Element::removeAttribute( const DOMString &name )
00176 {
00177     if (!impl) throw DOMException(DOMException::NOT_FOUND_ERR);
00178     NodeImpl::Id id = impl->getDocument()->getId(NodeImpl::AttributeId, name.implementation(), true, true);
00179     if (!id) return;
00180 
00181     int exceptioncode = 0;
00182     NamedNodeMapImpl *attributes = static_cast<ElementImpl*>(impl)->attributes(false);
00183     attributes->removeNamedItem(id, false, name.implementation(), exceptioncode);
00184     // it's allowed to remove attributes that don't exist.
00185     if ( exceptioncode && exceptioncode != DOMException::NOT_FOUND_ERR )
00186         throw DOMException( exceptioncode );
00187 }
00188 
00189 Attr Element::getAttributeNode( const DOMString &name )
00190 {
00191     if (!impl) throw DOMException(DOMException::NOT_FOUND_ERR);
00192     if (!name.implementation()) throw DOMException(DOMException::NOT_FOUND_ERR);
00193     NodeImpl::Id id = impl->getDocument()->getId(NodeImpl::AttributeId, name.implementation(), true, true);
00194     if (!id) return 0;
00195 
00196     ElementImpl* e = static_cast<ElementImpl*>(impl);
00197     if (!e->attributes()) return 0;
00198 
00199     return static_cast<AttrImpl*>(e->attributes()->getNamedItem(id, false, name.implementation()));
00200 }
00201 
00202 Attr Element::setAttributeNode( const Attr &newAttr )
00203 {
00204     if (!impl || newAttr.isNull())
00205         throw DOMException(DOMException::NOT_FOUND_ERR);
00206     // WRONG_DOCUMENT_ERR and INUSE_ATTRIBUTE_ERR are already tested & thrown by setNamedItem
00207 
00208     int exceptioncode = 0;
00209     Attr r = static_cast<ElementImpl*>(impl)->attributes(false)->setNamedItem(newAttr.handle(), false,
00210                                newAttr.handle()->nodeName().implementation(), exceptioncode);
00211     if ( exceptioncode )
00212         throw DOMException( exceptioncode );
00213     static_cast<AttrImpl *>(newAttr.handle())->setOwnerElement( static_cast<ElementImpl*>(impl) );
00214     return r;
00215 }
00216 
00217 Attr Element::removeAttributeNode( const Attr &oldAttr )
00218 {
00219     if (!impl || oldAttr.isNull() || oldAttr.ownerElement().handle() != impl)
00220         throw DOMException(DOMException::NOT_FOUND_ERR);
00221 
00222     if (impl->isReadOnly())
00223         throw DOMException(DOMException::NO_MODIFICATION_ALLOWED_ERR);
00224 
00225     if (!static_cast<ElementImpl*>(impl)->attributes(true))
00226         throw DOMException(DOMException::NOT_FOUND_ERR);
00227 
00228     NamedAttrMapImpl *attributes = static_cast<ElementImpl*>(impl)->attributes(false);
00229     return attributes->removeAttr(static_cast<AttrImpl*>(static_cast<AttrImpl*>(oldAttr.handle())));
00230 }
00231 
00232 NodeList Element::getElementsByTagName( const DOMString &tagName )
00233 {
00234     if (!impl) return 0;
00235     NodeImpl::Id id;
00236     if ( tagName == "*" )
00237         id = 0;
00238     else
00239         id = impl->getDocument()->getId(NodeImpl::ElementId, tagName.implementation(), false, true);
00240     return new TagNodeListImpl( impl, id );
00241 }
00242 
00243 NodeList Element::getElementsByTagNameNS( const DOMString &namespaceURI,
00244                                           const DOMString &localName )
00245 {
00246     if (!impl) return 0;
00247     return new TagNodeListImpl( impl, namespaceURI, localName );
00248 }
00249 
00250 DOMString Element::getAttributeNS( const DOMString &namespaceURI,
00251                                    const DOMString &localName)
00252 {
00253     if (!impl) throw DOMException(DOMException::NOT_FOUND_ERR);
00254     if (!localName.implementation()) throw DOMException(DOMException::NOT_FOUND_ERR);
00255     NodeImpl::Id id = impl->getDocument()->getId(NodeImpl::AttributeId, namespaceURI.implementation(), 0/*prefix*/, localName.implementation(), true, true);
00256     ElementImpl* e = static_cast<ElementImpl*>(impl);
00257     return e->getAttribute(id, true);
00258 }
00259 
00260 void Element::setAttributeNS( const DOMString &namespaceURI,
00261                               const DOMString &qualifiedName,
00262                               const DOMString &value)
00263 {
00264     if (!impl) throw DOMException(DOMException::NOT_FOUND_ERR);
00265 
00266     int exceptioncode = 0;
00267     static_cast<ElementImpl*>(impl)->setAttributeNS(namespaceURI, qualifiedName, value, exceptioncode);
00268     if ( exceptioncode )
00269         throw DOMException( exceptioncode );
00270 }
00271 
00272 void Element::removeAttributeNS( const DOMString &namespaceURI,
00273                                  const DOMString &localName )
00274 {
00275     if (!impl) throw DOMException(DOMException::NOT_FOUND_ERR);
00276 
00277     int exceptioncode = 0;
00278     NamedNodeMapImpl *attributes = static_cast<ElementImpl*>(impl)->attributes(false);
00279     NodeImpl::Id id = impl->getDocument()->getId(NodeImpl::AttributeId, namespaceURI.implementation(), 0/*prefix*/, localName.implementation(), false, true);
00280     attributes->removeNamedItem(id, true, 0, exceptioncode);
00281     if ( exceptioncode )
00282         throw DOMException( exceptioncode );
00283 }
00284 
00285 Attr Element::getAttributeNodeNS( const DOMString &namespaceURI,
00286                                   const DOMString &localName )
00287 {
00288     if (!impl) throw DOMException(DOMException::NOT_FOUND_ERR);
00289     if (!localName.implementation()) throw DOMException(DOMException::NOT_FOUND_ERR);
00290     NodeImpl::Id id = impl->getDocument()->getId(NodeImpl::AttributeId, namespaceURI.implementation(),
00291                         0/*prefix*/, localName.implementation(), true, true);
00292     ElementImpl* e = static_cast<ElementImpl*>(impl);
00293     if (!e->attributes()) return 0;
00294 
00295     return static_cast<AttrImpl*>(e->attributes()->getNamedItem(id, true));
00296 }
00297 
00298 Attr Element::setAttributeNodeNS( const Attr &newAttr )
00299 {
00300     if (!impl || newAttr.isNull())
00301         throw DOMException(DOMException::NOT_FOUND_ERR);
00302     // WRONG_DOCUMENT_ERR and INUSE_ATTRIBUTE_ERR are already tested & thrown by setNamedItem
00303 
00304     int exceptioncode = 0;
00305     Attr r = static_cast<ElementImpl*>(impl)->attributes(false)->setNamedItem(newAttr.handle(), true, 0, exceptioncode);
00306     if ( exceptioncode )
00307         throw DOMException( exceptioncode );
00308     static_cast<AttrImpl *>(newAttr.handle())->setOwnerElement( static_cast<ElementImpl*>(impl) );
00309     return r;
00310 }
00311 
00312 
00313 bool Element::hasAttribute( const DOMString& name )
00314 {
00315     if (!impl || !static_cast<ElementImpl*>(impl)->attributes()) return false; // ### throw ?
00316     NodeImpl::Id id = impl->getDocument()->getId(NodeImpl::AttributeId, name.implementation(), true, true);
00317     if (!id) return false;
00318 
00319     if (!static_cast<ElementImpl*>(impl)->attributes(true /*readonly*/)) return false;
00320     return static_cast<ElementImpl*>(impl)->attributes(true)->getValue(id, false, name.implementation()) != 0;
00321 }
00322 
00323 bool Element::hasAttributeNS( const DOMString &namespaceURI,
00324                               const DOMString &localName )
00325 {
00326     if (!impl || !static_cast<ElementImpl*>(impl)->attributes()) return false; // ### throw ?
00327     if (!static_cast<ElementImpl*>(impl)->attributes(true /*readonly*/)) return false;
00328     NodeImpl::Id id = impl->getDocument()->getId(NodeImpl::AttributeId,namespaceURI.implementation(),
00329                          0/*prefix*/, localName.implementation(), true, true);
00330     return static_cast<ElementImpl*>(impl)->attributes(true)->getValue(id, true) != 0;
00331 }
00332 
00333 bool Element::isHTMLElement() const
00334 {
00335     if(!impl) return false;
00336     return ((ElementImpl *)impl)->isHTMLElement();
00337 }
00338 
00339 Element Element::form() const
00340 {
00341     if (!impl || !impl->isGenericFormElement()) return 0;
00342     return static_cast<HTMLGenericFormElementImpl*>(impl)->form();
00343     ElementImpl* f = static_cast<HTMLGenericFormElementImpl*>( impl )->form();
00344 
00345     if( f && f->implicitNode() )
00346         return 0;
00347     return f;
00348 }
00349 
00350 CSSStyleDeclaration Element::style()
00351 {
00352     if (impl) return ((ElementImpl *)impl)->styleRules();
00353     return 0;
00354 }
00355 
00356 bool Element::contentEditable() const {
00357     if(!impl) return false;
00358     return static_cast<ElementImpl *>(impl)->contentEditable();
00359 }
00360 
00361 void Element::setContentEditable(bool enabled) {
00362     if(!impl)
00363         throw DOMException(DOMException::INVALID_STATE_ERR);
00364 
00365     static_cast<ElementImpl *>(impl)->setContentEditable(enabled);
00366 }
00367 
00368 bool Element::khtmlValidAttrName(const DOMString &name)
00369 {
00370     // Check if name is valid
00371     // http://www.w3.org/TR/2000/REC-xml-20001006#NT-Name
00372     DOMStringImpl* _name = name.implementation();
00373     QChar ch = _name->s[0];
00374     if ( !ch.isLetter() && ch != '_' && ch != ':' )
00375         return false; // first char isn't valid
00376     for ( uint i = 0; i < _name->l; ++i )
00377     {
00378         ch = _name->s[i];
00379         if ( !ch.isLetter() && !ch.isDigit() && ch != '.'
00380              && ch != '-' && ch != '_' && ch != ':'
00381              && ch.category() != QChar::Mark_SpacingCombining
00382              /* no idea what "extender is" */ )
00383             return false;
00384     }
00385     return true;
00386 }
00387 
00388 bool Element::khtmlValidPrefix(const DOMString &name)
00389 {
00390     // Null prefix is ok. If not null, reuse code from khtmlValidAttrName
00391     return !name.implementation() || khtmlValidAttrName(name);
00392 }
00393 
00394 bool Element::khtmlValidQualifiedName(const DOMString &name)
00395 {
00396     return khtmlValidAttrName(name);
00397 }
00398 
00399 bool Element::khtmlMalformedQualifiedName(const DOMString &name)
00400 {
00401     // #### Not clearly defined in the DOM spec...
00402     // But we know for sure that a null qualified name is malformed
00403     return name.isNull();
00404 }
00405 
00406 bool Element::khtmlMalformedPrefix(const DOMString &/*name*/)
00407 {
00408     // ####
00409     return false;
00410 }
KDE Logo
This file is part of the documentation for khtml Library Version 3.2.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Thu Mar 3 19:24:46 2005 by doxygen 1.3.6 written by Dimitri van Heesch, © 1997-2003