Reviewed by Ken.
[WebKit-https.git] / WebCore / khtml / xml / dom_nodeimpl.cpp
1 /**
2  * This file is part of the DOM implementation for KDE.
3  *
4  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
5  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
6  *           (C) 2001 Dirk Mueller (mueller@kde.org)
7  * Copyright (C) 2004 Apple Computer, Inc.
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Library General Public
11  * License as published by the Free Software Foundation; either
12  * version 2 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Library General Public License for more details.
18  *
19  * You should have received a copy of the GNU Library General Public License
20  * along with this library; see the file COPYING.LIB.  If not, write to
21  * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22  * Boston, MA 02111-1307, USA.
23  */
24
25 #include "xml/dom_nodeimpl.h"
26
27 #include "dom/dom_exception.h"
28 #include "misc/htmlattrs.h"
29 #include "misc/htmltags.h"
30 #include "xml/dom_elementimpl.h"
31 #include "xml/dom_textimpl.h"
32 #include "xml/dom2_eventsimpl.h"
33 #include "xml/dom_docimpl.h"
34 #include "xml/dom_position.h"
35 #include "xml/dom2_rangeimpl.h"
36 #include "css/csshelper.h"
37 #include "css/cssstyleselector.h"
38 #include "editing/selection.h"
39
40 #include <kglobal.h>
41 #include <kdebug.h>
42
43 #include "rendering/render_object.h"
44 #include "rendering/render_text.h"
45
46 #include "ecma/kjs_binding.h"
47 #include "ecma/kjs_proxy.h"
48 #include "khtmlview.h"
49 #include "khtml_part.h"
50
51 #include "html/dtd.h"
52
53 #ifndef KHTML_NO_XBL
54 #include "xbl/xbl_binding_manager.h"
55 #endif
56
57 #if APPLE_CHANGES
58 #include "KWQAssertions.h"
59 #include "KWQLogging.h"
60 #else
61 #define ASSERT(assertion) assert(assertion)
62 #define LOG(channel, formatAndArgs...) ((void)0)
63 #endif
64
65 using namespace DOM;
66 using namespace khtml;
67
68 NodeImpl::NodeImpl(DocumentPtr *doc)
69     : document(doc),
70       m_previous(0),
71       m_next(0),
72       m_render(0),
73       m_regdListeners( 0 ),
74       m_nodeLists( 0 ),
75       m_tabIndex( 0 ),
76       m_hasId( false ),
77       m_hasClass( false ),
78       m_hasStyle( false ),
79       m_attached(false),
80       m_changed( false ),
81       m_hasChangedChild( false ),
82       m_inDocument( false ),
83       m_hasAnchor( false ),
84       m_specified( false ),
85       m_focused( false ),
86       m_active( false ),
87       m_styleElement( false ),
88       m_implicit( false )
89 {
90     if (document)
91         document->ref();
92 }
93
94 void NodeImpl::setDocument(DocumentPtr *doc)
95 {
96     if (inDocument())
97         return;
98     
99     if (doc)
100         doc->ref();
101     
102     if (document)
103         document->deref();
104
105     document = doc;
106 }
107
108 NodeImpl::~NodeImpl()
109 {
110     if (m_render)
111         detach();
112     delete m_regdListeners;
113     delete m_nodeLists;
114     if (document)
115         document->deref();
116     if (m_previous)
117         m_previous->setNextSibling(0);
118     if (m_next)
119         m_next->setPreviousSibling(0);
120 }
121
122 DOMString NodeImpl::nodeValue() const
123 {
124   return DOMString();
125 }
126
127 void NodeImpl::setNodeValue( const DOMString &/*_nodeValue*/, int &exceptioncode )
128 {
129     // NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly
130     if (isReadOnly()) {
131         exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR;
132         return;
133     }
134
135     // be default nodeValue is null, so setting it has no effect
136 }
137
138 DOMString NodeImpl::nodeName() const
139 {
140   return DOMString();
141 }
142
143 unsigned short NodeImpl::nodeType() const
144 {
145   return 0;
146 }
147
148 NodeListImpl *NodeImpl::childNodes()
149 {
150   return new ChildNodeListImpl(this);
151 }
152
153 NodeImpl *NodeImpl::firstChild() const
154 {
155   return 0;
156 }
157
158 NodeImpl *NodeImpl::lastChild() const
159 {
160   return 0;
161 }
162
163 NodeImpl *NodeImpl::insertBefore( NodeImpl *newChild, NodeImpl *, int &exceptioncode )
164 {
165     newChild->ref();
166     newChild->deref();
167     exceptioncode = DOMException::HIERARCHY_REQUEST_ERR;
168     return 0;
169 }
170
171 NodeImpl *NodeImpl::replaceChild( NodeImpl *newChild, NodeImpl *, int &exceptioncode )
172 {
173   newChild->ref();
174   newChild->deref();
175   exceptioncode = DOMException::HIERARCHY_REQUEST_ERR;
176   return 0;
177 }
178
179 NodeImpl *NodeImpl::removeChild( NodeImpl *, int &exceptioncode )
180 {
181   exceptioncode = DOMException::NOT_FOUND_ERR;
182   return 0;
183 }
184
185 NodeImpl *NodeImpl::appendChild( NodeImpl *newChild, int &exceptioncode )
186 {
187     newChild->ref();
188     newChild->deref();
189     exceptioncode = DOMException::HIERARCHY_REQUEST_ERR;
190     return 0;
191 }
192
193 void NodeImpl::remove(int &exceptioncode)
194 {
195     exceptioncode = 0;
196     if (!parentNode()) {
197         exceptioncode = DOMException::HIERARCHY_REQUEST_ERR;
198         return;
199     }
200     
201     parentNode()->removeChild(this, exceptioncode);
202 }
203
204 bool NodeImpl::hasChildNodes(  ) const
205 {
206   return false;
207 }
208
209 void NodeImpl::normalize ()
210 {
211     // ### normalize attributes? (when we store attributes using child nodes)
212     int exceptioncode = 0;
213     NodeImpl *child = firstChild();
214
215     // Recursively go through the subtree beneath us, normalizing all nodes. In the case
216     // where there are two adjacent text nodes, they are merged together
217     while (child) {
218         NodeImpl *nextChild = child->nextSibling();
219
220         if (nextChild && child->nodeType() == Node::TEXT_NODE && nextChild->nodeType() == Node::TEXT_NODE) {
221             // Current child and the next one are both text nodes... merge them
222             TextImpl *currentText = static_cast<TextImpl*>(child);
223             TextImpl *nextText = static_cast<TextImpl*>(nextChild);
224
225             currentText->appendData(nextText->data(),exceptioncode);
226             if (exceptioncode)
227                 return;
228
229             removeChild(nextChild,exceptioncode);
230             if (exceptioncode)
231                 return;
232         }
233         else {
234             child->normalize();
235             child = nextChild;
236         }
237     }
238 }
239
240 DOMString NodeImpl::prefix() const
241 {
242     // For nodes other than elements and attributes, the prefix is always null
243     return DOMString();
244 }
245
246 void NodeImpl::setPrefix(const DOMString &/*_prefix*/, int &exceptioncode )
247 {
248     // The spec says that for nodes other than elements and attributes, prefix is always null.
249     // It does not say what to do when the user tries to set the prefix on another type of
250     // node, however mozilla throws a NAMESPACE_ERR exception
251     exceptioncode = DOMException::NAMESPACE_ERR;
252 }
253
254 DOMString NodeImpl::localName() const
255 {
256     return DOMString();
257 }
258
259 void NodeImpl::setFirstChild(NodeImpl *)
260 {
261 }
262
263 void NodeImpl::setLastChild(NodeImpl *)
264 {
265 }
266
267 NodeImpl *NodeImpl::addChild(NodeImpl *)
268 {
269   return 0;
270 }
271
272 QString NodeImpl::toHTML() const
273 {
274     return recursive_toHTML(true);
275 }
276
277 static QString escapeHTML( const QString& in )
278 {
279     QString s;
280     for ( unsigned int i = 0; i < in.length(); ++i ) {
281         switch( in[i].latin1() ) {
282         case '&':
283             s += "&amp;";
284             break;
285         case '<':
286             s += "&lt;";
287             break;
288         case '>':
289             s += "&gt;";
290             break;
291         default:
292             s += in[i];
293         }
294     }
295
296     return s;
297 }
298
299 QString NodeImpl::startMarkup(const RangeImpl *range) const
300 {
301     unsigned short type = nodeType();
302     if (type == Node::TEXT_NODE) {
303         DOMString str = nodeValue().copy();
304         if (range) {
305             int exceptionCode;
306             if (this == range->endContainer(exceptionCode)) {
307                 str.truncate(range->endOffset(exceptionCode));
308             }
309             if (this == range->startContainer(exceptionCode)) {
310                 str.remove(0, range->startOffset(exceptionCode));
311             }
312         }
313         Id parentID = parentNode()->id();
314         bool dontEscape = (parentID == ID_SCRIPT || parentID == ID_TEXTAREA || parentID == ID_STYLE);
315         return dontEscape ? str.string() : escapeHTML(str.string());        
316     } else if (type != Node::DOCUMENT_NODE) {
317         QString markup = QChar('<') + nodeName().string();
318         if (type == Node::ELEMENT_NODE) {
319             const ElementImpl *el = static_cast<const ElementImpl *>(this);
320             NamedAttrMapImpl *attrs = el->attributes();
321             unsigned long length = attrs->length();
322             for (unsigned int i=0; i<length; i++) {
323                 AttributeImpl *attr = attrs->attributeItem(i);
324                 markup += " " + getDocument()->attrName(attr->id()).string() + "=\"" + attr->value().string() + "\"";
325             }
326         }
327         markup += isHTMLElement() ? ">" : "/>";
328         return markup;
329     }
330     return "";
331 }
332
333 QString NodeImpl::endMarkup(void) const
334 {
335     if ((!isHTMLElement() || endTag[id()] != FORBIDDEN) && nodeType() != Node::TEXT_NODE && nodeType() != Node::DOCUMENT_NODE) {
336         return "</" + nodeName().string() + ">";
337     }
338     return "";
339 }
340
341 QString NodeImpl::recursive_toString(const NodeImpl *startNode, bool onlyIncludeChildren, bool includeSiblings, QPtrList<NodeImpl> *nodes)
342 {
343     // Doesn't make sense to only include children and include siblings.
344     assert(!(onlyIncludeChildren && includeSiblings));
345     QString me = "";
346     for (const NodeImpl *current = startNode; current != NULL; current = includeSiblings ? current->nextSibling() : NULL) {
347         if (!onlyIncludeChildren) {
348             if (nodes) {
349                 nodes->append(current);
350             }
351             me += current->startMarkup(0);
352         }        
353         if (!current->isHTMLElement() || endTag[current->id()] != FORBIDDEN) {
354             // print children
355             if (NodeImpl *n = current->firstChild()) {
356                 me += recursive_toString(n, false, true, nodes);
357             }
358             // Print my ending tag
359             if (!onlyIncludeChildren) {
360                 me += current->endMarkup();
361             }
362         }
363     }
364     return me;
365 }
366
367 QString NodeImpl::recursive_toHTML(bool onlyIncludeChildren, QPtrList<NodeImpl> *nodes) const
368 {       
369     return NodeImpl::recursive_toString(this, onlyIncludeChildren, false, nodes);
370 }
371
372 void NodeImpl::recursive_completeURLs(QString baseURL)
373 {
374     if (nodeType() == Node::ELEMENT_NODE) {
375         ElementImpl *el = static_cast<ElementImpl *>(this);
376         NamedAttrMapImpl *attrs = el->attributes();
377         unsigned long length = attrs->length();
378         for (unsigned int i=0; i<length; i++) {
379             AttributeImpl *attr = attrs->attributeItem(i);
380             if (el->isURLAttribute(attr)) {
381                 el->setAttribute(attr->id(), KURL(baseURL, attr->value().string()).url());
382             }
383         }
384     }
385     
386     NodeImpl *n;
387     if ((n = firstChild())) {
388         n->recursive_completeURLs(baseURL);
389     }
390     if ((n = nextSibling())) {
391         n->recursive_completeURLs(baseURL);
392     }
393 }
394
395 bool NodeImpl::isContentEditable() const
396 {
397     return m_parent ? m_parent->isContentEditable() : false;
398 }
399
400 QRect NodeImpl::getRect() const
401 {
402     int _x, _y;
403     if(m_render && m_render->absolutePosition(_x, _y))
404         return QRect( _x, _y, m_render->width(), m_render->height() );
405
406     return QRect();
407 }
408
409 void NodeImpl::setChanged(bool b)
410 {
411     if (b && !attached()) // changed compared to what?
412         return;
413
414     m_changed = b;
415     if ( b ) {
416         NodeImpl *p = parentNode();
417         while ( p ) {
418             p->setHasChangedChild( true );
419             p = p->parentNode();
420         }
421         getDocument()->setDocumentChanged(true);
422     }
423 }
424
425 bool NodeImpl::isInline() const
426 {
427     if (m_render) return m_render->style()->display() == khtml::INLINE;
428     return !isElementNode();
429 }
430
431 bool NodeImpl::isFocusable() const
432 {
433     return false;
434 }
435
436 bool NodeImpl::isKeyboardFocusable() const
437 {
438     return isFocusable();
439 }
440
441 bool NodeImpl::isMouseFocusable() const
442 {
443     return isFocusable();
444 }
445
446 unsigned long NodeImpl::nodeIndex() const
447 {
448     NodeImpl *_tempNode = previousSibling();
449     unsigned long count=0;
450     for( count=0; _tempNode; count++ )
451         _tempNode = _tempNode->previousSibling();
452     return count;
453 }
454
455 void NodeImpl::addEventListener(int id, EventListener *listener, const bool useCapture)
456 {
457     switch (id) {
458         case EventImpl::DOMSUBTREEMODIFIED_EVENT:
459             getDocument()->addListenerType(DocumentImpl::DOMSUBTREEMODIFIED_LISTENER);
460             break;
461         case EventImpl::DOMNODEINSERTED_EVENT:
462             getDocument()->addListenerType(DocumentImpl::DOMNODEINSERTED_LISTENER);
463             break;
464         case EventImpl::DOMNODEREMOVED_EVENT:
465             getDocument()->addListenerType(DocumentImpl::DOMNODEREMOVED_LISTENER);
466             break;
467         case EventImpl::DOMNODEREMOVEDFROMDOCUMENT_EVENT:
468             getDocument()->addListenerType(DocumentImpl::DOMNODEREMOVEDFROMDOCUMENT_LISTENER);
469             break;
470         case EventImpl::DOMNODEINSERTEDINTODOCUMENT_EVENT:
471             getDocument()->addListenerType(DocumentImpl::DOMNODEINSERTEDINTODOCUMENT_LISTENER);
472             break;
473         case EventImpl::DOMATTRMODIFIED_EVENT:
474             getDocument()->addListenerType(DocumentImpl::DOMATTRMODIFIED_LISTENER);
475             break;
476         case EventImpl::DOMCHARACTERDATAMODIFIED_EVENT:
477             getDocument()->addListenerType(DocumentImpl::DOMCHARACTERDATAMODIFIED_LISTENER);
478             break;
479         default:
480             break;
481     }
482
483     RegisteredEventListener *rl = new RegisteredEventListener(static_cast<EventImpl::EventId>(id),listener,useCapture);
484     if (!m_regdListeners) {
485         m_regdListeners = new QPtrList<RegisteredEventListener>;
486         m_regdListeners->setAutoDelete(true);
487     }
488
489     listener->ref();
490
491     // remove existing identical listener set with identical arguments - the DOM2
492     // spec says that "duplicate instances are discarded" in this case.
493     removeEventListener(id,listener,useCapture);
494
495     m_regdListeners->append(rl);
496     listener->deref();
497 }
498
499 void NodeImpl::removeEventListener(int id, EventListener *listener, bool useCapture)
500 {
501     if (!m_regdListeners) // nothing to remove
502         return;
503
504     RegisteredEventListener rl(static_cast<EventImpl::EventId>(id),listener,useCapture);
505
506     QPtrListIterator<RegisteredEventListener> it(*m_regdListeners);
507     for (; it.current(); ++it)
508         if (*(it.current()) == rl) {
509             m_regdListeners->removeRef(it.current());
510             return;
511         }
512 }
513
514 void NodeImpl::removeHTMLEventListener(int id)
515 {
516     if (!m_regdListeners) // nothing to remove
517         return;
518
519     QPtrListIterator<RegisteredEventListener> it(*m_regdListeners);
520     for (; it.current(); ++it)
521         if (it.current()->id == id &&
522             it.current()->listener->eventListenerType() == "_khtml_HTMLEventListener") {
523             m_regdListeners->removeRef(it.current());
524             return;
525         }
526 }
527
528 void NodeImpl::setHTMLEventListener(int id, EventListener *listener)
529 {
530     // in case we already have it, we don't want removeHTMLEventListener to destroy it
531     if (listener)
532         listener->ref();
533     removeHTMLEventListener(id);
534     if (listener)
535     {
536         addEventListener(id,listener,false);
537         listener->deref();
538     }
539 }
540
541 EventListener *NodeImpl::getHTMLEventListener(int id)
542 {
543     if (!m_regdListeners)
544         return 0;
545
546     QPtrListIterator<RegisteredEventListener> it(*m_regdListeners);
547     for (; it.current(); ++it)
548         if (it.current()->id == id &&
549             it.current()->listener->eventListenerType() == "_khtml_HTMLEventListener") {
550             return it.current()->listener;
551         }
552     return 0;
553 }
554
555
556 bool NodeImpl::dispatchEvent(EventImpl *evt, int &exceptioncode, bool tempEvent)
557 {
558     evt->ref();
559
560     evt->setTarget(this);
561
562     // We've had at least one report of a crash on a page where document is nil here.
563     // Unfortunately that page no longer exists, but we'll make this code robust against
564     // that anyway.
565     // FIXME: Much code in this class assumes document is non-nil; it would be better to
566     // ensure that document can never be nil.
567     KHTMLPart *part = nil;
568     KHTMLView *view = nil;
569     
570     if (document && document->document()) {
571         part = document->document()->part();
572         view = document->document()->view();
573         // Since event handling code could cause this object to be deleted, grab a reference to the view now
574         if (view)
575             view->ref();
576     }    
577
578     bool ret = dispatchGenericEvent( evt, exceptioncode );
579
580     // If tempEvent is true, this means that the DOM implementation will not be storing a reference to the event, i.e.
581     // there is no way to retrieve it from javascript if a script does not already have a reference to it in a variable.
582     // So there is no need for the interpreter to keep the event in it's cache
583     if (tempEvent && part && part->jScript())
584         part->jScript()->finishedWithEvent(evt);
585
586     if (view)
587         view->deref();
588
589     evt->deref();
590
591     return ret;
592 }
593
594 bool NodeImpl::dispatchGenericEvent( EventImpl *evt, int &/*exceptioncode */)
595 {
596     evt->ref();
597
598     // ### check that type specified
599
600     // work out what nodes to send event to
601     QPtrList<NodeImpl> nodeChain;
602     NodeImpl *n;
603     for (n = this; n; n = n->parentNode()) {
604         n->ref();
605         nodeChain.prepend(n);
606     }
607
608     // trigger any capturing event handlers on our way down
609     evt->setEventPhase(Event::CAPTURING_PHASE);
610     QPtrListIterator<NodeImpl> it(nodeChain);
611     for (; it.current() && it.current() != this && !evt->propagationStopped(); ++it) {
612         evt->setCurrentTarget(it.current());
613         it.current()->handleLocalEvents(evt,true);
614     }
615
616     // dispatch to the actual target node
617     it.toLast();
618     if (!evt->propagationStopped()) {
619         evt->setEventPhase(Event::AT_TARGET);
620         evt->setCurrentTarget(it.current());
621
622         // Capturing first. -dwh
623         it.current()->handleLocalEvents(evt,true);
624
625         // Bubbling second. -dwh
626         if (!evt->propagationStopped())
627           it.current()->handleLocalEvents(evt,false);
628     }
629     --it;
630
631     // ok, now bubble up again (only non-capturing event handlers will be called)
632     // ### recalculate the node chain here? (e.g. if target node moved in document by previous event handlers)
633     // no. the DOM specs says:
634     // The chain of EventTargets from the event target to the top of the tree
635     // is determined before the initial dispatch of the event.
636     // If modifications occur to the tree during event processing,
637     // event flow will proceed based on the initial state of the tree.
638     //
639     // since the initial dispatch is before the capturing phase,
640     // there's no need to recalculate the node chain.
641     // (tobias)
642
643     if (evt->bubbles()) {
644         evt->setEventPhase(Event::BUBBLING_PHASE);
645         for (; it.current() && !evt->propagationStopped() && !evt->getCancelBubble(); --it) {
646             evt->setCurrentTarget(it.current());
647             it.current()->handleLocalEvents(evt,false);
648         }
649     }
650
651     evt->setCurrentTarget(0);
652     evt->setEventPhase(0); // I guess this is correct, the spec does not seem to say
653                            // anything about the default event handler phase.
654
655
656     if (evt->bubbles()) {
657         // now we call all default event handlers (this is not part of DOM - it is internal to khtml)
658
659         it.toLast();
660         for (; it.current() && !evt->propagationStopped() && !evt->defaultPrevented() && !evt->defaultHandled(); --it)
661             it.current()->defaultEventHandler(evt);
662     }
663     
664     // In the case of a mouse click, also send a DOMActivate event, which causes things like form submissions
665     // to occur. Note that this only happens for _real_ mouse clicks (for which we get a KHTML_CLICK_EVENT or
666     // KHTML_DBLCLICK_EVENT), not the standard DOM "click" event that could be sent from js code.
667     if (!evt->defaultPrevented() && !disabled())
668         if (evt->id() == EventImpl::KHTML_CLICK_EVENT)
669             dispatchUIEvent(EventImpl::DOMACTIVATE_EVENT, 1);
670         else if (evt->id() == EventImpl::KHTML_DBLCLICK_EVENT)
671             dispatchUIEvent(EventImpl::DOMACTIVATE_EVENT, 2);
672
673     // deref all nodes in chain
674     it.toFirst();
675     for (; it.current(); ++it)
676         it.current()->deref(); // this may delete us
677
678     DocumentImpl::updateDocumentsRendering();
679
680     bool defaultPrevented = evt->defaultPrevented();
681
682     evt->deref();
683
684     return !defaultPrevented; // ### what if defaultPrevented was called before dispatchEvent?
685 }
686
687 bool NodeImpl::dispatchHTMLEvent(int _id, bool canBubbleArg, bool cancelableArg)
688 {
689     int exceptioncode = 0;
690     EventImpl *evt = new EventImpl(static_cast<EventImpl::EventId>(_id),canBubbleArg,cancelableArg);
691     return dispatchEvent(evt,exceptioncode,true);
692 }
693
694 bool NodeImpl::dispatchWindowEvent(int _id, bool canBubbleArg, bool cancelableArg)
695 {
696     int exceptioncode = 0;
697     EventImpl *evt = new EventImpl(static_cast<EventImpl::EventId>(_id),canBubbleArg,cancelableArg);
698     evt->setTarget( 0 );
699     evt->ref();
700     DocumentPtr *doc = document;
701     doc->ref();
702     bool r = dispatchGenericEvent( evt, exceptioncode );
703     if (!evt->defaultPrevented() && doc->document())
704         doc->document()->defaultEventHandler(evt);
705     
706     if (_id == EventImpl::LOAD_EVENT && !evt->propagationStopped() && doc->document()) {
707         // For onload events, send them to the enclosing frame only.
708         // This is a DOM extension and is independent of bubbling/capturing rules of
709         // the DOM.  You send the event only to the enclosing frame.  It does not
710         // bubble through the parent document.
711         ElementImpl* elt = doc->document()->ownerElement();
712         if (elt && (elt->getDocument()->domain().isNull() ||
713                     elt->getDocument()->domain() == doc->document()->domain())) {
714             // We also do a security check, since we don't want to allow the enclosing
715             // iframe to see loads of child documents in other domains.
716             evt->setCurrentTarget(elt);
717
718             // Capturing first.
719             elt->handleLocalEvents(evt,true);
720
721             // Bubbling second.
722             if (!evt->propagationStopped())
723                 elt->handleLocalEvents(evt,false);
724             r = !evt->defaultPrevented();
725         }
726     }
727
728     doc->deref();
729     evt->deref();
730
731     return r;
732 }
733
734 bool NodeImpl::dispatchMouseEvent(QMouseEvent *_mouse, int overrideId, int overrideDetail)
735 {
736     bool cancelable = true;
737     int detail = overrideDetail; // defaults to 0
738     EventImpl::EventId evtId = EventImpl::UNKNOWN_EVENT;
739     if (overrideId) {
740         evtId = static_cast<EventImpl::EventId>(overrideId);
741     }
742     else {
743         switch (_mouse->type()) {
744             case QEvent::MouseButtonPress:
745                 evtId = EventImpl::MOUSEDOWN_EVENT;
746                 break;
747             case QEvent::MouseButtonRelease:
748                 evtId = EventImpl::MOUSEUP_EVENT;
749                 break;
750             case QEvent::MouseButtonDblClick:
751                 evtId = EventImpl::CLICK_EVENT;
752                 detail = 1; // ### support for multiple double clicks
753                 break;
754             case QEvent::MouseMove:
755                 evtId = EventImpl::MOUSEMOVE_EVENT;
756                 cancelable = false;
757                 break;
758             default:
759                 break;
760         }
761     }
762     if (evtId == EventImpl::UNKNOWN_EVENT)
763         return false; // shouldn't happen
764
765
766     int exceptioncode = 0;
767
768 #if APPLE_CHANGES
769 // Careful here - our viewportToContents() converts points from NSEvents, in NSWindow coord system to
770 // our khtmlview's coord system.  This works for QMouseEvents coming from Cocoa because those events
771 // hold the location from the NSEvent.  The QMouseEvent param here was made by other khtml code, so it
772 // will be a "proper" QT event with coords in terms of this widget.  So in WebCore it would never be
773 // right to pass coords from _mouse to viewportToContents().
774 #endif
775 //    int clientX, clientY;
776 //    viewportToContents(_mouse->x(), _mouse->y(), clientX, clientY);
777     int clientX = _mouse->x(); // ### adjust to be relative to view
778     int clientY = _mouse->y(); // ### adjust to be relative to view
779
780 #if APPLE_CHANGES
781     int screenX;
782     int screenY;
783     KHTMLView *view = document->document()->view();
784     if (view) {
785         // This gets us as far as NSWindow coords
786         QPoint windowLoc = view->contentsToViewport(_mouse->pos());
787         // Then from NSWindow coords to screen coords
788         QPoint screenLoc = view->viewportToGlobal(windowLoc);
789         screenX = screenLoc.x();
790         screenY = screenLoc.y();
791     } else {
792         screenX = _mouse->x();
793         screenY = _mouse->y();
794     }
795 #else
796     int screenX = _mouse->globalX();
797     int screenY = _mouse->globalY();
798 #endif
799
800     int button = -1;
801     switch (_mouse->button()) {
802         case Qt::LeftButton:
803             button = 0;
804             break;
805         case Qt::MidButton:
806             button = 1;
807             break;
808         case Qt::RightButton:
809             button = 2;
810             break;
811         default:
812             break;
813     }
814     bool ctrlKey = (_mouse->state() & Qt::ControlButton);
815     bool altKey = (_mouse->state() & Qt::AltButton);
816     bool shiftKey = (_mouse->state() & Qt::ShiftButton);
817     bool metaKey = false; // ### qt support?
818
819     EventImpl *evt = new MouseEventImpl(evtId,true,cancelable,getDocument()->defaultView(),
820                    detail,screenX,screenY,clientX,clientY,ctrlKey,altKey,shiftKey,metaKey,
821                    button,0);
822     return dispatchEvent(evt,exceptioncode,true);
823
824 }
825
826 bool NodeImpl::dispatchUIEvent(int _id, int detail)
827 {
828     assert (!( (_id != EventImpl::DOMFOCUSIN_EVENT &&
829         _id != EventImpl::DOMFOCUSOUT_EVENT &&
830                 _id != EventImpl::DOMACTIVATE_EVENT)));
831
832     bool cancelable = false;
833     if (_id == EventImpl::DOMACTIVATE_EVENT)
834         cancelable = true;
835
836     int exceptioncode = 0;
837     UIEventImpl *evt = new UIEventImpl(static_cast<EventImpl::EventId>(_id),true,
838                                        cancelable,getDocument()->defaultView(),detail);
839     return dispatchEvent(evt,exceptioncode,true);
840 }
841
842 void NodeImpl::registerNodeList(NodeListImpl *list)
843 {
844     if (!m_nodeLists) {
845         m_nodeLists = new QPtrDict<NodeListImpl>;
846     }
847
848     m_nodeLists->insert(list, list);
849 }
850
851 void NodeImpl::unregisterNodeList(NodeListImpl *list)
852 {
853     if (!m_nodeLists)
854         return;
855
856     m_nodeLists->remove(list);
857 }
858
859 void NodeImpl::notifyLocalNodeListsSubtreeModified()
860 {
861     if (!m_nodeLists)
862         return;
863
864     QPtrDictIterator<NodeListImpl> i(*m_nodeLists);
865
866     while (NodeListImpl *list = i.current()) {
867         list->rootNodeSubtreeModified();
868         ++i;
869     }
870 }
871
872 void NodeImpl::notifyNodeListsSubtreeModified()
873 {
874     for (NodeImpl *n = this; n; n = n->parentNode()) {
875         n->notifyLocalNodeListsSubtreeModified();
876     }
877 }
878
879 bool NodeImpl::dispatchSubtreeModifiedEvent(bool sendChildrenChanged)
880 {
881     notifyNodeListsSubtreeModified();
882     if (sendChildrenChanged)
883         childrenChanged();
884     if (!getDocument()->hasListenerType(DocumentImpl::DOMSUBTREEMODIFIED_LISTENER))
885         return false;
886     int exceptioncode = 0;
887     return dispatchEvent(new MutationEventImpl(EventImpl::DOMSUBTREEMODIFIED_EVENT,
888                          true,false,0,DOMString(),DOMString(),DOMString(),0),exceptioncode,true);
889 }
890
891 bool NodeImpl::dispatchKeyEvent(QKeyEvent *key)
892 {
893     int exceptioncode = 0;
894     //kdDebug(6010) << "DOM::NodeImpl: dispatching keyboard event" << endl;
895     KeyboardEventImpl *keyboardEventImpl = new KeyboardEventImpl(key, getDocument()->defaultView());
896     keyboardEventImpl->ref();
897     bool r = dispatchEvent(keyboardEventImpl,exceptioncode,true);
898
899 #if APPLE_CHANGES
900     // we want to return false if default is prevented (already taken care of)
901     // or if the element is default-handled by the DOM. Otherwise we let it just
902     // let it get handled by AppKit 
903     if (keyboardEventImpl->defaultHandled())
904 #else
905     // the default event handler should accept() the internal QKeyEvent
906     // to prevent the view from further evaluating it.
907     if (!keyboardEventImpl->defaultPrevented() && !keyboardEventImpl->qKeyEvent->isAccepted())
908 #endif
909       r = false;
910
911     keyboardEventImpl->deref();
912     return r;
913 }
914
915 void NodeImpl::handleLocalEvents(EventImpl *evt, bool useCapture)
916 {
917     if (!m_regdListeners)
918         return;
919
920     if (disabled() && evt->isMouseEvent())
921         return;
922
923     QPtrList<RegisteredEventListener> listenersCopy = *m_regdListeners;
924     QPtrListIterator<RegisteredEventListener> it(listenersCopy);
925     Event ev = evt;
926     for (; it.current(); ++it) {
927         if (it.current()->id == evt->id() && it.current()->useCapture == useCapture)
928             it.current()->listener->handleEvent(ev, false);
929     }
930
931 }
932
933 void NodeImpl::defaultEventHandler(EventImpl *evt)
934 {
935 }
936
937 unsigned long NodeImpl::childNodeCount() const
938 {
939     return 0;
940 }
941
942 NodeImpl *NodeImpl::childNode(unsigned long /*index*/)
943 {
944     return 0;
945 }
946
947 NodeImpl *NodeImpl::traverseNextNode(NodeImpl *stayWithin) const
948 {
949     if (firstChild()) {
950         assert(!stayWithin || firstChild()->isAncestor(stayWithin));
951         return firstChild();
952     }
953     if (this == stayWithin)
954         return 0;
955     if (nextSibling()) {
956         assert(!stayWithin || nextSibling()->isAncestor(stayWithin));
957         return nextSibling();
958     }
959     const NodeImpl *n = this;
960     while (n && !n->nextSibling() && (!stayWithin || n->parentNode() != stayWithin))
961         n = n->parentNode();
962     if (n) {
963         assert(!stayWithin || !n->nextSibling() || n->nextSibling()->isAncestor(stayWithin));
964         return n->nextSibling();
965     }
966     return 0;
967 }
968
969 NodeImpl *NodeImpl::traverseNextSibling(NodeImpl *stayWithin) const
970 {
971     if (this == stayWithin)
972         return 0;
973     if (nextSibling()) {
974         assert(!stayWithin || nextSibling()->isAncestor(stayWithin));
975         return nextSibling();
976     }
977     const NodeImpl *n = this;
978     while (n && !n->nextSibling() && (!stayWithin || n->parentNode() != stayWithin))
979         n = n->parentNode();
980     if (n) {
981         assert(!stayWithin || !n->nextSibling() || n->nextSibling()->isAncestor(stayWithin));
982         return n->nextSibling();
983     }
984     return 0;
985 }
986
987 NodeImpl *NodeImpl::traversePreviousNode() const
988 {
989     if (previousSibling()) {
990         NodeImpl *n = previousSibling();
991         while (n->lastChild())
992             n = n->lastChild();
993         return n;
994     }
995     else if (parentNode()) {
996         return parentNode();
997     }
998     else {
999         return 0;
1000     }
1001 }
1002
1003 NodeImpl *NodeImpl::traversePreviousNodePostOrder(NodeImpl *stayWithin) const
1004 {
1005     if (lastChild()) {
1006         assert(!stayWithin || lastChild()->isAncestor(stayWithin));
1007         return lastChild();
1008     }
1009     if (this == stayWithin)
1010         return 0;
1011     if (previousSibling()) {
1012         assert(!stayWithin || previousSibling()->isAncestor(stayWithin));
1013         return previousSibling();
1014     }
1015     const NodeImpl *n = this;
1016     while (n && !n->previousSibling() && (!stayWithin || n->parentNode() != stayWithin))
1017         n = n->parentNode();
1018     if (n) {
1019         assert(!stayWithin || !n->previousSibling() || n->previousSibling()->isAncestor(stayWithin));
1020         return n->previousSibling();
1021     }
1022     return 0;
1023 }
1024
1025 void NodeImpl::checkSetPrefix(const DOMString &_prefix, int &exceptioncode)
1026 {
1027     // Perform error checking as required by spec for setting Node.prefix. Used by
1028     // ElementImpl::setPrefix() and AttrImpl::setPrefix()
1029
1030     // INVALID_CHARACTER_ERR: Raised if the specified prefix contains an illegal character.
1031     if (!Element::khtmlValidPrefix(_prefix)) {
1032         exceptioncode = DOMException::INVALID_CHARACTER_ERR;
1033         return;
1034     }
1035
1036     // NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
1037     if (isReadOnly()) {
1038         exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR;
1039         return;
1040     }
1041
1042     // NAMESPACE_ERR: - Raised if the specified prefix is malformed
1043     // - if the namespaceURI of this node is null,
1044     // - if the specified prefix is "xml" and the namespaceURI of this node is different from
1045     //   "http://www.w3.org/XML/1998/namespace",
1046     // - if this node is an attribute and the specified prefix is "xmlns" and
1047     //   the namespaceURI of this node is different from "http://www.w3.org/2000/xmlns/",
1048     // - or if this node is an attribute and the qualifiedName of this node is "xmlns" [Namespaces].
1049     if (Element::khtmlMalformedPrefix(_prefix) || (namespacePart(id()) == noNamespace && id() > ID_LAST_TAG) ||
1050         (_prefix == "xml" && DOMString(getDocument()->namespaceURI(id())) != "http://www.w3.org/XML/1998/namespace")) {
1051         exceptioncode = DOMException::NAMESPACE_ERR;
1052         return;
1053     }
1054 }
1055
1056 void NodeImpl::checkAddChild(NodeImpl *newChild, int &exceptioncode)
1057 {
1058     // Perform error checking as required by spec for adding a new child. Used by
1059     // appendChild(), replaceChild() and insertBefore()
1060
1061     // Not mentioned in spec: throw NOT_FOUND_ERR if newChild is null
1062     if (!newChild) {
1063         exceptioncode = DOMException::NOT_FOUND_ERR;
1064         return;
1065     }
1066
1067     // NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly
1068     if (isReadOnly()) {
1069         exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR;
1070         return;
1071     }
1072
1073     bool shouldAdoptChild = false;
1074
1075     // WRONG_DOCUMENT_ERR: Raised if newChild was created from a different document than the one that
1076     // created this node.
1077     // We assume that if newChild is a DocumentFragment, all children are created from the same document
1078     // as the fragment itself (otherwise they could not have been added as children)
1079     if (newChild->getDocument() != getDocument()) {
1080         // but if the child is not in a document yet then loosen the
1081         // restriction, so that e.g. creating an element with the Option()
1082         // constructor and then adding it to a different document works,
1083         // as it does in Mozilla and Mac IE.
1084         if (!newChild->inDocument()) {
1085             shouldAdoptChild = true;
1086         } else {
1087             exceptioncode = DOMException::WRONG_DOCUMENT_ERR;
1088             return;
1089         }
1090     }
1091
1092     // HIERARCHY_REQUEST_ERR: Raised if this node is of a type that does not allow children of the type of the
1093     // newChild node, or if the node to append is one of this node's ancestors.
1094
1095     // check for ancestor/same node
1096     if (newChild == this || isAncestor(newChild)) {
1097         exceptioncode = DOMException::HIERARCHY_REQUEST_ERR;
1098         return;
1099     }
1100
1101     // only do this once we know there won't be an exception
1102     if (shouldAdoptChild) {
1103         KJS::ScriptInterpreter::updateDOMObjectDocument(newChild, newChild->getDocument(), getDocument());
1104         newChild->setDocument(getDocument()->docPtr());
1105     }
1106 }
1107
1108 bool NodeImpl::isAncestor(const NodeImpl *other) const
1109 {
1110     // Return true if other is an ancestor of this, otherwise false
1111     for (const NodeImpl *n = parentNode(); n; n = n->parentNode()) {
1112         if (n == other)
1113             return true;
1114     }
1115     return false;
1116 }
1117
1118 bool NodeImpl::childAllowed( NodeImpl *newChild )
1119 {
1120     return childTypeAllowed(newChild->nodeType());
1121 }
1122
1123 NodeImpl::StyleChange NodeImpl::diff( khtml::RenderStyle *s1, khtml::RenderStyle *s2 ) const
1124 {
1125     // FIXME: The behavior of this function is just totally wrong.  It doesn't handle
1126     // explicit inheritance of non-inherited properties and so you end up not re-resolving
1127     // style in cases where you need to.
1128     StyleChange ch = NoInherit;
1129     EDisplay display1 = s1 ? s1->display() : NONE;
1130     bool fl1 = s1 ? s1->hasPseudoStyle(RenderStyle::FIRST_LETTER) : false;
1131     EDisplay display2 = s2 ? s2->display() : NONE;
1132     bool fl2 = s2 ? s2->hasPseudoStyle(RenderStyle::FIRST_LETTER) : false;
1133     if (display1 != display2 || fl1 != fl2)
1134         ch = Detach;
1135     else if ( !s1 || !s2 )
1136         ch = Inherit;
1137     else if ( *s1 == *s2 )
1138         ch = NoChange;
1139     else if ( s1->inheritedNotEqual( s2 ) )
1140         ch = Inherit;
1141     return ch;
1142 }
1143
1144 #ifndef NDEBUG
1145 void NodeImpl::dump(QTextStream *stream, QString ind) const
1146 {
1147     // ### implement dump() for all appropriate subclasses
1148
1149     if (m_hasId) { *stream << " hasId"; }
1150     if (m_hasClass) { *stream << " hasClass"; }
1151     if (m_hasStyle) { *stream << " hasStyle"; }
1152     if (m_specified) { *stream << " specified"; }
1153     if (m_focused) { *stream << " focused"; }
1154     if (m_active) { *stream << " active"; }
1155     if (m_styleElement) { *stream << " styleElement"; }
1156     if (m_implicit) { *stream << " implicit"; }
1157
1158     *stream << " tabIndex=" << m_tabIndex;
1159     if (m_regdListeners)
1160         *stream << " #regdListeners=" << m_regdListeners->count(); // ### more detail
1161     *stream << endl;
1162
1163     NodeImpl *child = firstChild();
1164     while( child != 0 )
1165     {
1166         *stream << ind << child->nodeName().string().ascii() << ": ";
1167         child->dump(stream,ind+"  ");
1168         child = child->nextSibling();
1169     }
1170 }
1171 #endif
1172
1173 void NodeImpl::attach()
1174 {
1175     assert(!attached());
1176     assert(!m_render || (m_render->style() && m_render->parent()));
1177     getDocument()->incDOMTreeVersion();
1178     m_attached = true;
1179 }
1180
1181 void NodeImpl::detach()
1182 {
1183 //    assert(m_attached);
1184
1185     if (m_render)
1186         m_render->detach();
1187
1188     m_render = 0;
1189     getDocument()->incDOMTreeVersion();
1190     m_attached = false;
1191 }
1192
1193 bool NodeImpl::maintainsState()
1194 {
1195     return false;
1196 }
1197
1198 QString NodeImpl::state()
1199 {
1200     return QString::null;
1201 }
1202
1203 void NodeImpl::restoreState(QStringList &/*states*/)
1204 {
1205 }
1206
1207 void NodeImpl::insertedIntoDocument()
1208 {
1209     setInDocument(true);
1210 }
1211
1212 void NodeImpl::removedFromDocument()
1213 {
1214     setInDocument(false);
1215 }
1216
1217 void NodeImpl::childrenChanged()
1218 {
1219 }
1220
1221 bool NodeImpl::disabled() const
1222 {
1223     return false;
1224 }
1225
1226 bool NodeImpl::isReadOnly()
1227 {
1228     // Entity & Entity Reference nodes and their descendants are read-only
1229     NodeImpl *n = this;
1230     while (n) {
1231         if (n->nodeType() == Node::ENTITY_NODE ||
1232             n->nodeType() == Node::ENTITY_REFERENCE_NODE)
1233             return true;
1234         n = n->parentNode();
1235     }
1236     return false;
1237 }
1238
1239 NodeImpl *NodeImpl::previousEditable() const
1240 {
1241     NodeImpl *node = previousLeafNode();
1242     while (node) {
1243         if (node->isContentEditable())
1244             return node;
1245         node = node->previousLeafNode();
1246     }
1247     return 0;
1248 }
1249
1250 NodeImpl *NodeImpl::nextEditable() const
1251 {
1252     NodeImpl *node = nextLeafNode();
1253     while (node) {
1254         if (node->isContentEditable())
1255             return node;
1256         node = node->nextLeafNode();
1257     }
1258     return 0;
1259 }
1260
1261 RenderObject * NodeImpl::previousRenderer()
1262 {
1263     for (NodeImpl *n = previousSibling(); n; n = n->previousSibling()) {
1264         if (n->renderer())
1265             return n->renderer();
1266     }
1267     return 0;
1268 }
1269
1270 RenderObject * NodeImpl::nextRenderer()
1271 {
1272     for (NodeImpl *n = nextSibling(); n; n = n->nextSibling()) {
1273         if (n->renderer())
1274             return n->renderer();
1275     }
1276     return 0;
1277 }
1278
1279 bool NodeImpl::isAtomicNode() const
1280 {
1281     return !hasChildNodes() || (id() == ID_OBJECT && renderer() && renderer()->isReplaced());
1282 }
1283
1284 NodeImpl *NodeImpl::previousNodeConsideringAtomicNodes() const
1285 {
1286     if (previousSibling()) {
1287         NodeImpl *n = previousSibling();
1288         while (!n->isAtomicNode() && n->lastChild())
1289             n = n->lastChild();
1290         return n;
1291     }
1292     else if (parentNode()) {
1293         return parentNode();
1294     }
1295     else {
1296         return 0;
1297     }
1298 }
1299
1300 NodeImpl *NodeImpl::nextNodeConsideringAtomicNodes() const
1301 {
1302     if (!isAtomicNode() && firstChild())
1303         return firstChild();
1304     if (nextSibling())
1305         return nextSibling();
1306     const NodeImpl *n = this;
1307     while (n && !n->nextSibling())
1308         n = n->parentNode();
1309     if (n)
1310         return n->nextSibling();
1311     return 0;
1312 }
1313
1314 NodeImpl *NodeImpl::previousLeafNode() const
1315 {
1316     NodeImpl *node = previousNodeConsideringAtomicNodes();
1317     while (node) {
1318         if (node->isAtomicNode())
1319             return node;
1320         node = node->previousNodeConsideringAtomicNodes();
1321     }
1322     return 0;
1323 }
1324
1325 NodeImpl *NodeImpl::nextLeafNode() const
1326 {
1327     NodeImpl *node = nextNodeConsideringAtomicNodes();
1328     while (node) {
1329         if (node->isAtomicNode())
1330             return node;
1331         node = node->nextNodeConsideringAtomicNodes();
1332     }
1333     return 0;
1334 }
1335
1336 void NodeImpl::createRendererIfNeeded()
1337 {
1338
1339 #if APPLE_CHANGES
1340     if (!getDocument()->shouldCreateRenderers())
1341         return;
1342 #endif
1343         
1344     assert(!attached());
1345     assert(!m_render);
1346     
1347     NodeImpl *parent = parentNode();    
1348     assert(parent);
1349     
1350     RenderObject *parentRenderer = parent->renderer();
1351     if (parentRenderer && parentRenderer->canHaveChildren()) {
1352         RenderStyle *style = styleForRenderer(parentRenderer);
1353         style->ref();
1354 #ifndef KHTML_NO_XBL
1355         bool resolveStyle = false;
1356         if (getDocument()->bindingManager()->loadBindings(this, style->bindingURIs(), true, &resolveStyle) && 
1357             rendererIsNeeded(style)) {
1358             if (resolveStyle) {
1359                 style->deref();
1360                 style = styleForRenderer(parentRenderer);
1361             }
1362 #else
1363         if (rendererIsNeeded(style)) {
1364 #endif
1365             m_render = createRenderer(getDocument()->renderArena(), style);
1366             m_render->setStyle(style);
1367             parentRenderer->addChild(m_render, nextRenderer());
1368 #ifndef KHTML_NO_XBL
1369         } // avoid confusing the change log code parser by having two close braces to match the two open braces above
1370 #else
1371         }
1372 #endif
1373         style->deref(getDocument()->renderArena());
1374     }
1375 }
1376
1377 RenderStyle *NodeImpl::styleForRenderer(RenderObject *parent)
1378 {
1379     return parent->style();
1380 }
1381
1382 bool NodeImpl::rendererIsNeeded(RenderStyle *style)
1383 {
1384     return (getDocument()->documentElement() == this) || (style->display() != NONE);
1385 }
1386
1387 RenderObject *NodeImpl::createRenderer(RenderArena *arena, RenderStyle *style)
1388 {
1389     assert(false);
1390     return 0;
1391 }
1392
1393 long NodeImpl::maxOffset() const
1394 {
1395     return 1;
1396 }
1397
1398 long NodeImpl::caretMinOffset() const
1399 {
1400     return renderer() ? renderer()->caretMinOffset() : 0;
1401 }
1402
1403 long NodeImpl::caretMaxOffset() const
1404 {
1405     return renderer() ? renderer()->caretMaxOffset() : 1;
1406 }
1407
1408 unsigned long NodeImpl::caretMaxRenderedOffset() const
1409 {
1410     return renderer() ? renderer()->caretMaxRenderedOffset() : 1;
1411 }
1412
1413 bool NodeImpl::isBlockFlow() const
1414 {
1415     return renderer() && renderer()->isBlockFlow();
1416 }
1417
1418 bool NodeImpl::isEditableBlock() const
1419 {
1420     return isContentEditable() && isBlockFlow();
1421 }
1422
1423 ElementImpl *NodeImpl::enclosingBlockFlowElement() const
1424 {
1425     NodeImpl *n = const_cast<NodeImpl *>(this);
1426     if (isBlockFlow())
1427         return static_cast<ElementImpl *>(n);
1428
1429     while (1) {
1430         n = n->parentNode();
1431         if (!n)
1432             break;
1433         if (n->isBlockFlow() || n->id() == ID_BODY)
1434             return static_cast<ElementImpl *>(n);
1435     }
1436     return 0;
1437 }
1438
1439 ElementImpl *NodeImpl::enclosingInlineElement() const
1440 {
1441     NodeImpl *n = const_cast<NodeImpl *>(this);
1442     NodeImpl *p;
1443
1444     while (1) {
1445         p = n->parentNode();
1446         if (!p || p->isBlockFlow() || p->id() == ID_BODY)
1447             return static_cast<ElementImpl *>(n);
1448         n = p;
1449     }
1450     ASSERT_NOT_REACHED();
1451     return 0;
1452 }
1453
1454 ElementImpl *NodeImpl::rootEditableElement() const
1455 {
1456     if (!isContentEditable())
1457         return 0;
1458
1459     NodeImpl *n = const_cast<NodeImpl *>(this);
1460     if (n->id() == ID_BODY)
1461         return static_cast<ElementImpl *>(n);
1462
1463     NodeImpl *result = n->isEditableBlock() ? n : 0;
1464     while (1) {
1465         n = n->parentNode();
1466         if (!n || !n->isContentEditable())
1467             break;
1468         if (n->id() == ID_BODY) {
1469             result = n;
1470             break;
1471         }
1472         if (n->isBlockFlow())
1473             result = n;
1474     }
1475     return static_cast<ElementImpl *>(result);
1476 }
1477
1478 bool NodeImpl::inSameRootEditableElement(NodeImpl *n)
1479 {
1480     return n ? rootEditableElement() == n->rootEditableElement() : false;
1481 }
1482
1483 bool NodeImpl::inSameContainingBlockFlowElement(NodeImpl *n)
1484 {
1485     return n ? enclosingBlockFlowElement() == n->enclosingBlockFlowElement() : false;
1486 }
1487
1488 #if APPLE_CHANGES
1489 NodeImpl::Id NodeImpl::identifier() const
1490 {
1491     return id();
1492 }
1493 #endif
1494
1495 #ifndef NDEBUG
1496 void NodeImpl::displayNode(const char *prefix)
1497 {
1498     if (!prefix)
1499         prefix = "";
1500     if (isTextNode())
1501         fprintf(stderr, "%s%s\t%p %s\n", prefix, getTagName(id()).string().latin1(), this, nodeValue().ascii());
1502     else
1503         fprintf(stderr, "%s%s\t%p\n", prefix, getTagName(id()).string().latin1(), this);
1504 }
1505
1506 void NodeImpl::displayTree()
1507 {
1508     NodeImpl    *rootNode = rootEditableElement();
1509     NodeImpl    *node;
1510     
1511     for (node = rootNode; node; node = node->traverseNextNode()) {
1512         NodeImpl *tmpNode;
1513         if (node == this)
1514             fprintf(stderr, "*");
1515         for (tmpNode = node; tmpNode != rootNode; tmpNode = tmpNode->parentNode())
1516             fprintf(stderr, "\t");
1517         node->displayNode(0);
1518     }
1519 }
1520
1521 void NodeImpl::formatForDebugger(char *buffer, unsigned length) const
1522 {
1523     DOMString result;
1524     DOMString s;
1525     
1526     s = nodeName();
1527     if (s.length() == 0)
1528         result += "<none>";
1529     else
1530         result += s;
1531           
1532     strncpy(buffer, result.string().latin1(), length - 1);
1533 }
1534 #endif
1535
1536 //-------------------------------------------------------------------------
1537
1538 NodeBaseImpl::NodeBaseImpl(DocumentPtr *doc)
1539     : NodeImpl(doc)
1540 {
1541     _first = _last = 0;
1542 }
1543
1544
1545 NodeBaseImpl::~NodeBaseImpl()
1546 {
1547     //kdDebug( 6020 ) << "NodeBaseImpl destructor" << endl;
1548
1549     // Avoid deep recursion when destroying the node tree.
1550     static bool alreadyInsideDestructor; 
1551     bool topLevel = !alreadyInsideDestructor;
1552     if (topLevel)
1553         alreadyInsideDestructor = true;
1554     
1555     // List of nodes to be deleted.
1556     static NodeImpl *head;
1557     static NodeImpl *tail;
1558     
1559     // We have to tell all children that their parent has died.
1560     NodeImpl *n;
1561     NodeImpl *next;
1562
1563     for( n = _first; n != 0; n = next ) {
1564         next = n->nextSibling();
1565         n->setPreviousSibling(0);
1566         n->setNextSibling(0);
1567         n->setParent(0);
1568         
1569         if ( !n->refCount() ) {
1570             // Add the node to the list of nodes to be deleted.
1571             // Reuse the nextSibling pointer for this purpose.
1572             if (tail)
1573                 tail->setNextSibling(n);
1574             else
1575                 head = n;
1576             tail = n;
1577         }
1578     }
1579     
1580     // Only for the top level call, do the actual deleting.
1581     if (topLevel) {
1582         while ((n = head) != 0) {
1583             next = n->nextSibling();
1584             n->setNextSibling(0);
1585
1586             head = next;
1587             if (next == 0)
1588                 tail = 0;
1589             
1590             delete n;
1591         }
1592         
1593         alreadyInsideDestructor = false;
1594     }
1595 }
1596
1597
1598 NodeImpl *NodeBaseImpl::firstChild() const
1599 {
1600     return _first;
1601 }
1602
1603 NodeImpl *NodeBaseImpl::lastChild() const
1604 {
1605     return _last;
1606 }
1607
1608 NodeImpl *NodeBaseImpl::insertBefore ( NodeImpl *newChild, NodeImpl *refChild, int &exceptioncode )
1609 {
1610     exceptioncode = 0;
1611
1612     // insertBefore(...,null) is equivalent to appendChild()
1613     if(!refChild)
1614         return appendChild(newChild, exceptioncode);
1615
1616     Node protectNewChild(newChild); // make sure the new child is ref'd and deref'd so we don't leak it
1617
1618     // Make sure adding the new child is ok
1619     checkAddChild(newChild, exceptioncode);
1620     if (exceptioncode)
1621         return 0;
1622
1623     // NOT_FOUND_ERR: Raised if refChild is not a child of this node
1624     if (refChild->parentNode() != this) {
1625         exceptioncode = DOMException::NOT_FOUND_ERR;
1626         return 0;
1627     }
1628
1629     bool isFragment = newChild->nodeType() == Node::DOCUMENT_FRAGMENT_NODE;
1630
1631     // If newChild is a DocumentFragment with no children.... there's nothing to do.
1632     // Just return the document fragment
1633     if (isFragment && !newChild->firstChild())
1634         return (newChild->hasOneRef() && !newChild->parent()) ? 0 : newChild;
1635
1636     // Now actually add the child(ren)
1637     NodeImpl *nextChild;
1638     NodeImpl *child = isFragment ? newChild->firstChild() : newChild;
1639
1640     NodeImpl *prev = refChild->previousSibling();
1641     if ( prev == newChild || refChild == newChild ) // nothing to do
1642         return newChild;
1643     
1644     while (child) {
1645         nextChild = isFragment ? child->nextSibling() : 0;
1646
1647         // If child is already present in the tree, first remove it
1648         NodeImpl *newParent = child->parentNode();
1649         if(newParent)
1650             newParent->removeChild( child, exceptioncode );
1651         if ( exceptioncode )
1652             return 0;
1653
1654         // Add child in the correct position
1655         if (prev)
1656             prev->setNextSibling(child);
1657         else
1658             _first = child;
1659         refChild->setPreviousSibling(child);
1660         child->setParent(this);
1661         child->setPreviousSibling(prev);
1662         child->setNextSibling(refChild);
1663
1664         // Add child to the rendering tree
1665         // ### should we detach() it first if it's already attached?
1666         if (attached() && !child->attached())
1667             child->attach();
1668
1669         // Dispatch the mutation events
1670         dispatchChildInsertedEvents(child,exceptioncode);
1671
1672         prev = child;
1673         child = nextChild;
1674     }
1675
1676     getDocument()->setDocumentChanged(true);
1677     dispatchSubtreeModifiedEvent();
1678     return newChild;
1679 }
1680
1681 NodeImpl *NodeBaseImpl::replaceChild ( NodeImpl *newChild, NodeImpl *oldChild, int &exceptioncode )
1682 {
1683     exceptioncode = 0;
1684
1685     Node protectNewChild(newChild); // make sure the new child is ref'd and deref'd so we don't leak it
1686
1687     if ( oldChild == newChild ) // nothing to do
1688         return oldChild;
1689     
1690     // Make sure adding the new child is ok
1691     checkAddChild(newChild, exceptioncode);
1692     if (exceptioncode)
1693         return 0;
1694
1695     // NOT_FOUND_ERR: Raised if oldChild is not a child of this node.
1696     if (!oldChild || oldChild->parentNode() != this) {
1697         exceptioncode = DOMException::NOT_FOUND_ERR;
1698         return 0;
1699     }
1700
1701     bool isFragment = newChild->nodeType() == Node::DOCUMENT_FRAGMENT_NODE;
1702     NodeImpl *nextChild;
1703     NodeImpl *child = isFragment ? newChild->firstChild() : newChild;
1704
1705     // Remove the old child
1706     NodeImpl *prev = oldChild->previousSibling();
1707     NodeImpl *next = oldChild->nextSibling();
1708
1709     removeChild(oldChild, exceptioncode);
1710     if (exceptioncode)
1711         return 0;
1712
1713     // Add the new child(ren)
1714     while (child) {
1715         nextChild = isFragment ? child->nextSibling() : 0;
1716
1717         // If child is already present in the tree, first remove it
1718         NodeImpl *newParent = child->parentNode();
1719         if(newParent)
1720             newParent->removeChild( child, exceptioncode );
1721         if (exceptioncode)
1722             return 0;
1723
1724         // Add child in the correct position
1725         if (prev) prev->setNextSibling(child);
1726         if (next) next->setPreviousSibling(child);
1727         if(!prev) _first = child;
1728         if(!next) _last = child;
1729         child->setParent(this);
1730         child->setPreviousSibling(prev);
1731         child->setNextSibling(next);
1732
1733         // Add child to the rendering tree
1734         // ### should we detach() it first if it's already attached?
1735         if (attached() && !child->attached())
1736             child->attach();
1737
1738         // Dispatch the mutation events
1739         dispatchChildInsertedEvents(child,exceptioncode);
1740
1741         prev = child;
1742         child = nextChild;
1743     }
1744
1745     // ### set style in case it's attached
1746     getDocument()->setDocumentChanged(true);
1747     dispatchSubtreeModifiedEvent();
1748     return oldChild;
1749 }
1750
1751 NodeImpl *NodeBaseImpl::removeChild ( NodeImpl *oldChild, int &exceptioncode )
1752 {
1753     exceptioncode = 0;
1754
1755     // NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
1756     if (isReadOnly()) {
1757         exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR;
1758         return 0;
1759     }
1760
1761     // NOT_FOUND_ERR: Raised if oldChild is not a child of this node.
1762     if (!oldChild || oldChild->parentNode() != this) {
1763         exceptioncode = DOMException::NOT_FOUND_ERR;
1764         return 0;
1765     }
1766
1767     // Dispatch pre-removal mutation events
1768     getDocument()->notifyBeforeNodeRemoval(oldChild); // ### use events instead
1769     if (getDocument()->hasListenerType(DocumentImpl::DOMNODEREMOVED_LISTENER)) {
1770         oldChild->dispatchEvent(new MutationEventImpl(EventImpl::DOMNODEREMOVED_EVENT,
1771                              true,false,this,DOMString(),DOMString(),DOMString(),0),exceptioncode,true);
1772         if (exceptioncode)
1773             return 0;
1774     }
1775
1776     dispatchChildRemovalEvents(oldChild,exceptioncode);
1777     if (exceptioncode)
1778         return 0;
1779
1780     // Remove from rendering tree
1781     if (oldChild->attached())
1782         oldChild->detach();
1783
1784     // Remove the child
1785     NodeImpl *prev, *next;
1786     prev = oldChild->previousSibling();
1787     next = oldChild->nextSibling();
1788
1789     if(next) next->setPreviousSibling(prev);
1790     if(prev) prev->setNextSibling(next);
1791     if(_first == oldChild) _first = next;
1792     if(_last == oldChild) _last = prev;
1793
1794     oldChild->setPreviousSibling(0);
1795     oldChild->setNextSibling(0);
1796     oldChild->setParent(0);
1797
1798     getDocument()->setDocumentChanged(true);
1799
1800     // Dispatch post-removal mutation events
1801     dispatchSubtreeModifiedEvent();
1802
1803     if (oldChild->inDocument())
1804         oldChild->removedFromDocument();
1805
1806     return oldChild;
1807 }
1808
1809 void NodeBaseImpl::removeChildren()
1810 {
1811     int exceptionCode;
1812     while (NodeImpl *n = _first) {
1813         NodeImpl *next = n->nextSibling();
1814         
1815         n->ref();
1816
1817         // Fire removed from document mutation events.
1818         dispatchChildRemovalEvents(n, exceptionCode);
1819
1820         if (n->attached())
1821             n->detach();
1822         n->setPreviousSibling(0);
1823         n->setNextSibling(0);
1824         n->setParent(0);
1825         
1826         if (n->inDocument())
1827             n->removedFromDocument();
1828
1829         n->deref();
1830
1831         _first = next;
1832     }
1833     _last = 0;
1834     
1835     // Dispatch a single post-removal mutation event denoting a modified subtree.
1836     dispatchSubtreeModifiedEvent();
1837 }
1838
1839
1840 NodeImpl *NodeBaseImpl::appendChild ( NodeImpl *newChild, int &exceptioncode )
1841 {
1842     exceptioncode = 0;
1843
1844     Node protectNewChild(newChild); // make sure the new child is ref'd and deref'd so we don't leak it
1845
1846     // Make sure adding the new child is ok
1847     checkAddChild(newChild, exceptioncode);
1848     if (exceptioncode)
1849         return 0;
1850     
1851     if ( newChild == _last ) // nothing to do
1852         return newChild;
1853
1854     bool isFragment = newChild->nodeType() == Node::DOCUMENT_FRAGMENT_NODE;
1855
1856     // If newChild is a DocumentFragment with no children.... there's nothing to do.
1857     // Just return the document fragment
1858     if (isFragment && !newChild->firstChild())
1859         return newChild;
1860
1861     // Now actually add the child(ren)
1862     NodeImpl *nextChild;
1863     NodeImpl *child = isFragment ? newChild->firstChild() : newChild;
1864
1865     while (child) {
1866         nextChild = isFragment ? child->nextSibling() : 0;
1867
1868         // If child is already present in the tree, first remove it
1869         NodeImpl *oldParent = child->parentNode();
1870         if(oldParent) {
1871             oldParent->removeChild( child, exceptioncode );
1872             if (exceptioncode)
1873                 return 0;
1874         }
1875
1876         // Append child to the end of the list
1877         child->setParent(this);
1878
1879         if(_last)
1880         {
1881             child->setPreviousSibling(_last);
1882             _last->setNextSibling(child);
1883             _last = child;
1884         }
1885         else
1886         {
1887             _first = _last = child;
1888         }
1889
1890         // Add child to the rendering tree
1891         // ### should we detach() it first if it's already attached?
1892         if (attached() && !child->attached())
1893             child->attach();
1894           
1895         // Dispatch the mutation events
1896         dispatchChildInsertedEvents(child,exceptioncode);
1897
1898         child = nextChild;
1899     }
1900
1901     getDocument()->setDocumentChanged(true);
1902     // ### set style in case it's attached
1903     dispatchSubtreeModifiedEvent();
1904     return newChild;
1905 }
1906
1907 bool NodeBaseImpl::hasChildNodes (  ) const
1908 {
1909     return _first != 0;
1910 }
1911
1912 // not part of the DOM
1913 void NodeBaseImpl::setFirstChild(NodeImpl *child)
1914 {
1915     _first = child;
1916 }
1917
1918 void NodeBaseImpl::setLastChild(NodeImpl *child)
1919 {
1920     _last = child;
1921 }
1922
1923 // check for same source document:
1924 bool NodeBaseImpl::checkSameDocument( NodeImpl *newChild, int &exceptioncode )
1925 {
1926     exceptioncode = 0;
1927     DocumentImpl *ownerDocThis = getDocument();
1928     DocumentImpl *ownerDocNew = getDocument();
1929     if(ownerDocThis != ownerDocNew) {
1930         kdDebug(6010)<< "not same document, newChild = " << newChild << "document = " << getDocument() << endl;
1931         exceptioncode = DOMException::WRONG_DOCUMENT_ERR;
1932         return true;
1933     }
1934     return false;
1935 }
1936
1937 // check for being (grand-..)father:
1938 // ### remove in favor or isAncestor()
1939 bool NodeBaseImpl::checkNoOwner( NodeImpl *newChild, int &exceptioncode )
1940 {
1941   //check if newChild is parent of this...
1942   NodeImpl *n;
1943   for( n = this; (n != getDocument()) && (n!= 0); n = n->parentNode() )
1944       if(n == newChild) {
1945           exceptioncode = DOMException::HIERARCHY_REQUEST_ERR;
1946           return true;
1947       }
1948   return false;
1949 }
1950
1951 // check for being child:
1952 bool NodeBaseImpl::checkIsChild( NodeImpl *oldChild, int &exceptioncode )
1953 {
1954     if(!oldChild || oldChild->parentNode() != this) {
1955         exceptioncode = DOMException::NOT_FOUND_ERR;
1956         return true;
1957     }
1958     return false;
1959 }
1960
1961 NodeImpl *NodeBaseImpl::addChild(NodeImpl *newChild)
1962 {
1963     // do not add applyChanges here! This function is only used during parsing
1964
1965     Node protectNewChild(newChild); // make sure the new child is ref'd and deref'd so we don't leak it
1966
1967     // short check for consistency with DTD
1968     if(!isXMLElementNode() && !newChild->isXMLElementNode() && !childAllowed(newChild))
1969     {
1970         //kdDebug( 6020 ) << "AddChild failed! id=" << id() << ", child->id=" << newChild->id() << endl;
1971         return 0;
1972     }
1973
1974     // just add it...
1975     newChild->setParent(this);
1976
1977     if(_last)
1978     {
1979         newChild->setPreviousSibling(_last);
1980         _last->setNextSibling(newChild);
1981         _last = newChild;
1982     }
1983     else
1984     {
1985         _first = _last = newChild;
1986     }
1987
1988     newChild->insertedIntoDocument();
1989     childrenChanged();
1990
1991     if(newChild->nodeType() == Node::ELEMENT_NODE)
1992         return newChild;
1993     return this;
1994 }
1995
1996 void NodeBaseImpl::attach()
1997 {
1998     NodeImpl *child = _first;
1999     while(child != 0)
2000     {
2001         child->attach();
2002         child = child->nextSibling();
2003     }
2004     NodeImpl::attach();
2005 }
2006
2007 void NodeBaseImpl::detach()
2008 {
2009     NodeImpl *child = _first;
2010     while(child != 0)
2011     {
2012         NodeImpl* prev = child;
2013         child = child->nextSibling();
2014         prev->detach();
2015     }
2016     NodeImpl::detach();
2017 }
2018
2019 void NodeBaseImpl::insertedIntoDocument()
2020 {
2021     NodeImpl::insertedIntoDocument();
2022     for (NodeImpl *child = _first; child; child = child->nextSibling())
2023         child->insertedIntoDocument();
2024 }
2025
2026 void NodeBaseImpl::removedFromDocument()
2027 {
2028     NodeImpl::removedFromDocument();
2029     for (NodeImpl *child = _first; child; child = child->nextSibling())
2030         child->removedFromDocument();
2031 }
2032
2033 void NodeBaseImpl::cloneChildNodes(NodeImpl *clone)
2034 {
2035     int exceptioncode = 0;
2036     NodeImpl *n;
2037     for(n = firstChild(); n && !exceptioncode; n = n->nextSibling())
2038     {
2039         clone->appendChild(n->cloneNode(true),exceptioncode);
2040     }
2041 }
2042
2043 NodeListImpl* NodeBaseImpl::getElementsByTagNameNS ( DOMStringImpl* namespaceURI,
2044                                                      DOMStringImpl* localName )
2045 {
2046     if (!localName) return 0;
2047
2048     NodeImpl::Id idMask = namespaceMask | localNameMask;
2049     if (localName->l && localName->s[0] == '*')
2050         idMask &= ~localNameMask;
2051     if (namespaceURI && namespaceURI->l && namespaceURI->s[0] == '*')
2052         idMask &= ~namespaceMask;
2053
2054     Id id = 0; // 0 means "all items"
2055     if ( (idMask & localNameMask) || namespaceURI ) // not getElementsByTagName("*")
2056     {
2057         id = getDocument()->tagId( namespaceURI, localName, true);
2058         if ( !id ) // not found -> we want to return an empty list, not "all items"
2059             id = (Id)-1; // HACK. HEAD has a cleaner implementation of TagNodeListImpl it seems.
2060     }
2061
2062     return new TagNodeListImpl( this, id, idMask );
2063 }
2064
2065 // I don't like this way of implementing the method, but I didn't find any
2066 // other way. Lars
2067 bool NodeBaseImpl::getUpperLeftCorner(int &xPos, int &yPos) const
2068 {
2069     if (!m_render)
2070         return false;
2071     RenderObject *o = m_render;
2072     xPos = yPos = 0;
2073     if ( !o->isInline() || o->isReplaced() ) {
2074         o->absolutePosition( xPos, yPos );
2075         return true;
2076     }
2077
2078     // find the next text/image child, to get a position
2079     while(o) {
2080         if(o->firstChild())
2081             o = o->firstChild();
2082         else if(o->nextSibling())
2083             o = o->nextSibling();
2084         else {
2085             RenderObject *next = 0;
2086             while(!next) {
2087                 o = o->parent();
2088                 if(!o) return false;
2089                 next = o->nextSibling();
2090             }
2091             o = next;
2092         }
2093         if((o->isText() && !o->isBR()) || o->isReplaced()) {
2094             o->container()->absolutePosition( xPos, yPos );
2095             if (o->isText())
2096                 xPos += static_cast<RenderText *>(o)->minXPos();
2097             else
2098                 xPos += o->xPos();
2099             yPos += o->yPos();
2100             return true;
2101         }
2102     }
2103     return true;
2104 }
2105
2106 bool NodeBaseImpl::getLowerRightCorner(int &xPos, int &yPos) const
2107 {
2108     if (!m_render)
2109         return false;
2110
2111     RenderObject *o = m_render;
2112     xPos = yPos = 0;
2113     if (!o->isInline() || o->isReplaced())
2114     {
2115         o->absolutePosition( xPos, yPos );
2116         xPos += o->width();
2117         yPos += o->height();
2118         return true;
2119     }
2120     // find the last text/image child, to get a position
2121     while(o) {
2122         if(o->lastChild())
2123             o = o->lastChild();
2124         else if(o->previousSibling())
2125             o = o->previousSibling();
2126         else {
2127             RenderObject *prev = 0;
2128             while(!prev) {
2129                 o = o->parent();
2130                 if(!o) return false;
2131                 prev = o->previousSibling();
2132             }
2133             o = prev;
2134         }
2135         if(o->isText() || o->isReplaced()) {
2136             o->container()->absolutePosition(xPos, yPos);
2137             if (o->isText())
2138                 xPos += static_cast<RenderText *>(o)->minXPos() + o->width();
2139             else
2140                 xPos += o->xPos()+o->width();
2141             yPos += o->yPos()+o->height();
2142             return true;
2143         }
2144     }
2145     return true;
2146 }
2147
2148 QRect NodeBaseImpl::getRect() const
2149 {
2150     int xPos, yPos;
2151     if (!getUpperLeftCorner(xPos,yPos))
2152     {
2153         xPos=0;
2154         yPos=0;
2155     }
2156     int xEnd, yEnd;
2157     if (!getLowerRightCorner(xEnd,yEnd))
2158     {
2159         if (xPos)
2160             xEnd = xPos;
2161         if (yPos)
2162             yEnd = yPos;
2163     }
2164     else
2165     {
2166         if (xPos==0)
2167             xPos = xEnd;
2168         if (yPos==0)
2169             yPos = yEnd;
2170     }
2171     if ( xEnd <= xPos || yEnd <= yPos )
2172         return QRect( QPoint( xPos, yPos ), QSize() );
2173
2174     return QRect(xPos, yPos, xEnd - xPos, yEnd - yPos);
2175 }
2176
2177 void NodeBaseImpl::setFocus(bool received)
2178 {
2179     if (m_focused == received) return;
2180
2181     NodeImpl::setFocus(received);
2182
2183     if (received && isEditableBlock() && !hasChildNodes()) {
2184         getDocument()->part()->setSelection(Position(this, 0));
2185     }
2186
2187     // note that we need to recalc the style
2188     setChanged();
2189 }
2190
2191 void NodeBaseImpl::setActive(bool down)
2192 {
2193     if (down == active()) return;
2194
2195     NodeImpl::setActive(down);
2196
2197     // note that we need to recalc the style
2198     if (m_render && m_render->style()->affectedByActiveRules())
2199         setChanged();
2200 }
2201
2202 unsigned long NodeBaseImpl::childNodeCount() const
2203 {
2204     unsigned long count = 0;
2205     NodeImpl *n;
2206     for (n = firstChild(); n; n = n->nextSibling())
2207         count++;
2208     return count;
2209 }
2210
2211 NodeImpl *NodeBaseImpl::childNode(unsigned long index)
2212 {
2213     unsigned long i;
2214     NodeImpl *n = firstChild();
2215     for (i = 0; i < index; i++)
2216         n = n->nextSibling();
2217     return n;
2218 }
2219
2220 void NodeBaseImpl::dispatchChildInsertedEvents( NodeImpl *child, int &exceptioncode )
2221 {
2222     if (getDocument()->hasListenerType(DocumentImpl::DOMNODEINSERTED_LISTENER)) {
2223         child->dispatchEvent(new MutationEventImpl(EventImpl::DOMNODEINSERTED_EVENT,
2224                                                    true,false,this,DOMString(),DOMString(),DOMString(),0),exceptioncode,true);
2225         if (exceptioncode)
2226             return;
2227     }
2228
2229     // dispatch the DOMNOdeInsertedInfoDocument event to all descendants
2230     bool hasInsertedListeners = getDocument()->hasListenerType(DocumentImpl::DOMNODEINSERTEDINTODOCUMENT_LISTENER);
2231     NodeImpl *p = this;
2232     while (p->parentNode())
2233         p = p->parentNode();
2234     if (p->nodeType() == Node::DOCUMENT_NODE) {
2235         for (NodeImpl *c = child; c; c = c->traverseNextNode(child)) {
2236             c->insertedIntoDocument();
2237
2238             if (hasInsertedListeners) {
2239                 c->dispatchEvent(new MutationEventImpl(EventImpl::DOMNODEINSERTEDINTODOCUMENT_EVENT,
2240                                                        false,false,0,DOMString(),DOMString(),DOMString(),0),exceptioncode,true);
2241                 if (exceptioncode)
2242                     return;
2243             }
2244         }
2245     }
2246 }
2247
2248 void NodeBaseImpl::dispatchChildRemovalEvents( NodeImpl *child, int &exceptioncode )
2249 {
2250     // Dispatch pre-removal mutation events
2251     getDocument()->notifyBeforeNodeRemoval(child); // ### use events instead
2252     if (getDocument()->hasListenerType(DocumentImpl::DOMNODEREMOVED_LISTENER)) {
2253         child->dispatchEvent(new MutationEventImpl(EventImpl::DOMNODEREMOVED_EVENT,
2254                              true,false,this,DOMString(),DOMString(),DOMString(),0),exceptioncode,true);
2255         if (exceptioncode)
2256             return;
2257     }
2258
2259     bool hasRemovalListeners = getDocument()->hasListenerType(DocumentImpl::DOMNODEREMOVEDFROMDOCUMENT_LISTENER);
2260
2261     // dispatch the DOMNodeRemovedFromDocument event to all descendants
2262     if (inDocument()) {
2263         for (NodeImpl *c = child; c; c = c->traverseNextNode(child)) {
2264             if (hasRemovalListeners) {
2265                 c->dispatchEvent(new MutationEventImpl(EventImpl::DOMNODEREMOVEDFROMDOCUMENT_EVENT,
2266                                  false,false,0,DOMString(),DOMString(),DOMString(),0),exceptioncode,true);
2267                 if (exceptioncode)
2268                     return;
2269             }
2270         }
2271     }
2272 }
2273
2274 // ---------------------------------------------------------------------------
2275
2276
2277 NodeListImpl::NodeListImpl(NodeImpl *_rootNode)
2278     : rootNode(_rootNode),
2279       isLengthCacheValid(false),
2280       isItemCacheValid(false)
2281 {
2282     rootNode->ref();
2283     rootNode->registerNodeList(this);
2284 }    
2285
2286 NodeListImpl::~NodeListImpl()
2287 {
2288     rootNode->unregisterNodeList(this);
2289     rootNode->deref();
2290 }
2291
2292 unsigned long NodeListImpl::recursiveLength( NodeImpl *start ) const
2293 {
2294     if (!start)
2295         start = rootNode;
2296
2297     if (isLengthCacheValid && start == rootNode) {
2298         return cachedLength;
2299     }
2300
2301     unsigned long len = 0;
2302
2303     for(NodeImpl *n = start->firstChild(); n != 0; n = n->nextSibling()) {
2304         if ( n->nodeType() == Node::ELEMENT_NODE ) {
2305             if (nodeMatches(n))
2306                 len++;
2307             len+= recursiveLength(n);
2308         }
2309     }
2310
2311     if (start == rootNode) {
2312         cachedLength = len;
2313         isLengthCacheValid = true;
2314     }
2315
2316     return len;
2317 }
2318
2319 NodeImpl *NodeListImpl::recursiveItem ( unsigned long offset, NodeImpl *start) const
2320 {
2321     int remainingOffset = offset;
2322     if (!start) {
2323         start = rootNode->firstChild();
2324         if (isItemCacheValid) {
2325             if (offset == lastItemOffset) {
2326                 return lastItem;
2327             } else if (offset > lastItemOffset) {
2328                 start = lastItem;
2329                 remainingOffset -= lastItemOffset;
2330             }
2331         }
2332     }
2333
2334     NodeImpl *end = rootNode->nextSibling();
2335     NodeImpl *n = start;
2336
2337     while (n != 0 && n != end) {
2338         if ( n->nodeType() == Node::ELEMENT_NODE ) {
2339             if (nodeMatches(n)) {
2340                 if (!remainingOffset) {
2341                     lastItem = n;
2342                     lastItemOffset = offset;
2343                     isItemCacheValid = 1;
2344                     return n;
2345                 }
2346                 remainingOffset--;
2347             }
2348         }
2349
2350         if (n->firstChild()) {
2351             n = n->firstChild();
2352         } else if (n->nextSibling()) {
2353             n = n->nextSibling();
2354         } else if (n->parentNode()) {
2355             n = n->parentNode()->nextSibling();
2356         } else {
2357             n = 0;
2358         }
2359     }
2360
2361     return 0; // no matching node in this subtree
2362 }
2363
2364 NodeImpl *NodeListImpl::itemById (const DOMString& elementId) const
2365 {
2366     if (rootNode->isDocumentNode() || rootNode->inDocument()) {
2367         NodeImpl *node = rootNode->getDocument()->getElementById(elementId);
2368
2369         if (node == NULL || !nodeMatches(node))
2370             return 0;
2371
2372         for (NodeImpl *p = node->parentNode(); p; p = p->parentNode()) {
2373             if (p == rootNode)
2374                 return node;
2375         }
2376
2377         return 0;
2378     }
2379
2380     unsigned long l = length();
2381
2382     for ( unsigned long i = 0; i < l; i++ ) {
2383         NodeImpl *node = item(i);
2384         
2385         if ( static_cast<ElementImpl *>(node)->getIDAttribute() == elementId ) {
2386             return node;
2387         }
2388     }
2389
2390     return 0;
2391 }
2392
2393
2394 void NodeListImpl::rootNodeSubtreeModified()
2395 {
2396     isLengthCacheValid = false;     
2397     isItemCacheValid = false;     
2398 }
2399
2400
2401 ChildNodeListImpl::ChildNodeListImpl( NodeImpl *n )
2402     : NodeListImpl(n)
2403 {
2404 }
2405
2406 unsigned long ChildNodeListImpl::length() const
2407 {
2408     unsigned long len = 0;
2409     NodeImpl *n;
2410     for(n = rootNode->firstChild(); n != 0; n = n->nextSibling())
2411         len++;
2412
2413     return len;
2414 }
2415
2416 NodeImpl *ChildNodeListImpl::item ( unsigned long index ) const
2417 {
2418     unsigned int pos = 0;
2419     NodeImpl *n = rootNode->firstChild();
2420
2421     while( n != 0 && pos < index )
2422     {
2423         n = n->nextSibling();
2424         pos++;
2425     }
2426
2427     return n;
2428 }
2429
2430 bool ChildNodeListImpl::nodeMatches(NodeImpl *testNode) const
2431 {
2432     return testNode->parentNode() == rootNode;
2433 }
2434
2435 TagNodeListImpl::TagNodeListImpl(NodeImpl *n, NodeImpl::Id _id, NodeImpl::Id _idMask )
2436     : NodeListImpl(n), 
2437       m_id(_id & _idMask), 
2438       m_idMask(_idMask)
2439 {
2440 }
2441
2442 unsigned long TagNodeListImpl::length() const
2443 {
2444     return recursiveLength();
2445 }
2446
2447 NodeImpl *TagNodeListImpl::item ( unsigned long index ) const
2448 {
2449     return recursiveItem( index );
2450 }
2451
2452 bool TagNodeListImpl::nodeMatches( NodeImpl *testNode ) const
2453 {
2454     return ( testNode->isElementNode() &&
2455              (testNode->id() & m_idMask) == m_id);
2456 }
2457
2458 NameNodeListImpl::NameNodeListImpl(NodeImpl *n, const DOMString &t )
2459   : NodeListImpl(n), nodeName(t)
2460 {
2461 }
2462
2463 unsigned long NameNodeListImpl::length() const
2464 {
2465     return recursiveLength();
2466 }
2467
2468 NodeImpl *NameNodeListImpl::item ( unsigned long index ) const
2469 {
2470     return recursiveItem( index );
2471 }
2472
2473 bool NameNodeListImpl::nodeMatches( NodeImpl *testNode ) const
2474 {
2475     return static_cast<ElementImpl *>(testNode)->getAttribute(ATTR_NAME) == nodeName;
2476 }
2477
2478 // ---------------------------------------------------------------------------
2479
2480 NamedNodeMapImpl::NamedNodeMapImpl()
2481 {
2482 }
2483
2484 NamedNodeMapImpl::~NamedNodeMapImpl()
2485 {
2486 }
2487
2488 // ----------------------------------------------------------------------------
2489
2490 // ### unused
2491 #if 0
2492 GenericRONamedNodeMapImpl::GenericRONamedNodeMapImpl(DocumentPtr* doc)
2493     : NamedNodeMapImpl()
2494 {
2495     m_doc = doc->document();
2496     m_contents = new QPtrList<NodeImpl>;
2497 }
2498
2499 GenericRONamedNodeMapImpl::~GenericRONamedNodeMapImpl()
2500 {
2501     while (m_contents->count() > 0)
2502         m_contents->take(0)->deref();
2503
2504     delete m_contents;
2505 }
2506
2507 NodeImpl *GenericRONamedNodeMapImpl::getNamedItem ( const DOMString &name, int &/*exceptioncode*/ ) const
2508 {
2509     QPtrListIterator<NodeImpl> it(*m_contents);
2510     for (; it.current(); ++it)
2511         if (it.current()->nodeName() == name)
2512             return it.current();
2513     return 0;
2514 }
2515
2516 Node GenericRONamedNodeMapImpl::setNamedItem ( const Node &/*arg*/, int &exceptioncode )
2517 {
2518     // can't modify this list through standard DOM functions
2519     // NO_MODIFICATION_ALLOWED_ERR: Raised if this map is readonly
2520     exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR;
2521     return 0;
2522 }
2523
2524 Node GenericRONamedNodeMapImpl::removeNamedItem ( const DOMString &/*name*/, int &exceptioncode )
2525 {
2526     // can't modify this list through standard DOM functions
2527     // NO_MODIFICATION_ALLOWED_ERR: Raised if this map is readonly
2528     exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR;
2529     return 0;
2530 }
2531
2532 NodeImpl *GenericRONamedNodeMapImpl::item ( unsigned long index ) const
2533 {
2534     // ### check this when calling from javascript using -1 = 2^sizeof(int)-1
2535     // (also for other similar methods)
2536     if (index >= m_contents->count())
2537         return 0;
2538
2539     return m_contents->at(index);
2540 }
2541
2542 unsigned long GenericRONamedNodeMapImpl::length(  ) const
2543 {
2544     return m_contents->count();
2545 }
2546
2547 NodeImpl *GenericRONamedNodeMapImpl::getNamedItemNS( const DOMString &namespaceURI,
2548                                                      const DOMString &localName,
2549                                                      int &/*exceptioncode*/ ) const
2550 {
2551     NodeImpl::Id searchId = m_doc->tagId(namespaceURI.implementation(),
2552                                                    localName.implementation(), true);
2553
2554     QPtrListIterator<NodeImpl> it(*m_contents);
2555     for (; it.current(); ++it)
2556         if (it.current()->id() == searchId)
2557             return it.current();
2558
2559     return 0;
2560 }
2561
2562 NodeImpl *GenericRONamedNodeMapImpl::setNamedItemNS( NodeImpl */*arg*/, int &exceptioncode )
2563 {
2564     // can't modify this list through standard DOM functions
2565     // NO_MODIFICATION_ALLOWED_ERR: Raised if this map is readonly
2566     exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR;
2567     return 0;
2568 }
2569
2570 NodeImpl *GenericRONamedNodeMapImpl::removeNamedItemNS( const DOMString &/*namespaceURI*/,
2571                                                         const DOMString &/*localName*/,
2572                                                         int &exceptioncode )
2573 {
2574     // can't modify this list through standard DOM functions
2575     exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR;
2576     return 0;
2577 }
2578
2579 void GenericRONamedNodeMapImpl::addNode(NodeImpl *n)
2580 {
2581     // The spec says that in the case of duplicates we only keep the first one
2582     int exceptioncode = 0;
2583     if (getNamedItem(n->nodeName(),exceptioncode))
2584         return;
2585
2586     n->ref();
2587     m_contents->append(n);
2588 }
2589
2590 #endif