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