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