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; 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 else
01216 for ( NodeImpl* c = n; c; c = c->traverseNextNode( n ) )
01217 c->removedFromDocument();
01218 }
01219 _first = _last = 0;
01220 }
01221
01222
01223 NodeImpl *NodeBaseImpl::appendChild ( NodeImpl *newChild, int &exceptioncode )
01224 {
01225 exceptioncode = 0;
01226
01227
01228 checkAddChild(newChild, exceptioncode);
01229 if (exceptioncode)
01230 return 0;
01231
01232 if ( newChild == _last )
01233 return newChild;
01234
01235 bool isFragment = newChild->nodeType() == Node::DOCUMENT_FRAGMENT_NODE;
01236
01237
01238
01239 if (isFragment && !newChild->firstChild())
01240 return newChild;
01241
01242
01243 NodeImpl *nextChild;
01244 NodeImpl *child = isFragment ? newChild->firstChild() : newChild;
01245
01246 while (child) {
01247 nextChild = isFragment ? child->nextSibling() : 0;
01248
01249
01250 NodeImpl *oldParent = child->parentNode();
01251 if(oldParent) {
01252 oldParent->removeChild( child, exceptioncode );
01253 if (exceptioncode)
01254 return 0;
01255 }
01256
01257
01258 child->setParent(this);
01259
01260 if(_last)
01261 {
01262 child->setPreviousSibling(_last);
01263 _last->setNextSibling(child);
01264 _last = child;
01265 }
01266 else
01267 {
01268 _first = _last = child;
01269 }
01270
01271
01272
01273 if (attached() && !child->attached())
01274 child->attach();
01275
01276
01277 dispatchChildInsertedEvents(child,exceptioncode);
01278
01279 child = nextChild;
01280 }
01281
01282 setChanged(true);
01283
01284 dispatchSubtreeModifiedEvent();
01285 return newChild;
01286 }
01287
01288 bool NodeBaseImpl::hasChildNodes ( ) const
01289 {
01290 return _first != 0;
01291 }
01292
01293
01294 void NodeBaseImpl::setFirstChild(NodeImpl *child)
01295 {
01296 _first = child;
01297 }
01298
01299 void NodeBaseImpl::setLastChild(NodeImpl *child)
01300 {
01301 _last = child;
01302 }
01303
01304
01305 bool NodeBaseImpl::checkSameDocument( NodeImpl *newChild, int &exceptioncode )
01306 {
01307 exceptioncode = 0;
01308 DocumentImpl *ownerDocThis = getDocument();
01309 DocumentImpl *ownerDocNew = getDocument();
01310 if(ownerDocThis != ownerDocNew) {
01311 kdDebug(6010)<< "not same document, newChild = " << newChild << "document = " << getDocument() << endl;
01312 exceptioncode = DOMException::WRONG_DOCUMENT_ERR;
01313 return true;
01314 }
01315 return false;
01316 }
01317
01318
01319 bool NodeBaseImpl::checkIsChild( NodeImpl *oldChild, int &exceptioncode )
01320 {
01321 if(!oldChild || oldChild->parentNode() != this) {
01322 exceptioncode = DOMException::NOT_FOUND_ERR;
01323 return true;
01324 }
01325 return false;
01326 }
01327
01328 NodeImpl *NodeBaseImpl::addChild(NodeImpl *newChild)
01329 {
01330
01331
01332
01333 if(!isXMLElementNode() && !newChild->isXMLElementNode() && !childAllowed(newChild))
01334 {
01335
01336 return 0;
01337 }
01338
01339
01340 newChild->setParent(this);
01341
01342 if(_last)
01343 {
01344 newChild->setPreviousSibling(_last);
01345 _last->setNextSibling(newChild);
01346 _last = newChild;
01347 }
01348 else
01349 {
01350 _first = _last = newChild;
01351 }
01352
01353 newChild->insertedIntoDocument();
01354 childrenChanged();
01355
01356 if(newChild->nodeType() == Node::ELEMENT_NODE)
01357 return newChild;
01358 return this;
01359 }
01360
01361 void NodeBaseImpl::attach()
01362 {
01363 NodeImpl *child = _first;
01364 while(child != 0)
01365 {
01366 child->attach();
01367 child = child->nextSibling();
01368 }
01369 NodeImpl::attach();
01370 }
01371
01372 void NodeBaseImpl::detach()
01373 {
01374 NodeImpl *child = _first;
01375 while(child != 0)
01376 {
01377 NodeImpl* prev = child;
01378 child = child->nextSibling();
01379 prev->detach();
01380 }
01381 NodeImpl::detach();
01382 }
01383
01384 void NodeBaseImpl::cloneChildNodes(NodeImpl *clone)
01385 {
01386 int exceptioncode = 0;
01387 NodeImpl *n;
01388 for(n = firstChild(); n && !exceptioncode; n = n->nextSibling())
01389 {
01390 clone->appendChild(n->cloneNode(true),exceptioncode);
01391 }
01392 }
01393
01394 NodeListImpl* NodeBaseImpl::getElementsByTagNameNS ( DOMStringImpl* namespaceURI,
01395 DOMStringImpl* localName )
01396 {
01397 if (!localName) return 0;
01398
01399 NodeImpl::Id idMask = NodeImpl_IdNSMask | NodeImpl_IdLocalMask;
01400 if (localName->l && localName->s[0] == '*')
01401 idMask &= ~NodeImpl_IdLocalMask;
01402 if (namespaceURI && namespaceURI->l && namespaceURI->s[0] == '*')
01403 idMask &= ~NodeImpl_IdNSMask;
01404
01405 Id id = 0;
01406 if ( (idMask & NodeImpl_IdLocalMask) || namespaceURI )
01407 {
01408 id = getDocument()->tagId( namespaceURI, localName, true , 0 );
01409 if ( !id )
01410 id = (Id)-1;
01411 }
01412
01413 return new TagNodeListImpl( this, id, idMask );
01414 }
01415
01416
01417
01418 bool NodeBaseImpl::getUpperLeftCorner(int &xPos, int &yPos) const
01419 {
01420 if (!m_render)
01421 return false;
01422 RenderObject *o = m_render;
01423 xPos = yPos = 0;
01424 if ( !o->isInline() || o->isReplaced() ) {
01425 o->absolutePosition( xPos, yPos );
01426 return true;
01427 }
01428
01429
01430 while(o) {
01431 if(o->firstChild())
01432 o = o->firstChild();
01433 else if(o->nextSibling())
01434 o = o->nextSibling();
01435 else {
01436 RenderObject *next = 0;
01437 while(!next) {
01438 o = o->parent();
01439 if(!o) return false;
01440 next = o->nextSibling();
01441 }
01442 o = next;
01443 }
01444 if((o->isText() && !o->isBR()) || o->isReplaced()) {
01445 o->container()->absolutePosition( xPos, yPos );
01446 if (o->isText())
01447 xPos += static_cast<RenderText *>(o)->minXPos();
01448 else
01449 xPos += o->xPos();
01450 yPos += o->yPos();
01451 return true;
01452 }
01453 }
01454 return true;
01455 }
01456
01457 bool NodeBaseImpl::getLowerRightCorner(int &xPos, int &yPos) const
01458 {
01459 if (!m_render)
01460 return false;
01461
01462 RenderObject *o = m_render;
01463 xPos = yPos = 0;
01464 if (!o->isInline() || o->isReplaced())
01465 {
01466 o->absolutePosition( xPos, yPos );
01467 xPos += o->width();
01468 yPos += o->height();
01469 return true;
01470 }
01471
01472 while(o) {
01473 if(o->lastChild())
01474 o = o->lastChild();
01475 else if(o->previousSibling())
01476 o = o->previousSibling();
01477 else {
01478 RenderObject *prev = 0;
01479 while(!prev) {
01480 o = o->parent();
01481 if(!o) return false;
01482 prev = o->previousSibling();
01483 }
01484 o = prev;
01485 }
01486 if((o->isText() && !o->isBR()) || o->isReplaced()) {
01487 o->container()->absolutePosition(xPos, yPos);
01488 if (o->isText())
01489 xPos += static_cast<RenderText *>(o)->minXPos() + o->width();
01490 else
01491 xPos += o->xPos()+o->width();
01492 yPos += o->yPos()+o->height();
01493 return true;
01494 }
01495 }
01496 return true;
01497 }
01498
01499 QRect NodeBaseImpl::getRect() const
01500 {
01501 int xPos, yPos;
01502 if (!getUpperLeftCorner(xPos,yPos))
01503 {
01504 xPos=0;
01505 yPos=0;
01506 }
01507 int xEnd, yEnd;
01508 if (!getLowerRightCorner(xEnd,yEnd))
01509 {
01510 if (xPos)
01511 xEnd = xPos;
01512 if (yPos)
01513 yEnd = yPos;
01514 }
01515 else
01516 {
01517 if (xPos==0)
01518 xPos = xEnd;
01519 if (yPos==0)
01520 yPos = yEnd;
01521 }
01522 if ( xEnd <= xPos || yEnd <= yPos )
01523 return QRect( QPoint( xPos, yPos ), QSize() );
01524
01525 return QRect(xPos, yPos, xEnd - xPos, yEnd - yPos);
01526 }
01527
01528 void NodeBaseImpl::setFocus(bool received)
01529 {
01530 if (m_focused == received) return;
01531
01532 NodeImpl::setFocus(received);
01533 for(NodeImpl *it=_first;it;it=it->nextSibling())
01534 it->setFocus(received);
01535
01536
01537 setChanged();
01538 }
01539
01540 void NodeBaseImpl::setActive(bool down)
01541 {
01542 if (down == active()) return;
01543
01544 NodeImpl::setActive(down);
01545
01546
01547 if (m_render && m_render->style()->hasActive())
01548 setChanged();
01549 }
01550
01551 unsigned long NodeBaseImpl::childNodeCount()
01552 {
01553 unsigned long count = 0;
01554 NodeImpl *n;
01555 for (n = firstChild(); n; n = n->nextSibling())
01556 count++;
01557 return count;
01558 }
01559
01560 NodeImpl *NodeBaseImpl::childNode(unsigned long index)
01561 {
01562 unsigned long i;
01563 NodeImpl *n = firstChild();
01564 for (i = 0; i < index; i++)
01565 n = n->nextSibling();
01566 return n;
01567 }
01568
01569 void NodeBaseImpl::dispatchChildInsertedEvents( NodeImpl *child, int &exceptioncode )
01570 {
01571 if (getDocument()->hasListenerType(DocumentImpl::DOMNODEINSERTED_LISTENER)) {
01572 child->dispatchEvent(new MutationEventImpl(EventImpl::DOMNODEINSERTED_EVENT,
01573 true,false,this,DOMString(),DOMString(),DOMString(),0),exceptioncode,true);
01574 if (exceptioncode)
01575 return;
01576 }
01577
01578
01579 bool hasInsertedListeners = getDocument()->hasListenerType(DocumentImpl::DOMNODEINSERTEDINTODOCUMENT_LISTENER);
01580 NodeImpl *p = this;
01581 while (p->parentNode())
01582 p = p->parentNode();
01583 if (p->nodeType() == Node::DOCUMENT_NODE) {
01584 for (NodeImpl *c = child; c; c = c->traverseNextNode(child)) {
01585 c->insertedIntoDocument();
01586
01587 if (hasInsertedListeners) {
01588 c->dispatchEvent(new MutationEventImpl(EventImpl::DOMNODEINSERTEDINTODOCUMENT_EVENT,
01589 false,false,0,DOMString(),DOMString(),DOMString(),0),exceptioncode,true);
01590 if (exceptioncode)
01591 return;
01592 }
01593 }
01594 }
01595 }
01596
01597 void NodeBaseImpl::dispatchChildRemovalEvents( NodeImpl *child, int &exceptioncode )
01598 {
01599
01600 getDocument()->notifyBeforeNodeRemoval(child);
01601 if (getDocument()->hasListenerType(DocumentImpl::DOMNODEREMOVED_LISTENER)) {
01602 child->dispatchEvent(new MutationEventImpl(EventImpl::DOMNODEREMOVED_EVENT,
01603 true,false,this,DOMString(),DOMString(),DOMString(),0),exceptioncode,true);
01604 if (exceptioncode)
01605 return;
01606 }
01607
01608 bool hasRemovalListeners = getDocument()->hasListenerType(DocumentImpl::DOMNODEREMOVEDFROMDOCUMENT_LISTENER);
01609
01610
01611 NodeImpl *p = this;
01612 while (p->parentNode())
01613 p = p->parentNode();
01614 if (p->nodeType() == Node::DOCUMENT_NODE) {
01615 for (NodeImpl *c = child; c; c = c->traverseNextNode(child)) {
01616 if (hasRemovalListeners) {
01617 c->dispatchEvent(new MutationEventImpl(EventImpl::DOMNODEREMOVEDFROMDOCUMENT_EVENT,
01618 false,false,0,DOMString(),DOMString(),DOMString(),0),exceptioncode,true);
01619 if (exceptioncode)
01620 return;
01621 }
01622 }
01623 }
01624 }
01625
01626
01627
01628 NodeImpl *NodeListImpl::item( unsigned long ) const
01629 {
01630 return 0;
01631 }
01632
01633 unsigned long NodeListImpl::length() const
01634 {
01635 return 0;
01636 }
01637
01638 unsigned long NodeListImpl::recursiveLength(NodeImpl *start) const
01639 {
01640 unsigned long len = 0;
01641
01642 for(NodeImpl *n = start->firstChild(); n != 0; n = n->nextSibling()) {
01643 if ( n->nodeType() == Node::ELEMENT_NODE ) {
01644 if (nodeMatches(n))
01645 len++;
01646 len+= recursiveLength(n);
01647 }
01648 }
01649
01650 return len;
01651 }
01652
01653 NodeImpl *NodeListImpl::recursiveItem ( NodeImpl *start, unsigned long &offset ) const
01654 {
01655 for(NodeImpl *n = start->firstChild(); n != 0; n = n->nextSibling()) {
01656 if ( n->nodeType() == Node::ELEMENT_NODE ) {
01657 if (nodeMatches(n))
01658 if (!offset--)
01659 return n;
01660
01661 NodeImpl *depthSearch= recursiveItem(n, offset);
01662 if (depthSearch)
01663 return depthSearch;
01664 }
01665 }
01666
01667 return 0;
01668 }
01669
01670 ChildNodeListImpl::ChildNodeListImpl( NodeImpl *n )
01671 {
01672 refNode = n;
01673 refNode->ref();
01674 }
01675
01676 ChildNodeListImpl::~ChildNodeListImpl()
01677 {
01678 refNode->deref();
01679 }
01680
01681 unsigned long ChildNodeListImpl::length() const
01682 {
01683 unsigned long len = 0;
01684 NodeImpl *n;
01685 for(n = refNode->firstChild(); n != 0; n = n->nextSibling())
01686 len++;
01687
01688 return len;
01689 }
01690
01691 NodeImpl *ChildNodeListImpl::item ( unsigned long index ) const
01692 {
01693 unsigned int pos = 0;
01694 NodeImpl *n = refNode->firstChild();
01695
01696 while( n != 0 && pos < index )
01697 {
01698 n = n->nextSibling();
01699 pos++;
01700 }
01701
01702 return n;
01703 }
01704
01705 bool ChildNodeListImpl::nodeMatches( NodeImpl * ) const
01706 {
01707 return true;
01708 }
01709
01710 TagNodeListImpl::TagNodeListImpl(NodeImpl *n, NodeImpl::Id _id, NodeImpl::Id _idMask )
01711 : refNode(n), m_id(_id & _idMask), m_idMask(_idMask)
01712 {
01713 refNode->ref();
01714 }
01715
01716 TagNodeListImpl::~TagNodeListImpl()
01717 {
01718 refNode->deref();
01719 }
01720
01721 unsigned long TagNodeListImpl::length() const
01722 {
01723 return recursiveLength( refNode );
01724 }
01725
01726 NodeImpl *TagNodeListImpl::item ( unsigned long index ) const
01727 {
01728 return recursiveItem( refNode, index );
01729 }
01730
01731 bool TagNodeListImpl::nodeMatches( NodeImpl *testNode ) const
01732 {
01733 return testNode->isElementNode() &&
01734 ((testNode->id() & m_idMask) == m_id);
01735 }
01736
01737 NameNodeListImpl::NameNodeListImpl(NodeImpl *n, const DOMString &t )
01738 : nodeName(t)
01739 {
01740 refNode= n;
01741 refNode->ref();
01742 }
01743
01744 NameNodeListImpl::~NameNodeListImpl()
01745 {
01746 refNode->deref();
01747 }
01748
01749 unsigned long NameNodeListImpl::length() const
01750 {
01751 return recursiveLength( refNode );
01752 }
01753
01754 NodeImpl *NameNodeListImpl::item ( unsigned long index ) const
01755 {
01756 return recursiveItem( refNode, index );
01757 }
01758
01759 bool NameNodeListImpl::nodeMatches( NodeImpl *testNode ) const
01760 {
01761 return static_cast<ElementImpl *>(testNode)->getAttribute(ATTR_NAME) == nodeName;
01762 }
01763
01764 NamedTagNodeListImpl::NamedTagNodeListImpl( NodeImpl *n, NodeImpl::Id tagId, const DOMString& name, NodeImpl::Id tagIdMask )
01765 : TagNodeListImpl( n, tagId, tagIdMask ), nodeName( name )
01766 {
01767 }
01768
01769 bool NamedTagNodeListImpl::nodeMatches( NodeImpl *testNode ) const
01770 {
01771 return TagNodeListImpl::nodeMatches( testNode )
01772 && static_cast<ElementImpl *>(testNode)->getAttribute(ATTR_NAME) == nodeName;
01773 }
01774
01775
01776
01777
01778 NamedNodeMapImpl::NamedNodeMapImpl()
01779 {
01780 }
01781
01782 NamedNodeMapImpl::~NamedNodeMapImpl()
01783 {
01784 }
01785
01786
01787
01788
01789 #if 0
01790 GenericRONamedNodeMapImpl::GenericRONamedNodeMapImpl(DocumentPtr* doc)
01791 : NamedNodeMapImpl()
01792 {
01793 m_doc = doc->document();
01794 m_contents = new QPtrList<NodeImpl>;
01795 }
01796
01797 GenericRONamedNodeMapImpl::~GenericRONamedNodeMapImpl()
01798 {
01799 while (m_contents->count() > 0)
01800 m_contents->take(0)->deref();
01801
01802 delete m_contents;
01803 }
01804
01805 NodeImpl *GenericRONamedNodeMapImpl::getNamedItem ( const DOMString &name, int & ) const
01806 {
01807 QPtrListIterator<NodeImpl> it(*m_contents);
01808 for (; it.current(); ++it)
01809 if (it.current()->nodeName() == name)
01810 return it.current();
01811 return 0;
01812 }
01813
01814 Node GenericRONamedNodeMapImpl::setNamedItem ( const Node &, int &exceptioncode )
01815 {
01816
01817
01818 exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR;
01819 return 0;
01820 }
01821
01822 Node GenericRONamedNodeMapImpl::removeNamedItem ( const DOMString &, int &exceptioncode )
01823 {
01824
01825
01826 exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR;
01827 return 0;
01828 }
01829
01830 NodeImpl *GenericRONamedNodeMapImpl::item ( unsigned long index ) const
01831 {
01832
01833
01834 if (index >= m_contents->count())
01835 return 0;
01836
01837 return m_contents->at(index);
01838 }
01839
01840 unsigned long GenericRONamedNodeMapImpl::length( ) const
01841 {
01842 return m_contents->count();
01843 }
01844
01845 NodeImpl *GenericRONamedNodeMapImpl::getNamedItemNS( const DOMString &namespaceURI,
01846 const DOMString &localName,
01847 int & ) const
01848 {
01849 NodeImpl::Id searchId = m_doc->tagId(namespaceURI.implementation(),
01850 localName.implementation(), true, 0);
01851
01852 QPtrListIterator<NodeImpl> it(*m_contents);
01853 for (; it.current(); ++it)
01854 if (it.current()->id() == searchId)
01855 return it.current();
01856
01857 return 0;
01858 }
01859
01860 NodeImpl *GenericRONamedNodeMapImpl::setNamedItemNS( NodeImpl *, int &exceptioncode )
01861 {
01862
01863
01864 exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR;
01865 return 0;
01866 }
01867
01868 NodeImpl *GenericRONamedNodeMapImpl::removeNamedItemNS( const DOMString &,
01869 const DOMString &,
01870 int &exceptioncode )
01871 {
01872
01873 exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR;
01874 return 0;
01875 }
01876
01877 void GenericRONamedNodeMapImpl::addNode(NodeImpl *n)
01878 {
01879
01880 int exceptioncode = 0;
01881 if (getNamedItem(n->nodeName(),exceptioncode))
01882 return;
01883
01884 n->ref();
01885 m_contents->append(n);
01886 }
01887
01888 #endif