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