00001
00024 #include "dom/dom_exception.h"
00025 #include "misc/htmlattrs.h"
00026 #include "misc/htmltags.h"
00027 #include "xml/dom_elementimpl.h"
00028 #include "xml/dom_textimpl.h"
00029 #include "xml/dom2_eventsimpl.h"
00030 #include "xml/dom_docimpl.h"
00031 #include "xml/dom_nodeimpl.h"
00032
00033 #include <kglobal.h>
00034 #include <kdebug.h>
00035
00036 #include "rendering/render_text.h"
00037
00038 #include "ecma/kjs_proxy.h"
00039 #include "khtmlview.h"
00040 #include "khtml_part.h"
00041
00042
00043 using namespace DOM;
00044 using namespace khtml;
00045
00046 NodeImpl::NodeImpl(DocumentPtr *doc)
00047 : document(doc),
00048 m_previous(0),
00049 m_next(0),
00050 m_render(0),
00051 m_regdListeners( 0 ),
00052 m_tabIndex( 0 ),
00053 m_hasId( false ),
00054 m_hasStyle( false ),
00055 m_pressed( false ),
00056 m_attached(false),
00057 m_changed( false ),
00058 m_hasChangedChild( false ),
00059 m_inDocument( false ),
00060 m_hasAnchor( false ),
00061 m_specified( false ),
00062 m_focused( false ),
00063 m_active( false ),
00064 m_styleElement( false ),
00065 m_implicit( false )
00066 {
00067 if (document)
00068 document->ref();
00069 }
00070
00071 NodeImpl::~NodeImpl()
00072 {
00073 if (m_render)
00074 detach();
00075 delete m_regdListeners;
00076 if (document)
00077 document->deref();
00078 if (m_previous)
00079 m_previous->setNextSibling(0);
00080 if (m_next)
00081 m_next->setPreviousSibling(0);
00082 }
00083
00084 DOMString NodeImpl::nodeValue() const
00085 {
00086 return DOMString();
00087 }
00088
00089 void NodeImpl::setNodeValue( const DOMString &, int &exceptioncode )
00090 {
00091
00092 if (isReadOnly()) {
00093 exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR;
00094 return;
00095 }
00096
00097
00098 }
00099
00100 DOMString NodeImpl::nodeName() const
00101 {
00102 return DOMString();
00103 }
00104
00105 unsigned short NodeImpl::nodeType() const
00106 {
00107 return 0;
00108 }
00109
00110 NodeListImpl *NodeImpl::childNodes()
00111 {
00112 return new ChildNodeListImpl(this);
00113 }
00114
00115 NodeImpl *NodeImpl::firstChild() const
00116 {
00117 return 0;
00118 }
00119
00120 NodeImpl *NodeImpl::lastChild() const
00121 {
00122 return 0;
00123 }
00124
00125 NodeImpl *NodeImpl::insertBefore( NodeImpl *, NodeImpl *, int &exceptioncode )
00126 {
00127 exceptioncode = DOMException::HIERARCHY_REQUEST_ERR;
00128 return 0;
00129 }
00130
00131 NodeImpl *NodeImpl::replaceChild( NodeImpl *, NodeImpl *, int &exceptioncode )
00132 {
00133 exceptioncode = DOMException::HIERARCHY_REQUEST_ERR;
00134 return 0;
00135 }
00136
00137 NodeImpl *NodeImpl::removeChild( NodeImpl *, int &exceptioncode )
00138 {
00139 exceptioncode = DOMException::NOT_FOUND_ERR;
00140 return 0;
00141 }
00142
00143 NodeImpl *NodeImpl::appendChild( NodeImpl *, int &exceptioncode )
00144 {
00145 exceptioncode = DOMException::HIERARCHY_REQUEST_ERR;
00146 return 0;
00147 }
00148
00149 bool NodeImpl::hasChildNodes( ) const
00150 {
00151 return false;
00152 }
00153
00154 void NodeImpl::normalize ()
00155 {
00156
00157 int exceptioncode = 0;
00158 NodeImpl *child = firstChild();
00159
00160
00161
00162 while (child) {
00163 NodeImpl *nextChild = child->nextSibling();
00164
00165 if (nextChild && child->nodeType() == Node::TEXT_NODE && nextChild->nodeType() == Node::TEXT_NODE) {
00166
00167 TextImpl *currentText = static_cast<TextImpl*>(child);
00168 TextImpl *nextText = static_cast<TextImpl*>(nextChild);
00169
00170 currentText->appendData(nextText->data(),exceptioncode);
00171 if (exceptioncode)
00172 return;
00173
00174 removeChild(nextChild,exceptioncode);
00175 if (exceptioncode)
00176 return;
00177 }
00178 else {
00179 child->normalize();
00180 child = nextChild;
00181 }
00182 }
00183 }
00184
00185 DOMString NodeImpl::prefix() const
00186 {
00187
00188 return DOMString();
00189 }
00190
00191 void NodeImpl::setPrefix(const DOMString &, int &exceptioncode )
00192 {
00193
00194
00195
00196 exceptioncode = DOMException::NAMESPACE_ERR;
00197 }
00198
00199 DOMString NodeImpl::localName() const
00200 {
00201 return DOMString();
00202 }
00203
00204 void NodeImpl::setFirstChild(NodeImpl *)
00205 {
00206 }
00207
00208 void NodeImpl::setLastChild(NodeImpl *)
00209 {
00210 }
00211
00212 NodeImpl *NodeImpl::addChild(NodeImpl *)
00213 {
00214 return 0;
00215 }
00216
00217 QString NodeImpl::toHTML() const
00218 {
00219 qDebug("NodeImpl::toHTML");
00220 NodeImpl* fc = firstChild();
00221 if ( fc )
00222 return fc->recursive_toHTML(true);
00223
00224 return "";
00225 }
00226
00227 static QString escapeHTML( const QString& in )
00228 {
00229 QString s;
00230 for ( unsigned int i = 0; i < in.length(); ++i ) {
00231 switch( in[i].latin1() ) {
00232 case '&':
00233 s += "&";
00234 break;
00235 case '<':
00236 s += "<";
00237 break;
00238 case '>':
00239 s += ">";
00240 break;
00241 default:
00242 s += in[i];
00243 }
00244 }
00245
00246 return s;
00247 }
00248
00249 QString NodeImpl::recursive_toHTML(bool start) const
00250 {
00251 QString me = "";
00252
00253
00254 if ( nodeType() == Node::TEXT_NODE )
00255 me = escapeHTML( nodeValue().string() );
00256 else
00257 {
00258
00259 NodeImpl* temp = previousSibling();
00260 if(temp)
00261 {
00262 if( !start && (temp->nodeType() != Node::TEXT_NODE && nodeType() != Node::TEXT_NODE ) )
00263 me = QString(" ") + QChar('<') + nodeName().string();
00264 else
00265 me = QChar('<') + nodeName().string();
00266 }
00267 else
00268 me = QChar('<') + nodeName().string();
00269
00270 if( nodeType() == Node::ELEMENT_NODE )
00271 {
00272 const ElementImpl *el = static_cast<const ElementImpl *>(this);
00273 NamedNodeMap attrs = el->attributes();
00274 unsigned long lmap = attrs.length();
00275 for( unsigned int j=0; j<lmap; j++ )
00276 me += " " + attrs.item(j).nodeName().string() + "=\"" + attrs.item(j).nodeValue().string() + "\"";
00277 }
00278
00279 if( firstChild() == 0 )
00280 me += " />\n";
00281 else
00282 {
00283 NodeImpl* temp = nextSibling();
00284 if(temp)
00285 {
00286 if( (temp->nodeType() != Node::TEXT_NODE) )
00287 me += ">\n";
00288 else
00289 me += ">";
00290 }
00291 else
00292 me += ">";
00293 }
00294 }
00295
00296 NodeImpl* n;
00297
00298 if( (n = firstChild()) )
00299 {
00300
00301 me += n->recursive_toHTML( );
00302
00303
00304 if ( nodeType() != Node::TEXT_NODE )
00305 me += "</" + nodeName().string() + ">\n";
00306 }
00307
00308 if( (n = nextSibling()) )
00309 me += n->recursive_toHTML( );
00310
00311 return me;
00312 }
00313
00314 void NodeImpl::getCursor(int offset, int &_x, int &_y, int &height)
00315 {
00316 if(m_render) m_render->cursorPos(offset, _x, _y, height);
00317 else _x = _y = height = -1;
00318 }
00319
00320 QRect NodeImpl::getRect() const
00321 {
00322 int _x, _y;
00323 if(m_render && m_render->absolutePosition(_x, _y))
00324 return QRect( _x, _y, m_render->width(), m_render->height() );
00325
00326 return QRect();
00327 }
00328
00329 void NodeImpl::setChanged(bool b)
00330 {
00331 if (b && !attached())
00332 return;
00333
00334 m_changed = b;
00335 if ( b ) {
00336 NodeImpl *p = parentNode();
00337 while ( p ) {
00338 p->setHasChangedChild( true );
00339 p = p->parentNode();
00340 }
00341 getDocument()->setDocumentChanged();
00342 }
00343 }
00344
00345 bool NodeImpl::isInline() const
00346 {
00347 if (m_render) return m_render->style()->display() == khtml::INLINE;
00348 return !isElementNode();
00349 }
00350
00351
00352 unsigned long NodeImpl::nodeIndex() const
00353 {
00354 NodeImpl *_tempNode = previousSibling();
00355 unsigned long count=0;
00356 for( count=0; _tempNode; count++ )
00357 _tempNode = _tempNode->previousSibling();
00358 return count;
00359 }
00360
00361 void NodeImpl::addEventListener(int id, EventListener *listener, const bool useCapture)
00362 {
00363 switch (id) {
00364 case EventImpl::DOMSUBTREEMODIFIED_EVENT:
00365 getDocument()->addListenerType(DocumentImpl::DOMSUBTREEMODIFIED_LISTENER);
00366 break;
00367 case EventImpl::DOMNODEINSERTED_EVENT:
00368 getDocument()->addListenerType(DocumentImpl::DOMNODEINSERTED_LISTENER);
00369 break;
00370 case EventImpl::DOMNODEREMOVED_EVENT:
00371 getDocument()->addListenerType(DocumentImpl::DOMNODEREMOVED_LISTENER);
00372 break;
00373 case EventImpl::DOMNODEREMOVEDFROMDOCUMENT_EVENT:
00374 getDocument()->addListenerType(DocumentImpl::DOMNODEREMOVEDFROMDOCUMENT_LISTENER);
00375 break;
00376 case EventImpl::DOMNODEINSERTEDINTODOCUMENT_EVENT:
00377 getDocument()->addListenerType(DocumentImpl::DOMNODEINSERTEDINTODOCUMENT_LISTENER);
00378 break;
00379 case EventImpl::DOMATTRMODIFIED_EVENT:
00380 getDocument()->addListenerType(DocumentImpl::DOMATTRMODIFIED_LISTENER);
00381 break;
00382 case EventImpl::DOMCHARACTERDATAMODIFIED_EVENT:
00383 getDocument()->addListenerType(DocumentImpl::DOMCHARACTERDATAMODIFIED_LISTENER);
00384 break;
00385 default:
00386 break;
00387 }
00388
00389 RegisteredEventListener *rl = new RegisteredEventListener(static_cast<EventImpl::EventId>(id),listener,useCapture);
00390 if (!m_regdListeners) {
00391 m_regdListeners = new QPtrList<RegisteredEventListener>;
00392 m_regdListeners->setAutoDelete(true);
00393 }
00394
00395
00396 removeEventListener(id,listener,useCapture);
00397
00398 m_regdListeners->append(rl);
00399 }
00400
00401 void NodeImpl::removeEventListener(int id, EventListener *listener, bool useCapture)
00402 {
00403 if (!m_regdListeners)
00404 return;
00405
00406 RegisteredEventListener rl(static_cast<EventImpl::EventId>(id),listener,useCapture);
00407
00408 QPtrListIterator<RegisteredEventListener> it(*m_regdListeners);
00409 for (; it.current(); ++it)
00410 if (*(it.current()) == rl) {
00411 m_regdListeners->removeRef(it.current());
00412 return;
00413 }
00414 }
00415
00416 void NodeImpl::removeHTMLEventListener(int id)
00417 {
00418 if (!m_regdListeners)
00419 return;
00420
00421 QPtrListIterator<RegisteredEventListener> it(*m_regdListeners);
00422 for (; it.current(); ++it)
00423 if (it.current()->id == id &&
00424 it.current()->listener->eventListenerType() == "_khtml_HTMLEventListener") {
00425 m_regdListeners->removeRef(it.current());
00426 return;
00427 }
00428 }
00429
00430 void NodeImpl::setHTMLEventListener(int id, EventListener *listener)
00431 {
00432
00433 if (listener)
00434 listener->ref();
00435 removeHTMLEventListener(id);
00436 if (listener)
00437 {
00438 addEventListener(id,listener,false);
00439 listener->deref();
00440 }
00441 }
00442
00443 EventListener *NodeImpl::getHTMLEventListener(int id)
00444 {
00445 if (!m_regdListeners)
00446 return 0;
00447
00448 QPtrListIterator<RegisteredEventListener> it(*m_regdListeners);
00449 for (; it.current(); ++it)
00450 if (it.current()->id == id &&
00451 it.current()->listener->eventListenerType() == "_khtml_HTMLEventListener") {
00452 return it.current()->listener;
00453 }
00454 return 0;
00455 }
00456
00457
00458 bool NodeImpl::dispatchEvent(EventImpl *evt, int &exceptioncode, bool tempEvent)
00459 {
00460
00461 if (!evt) {
00462 exceptioncode = DOMException::NOT_FOUND_ERR;
00463 return false;
00464 }
00465
00466 evt->setTarget(this);
00467
00468
00469 KHTMLView *view = document->document()->view();
00470
00471 bool ret = dispatchGenericEvent( evt, exceptioncode );
00472
00473
00474
00475
00476 if (tempEvent && view && view->part() && view->part()->jScript())
00477 view->part()->jScript()->finishedWithEvent(evt);
00478
00479 return ret;
00480 }
00481
00482 bool NodeImpl::dispatchGenericEvent( EventImpl *evt, int &)
00483 {
00484
00485
00486
00487 QPtrList<NodeImpl> nodeChain;
00488 NodeImpl *n;
00489 for (n = this; n; n = n->parentNode()) {
00490 n->ref();
00491 nodeChain.prepend(n);
00492 }
00493
00494
00495 evt->setEventPhase(Event::CAPTURING_PHASE);
00496 QPtrListIterator<NodeImpl> it(nodeChain);
00497 for (; it.current() && it.current() != this && !evt->propagationStopped(); ++it) {
00498 evt->setCurrentTarget(it.current());
00499 it.current()->handleLocalEvents(evt,true);
00500 }
00501
00502
00503 it.toLast();
00504 if (!evt->propagationStopped()) {
00505 evt->setEventPhase(Event::AT_TARGET);
00506 evt->setCurrentTarget(it.current());
00507 it.current()->handleLocalEvents(evt, true);
00508 if (!evt->propagationStopped())
00509 it.current()->handleLocalEvents(evt,false);
00510 }
00511 --it;
00512
00513 if (evt->bubbles()) {
00514 evt->stopPropagation(false);
00515 NodeImpl* propagationSentinel = 0;
00516
00517 evt->setEventPhase(Event::BUBBLING_PHASE);
00518 for (; it.current() && !evt->propagationStopped(); --it) {
00519 if (evt->propagationStopped()) propagationSentinel = it.current();
00520 evt->setCurrentTarget(it.current());
00521 it.current()->handleLocalEvents(evt,false);
00522 }
00523
00524
00525 evt->setCurrentTarget(0);
00526 evt->setEventPhase(0);
00527 for (it.toLast(); it.current() && it.current() != propagationSentinel &&
00528 !evt->defaultPrevented() && !evt->defaultHandled(); --it)
00529 it.current()->defaultEventHandler(evt);
00530
00531 if (evt->id() == EventImpl::CLICK_EVENT && !evt->defaultPrevented() &&
00532 static_cast<MouseEventImpl*>(evt)->button() == 0)
00533 dispatchUIEvent(EventImpl::DOMACTIVATE_EVENT, static_cast<UIEventImpl*>(evt)->detail());
00534 }
00535
00536
00537 DocumentPtr *doc = document;
00538 doc->ref();
00539
00540
00541 it.toFirst();
00542 for (; it.current(); ++it)
00543 it.current()->deref();
00544
00545 DocumentImpl::updateDocumentsRendering();
00546 doc->deref();
00547
00548 return !evt->defaultPrevented();
00549 }
00550
00551 bool NodeImpl::dispatchHTMLEvent(int _id, bool canBubbleArg, bool cancelableArg)
00552 {
00553 int exceptioncode = 0;
00554 EventImpl *evt = new EventImpl(static_cast<EventImpl::EventId>(_id),canBubbleArg,cancelableArg);
00555 evt->ref();
00556 bool r = dispatchEvent(evt,exceptioncode,true);
00557 evt->deref();
00558 return r;
00559 }
00560
00561 bool NodeImpl::dispatchWindowEvent(int _id, bool canBubbleArg, bool cancelableArg)
00562 {
00563 int exceptioncode = 0;
00564 EventImpl *evt = new EventImpl(static_cast<EventImpl::EventId>(_id),canBubbleArg,cancelableArg);
00565 evt->setTarget( 0 );
00566 evt->ref();
00567 DocumentPtr *doc = document;
00568 doc->ref();
00569 bool r = dispatchGenericEvent( evt, exceptioncode );
00570 if (!evt->defaultPrevented())
00571 doc->document()->defaultEventHandler(evt);
00572 doc->deref();
00573 evt->deref();
00574 return r;
00575 }
00576
00577 bool NodeImpl::dispatchMouseEvent(QMouseEvent *_mouse, int overrideId, int overrideDetail)
00578 {
00579 bool cancelable = true;
00580 int detail = overrideDetail;
00581 EventImpl::EventId evtId = EventImpl::UNKNOWN_EVENT;
00582 if (overrideId) {
00583 evtId = static_cast<EventImpl::EventId>(overrideId);
00584 }
00585 else {
00586 switch (_mouse->type()) {
00587 case QEvent::MouseButtonPress:
00588 evtId = EventImpl::MOUSEDOWN_EVENT;
00589 break;
00590 case QEvent::MouseButtonRelease:
00591 evtId = EventImpl::MOUSEUP_EVENT;
00592 break;
00593 case QEvent::MouseButtonDblClick:
00594 evtId = EventImpl::CLICK_EVENT;
00595 detail = 1;
00596 break;
00597 case QEvent::MouseMove:
00598 evtId = EventImpl::MOUSEMOVE_EVENT;
00599 cancelable = false;
00600 break;
00601 default:
00602 break;
00603 }
00604 }
00605 if (evtId == EventImpl::UNKNOWN_EVENT)
00606 return false;
00607
00608
00609 int exceptioncode = 0;
00610
00611
00612
00613 int clientX = _mouse->x();
00614 int clientY = _mouse->y();
00615
00616 int screenX = _mouse->globalX();
00617 int screenY = _mouse->globalY();
00618
00619 int button = -1;
00620 switch (_mouse->button()) {
00621 case Qt::LeftButton:
00622 button = 0;
00623 break;
00624 case Qt::MidButton:
00625 button = 1;
00626 break;
00627 case Qt::RightButton:
00628 button = 2;
00629 break;
00630 default:
00631 break;
00632 }
00633 bool ctrlKey = (_mouse->state() & Qt::ControlButton) == Qt::ControlButton;
00634 bool altKey = (_mouse->state() & Qt::AltButton) == Qt::AltButton;
00635 bool shiftKey = (_mouse->state() & Qt::ShiftButton) == Qt::ShiftButton;
00636 bool metaKey = false;
00637
00638 EventImpl *evt = new MouseEventImpl(evtId,true,cancelable,getDocument()->defaultView(),
00639 detail,screenX,screenY,clientX,clientY,ctrlKey,altKey,shiftKey,metaKey,
00640 button,0);
00641 evt->ref();
00642 bool r = dispatchEvent(evt,exceptioncode,true);
00643 evt->deref();
00644 return r;
00645
00646 }
00647
00648 bool NodeImpl::dispatchUIEvent(int _id, int detail)
00649 {
00650 assert (!( (_id != EventImpl::DOMFOCUSIN_EVENT &&
00651 _id != EventImpl::DOMFOCUSOUT_EVENT &&
00652 _id != EventImpl::DOMACTIVATE_EVENT)));
00653
00654 bool cancelable = false;
00655 if (_id == EventImpl::DOMACTIVATE_EVENT)
00656 cancelable = true;
00657
00658 int exceptioncode = 0;
00659 UIEventImpl *evt = new UIEventImpl(static_cast<EventImpl::EventId>(_id),true,
00660 cancelable,getDocument()->defaultView(),detail);
00661 evt->ref();
00662 bool r = dispatchEvent(evt,exceptioncode,true);
00663 evt->deref();
00664 return r;
00665 }
00666
00667 bool NodeImpl::dispatchSubtreeModifiedEvent()
00668 {
00669 childrenChanged();
00670 if (!getDocument()->hasListenerType(DocumentImpl::DOMSUBTREEMODIFIED_LISTENER))
00671 return false;
00672 int exceptioncode = 0;
00673 return dispatchEvent(new MutationEventImpl(EventImpl::DOMSUBTREEMODIFIED_EVENT,
00674 true,false,0,DOMString(),DOMString(),DOMString(),0),exceptioncode,true);
00675 }
00676
00677 bool NodeImpl::dispatchKeyEvent(QKeyEvent *key)
00678 {
00679 int exceptioncode = 0;
00680
00681 TextEventImpl *keyEventImpl = new TextEventImpl(key, getDocument()->defaultView());
00682 keyEventImpl->ref();
00683 bool r = dispatchEvent(keyEventImpl,exceptioncode,true);
00684
00685
00686 if (!keyEventImpl->defaultPrevented() && !keyEventImpl->qKeyEvent->isAccepted())
00687 r = false;
00688 keyEventImpl->deref();
00689 return r;
00690 }
00691
00692 void NodeImpl::handleLocalEvents(EventImpl *evt, bool useCapture)
00693 {
00694 if (!m_regdListeners)
00695 return;
00696
00697 Event ev = evt;
00698 for (QPtrListIterator<RegisteredEventListener> it(*m_regdListeners); it.current();) {
00699 RegisteredEventListener* current = it();
00700 if (current->id == evt->id() && current->useCapture == useCapture)
00701 current->listener->handleEvent(ev);
00702
00703 if (current->useCapture == useCapture && evt->id() == EventImpl::CLICK_EVENT &&
00704 ( ( static_cast<MouseEventImpl*>(evt)->detail() == 1 && current->id == EventImpl::KHTML_ECMA_CLICK_EVENT) ||
00705 ( static_cast<MouseEventImpl*>(evt)->detail() > 1 && current->id == EventImpl::KHTML_ECMA_DBLCLICK_EVENT) ) )
00706 current->listener->handleEvent(ev);
00707 }
00708 }
00709
00710 void NodeImpl::defaultEventHandler(EventImpl *)
00711 {
00712 }
00713
00714 unsigned long NodeImpl::childNodeCount()
00715 {
00716 return 0;
00717 }
00718
00719 NodeImpl *NodeImpl::childNode(unsigned long )
00720 {
00721 return 0;
00722 }
00723
00724 NodeImpl *NodeImpl::traverseNextNode(NodeImpl *stayWithin) const
00725 {
00726 if (firstChild())
00727 return firstChild();
00728 else if (nextSibling())
00729 return nextSibling();
00730 else {
00731 const NodeImpl *n = this;
00732 while (n && !n->nextSibling() && (!stayWithin || n->parentNode() != stayWithin))
00733 n = n->parentNode();
00734 if (n && (!stayWithin || n->parentNode() != stayWithin))
00735 return n->nextSibling();
00736 }
00737 return 0;
00738 }
00739
00740 NodeImpl *NodeImpl::traversePreviousNode() const
00741 {
00742 if (previousSibling()) {
00743 NodeImpl *n = previousSibling();
00744 while (n->lastChild())
00745 n = n->lastChild();
00746 return n;
00747 }
00748 else if (parentNode()) {
00749 return parentNode();
00750 }
00751 else {
00752 return 0;
00753 }
00754 }
00755
00756 void NodeImpl::checkSetPrefix(const DOMString &_prefix, int &exceptioncode)
00757 {
00758
00759
00760
00761
00762 if (!Element::khtmlValidPrefix(_prefix)) {
00763 exceptioncode = DOMException::INVALID_CHARACTER_ERR;
00764 return;
00765 }
00766
00767
00768 if (isReadOnly()) {
00769 exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR;
00770 return;
00771 }
00772
00773
00774
00775
00776
00777
00778
00779
00780 if (Element::khtmlMalformedPrefix(_prefix) || (!(id() & NodeImpl_IdNSMask) && id() > ID_LAST_TAG) ||
00781 (_prefix == "xml" && DOMString(getDocument()->namespaceURI(id())) != "http://www.w3.org/XML/1998/namespace")) {
00782 exceptioncode = DOMException::NAMESPACE_ERR;
00783 return;
00784 }
00785 }
00786
00787 void NodeImpl::checkAddChild(NodeImpl *newChild, int &exceptioncode)
00788 {
00789
00790
00791
00792
00793 if (!newChild) {
00794 exceptioncode = DOMException::NOT_FOUND_ERR;
00795 return;
00796 }
00797
00798
00799 if (isReadOnly()) {
00800 exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR;
00801 return;
00802 }
00803
00804
00805
00806
00807
00808 if (newChild->getDocument() != getDocument()) {
00809 exceptioncode = DOMException::WRONG_DOCUMENT_ERR;
00810 return;
00811 }
00812
00813
00814
00815
00816
00817 if (isAncestor(newChild)) {
00818 exceptioncode = DOMException::HIERARCHY_REQUEST_ERR;
00819 return;
00820 }
00821
00822
00823 if (newChild->nodeType() == Node::DOCUMENT_FRAGMENT_NODE) {
00824
00825 NodeImpl *child;
00826 for (child = newChild->firstChild(); child; child = child->nextSibling()) {
00827 if (!childAllowed(child)) {
00828 exceptioncode = DOMException::HIERARCHY_REQUEST_ERR;
00829 return;
00830 }
00831 }
00832 }
00833 else {
00834
00835 if(!childAllowed(newChild)) {
00836 exceptioncode = DOMException::HIERARCHY_REQUEST_ERR;
00837 return;
00838 }
00839 }
00840 }
00841
00842 bool NodeImpl::isAncestor( NodeImpl *other )
00843 {
00844
00845 NodeImpl *n;
00846 for (n = this; n; n = n->parentNode()) {
00847 if (n == other)
00848 return true;
00849 }
00850 return false;
00851 }
00852
00853 bool NodeImpl::childAllowed( NodeImpl *newChild )
00854 {
00855 return childTypeAllowed(newChild->nodeType());
00856 }
00857
00858 NodeImpl::StyleChange NodeImpl::diff( khtml::RenderStyle *s1, khtml::RenderStyle *s2 ) const
00859 {
00860 StyleChange ch = NoInherit;
00861 if ( !s1 || !s2 )
00862 ch = Inherit;
00863 else if ( *s1 == *s2 )
00864 ch = NoChange;
00865 else if ( s1->inheritedNotEqual( s2 ) )
00866 ch = Inherit;
00867 return ch;
00868 }
00869
00870 #ifndef NDEBUG
00871 void NodeImpl::dump(QTextStream *stream, QString ind) const
00872 {
00873
00874
00875 if (m_hasId) { *stream << " hasId"; }
00876 if (m_hasStyle) { *stream << " hasStyle"; }
00877 if (m_specified) { *stream << " specified"; }
00878 if (m_focused) { *stream << " focused"; }
00879 if (m_active) { *stream << " active"; }
00880 if (m_styleElement) { *stream << " styleElement"; }
00881 if (m_implicit) { *stream << " implicit"; }
00882
00883 *stream << " tabIndex=" << m_tabIndex;
00884 if (m_regdListeners)
00885 *stream << " #regdListeners=" << m_regdListeners->count();
00886 *stream << endl;
00887
00888 NodeImpl *child = firstChild();
00889 while( child != 0 )
00890 {
00891 *stream << ind << child->nodeName().string().ascii() << ": ";
00892 child->dump(stream,ind+" ");
00893 child = child->nextSibling();
00894 }
00895 }
00896 #endif
00897
00898 void NodeImpl::attach()
00899 {
00900 assert(!attached());
00901 assert(!m_render || (m_render->style() && m_render->parent()));
00902 m_attached = true;
00903 }
00904
00905 void NodeImpl::detach()
00906 {
00907
00908
00909 if ( m_render )
00910 m_render->detach();
00911
00912 m_render = 0;
00913 m_attached = false;
00914 }
00915
00916 bool NodeImpl::maintainsState()
00917 {
00918 return false;
00919 }
00920
00921 QString NodeImpl::state()
00922 {
00923 return QString::null;
00924 }
00925
00926 void NodeImpl::restoreState(const QString &)
00927 {
00928 }
00929
00930 void NodeImpl::insertedIntoDocument()
00931 {
00932 setInDocument(true);
00933 }
00934
00935 void NodeImpl::removedFromDocument()
00936 {
00937 setInDocument(false);
00938 }
00939
00940 void NodeImpl::childrenChanged()
00941 {
00942 if (parentNode())
00943 parentNode()->childrenChanged();
00944 }
00945
00946 bool NodeImpl::isReadOnly()
00947 {
00948
00949 NodeImpl *n = this;
00950 while (n) {
00951 if (n->nodeType() == Node::ENTITY_NODE ||
00952 n->nodeType() == Node::ENTITY_REFERENCE_NODE)
00953 return true;
00954 n = n->parentNode();
00955 }
00956 return false;
00957 }
00958
00959 RenderObject * NodeImpl::nextRenderer()
00960 {
00961 for (NodeImpl *n = nextSibling(); n; n = n->nextSibling()) {
00962 if (n->renderer())
00963 return n->renderer();
00964 }
00965 return 0;
00966 }
00967
00968
00969
00970 NodeBaseImpl::~NodeBaseImpl()
00971 {
00972
00973
00974 NodeImpl *n;
00975 NodeImpl *next;
00976
00977 for( n = _first; n != 0; n = next ) {
00978 next = n->nextSibling();
00979 n->setPreviousSibling(0);
00980 n->setNextSibling(0);
00981 n->setParent(0);
00982 if ( !n->refCount() )
00983 delete n;
00984 }
00985 }
00986
00987
00988 NodeImpl *NodeBaseImpl::firstChild() const
00989 {
00990 return _first;
00991 }
00992
00993 NodeImpl *NodeBaseImpl::lastChild() const
00994 {
00995 return _last;
00996 }
00997
00998 NodeImpl *NodeBaseImpl::insertBefore ( NodeImpl *newChild, NodeImpl *refChild, int &exceptioncode )
00999 {
01000 exceptioncode = 0;
01001
01002
01003 if(!refChild)
01004 return appendChild(newChild, exceptioncode);
01005
01006
01007 checkAddChild(newChild, exceptioncode);
01008 if (exceptioncode)
01009 return 0;
01010
01011
01012 if (refChild->parentNode() != this) {
01013 exceptioncode = DOMException::NOT_FOUND_ERR;
01014 return 0;
01015 }
01016
01017 bool isFragment = newChild->nodeType() == Node::DOCUMENT_FRAGMENT_NODE;
01018
01019
01020
01021 if (isFragment && !newChild->firstChild())
01022 return newChild;
01023
01024
01025 NodeImpl *nextChild;
01026 NodeImpl *child = isFragment ? newChild->firstChild() : newChild;
01027
01028 NodeImpl *prev = refChild->previousSibling();
01029 if ( prev == newChild || refChild == newChild )
01030 return newChild;
01031
01032 while (child) {
01033 nextChild = isFragment ? child->nextSibling() : 0;
01034
01035
01036 NodeImpl *newParent = child->parentNode();
01037 if(newParent)
01038 newParent->removeChild( child, exceptioncode );
01039 if ( exceptioncode )
01040 return 0;
01041
01042
01043 if (prev)
01044 prev->setNextSibling(child);
01045 else
01046 _first = child;
01047 refChild->setPreviousSibling(child);
01048 child->setParent(this);
01049 child->setPreviousSibling(prev);
01050 child->setNextSibling(refChild);
01051
01052
01053
01054 if (attached() && !child->attached())
01055 child->attach();
01056
01057
01058 dispatchChildInsertedEvents(child,exceptioncode);
01059
01060 prev = child;
01061 child = nextChild;
01062 }
01063
01064
01065 setChanged(true);
01066 dispatchSubtreeModifiedEvent();
01067 return newChild;
01068 }
01069
01070 NodeImpl *NodeBaseImpl::replaceChild ( NodeImpl *newChild, NodeImpl *oldChild, int &exceptioncode )
01071 {
01072 exceptioncode = 0;
01073
01074 if ( oldChild == newChild )
01075 return oldChild;
01076
01077
01078 checkAddChild(newChild, exceptioncode);
01079 if (exceptioncode)
01080 return 0;
01081
01082
01083 if (!oldChild || oldChild->parentNode() != this) {
01084 exceptioncode = DOMException::NOT_FOUND_ERR;
01085 return 0;
01086 }
01087
01088 bool isFragment = newChild->nodeType() == Node::DOCUMENT_FRAGMENT_NODE;
01089 NodeImpl *nextChild;
01090 NodeImpl *child = isFragment ? newChild->firstChild() : newChild;
01091
01092
01093
01094 NodeImpl *prev = oldChild->previousSibling();
01095 NodeImpl *next = oldChild->nextSibling();
01096
01097 removeChild(oldChild, exceptioncode);
01098 if (exceptioncode)
01099 return 0;
01100
01101
01102 while (child) {
01103 nextChild = isFragment ? child->nextSibling() : 0;
01104
01105
01106 NodeImpl *newParent = child->parentNode();
01107 if(newParent)
01108 newParent->removeChild( child, exceptioncode );
01109 if (exceptioncode)
01110 return 0;
01111
01112
01113 if (prev) prev->setNextSibling(child);
01114 if (next) next->setPreviousSibling(child);
01115 if(!prev) _first = child;
01116 if(!next) _last = child;
01117 child->setParent(this);
01118 child->setPreviousSibling(prev);
01119 child->setNextSibling(next);
01120
01121
01122
01123 if (attached() && !child->attached())
01124 child->attach();
01125
01126
01127 dispatchChildInsertedEvents(child,exceptioncode);
01128
01129 prev = child;
01130 child = nextChild;
01131 }
01132
01133
01134 setChanged(true);
01135 dispatchSubtreeModifiedEvent();
01136 return oldChild;
01137 }
01138
01139 NodeImpl *NodeBaseImpl::removeChild ( NodeImpl *oldChild, int &exceptioncode )
01140 {
01141 exceptioncode = 0;
01142
01143
01144 if (isReadOnly()) {
01145 exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR;
01146 return 0;
01147 }
01148
01149
01150 if (!oldChild || oldChild->parentNode() != this) {
01151 exceptioncode = DOMException::NOT_FOUND_ERR;
01152 return 0;
01153 }
01154
01155
01156 getDocument()->notifyBeforeNodeRemoval(oldChild);
01157 if (getDocument()->hasListenerType(DocumentImpl::DOMNODEREMOVED_LISTENER)) {
01158 oldChild->dispatchEvent(new MutationEventImpl(EventImpl::DOMNODEREMOVED_EVENT,
01159 true,false,this,DOMString(),DOMString(),DOMString(),0),exceptioncode,true);
01160 if (exceptioncode)
01161 return 0;
01162 }
01163
01164 dispatchChildRemovalEvents(oldChild,exceptioncode);
01165 if (exceptioncode)
01166 return 0;
01167
01168
01169 if (oldChild->attached())
01170 oldChild->detach();
01171
01172
01173 NodeImpl *prev, *next;
01174 prev = oldChild->previousSibling();
01175 next = oldChild->nextSibling();
01176
01177 if(next) next->setPreviousSibling(prev);
01178 if(prev) prev->setNextSibling(next);
01179 if(_first == oldChild) _first = next;
01180 if(_last == oldChild) _last = prev;
01181
01182 oldChild->setPreviousSibling(0);
01183 oldChild->setNextSibling(0);
01184 oldChild->setParent(0);
01185
01186 setChanged(true);
01187
01188
01189 dispatchSubtreeModifiedEvent();
01190
01191 NodeImpl *p = this;
01192 while (p->parentNode())
01193 p = p->parentNode();
01194 if (p->nodeType() == Node::DOCUMENT_NODE) {
01195 for (NodeImpl *c = oldChild; c; c = c->traverseNextNode(oldChild))
01196 c->removedFromDocument();
01197 }
01198
01199 return oldChild;
01200 }
01201
01202 void NodeBaseImpl::removeChildren()
01203 {
01204 NodeImpl *n, *next;
01205 for( n = _first; n != 0; n = next )
01206 {
01207 next = n->nextSibling();
01208 if (n->attached())
01209 n->detach();
01210 n->setPreviousSibling(0);
01211 n->setNextSibling(0);
01212 n->setParent(0);
01213 if( !n->refCount() )
01214 delete n;
01215 }
01216 _first = _last = 0;
01217 }
01218
01219
01220 NodeImpl *NodeBaseImpl::appendChild ( NodeImpl *newChild, int &exceptioncode )
01221 {
01222 exceptioncode = 0;
01223
01224
01225 checkAddChild(newChild, exceptioncode);
01226 if (exceptioncode)
01227 return 0;
01228
01229 if ( newChild == _last )
01230 return newChild;
01231
01232 bool isFragment = newChild->nodeType() == Node::DOCUMENT_FRAGMENT_NODE;
01233
01234
01235
01236 if (isFragment && !newChild->firstChild())
01237 return newChild;
01238
01239
01240 NodeImpl *nextChild;
01241 NodeImpl *child = isFragment ? newChild->firstChild() : newChild;
01242
01243 while (child) {
01244 nextChild = isFragment ? child->nextSibling() : 0;
01245
01246
01247 NodeImpl *oldParent = child->parentNode();
01248 if(oldParent) {
01249 oldParent->removeChild( child, exceptioncode );
01250 if (exceptioncode)
01251 return 0;
01252 }
01253
01254
01255 child->setParent(this);
01256
01257 if(_last)
01258 {
01259 child->setPreviousSibling(_last);
01260 _last->setNextSibling(child);
01261 _last = child;
01262 }
01263 else
01264 {
01265 _first = _last = child;
01266 }
01267
01268
01269
01270 if (attached() && !child->attached())
01271 child->attach();
01272
01273
01274 dispatchChildInsertedEvents(child,exceptioncode);
01275
01276 child = nextChild;
01277 }
01278
01279 setChanged(true);
01280
01281 dispatchSubtreeModifiedEvent();
01282 return newChild;
01283 }
01284
01285 bool NodeBaseImpl::hasChildNodes ( ) const
01286 {
01287 return _first != 0;
01288 }
01289
01290
01291 void NodeBaseImpl::setFirstChild(NodeImpl *child)
01292 {
01293 _first = child;
01294 }
01295
01296 void NodeBaseImpl::setLastChild(NodeImpl *child)
01297 {
01298 _last = child;
01299 }
01300
01301
01302 bool NodeBaseImpl::checkSameDocument( NodeImpl *newChild, int &exceptioncode )
01303 {
01304 exceptioncode = 0;
01305 DocumentImpl *ownerDocThis = getDocument();
01306 DocumentImpl *ownerDocNew = getDocument();
01307 if(ownerDocThis != ownerDocNew) {
01308 kdDebug(6010)<< "not same document, newChild = " << newChild << "document = " << getDocument() << endl;
01309 exceptioncode = DOMException::WRONG_DOCUMENT_ERR;
01310 return true;
01311 }
01312 return false;
01313 }
01314
01315
01316 bool NodeBaseImpl::checkIsChild( NodeImpl *oldChild, int &exceptioncode )
01317 {
01318 if(!oldChild || oldChild->parentNode() != this) {
01319 exceptioncode = DOMException::NOT_FOUND_ERR;
01320 return true;
01321 }
01322 return false;
01323 }
01324
01325 NodeImpl *NodeBaseImpl::addChild(NodeImpl *newChild)
01326 {
01327
01328
01329
01330 if(!isXMLElementNode() && !newChild->isXMLElementNode() && !childAllowed(newChild))
01331 {
01332
01333 return 0;
01334 }
01335
01336
01337 newChild->setParent(this);
01338
01339 if(_last)
01340 {
01341 newChild->setPreviousSibling(_last);
01342 _last->setNextSibling(newChild);
01343 _last = newChild;
01344 }
01345 else
01346 {
01347 _first = _last = newChild;
01348 }
01349
01350 newChild->insertedIntoDocument();
01351 childrenChanged();
01352
01353 if(newChild->nodeType() == Node::ELEMENT_NODE)
01354 return newChild;
01355 return this;
01356 }
01357
01358 void NodeBaseImpl::attach()
01359 {
01360 NodeImpl *child = _first;
01361 while(child != 0)
01362 {
01363 child->attach();
01364 child = child->nextSibling();
01365 }
01366 NodeImpl::attach();
01367 }
01368
01369 void NodeBaseImpl::detach()
01370 {
01371 NodeImpl *child = _first;
01372 while(child != 0)
01373 {
01374 NodeImpl* prev = child;
01375 child = child->nextSibling();
01376 prev->detach();
01377 }
01378 NodeImpl::detach();
01379 }
01380
01381 void NodeBaseImpl::cloneChildNodes(NodeImpl *clone)
01382 {
01383 int exceptioncode = 0;
01384 NodeImpl *n;
01385 for(n = firstChild(); n && !exceptioncode; n = n->nextSibling())
01386 {
01387 clone->appendChild(n->cloneNode(true),exceptioncode);
01388 }
01389 }
01390
01391 NodeListImpl* NodeBaseImpl::getElementsByTagNameNS ( DOMStringImpl* namespaceURI,
01392 DOMStringImpl* localName )
01393 {
01394 if (!localName) return 0;
01395
01396 NodeImpl::Id idMask = NodeImpl_IdNSMask | NodeImpl_IdLocalMask;
01397 if (localName->l && localName->s[0] == '*')
01398 idMask &= ~NodeImpl_IdLocalMask;
01399 if (namespaceURI && namespaceURI->l && namespaceURI->s[0] == '*')
01400 idMask &= ~NodeImpl_IdNSMask;
01401
01402 return new TagNodeListImpl( this,
01403 getDocument()->tagId(namespaceURI, localName, true), idMask);
01404 }
01405
01406
01407
01408 bool NodeBaseImpl::getUpperLeftCorner(int &xPos, int &yPos) const
01409 {
01410 if (!m_render)
01411 return false;
01412 RenderObject *o = m_render;
01413 xPos = yPos = 0;
01414 if ( !o->isInline() || o->isReplaced() ) {
01415 o->absolutePosition( xPos, yPos );
01416 return true;
01417 }
01418
01419
01420 while(o) {
01421 if(o->firstChild())
01422 o = o->firstChild();
01423 else if(o->nextSibling())
01424 o = o->nextSibling();
01425 else {
01426 RenderObject *next = 0;
01427 while(!next) {
01428 o = o->parent();
01429 if(!o) return false;
01430 next = o->nextSibling();
01431 }
01432 o = next;
01433 }
01434 if((o->isText() && !o->isBR()) || o->isReplaced()) {
01435 o->container()->absolutePosition( xPos, yPos );
01436 if (o->isText())
01437 xPos += static_cast<RenderText *>(o)->minXPos();
01438 else
01439 xPos += o->xPos();
01440 yPos += o->yPos();
01441 return true;
01442 }
01443 }
01444 return true;
01445 }
01446
01447 bool NodeBaseImpl::getLowerRightCorner(int &xPos, int &yPos) const
01448 {
01449 if (!m_render)
01450 return false;
01451
01452 RenderObject *o = m_render;
01453 xPos = yPos = 0;
01454 if (!o->isInline() || o->isReplaced())
01455 {
01456 o->absolutePosition( xPos, yPos );
01457 xPos += o->width();
01458 yPos += o->height();
01459 return true;
01460 }
01461
01462 while(o) {
01463 if(o->lastChild())
01464 o = o->lastChild();
01465 else if(o->previousSibling())
01466 o = o->previousSibling();
01467 else {
01468 RenderObject *prev = 0;
01469 while(!prev) {
01470 o = o->parent();
01471 if(!o) return false;
01472 prev = o->previousSibling();
01473 }
01474 o = prev;
01475 }
01476 if((o->isText() && !o->isBR()) || o->isReplaced()) {
01477 o->container()->absolutePosition(xPos, yPos);
01478 if (o->isText())
01479 xPos += static_cast<RenderText *>(o)->minXPos() + o->width();
01480 else
01481 xPos += o->xPos()+o->width();
01482 yPos += o->yPos()+o->height();
01483 return true;
01484 }
01485 }
01486 return true;
01487 }
01488
01489 QRect NodeBaseImpl::getRect() const
01490 {
01491 int xPos, yPos;
01492 if (!getUpperLeftCorner(xPos,yPos))
01493 {
01494 xPos=0;
01495 yPos=0;
01496 }
01497 int xEnd, yEnd;
01498 if (!getLowerRightCorner(xEnd,yEnd))
01499 {
01500 if (xPos)
01501 xEnd = xPos;
01502 if (yPos)
01503 yEnd = yPos;
01504 }
01505 else
01506 {
01507 if (xPos==0)
01508 xPos = xEnd;
01509 if (yPos==0)
01510 yPos = yEnd;
01511 }
01512 if ( xEnd <= xPos || yEnd <= yPos )
01513 return QRect( QPoint( xPos, yPos ), QSize() );
01514
01515 return QRect(xPos, yPos, xEnd - xPos, yEnd - yPos);
01516 }
01517
01518 void NodeBaseImpl::setFocus(bool received)
01519 {
01520 if (m_focused == received) return;
01521
01522 NodeImpl::setFocus(received);
01523 for(NodeImpl *it=_first;it;it=it->nextSibling())
01524 it->setFocus(received);
01525
01526
01527 setChanged();
01528 }
01529
01530 void NodeBaseImpl::setActive(bool down)
01531 {
01532 if (down == active()) return;
01533
01534 NodeImpl::setActive(down);
01535
01536
01537 if (m_render && m_render->style()->hasActive())
01538 setChanged();
01539 }
01540
01541 unsigned long NodeBaseImpl::childNodeCount()
01542 {
01543 unsigned long count = 0;
01544 NodeImpl *n;
01545 for (n = firstChild(); n; n = n->nextSibling())
01546 count++;
01547 return count;
01548 }
01549
01550 NodeImpl *NodeBaseImpl::childNode(unsigned long index)
01551 {
01552 unsigned long i;
01553 NodeImpl *n = firstChild();
01554 for (i = 0; i < index; i++)
01555 n = n->nextSibling();
01556 return n;
01557 }
01558
01559 void NodeBaseImpl::dispatchChildInsertedEvents( NodeImpl *child, int &exceptioncode )
01560 {
01561 if (getDocument()->hasListenerType(DocumentImpl::DOMNODEINSERTED_LISTENER)) {
01562 child->dispatchEvent(new MutationEventImpl(EventImpl::DOMNODEINSERTED_EVENT,
01563 true,false,this,DOMString(),DOMString(),DOMString(),0),exceptioncode,true);
01564 if (exceptioncode)
01565 return;
01566 }
01567
01568
01569 bool hasInsertedListeners = getDocument()->hasListenerType(DocumentImpl::DOMNODEINSERTEDINTODOCUMENT_LISTENER);
01570 NodeImpl *p = this;
01571 while (p->parentNode())
01572 p = p->parentNode();
01573 if (p->nodeType() == Node::DOCUMENT_NODE) {
01574 for (NodeImpl *c = child; c; c = c->traverseNextNode(child)) {
01575 c->insertedIntoDocument();
01576
01577 if (hasInsertedListeners) {
01578 c->dispatchEvent(new MutationEventImpl(EventImpl::DOMNODEINSERTEDINTODOCUMENT_EVENT,
01579 false,false,0,DOMString(),DOMString(),DOMString(),0),exceptioncode,true);
01580 if (exceptioncode)
01581 return;
01582 }
01583 }
01584 }
01585 }
01586
01587 void NodeBaseImpl::dispatchChildRemovalEvents( NodeImpl *child, int &exceptioncode )
01588 {
01589
01590 getDocument()->notifyBeforeNodeRemoval(child);
01591 if (getDocument()->hasListenerType(DocumentImpl::DOMNODEREMOVED_LISTENER)) {
01592 child->dispatchEvent(new MutationEventImpl(EventImpl::DOMNODEREMOVED_EVENT,
01593 true,false,this,DOMString(),DOMString(),DOMString(),0),exceptioncode,true);
01594 if (exceptioncode)
01595 return;
01596 }
01597
01598 bool hasRemovalListeners = getDocument()->hasListenerType(DocumentImpl::DOMNODEREMOVEDFROMDOCUMENT_LISTENER);
01599
01600
01601 NodeImpl *p = this;
01602 while (p->parentNode())
01603 p = p->parentNode();
01604 if (p->nodeType() == Node::DOCUMENT_NODE) {
01605 for (NodeImpl *c = child; c; c = c->traverseNextNode(child)) {
01606 if (hasRemovalListeners) {
01607 c->dispatchEvent(new MutationEventImpl(EventImpl::DOMNODEREMOVEDFROMDOCUMENT_EVENT,
01608 false,false,0,DOMString(),DOMString(),DOMString(),0),exceptioncode,true);
01609 if (exceptioncode)
01610 return;
01611 }
01612 }
01613 }
01614 }
01615
01616
01617
01618 NodeImpl *NodeListImpl::item( unsigned long ) const
01619 {
01620 return 0;
01621 }
01622
01623 unsigned long NodeListImpl::length() const
01624 {
01625 return 0;
01626 }
01627
01628 unsigned long NodeListImpl::recursiveLength(NodeImpl *start) const
01629 {
01630 unsigned long len = 0;
01631
01632 for(NodeImpl *n = start->firstChild(); n != 0; n = n->nextSibling()) {
01633 if ( n->nodeType() == Node::ELEMENT_NODE ) {
01634 if (nodeMatches(n))
01635 len++;
01636 len+= recursiveLength(n);
01637 }
01638 }
01639
01640 return len;
01641 }
01642
01643 NodeImpl *NodeListImpl::recursiveItem ( NodeImpl *start, unsigned long &offset ) const
01644 {
01645 for(NodeImpl *n = start->firstChild(); n != 0; n = n->nextSibling()) {
01646 if ( n->nodeType() == Node::ELEMENT_NODE ) {
01647 if (nodeMatches(n))
01648 if (!offset--)
01649 return n;
01650
01651 NodeImpl *depthSearch= recursiveItem(n, offset);
01652 if (depthSearch)
01653 return depthSearch;
01654 }
01655 }
01656
01657 return 0;
01658 }
01659
01660 ChildNodeListImpl::ChildNodeListImpl( NodeImpl *n )
01661 {
01662 refNode = n;
01663 refNode->ref();
01664 }
01665
01666 ChildNodeListImpl::~ChildNodeListImpl()
01667 {
01668 refNode->deref();
01669 }
01670
01671 unsigned long ChildNodeListImpl::length() const
01672 {
01673 unsigned long len = 0;
01674 NodeImpl *n;
01675 for(n = refNode->firstChild(); n != 0; n = n->nextSibling())
01676 len++;
01677
01678 return len;
01679 }
01680
01681 NodeImpl *ChildNodeListImpl::item ( unsigned long index ) const
01682 {
01683 unsigned int pos = 0;
01684 NodeImpl *n = refNode->firstChild();
01685
01686 while( n != 0 && pos < index )
01687 {
01688 n = n->nextSibling();
01689 pos++;
01690 }
01691
01692 return n;
01693 }
01694
01695 bool ChildNodeListImpl::nodeMatches( NodeImpl * ) const
01696 {
01697 return true;
01698 }
01699
01700 TagNodeListImpl::TagNodeListImpl(NodeImpl *n, NodeImpl::Id _id, NodeImpl::Id _idMask )
01701 : refNode(n), m_id(_id & _idMask), m_idMask(_idMask)
01702 {
01703 refNode->ref();
01704 }
01705
01706 TagNodeListImpl::~TagNodeListImpl()
01707 {
01708 refNode->deref();
01709 }
01710
01711 unsigned long TagNodeListImpl::length() const
01712 {
01713 return recursiveLength( refNode );
01714 }
01715
01716 NodeImpl *TagNodeListImpl::item ( unsigned long index ) const
01717 {
01718 return recursiveItem( refNode, index );
01719 }
01720
01721 bool TagNodeListImpl::nodeMatches( NodeImpl *testNode ) const
01722 {
01723 return ( testNode->isElementNode() && m_id &&
01724 (testNode->id() & m_idMask) == m_id);
01725 }
01726
01727 NameNodeListImpl::NameNodeListImpl(NodeImpl *n, const DOMString &t )
01728 : nodeName(t)
01729 {
01730 refNode= n;
01731 refNode->ref();
01732 }
01733
01734 NameNodeListImpl::~NameNodeListImpl()
01735 {
01736 refNode->deref();
01737 }
01738
01739 unsigned long NameNodeListImpl::length() const
01740 {
01741 return recursiveLength( refNode );
01742 }
01743
01744 NodeImpl *NameNodeListImpl::item ( unsigned long index ) const
01745 {
01746 return recursiveItem( refNode, index );
01747 }
01748
01749 bool NameNodeListImpl::nodeMatches( NodeImpl *testNode ) const
01750 {
01751 return static_cast<ElementImpl *>(testNode)->getAttribute(ATTR_NAME) == nodeName;
01752 }
01753
01754 NamedTagNodeListImpl::NamedTagNodeListImpl( NodeImpl *n, NodeImpl::Id tagId, const DOMString& name, NodeImpl::Id tagIdMask )
01755 : TagNodeListImpl( n, tagId, tagIdMask ), nodeName( name )
01756 {
01757 }
01758
01759 bool NamedTagNodeListImpl::nodeMatches( NodeImpl *testNode ) const
01760 {
01761 return TagNodeListImpl::nodeMatches( testNode )
01762 && static_cast<ElementImpl *>(testNode)->getAttribute(ATTR_NAME) == nodeName;
01763 }
01764
01765
01766
01767
01768 NamedNodeMapImpl::NamedNodeMapImpl()
01769 {
01770 }
01771
01772 NamedNodeMapImpl::~NamedNodeMapImpl()
01773 {
01774 }
01775
01776
01777
01778
01779 #if 0
01780 GenericRONamedNodeMapImpl::GenericRONamedNodeMapImpl(DocumentPtr* doc)
01781 : NamedNodeMapImpl()
01782 {
01783 m_doc = doc->document();
01784 m_contents = new QPtrList<NodeImpl>;
01785 }
01786
01787 GenericRONamedNodeMapImpl::~GenericRONamedNodeMapImpl()
01788 {
01789 while (m_contents->count() > 0)
01790 m_contents->take(0)->deref();
01791
01792 delete m_contents;
01793 }
01794
01795 NodeImpl *GenericRONamedNodeMapImpl::getNamedItem ( const DOMString &name, int & ) const
01796 {
01797 QPtrListIterator<NodeImpl> it(*m_contents);
01798 for (; it.current(); ++it)
01799 if (it.current()->nodeName() == name)
01800 return it.current();
01801 return 0;
01802 }
01803
01804 Node GenericRONamedNodeMapImpl::setNamedItem ( const Node &, int &exceptioncode )
01805 {
01806
01807
01808 exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR;
01809 return 0;
01810 }
01811
01812 Node GenericRONamedNodeMapImpl::removeNamedItem ( const DOMString &, int &exceptioncode )
01813 {
01814
01815
01816 exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR;
01817 return 0;
01818 }
01819
01820 NodeImpl *GenericRONamedNodeMapImpl::item ( unsigned long index ) const
01821 {
01822
01823
01824 if (index >= m_contents->count())
01825 return 0;
01826
01827 return m_contents->at(index);
01828 }
01829
01830 unsigned long GenericRONamedNodeMapImpl::length( ) const
01831 {
01832 return m_contents->count();
01833 }
01834
01835 NodeImpl *GenericRONamedNodeMapImpl::getNamedItemNS( const DOMString &namespaceURI,
01836 const DOMString &localName,
01837 int & ) const
01838 {
01839 NodeImpl::Id searchId = m_doc->tagId(namespaceURI.implementation(),
01840 localName.implementation(), true);
01841
01842 QPtrListIterator<NodeImpl> it(*m_contents);
01843 for (; it.current(); ++it)
01844 if (it.current()->id() == searchId)
01845 return it.current();
01846
01847 return 0;
01848 }
01849
01850 NodeImpl *GenericRONamedNodeMapImpl::setNamedItemNS( NodeImpl *, int &exceptioncode )
01851 {
01852
01853
01854 exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR;
01855 return 0;
01856 }
01857
01858 NodeImpl *GenericRONamedNodeMapImpl::removeNamedItemNS( const DOMString &,
01859 const DOMString &,
01860 int &exceptioncode )
01861 {
01862
01863 exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR;
01864 return 0;
01865 }
01866
01867 void GenericRONamedNodeMapImpl::addNode(NodeImpl *n)
01868 {
01869
01870 int exceptioncode = 0;
01871 if (getNamedItem(n->nodeName(),exceptioncode))
01872 return;
01873
01874 n->ref();
01875 m_contents->append(n);
01876 }
01877
01878 #endif