File indexing completed on 2024-04-28 15:22:57

0001 /**
0002  * This file is part of the DOM implementation for KDE.
0003  *
0004  * Copyright 1999 Lars Knoll (knoll@kde.org)
0005  *
0006  * This library is free software; you can redistribute it and/or
0007  * modify it under the terms of the GNU Library General Public
0008  * License as published by the Free Software Foundation; either
0009  * version 2 of the License, or (at your option) any later version.
0010  *
0011  * This library is distributed in the hope that it will be useful,
0012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0014  * Library General Public License for more details.
0015  *
0016  * You should have received a copy of the GNU Library General Public License
0017  * along with this library; see the file COPYING.LIB.  If not, write to
0018  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0019  * Boston, MA 02110-1301, USA.
0020  *
0021  */
0022 
0023 #include "dom/dom_doc.h"
0024 #include "dom/dom_exception.h"
0025 #include "dom/dom2_events.h"
0026 #include "xml/dom_docimpl.h"
0027 #include "xml/dom_elementimpl.h"
0028 #include "xml/dom2_eventsimpl.h"
0029 
0030 #include <QRect>
0031 
0032 using namespace DOM;
0033 
0034 NamedNodeMap::NamedNodeMap()
0035 {
0036     impl = nullptr;
0037 }
0038 
0039 NamedNodeMap::NamedNodeMap(const NamedNodeMap &other)
0040 {
0041     impl = other.impl;
0042     if (impl) {
0043         impl->ref();
0044     }
0045 }
0046 
0047 NamedNodeMap::NamedNodeMap(NamedNodeMapImpl *i)
0048 {
0049     impl = i;
0050     if (impl) {
0051         impl->ref();
0052     }
0053 }
0054 
0055 NamedNodeMap &NamedNodeMap::operator = (const NamedNodeMap &other)
0056 {
0057     if (impl != other.impl) {
0058         if (impl) {
0059             impl->deref();
0060         }
0061         impl = other.impl;
0062         if (impl) {
0063             impl->ref();
0064         }
0065     }
0066     return *this;
0067 }
0068 
0069 NamedNodeMap::~NamedNodeMap()
0070 {
0071     if (impl) {
0072         impl->deref();
0073     }
0074 }
0075 
0076 Node NamedNodeMap::getNamedItem(const DOMString &name) const
0077 {
0078     if (!impl) {
0079         return nullptr;
0080     }
0081     return impl->getNamedItem(name);
0082 }
0083 
0084 Node NamedNodeMap::setNamedItem(const Node &arg)
0085 {
0086     if (!impl) {
0087         throw DOMException(DOMException::NOT_FOUND_ERR);
0088     }
0089 
0090     int exceptioncode = 0;
0091     Node r = impl->setNamedItem(arg, exceptioncode);
0092     if (exceptioncode) {
0093         throw DOMException(exceptioncode);
0094     }
0095     return r;
0096 }
0097 
0098 Node NamedNodeMap::removeNamedItem(const DOMString &name)
0099 {
0100     if (!impl) {
0101         throw DOMException(DOMException::NOT_FOUND_ERR);
0102     }
0103     int exceptioncode = 0;
0104     Node r = impl->removeNamedItem(name, exceptioncode);
0105     if (exceptioncode) {
0106         throw DOMException(exceptioncode);
0107     }
0108     return r;
0109 }
0110 
0111 Node NamedNodeMap::item(unsigned long index) const
0112 {
0113     if (!impl) {
0114         return nullptr;
0115     }
0116     return impl->item(index);
0117 }
0118 
0119 Node NamedNodeMap::getNamedItemNS(const DOMString &namespaceURI, const DOMString &localName) const
0120 {
0121     if (!impl) {
0122         return nullptr;
0123     }
0124     return impl->getNamedItemNS(namespaceURI, localName);
0125 }
0126 
0127 Node NamedNodeMap::setNamedItemNS(const Node &arg)
0128 {
0129     if (!impl) {
0130         throw DOMException(DOMException::NOT_FOUND_ERR);
0131     }
0132     int exceptioncode = 0;
0133     Node r = impl->setNamedItemNS(arg, exceptioncode);
0134     if (exceptioncode) {
0135         throw DOMException(exceptioncode);
0136     }
0137     return r;
0138 }
0139 
0140 Node NamedNodeMap::removeNamedItemNS(const DOMString &namespaceURI, const DOMString &localName)
0141 {
0142     if (!impl) {
0143         throw DOMException(DOMException::NOT_FOUND_ERR);
0144     }
0145     int exceptioncode = 0;
0146     Node r = impl->removeNamedItemNS(namespaceURI, localName, exceptioncode);
0147     if (exceptioncode) {
0148         throw DOMException(exceptioncode);
0149     }
0150     return r;
0151 }
0152 
0153 unsigned long NamedNodeMap::length() const
0154 {
0155     if (!impl) {
0156         return 0;
0157     }
0158     return impl->length();
0159 }
0160 
0161 // ---------------------------------------------------------------------------
0162 
0163 Node::Node(const Node &other)
0164 {
0165     impl = other.impl;
0166     if (impl) {
0167         impl->ref();
0168     }
0169 }
0170 
0171 Node::Node(NodeImpl *i)
0172 {
0173     impl = i;
0174     if (impl) {
0175         impl->ref();
0176     }
0177 }
0178 
0179 Node &Node::operator = (const Node &other)
0180 {
0181     if (impl != other.impl) {
0182         if (impl) {
0183             impl->deref();
0184         }
0185         impl = other.impl;
0186         if (impl) {
0187             impl->ref();
0188         }
0189     }
0190     return *this;
0191 }
0192 
0193 bool Node::operator == (const Node &other) const
0194 {
0195     return (impl == other.impl);
0196 }
0197 
0198 bool Node::operator != (const Node &other) const
0199 {
0200     return !(impl == other.impl);
0201 }
0202 
0203 Node::~Node()
0204 {
0205     if (impl) {
0206         impl->deref();
0207     }
0208 }
0209 
0210 DOMString Node::nodeName() const
0211 {
0212     if (impl) {
0213         return impl->nodeName();
0214     }
0215     return DOMString();
0216 }
0217 
0218 DOMString Node::nodeValue() const
0219 {
0220     // ### should throw exception on plain node ?
0221     if (impl) {
0222         return impl->nodeValue();
0223     }
0224     return DOMString();
0225 }
0226 
0227 void Node::setNodeValue(const DOMString &_str)
0228 {
0229     if (!impl) {
0230         throw DOMException(DOMException::NOT_FOUND_ERR);
0231     }
0232 
0233     int exceptioncode = 0;
0234     if (impl) {
0235         impl->setNodeValue(_str, exceptioncode);
0236     }
0237     if (exceptioncode) {
0238         throw DOMException(exceptioncode);
0239     }
0240 }
0241 
0242 unsigned short Node::nodeType() const
0243 {
0244     if (!impl) {
0245         throw DOMException(DOMException::NOT_FOUND_ERR);
0246     }
0247     return impl->nodeType();
0248 }
0249 
0250 Node Node::parentNode() const
0251 {
0252     if (!impl) {
0253         throw DOMException(DOMException::NOT_FOUND_ERR);
0254     }
0255     return impl->parentNode();
0256 }
0257 
0258 NodeList Node::childNodes() const
0259 {
0260     if (!impl) {
0261         return nullptr;
0262     }
0263     return impl->childNodes().get();
0264 }
0265 
0266 Node Node::firstChild() const
0267 {
0268     if (!impl) {
0269         throw DOMException(DOMException::NOT_FOUND_ERR);
0270     }
0271     return impl->firstChild();
0272 }
0273 
0274 Node Node::lastChild() const
0275 {
0276     if (!impl) {
0277         throw DOMException(DOMException::NOT_FOUND_ERR);
0278     }
0279     return impl->lastChild();
0280 }
0281 
0282 Node Node::previousSibling() const
0283 {
0284     if (!impl) {
0285         throw DOMException(DOMException::NOT_FOUND_ERR);
0286     }
0287     return impl->previousSibling();
0288 }
0289 
0290 Node Node::nextSibling() const
0291 {
0292     if (!impl) {
0293         throw DOMException(DOMException::NOT_FOUND_ERR);
0294     }
0295     return impl->nextSibling();
0296 }
0297 
0298 NamedNodeMap Node::attributes() const
0299 {
0300     if (!impl || !impl->isElementNode()) {
0301         return nullptr;
0302     }
0303     return static_cast<ElementImpl *>(impl)->attributes();
0304 }
0305 
0306 Document Node::ownerDocument() const
0307 {
0308     if (!impl || !impl->ownerDocument()) {
0309         return Document(false);
0310     }
0311     return impl->ownerDocument();
0312 }
0313 
0314 Node Node::insertBefore(const Node &newChild, const Node &refChild)
0315 {
0316     if (!impl) {
0317         throw DOMException(DOMException::NOT_FOUND_ERR);
0318     }
0319     int exceptioncode = 0;
0320     NodeImpl *r = impl->insertBefore(newChild.impl, refChild.impl, exceptioncode);
0321     if (exceptioncode) {
0322         throw DOMException(exceptioncode);
0323     }
0324     return r;
0325 }
0326 
0327 Node Node::replaceChild(const Node &newChild, const Node &oldChild)
0328 {
0329     if (!impl) {
0330         throw DOMException(DOMException::NOT_FOUND_ERR);
0331     }
0332     int exceptioncode = 0;
0333     impl->replaceChild(newChild.impl, oldChild.impl, exceptioncode);
0334     if (exceptioncode) {
0335         throw DOMException(exceptioncode);
0336     }
0337     return oldChild;
0338 }
0339 
0340 Node Node::removeChild(const Node &oldChild)
0341 {
0342     if (!impl) {
0343         throw DOMException(DOMException::NOT_FOUND_ERR);
0344     }
0345     int exceptioncode = 0;
0346     impl->removeChild(oldChild.impl, exceptioncode);
0347     if (exceptioncode) {
0348         throw DOMException(exceptioncode);
0349     }
0350 
0351     return oldChild;
0352 }
0353 
0354 Node Node::appendChild(const Node &newChild)
0355 {
0356     if (!impl) {
0357         throw DOMException(DOMException::NOT_FOUND_ERR);
0358     }
0359     int exceptioncode = 0;
0360     NodeImpl *r = impl->appendChild(newChild.impl, exceptioncode);
0361     if (exceptioncode) {
0362         throw DOMException(exceptioncode);
0363     }
0364     return r;
0365 }
0366 
0367 bool Node::hasAttributes()
0368 {
0369     if (!impl) {
0370         throw DOMException(DOMException::NOT_FOUND_ERR);
0371     }
0372     return impl->hasAttributes();
0373 }
0374 
0375 bool Node::hasChildNodes()
0376 {
0377     if (!impl) {
0378         return false;
0379     }
0380     return impl->hasChildNodes();
0381 }
0382 
0383 Node Node::cloneNode(bool deep)
0384 {
0385     if (!impl) {
0386         return nullptr;
0387     }
0388     return impl->cloneNode(deep).get();
0389 }
0390 
0391 void Node::normalize()
0392 {
0393     if (!impl) {
0394         return;
0395     }
0396     impl->normalize();
0397 }
0398 
0399 bool Node::isSupported(const DOMString &feature,
0400                        const DOMString &version) const
0401 {
0402     return NodeImpl::isSupported(feature, version);
0403 }
0404 
0405 DOMString Node::namespaceURI() const
0406 {
0407     if (!impl) {
0408         return DOMString();
0409     }
0410     return impl->namespaceURI();
0411 }
0412 
0413 DOMString Node::prefix() const
0414 {
0415     if (!impl) {
0416         return DOMString();
0417     }
0418     return impl->prefix();
0419 }
0420 
0421 void Node::setPrefix(const DOMString &prefix)
0422 {
0423     if (!impl) {
0424         throw DOMException(DOMException::NOT_FOUND_ERR);
0425     }
0426     int exceptioncode = 0;
0427     impl->setPrefix(prefix, exceptioncode);
0428     if (exceptioncode) {
0429         throw DOMException(exceptioncode);
0430     }
0431 }
0432 
0433 DOMString Node::localName() const
0434 {
0435     if (!impl) {
0436         return DOMString();
0437     }
0438     return impl->localName();
0439 }
0440 
0441 void Node::addEventListener(const DOMString &type,
0442                             EventListener *listener,
0443                             const bool useCapture)
0444 {
0445     if (!impl) {
0446         return;
0447     }
0448     if (listener) {
0449         impl->addEventListener(EventName::fromString(type), listener, useCapture);
0450     }
0451 }
0452 
0453 void Node::removeEventListener(const DOMString &type,
0454                                EventListener *listener,
0455                                bool useCapture)
0456 {
0457     if (!impl) {
0458         return;
0459     }
0460     impl->removeEventListener(EventName::fromString(type), listener, useCapture);
0461 }
0462 
0463 bool Node::dispatchEvent(const Event &evt)
0464 {
0465     if (!impl) {
0466         throw DOMException(DOMException::INVALID_STATE_ERR);
0467     }
0468 
0469     if (!evt.handle()) {
0470         throw DOMException(DOMException::NOT_FOUND_ERR);
0471     }
0472 
0473     int exceptioncode = 0;
0474     impl->dispatchEvent(evt.handle(), exceptioncode);
0475     if (exceptioncode) {
0476         throw DOMException(exceptioncode);
0477     }
0478     return !evt.handle()->defaultPrevented();
0479 }
0480 
0481 DOMString Node::textContent() const
0482 {
0483     if (!impl) {
0484         return DOMString();
0485     }
0486     return impl->textContent();
0487 }
0488 
0489 void Node::setTextContent(const DOMString &content)
0490 {
0491     if (!impl) {
0492         throw DOMException(DOMException::NOT_FOUND_ERR);
0493     }
0494     int exceptioncode = 0;
0495     impl->setTextContent(content, exceptioncode);
0496     if (exceptioncode) {
0497         throw DOMException(exceptioncode);
0498     }
0499 }
0500 
0501 unsigned Node::compareDocumentPosition(const Node &other)
0502 {
0503     if (!impl || !other.impl) {
0504         throw DOMException(DOMException::NOT_FOUND_ERR);
0505     }
0506     return impl->compareDocumentPosition(other.impl);
0507 }
0508 
0509 unsigned int Node::elementId() const
0510 {
0511     if (!impl) {
0512         return 0;
0513     }
0514     return impl->id();
0515 }
0516 
0517 unsigned long Node::index() const
0518 {
0519     if (!impl) {
0520         return 0;
0521     }
0522     return impl->nodeIndex();
0523 }
0524 
0525 #ifndef KHTML_NO_DEPRECATED
0526 QString Node::toHTML()
0527 {
0528     if (!impl) {
0529         return QString();
0530     }
0531     return impl->toString().string();
0532 }
0533 #endif
0534 
0535 void Node::applyChanges()
0536 {
0537     if (!impl) {
0538         return;
0539     }
0540     impl->recalcStyle(NodeImpl::Inherit);
0541 }
0542 
0543 #ifndef KHTML_NO_DEPRECATED
0544 void Node::getCursor(int offset, int &_x, int &_y, int &height)
0545 {
0546     if (!impl) {
0547         throw DOMException(DOMException::NOT_FOUND_ERR);
0548     }
0549     int dummy;
0550     impl->getCaret(offset, false, _x, _y, dummy, height);
0551 }
0552 #endif
0553 
0554 QRect Node::getRect()
0555 {
0556     if (!impl) {
0557         throw DOMException(DOMException::NOT_FOUND_ERR);
0558     }
0559     return impl->getRect();
0560 }
0561 
0562 //-----------------------------------------------------------------------------
0563 
0564 NodeList::NodeList()
0565 {
0566     impl = nullptr;
0567 }
0568 
0569 NodeList::NodeList(const NodeList &other)
0570 {
0571     impl = other.impl;
0572     if (impl) {
0573         impl->ref();
0574     }
0575 }
0576 
0577 NodeList::NodeList(const NodeListImpl *i)
0578 {
0579     impl = const_cast<NodeListImpl *>(i);
0580     if (impl) {
0581         impl->ref();
0582     }
0583 }
0584 
0585 NodeList &NodeList::operator = (const NodeList &other)
0586 {
0587     if (impl != other.impl) {
0588         if (impl) {
0589             impl->deref();
0590         }
0591         impl = other.impl;
0592         if (impl) {
0593             impl->ref();
0594         }
0595     }
0596     return *this;
0597 }
0598 
0599 NodeList::~NodeList()
0600 {
0601     if (impl) {
0602         impl->deref();
0603     }
0604 }
0605 
0606 Node NodeList::item(unsigned long index) const
0607 {
0608     if (!impl) {
0609         return nullptr;
0610     }
0611     return impl->item(index);
0612 }
0613 
0614 unsigned long NodeList::length() const
0615 {
0616     if (!impl) {
0617         return 0;
0618     }
0619     return impl->length();
0620 }
0621 
0622 //-----------------------------------------------------------------------------
0623 
0624 DOMString DOMException::codeAsString() const
0625 {
0626     return codeAsString(code);
0627 }
0628 
0629 DOMString DOMException::codeAsString(int code)
0630 {
0631     switch (code) {
0632     case INDEX_SIZE_ERR:
0633         return DOMString("INDEX_SIZE_ERR");
0634     case DOMSTRING_SIZE_ERR:
0635         return DOMString("DOMSTRING_SIZE_ERR");
0636     case HIERARCHY_REQUEST_ERR:
0637         return DOMString("HIERARCHY_REQUEST_ERR");
0638     case WRONG_DOCUMENT_ERR:
0639         return DOMString("WRONG_DOCUMENT_ERR");
0640     case INVALID_CHARACTER_ERR:
0641         return DOMString("INVALID_CHARACTER_ERR");
0642     case NO_DATA_ALLOWED_ERR:
0643         return DOMString("NO_DATA_ALLOWED_ERR");
0644     case NO_MODIFICATION_ALLOWED_ERR:
0645         return DOMString("NO_MODIFICATION_ALLOWED_ERR");
0646     case NOT_FOUND_ERR:
0647         return DOMString("NOT_FOUND_ERR");
0648     case NOT_SUPPORTED_ERR:
0649         return DOMString("NOT_SUPPORTED_ERR");
0650     case INUSE_ATTRIBUTE_ERR:
0651         return DOMString("INUSE_ATTRIBUTE_ERR");
0652     case INVALID_STATE_ERR:
0653         return DOMString("INVALID_STATE_ERR");
0654     case SYNTAX_ERR:
0655         return DOMString("SYNTAX_ERR");
0656     case INVALID_MODIFICATION_ERR:
0657         return DOMString("INVALID_MODIFICATION_ERR");
0658     case NAMESPACE_ERR:
0659         return DOMString("NAMESPACE_ERR");
0660     case INVALID_ACCESS_ERR:
0661         return DOMString("INVALID_ACCESS_ERR");
0662     case VALIDATION_ERR:
0663         return DOMString("VALIDATION_ERR");
0664     case TYPE_MISMATCH_ERR:
0665         return DOMString("TYPE_MISMATCH_ERR");
0666     case SECURITY_ERR:
0667         return DOMString("SECURITY_ERR");
0668     case NETWORK_ERR:
0669         return DOMString("NETWORK_ERR");
0670     case ABORT_ERR:
0671         return DOMString("ABORT_ERR");
0672     case URL_MISMATCH_ERR:
0673         return DOMString("URL_MISMATCH_ERR");
0674     case QUOTA_EXCEEDED_ERR:
0675         return DOMString("QUOTA_EXCEEDED_ERR");
0676     case TIMEOUT_ERR:
0677         return DOMString("TIMEOUT_ERR");
0678     case NOT_READABLE_ERR:
0679         return DOMString("NOT_READABLE_ERR");
0680     case DATA_CLONE_ERR:
0681         return DOMString("DATA_CLONE_ERR");
0682     case ENCODING_ERR:
0683         return DOMString("ENCODING_ERR");
0684     default:
0685         return DOMString("(unknown exception code)");
0686     }
0687 }
0688 
0689 bool DOMException::isDOMExceptionCode(int exceptioncode)
0690 {
0691     return exceptioncode < 100;
0692 }
0693