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.3.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sun Oct 10 18:56:11 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003