2 * This file is part of the DOM implementation for KDE.
4 * Copyright 1999 Lars Knoll (knoll@kde.org)
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
16 * You should have received a copy of the GNU Library General Public License
17 * along with this library; see the file COPYING.LIB. If not, write to
18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
23 #include "dom/dom_exception.h"
24 #include "xml/dom_docimpl.h"
25 #include "xml/dom_elementimpl.h"
26 #include "html/html_formimpl.h"
34 Attr::Attr(const Attr
&other
) : Node(other
)
38 Attr::Attr( AttrImpl
*_impl
)
41 if (impl
) impl
->ref();
44 Attr
&Attr::operator = (const Node
&other
)
46 NodeImpl
* ohandle
= other
.handle();
47 if ( impl
!= ohandle
) {
48 if (!ohandle
|| !ohandle
->isAttributeNode()) {
49 if (impl
) impl
->deref();
52 Node::operator =(other
);
58 Attr
&Attr::operator = (const Attr
&other
)
60 Node::operator =(other
);
68 DOMString
Attr::name() const
70 if (!impl
) throw DOMException(DOMException::NOT_FOUND_ERR
);
71 return ((AttrImpl
*)impl
)->name();
74 bool Attr::specified() const
76 if (impl
) return ((AttrImpl
*)impl
)->specified();
80 Element
Attr::ownerElement() const
83 return static_cast<AttrImpl
*>(impl
)->ownerElement();
86 DOMString
Attr::value() const
88 if (!impl
) throw DOMException(DOMException::NOT_FOUND_ERR
);
89 return impl
->nodeValue();
92 void Attr::setValue( const DOMString
&newValue
)
97 int exceptioncode
= 0;
98 ((AttrImpl
*)impl
)->setValue(newValue
,exceptioncode
);
100 throw DOMException(exceptioncode
);
103 // ---------------------------------------------------------------------------
105 Element::Element() : Node()
109 Element::Element(const Element
&other
) : Node(other
)
113 Element::Element(ElementImpl
*impl
) : Node(impl
)
117 Element
&Element::operator = (const Node
&other
)
119 NodeImpl
* ohandle
= other
.handle();
120 if ( impl
!= ohandle
) {
121 if (!ohandle
|| !ohandle
->isElementNode()) {
122 if (impl
) impl
->deref();
125 Node::operator =(other
);
131 Element
&Element::operator = (const Element
&other
)
133 Node::operator =(other
);
141 DOMString
Element::tagName() const
143 if (!impl
) throw DOMException(DOMException::NOT_FOUND_ERR
);
144 return static_cast<ElementImpl
*>(impl
)->tagName();
147 DOMString
Element::getAttribute( const DOMString
&name
)
149 // ### getAttribute() and getAttributeNS() are supposed to return the empty string if the attribute
150 // does not exist. However, there are a number of places around khtml that expect a null string
151 // for nonexistent attributes. These need to be changed to use hasAttribute() instead.
152 if (!impl
) throw DOMException(DOMException::NOT_FOUND_ERR
);
153 if (!name
.implementation()) throw DOMException(DOMException::NOT_FOUND_ERR
);
155 return static_cast<ElementImpl
*>(impl
)->getAttribute(name
);
158 void Element::setAttribute( const DOMString
&name
, const DOMString
&value
)
160 if (!impl
) throw DOMException(DOMException::NOT_FOUND_ERR
);
161 int exceptioncode
= 0;
162 static_cast<ElementImpl
*>(impl
)->setAttribute(name
, value
, exceptioncode
);
164 throw DOMException( exceptioncode
);
167 void Element::removeAttribute( const DOMString
&name
)
169 if (!impl
) throw DOMException(DOMException::NOT_FOUND_ERR
);
171 int exceptioncode
= 0;
172 static_cast<ElementImpl
*>(impl
)->removeAttribute(name
, exceptioncode
);
173 // it's allowed to remove attributes that don't exist.
174 if ( exceptioncode
&& exceptioncode
!= DOMException::NOT_FOUND_ERR
)
175 throw DOMException( exceptioncode
);
178 Attr
Element::getAttributeNode( const DOMString
&name
)
180 if (!impl
) throw DOMException(DOMException::NOT_FOUND_ERR
);
181 if (!name
.implementation()) throw DOMException(DOMException::NOT_FOUND_ERR
);
183 return static_cast<ElementImpl
*>(impl
)->getAttributeNode(name
);
186 Attr
Element::setAttributeNode( const Attr
&newAttr
)
188 if (!impl
|| newAttr
.isNull())
189 throw DOMException(DOMException::NOT_FOUND_ERR
);
190 // WRONG_DOCUMENT_ERR and INUSE_ATTRIBUTE_ERR are already tested & thrown by setNamedItem
192 int exceptioncode
= 0;
193 Attr r
= static_cast<ElementImpl
*>(impl
)->setAttributeNode(
194 static_cast<AttrImpl
*>(newAttr
.handle()), exceptioncode
);
196 throw DOMException( exceptioncode
);
200 Attr
Element::removeAttributeNode( const Attr
&oldAttr
)
202 int exceptioncode
= 0;
204 throw DOMException(DOMException::NOT_FOUND_ERR
);
206 Attr ret
= static_cast<ElementImpl
*>(impl
)->removeAttributeNode(
207 static_cast<AttrImpl
*>(oldAttr
.handle()), exceptioncode
);
209 throw DOMException(exceptioncode
);
214 NodeList
Element::getElementsByTagName( const DOMString
&tagName
)
217 return static_cast<ElementImpl
*>(impl
)->getElementsByTagName( tagName
);
220 NodeList
Element::getElementsByTagNameNS( const DOMString
&namespaceURI
,
221 const DOMString
&localName
)
224 return static_cast<ElementImpl
*>(impl
)->getElementsByTagNameNS( namespaceURI
, localName
);
227 NodeList
Element::getElementsByClassName( const DOMString
& className
)
230 return impl
->getElementsByClassName( className
);
233 DOMString
Element::getAttributeNS( const DOMString
&namespaceURI
,
234 const DOMString
&localName
)
236 if (!impl
) throw DOMException(DOMException::NOT_FOUND_ERR
);
237 ElementImpl
* e
= static_cast<ElementImpl
*>(impl
);
238 int exceptioncode
= 0;
239 DOMString ret
= e
->getAttributeNS(namespaceURI
, localName
, exceptioncode
);
241 throw DOMException(exceptioncode
);
245 void Element::setAttributeNS( const DOMString
&namespaceURI
,
246 const DOMString
&qualifiedName
,
247 const DOMString
&value
)
249 if (!impl
) throw DOMException(DOMException::NOT_FOUND_ERR
);
251 int exceptioncode
= 0;
252 static_cast<ElementImpl
*>(impl
)->setAttributeNS(namespaceURI
, qualifiedName
, value
, exceptioncode
);
254 throw DOMException( exceptioncode
);
257 void Element::removeAttributeNS( const DOMString
&namespaceURI
,
258 const DOMString
&localName
)
260 if (!impl
) throw DOMException(DOMException::NOT_FOUND_ERR
);
262 int exceptioncode
= 0;
263 static_cast<ElementImpl
*>(impl
)->removeAttributeNS(namespaceURI
, localName
, exceptioncode
);
265 throw DOMException( exceptioncode
);
268 Attr
Element::getAttributeNodeNS( const DOMString
&namespaceURI
,
269 const DOMString
&localName
)
271 if (!impl
) throw DOMException(DOMException::NOT_FOUND_ERR
);
273 int exceptioncode
= 0;
274 Attr r
= static_cast<ElementImpl
*>(impl
)->getAttributeNodeNS(namespaceURI
, localName
, exceptioncode
);
276 throw DOMException( exceptioncode
);
280 Attr
Element::setAttributeNodeNS( const Attr
&newAttr
)
283 throw DOMException(DOMException::NOT_FOUND_ERR
);
285 int exceptioncode
= 0;
286 Attr r
= static_cast<ElementImpl
*>(impl
)->setAttributeNodeNS(
287 static_cast<AttrImpl
*>(newAttr
.handle()), exceptioncode
);
291 bool Element::hasAttribute( const DOMString
& name
)
293 if (!impl
) return false; // ### throw ?
294 return static_cast<ElementImpl
*>(impl
)->hasAttribute(name
);
297 bool Element::hasAttributeNS( const DOMString
&namespaceURI
,
298 const DOMString
&localName
)
300 if (!impl
) return false;
301 return static_cast<ElementImpl
*>(impl
)->hasAttributeNS(namespaceURI
, localName
);
304 bool Element::isHTMLElement() const
306 if(!impl
) return false;
307 return ((ElementImpl
*)impl
)->isHTMLElement();
310 Element
Element::form() const
312 if (!impl
|| !impl
->isGenericFormElement()) return 0;
313 return static_cast<HTMLGenericFormElementImpl
*>(impl
)->form();
314 ElementImpl
* f
= static_cast<HTMLGenericFormElementImpl
*>( impl
)->form();
316 if( f
&& f
->implicitNode() )
321 CSSStyleDeclaration
Element::style()
323 if (impl
) return ((ElementImpl
*)impl
)->getInlineStyleDecls();
327 Element
Element::firstElementChild() const
329 if (!impl
) throw DOMException(DOMException::NOT_FOUND_ERR
);
330 return static_cast<ElementImpl
*>(impl
)->firstElementChild();
333 Element
Element::lastElementChild() const
335 if (!impl
) throw DOMException(DOMException::NOT_FOUND_ERR
);
336 return static_cast<ElementImpl
*>(impl
)->lastElementChild();
339 Element
Element::previousElementSibling() const
341 if (!impl
) throw DOMException(DOMException::NOT_FOUND_ERR
);
342 return static_cast<ElementImpl
*>(impl
)->previousElementSibling();
345 Element
Element::nextElementSibling() const
347 if (!impl
) throw DOMException(DOMException::NOT_FOUND_ERR
);
348 return static_cast<ElementImpl
*>(impl
)->nextElementSibling();
351 unsigned long Element::childElementCount() const
353 if (!impl
) throw DOMException(DOMException::NOT_FOUND_ERR
);
354 return static_cast<ElementImpl
*>(impl
)->childElementCount();
357 bool Element::khtmlValidAttrName(const DOMString
&name
)
359 // Check if name is valid
360 // http://www.w3.org/TR/2000/REC-xml-20001006#NT-Name
361 DOMStringImpl
* _name
= name
.implementation();
362 QChar ch
= _name
->s
[0];
363 if ( !ch
.isLetter() && ch
!= '_' && ch
!= ':' )
364 return false; // first char isn't valid
365 for ( uint i
= 0; i
< _name
->l
; ++i
)
368 if ( !ch
.isLetter() && !ch
.isDigit() && ch
!= '.'
369 && ch
!= '-' && ch
!= '_' && ch
!= ':'
370 && ch
.category() != QChar::Mark_SpacingCombining
371 /* no idea what "extender is" */ )
377 bool Element::khtmlValidPrefix(const DOMString
&name
)
379 // Null prefix is ok. If not null, reuse code from khtmlValidAttrName
380 return !name
.implementation() || khtmlValidAttrName(name
);
383 bool Element::khtmlValidQualifiedName(const DOMString
&name
)
385 return khtmlValidAttrName(name
);
388 bool Element::khtmlMalformedQualifiedName(const DOMString
&name
)
390 // #### see XML Namespaces spec for possibly more
392 // ### does this disctinction make sense?
398 // a prefix is optional but both prefix as well as local part
400 int colonpos
= name
.find(':');
401 if (colonpos
== 0 || colonpos
== name
.length() - 1)
407 bool Element::khtmlMalformedPrefix(const DOMString
&/*name*/)