[webkit-changes] cvs commit: WebCore/khtml/xml dom2_traversalimpl.cpp dom_docimpl.cpp dom_docimpl.h dom_nodeimpl.cpp dom_nodeimpl.h

Timothy thatcher at opensource.apple.com
Fri Nov 11 17:24:39 PST 2005


thatcher    05/11/11 17:24:39

  Modified:    .        Tag: Safari-2-0-branch ChangeLog
               khtml/html Tag: Safari-2-0-branch html_baseimpl.cpp
                        html_baseimpl.h html_objectimpl.cpp
               khtml/xml Tag: Safari-2-0-branch dom2_traversalimpl.cpp
                        dom_docimpl.cpp dom_docimpl.h dom_nodeimpl.cpp
                        dom_nodeimpl.h
  Log:
          Merged fix from TOT to Safari-2-0-branch
  
      2005-10-27  David Harrison  <harrison at apple.com>
  
          Reviewed by Justin Garcia and Dave Hyatt.
  
          <rdar://problem/4134884> crash trying to forward msg - khtml::RenderBlock::addChildToFlow
  
          Problem was that onunload events were being fired while in the middle of trying to detach, which resulted in updateDocumentsRendering re-attaching the previously detached nodes.  Similar problem with load events while attaching.
  
          Solved by eliminating load and unload for object nodes, pre-sending unload before detach, and sending dom mutation and load events after attaching.
  
          Also, added asserts to catch this problem more easily in the future.
  
          Added test:
          * fast/events/event-targets.html
          Make sure that load and unload events do not fire on certain objects.
  
          * khtml/ecma/kjs_html.cpp:
          (KJS::Image::notifyFinished):
          Use constant string for "load" event name.
          * khtml/ecma/xmlhttprequest.cpp:
          (KJS::XMLHttpRequest::changeState):
          Use constant strings for "load" and "readystatechange" event names.
          * khtml/html/html_baseimpl.cpp:
          (HTMLFrameElementImpl::close):
          (HTMLFrameElementImpl::willRemove):
          (HTMLFrameElementImpl::detach):
          Add willRemove() function.
          * khtml/html/html_baseimpl.h:
          Add willRemove() function.
          * khtml/html/html_objectimpl.cpp:
          (DOM::HTMLObjectElementImpl::attach):
          (DOM::HTMLObjectElementImpl::detach):
          Stop needlessly sending load and unload events for OBJECT elements.
          * khtml/xml/dom2_traversalimpl.cpp:
          (DOM::NodeIteratorImpl::notifyBeforeNodeRemoval):
          Rename local variable from willRemove to removedNode for clarity.
          * khtml/xml/dom_docimpl.cpp:
          (DocumentImpl::DocumentImpl):
          (DocumentImpl::forbidEventDispatch):
          (DocumentImpl::allowEventDispatch):
          (DocumentImpl::eventDispatchForbidden):
          (DocumentImpl::createEvent):
          Add mechanism to prevent event dispatch.
          * khtml/xml/dom_docimpl.h:
          * khtml/xml/dom_nodeimpl.cpp:
          (DOM::NodeImpl::dispatchEvent):
          (DOM::NodeImpl::dispatchGenericEvent):
          (DOM::NodeImpl::dispatchHTMLEvent):
          (DOM::NodeImpl::dispatchWindowEvent):
          (DOM::NodeImpl::dispatchMouseEvent):
          (DOM::NodeImpl::dispatchSimulatedMouseEvent):
          (DOM::NodeImpl::dispatchUIEvent):
          (DOM::NodeImpl::dispatchSubtreeModifiedEvent):
          (DOM::NodeImpl::dispatchKeyEvent):
          (DOM::NodeImpl::dispatchWheelEvent):
          (DOM::NodeImpl::willRemove):
          (DOM::ContainerNodeImpl::insertBefore):
          (DOM::ContainerNodeImpl::replaceChild):
          (DOM::ContainerNodeImpl::willRemove):
          (DOM::ContainerNodeImpl::willRemoveChild):
          (DOM::ContainerNodeImpl::removeChild):
          (DOM::ContainerNodeImpl::removeChildren):
          (DOM::ContainerNodeImpl::appendChild):
          (DOM::ContainerNodeImpl::addChild):
          (DOM::ContainerNodeImpl::dispatchChildInsertedEvents):
          (DOM::ContainerNodeImpl::dispatchChildRemovalEvents):
          Prevent event dispatch during DOM node removals and additions.
          * khtml/xml/dom_nodeimpl.h:
  
  Revision  Changes    Path
  No                   revision
  
  
  No                   revision
  
  
  1.1.2.56  +73 -0     WebCore/ChangeLog
  
  Index: ChangeLog
  ===================================================================
  RCS file: /cvs/root/WebCore/ChangeLog,v
  retrieving revision 1.1.2.55
  retrieving revision 1.1.2.56
  diff -u -r1.1.2.55 -r1.1.2.56
  --- ChangeLog	11 Nov 2005 19:37:57 -0000	1.1.2.55
  +++ ChangeLog	12 Nov 2005 01:24:26 -0000	1.1.2.56
  @@ -1,5 +1,78 @@
   2005-11-11  Timothy Hatcher  <timothy at apple.com>
   
  +        Merged fix from TOT to Safari-2-0-branch
  +
  +    2005-10-27  David Harrison  <harrison at apple.com>
  + 
  +        Reviewed by Justin Garcia and Dave Hyatt.
  +
  +        <rdar://problem/4134884> crash trying to forward msg - khtml::RenderBlock::addChildToFlow
  +
  +        Problem was that onunload events were being fired while in the middle of trying to detach, which resulted in updateDocumentsRendering re-attaching the previously detached nodes.  Similar problem with load events while attaching.
  +        
  +        Solved by eliminating load and unload for object nodes, pre-sending unload before detach, and sending dom mutation and load events after attaching.
  +        
  +        Also, added asserts to catch this problem more easily in the future.
  +        
  +        Added test:
  +        * fast/events/event-targets.html
  +        Make sure that load and unload events do not fire on certain objects.
  +        
  +        * khtml/ecma/kjs_html.cpp:
  +        (KJS::Image::notifyFinished):
  +        Use constant string for "load" event name.
  +        * khtml/ecma/xmlhttprequest.cpp:
  +        (KJS::XMLHttpRequest::changeState):
  +        Use constant strings for "load" and "readystatechange" event names.
  +        * khtml/html/html_baseimpl.cpp:
  +        (HTMLFrameElementImpl::close):
  +        (HTMLFrameElementImpl::willRemove):
  +        (HTMLFrameElementImpl::detach):
  +        Add willRemove() function.
  +        * khtml/html/html_baseimpl.h:
  +        Add willRemove() function.
  +        * khtml/html/html_objectimpl.cpp:
  +        (DOM::HTMLObjectElementImpl::attach):
  +        (DOM::HTMLObjectElementImpl::detach):
  +        Stop needlessly sending load and unload events for OBJECT elements.
  +        * khtml/xml/dom2_traversalimpl.cpp:
  +        (DOM::NodeIteratorImpl::notifyBeforeNodeRemoval):
  +        Rename local variable from willRemove to removedNode for clarity.
  +        * khtml/xml/dom_docimpl.cpp:
  +        (DocumentImpl::DocumentImpl):
  +        (DocumentImpl::forbidEventDispatch):
  +        (DocumentImpl::allowEventDispatch):
  +        (DocumentImpl::eventDispatchForbidden):
  +        (DocumentImpl::createEvent):
  +        Add mechanism to prevent event dispatch.
  +        * khtml/xml/dom_docimpl.h:
  +        * khtml/xml/dom_nodeimpl.cpp:
  +        (DOM::NodeImpl::dispatchEvent):
  +        (DOM::NodeImpl::dispatchGenericEvent):
  +        (DOM::NodeImpl::dispatchHTMLEvent):
  +        (DOM::NodeImpl::dispatchWindowEvent):
  +        (DOM::NodeImpl::dispatchMouseEvent):
  +        (DOM::NodeImpl::dispatchSimulatedMouseEvent):
  +        (DOM::NodeImpl::dispatchUIEvent):
  +        (DOM::NodeImpl::dispatchSubtreeModifiedEvent):
  +        (DOM::NodeImpl::dispatchKeyEvent):
  +        (DOM::NodeImpl::dispatchWheelEvent):
  +        (DOM::NodeImpl::willRemove):
  +        (DOM::ContainerNodeImpl::insertBefore):
  +        (DOM::ContainerNodeImpl::replaceChild):
  +        (DOM::ContainerNodeImpl::willRemove):
  +        (DOM::ContainerNodeImpl::willRemoveChild):
  +        (DOM::ContainerNodeImpl::removeChild):
  +        (DOM::ContainerNodeImpl::removeChildren):
  +        (DOM::ContainerNodeImpl::appendChild):
  +        (DOM::ContainerNodeImpl::addChild):
  +        (DOM::ContainerNodeImpl::dispatchChildInsertedEvents):
  +        (DOM::ContainerNodeImpl::dispatchChildRemovalEvents):
  +        Prevent event dispatch during DOM node removals and additions.
  +        * khtml/xml/dom_nodeimpl.h:
  +
  +2005-11-11  Timothy Hatcher  <timothy at apple.com>
  +
           Fix for http://bugzilla.opendarwin.org/show_bug.cgi?id=4170
           and <rdar://problem/3849434> SLIDER: Article length goes from a 
           subject line, back to the whole article, when decreasing (4170)
  
  
  
  No                   revision
  
  
  No                   revision
  
  
  1.68.8.3  +19 -10    WebCore/khtml/html/html_baseimpl.cpp
  
  Index: html_baseimpl.cpp
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/html/html_baseimpl.cpp,v
  retrieving revision 1.68.8.2
  retrieving revision 1.68.8.3
  diff -u -r1.68.8.2 -r1.68.8.3
  --- html_baseimpl.cpp	12 Jul 2005 20:50:35 -0000	1.68.8.2
  +++ html_baseimpl.cpp	12 Nov 2005 01:24:32 -0000	1.68.8.3
  @@ -458,7 +458,7 @@
       part->requestFrame( static_cast<RenderFrame*>(m_render), relativeURL.string(), name.string() );
   }
   
  -void HTMLFrameElementImpl::detach()
  +void HTMLFrameElementImpl::close()
   {
       KHTMLPart *part = getDocument()->part();
   
  @@ -468,7 +468,25 @@
           if (framePart)
               framePart->frameDetached();
       }
  +}
  +
  +void HTMLFrameElementImpl::willRemove()
  +{
  +    // close the frame and dissociate the renderer, but leave the
  +    // node attached so that frame does not get re-attached before
  +    // actually leaving the document.  see <rdar://problem/4132581>
  +    close();
  +    if (m_render) {
  +        m_render->detach();
  +        m_render = 0;
  +    }
  +    
  +    HTMLElementImpl::willRemove();
  +}
   
  +void HTMLFrameElementImpl::detach()
  +{
  +    close();
       HTMLElementImpl::detach();
   }
   
  @@ -641,15 +659,6 @@
       HTMLElementImpl::defaultEventHandler(evt);
   }
   
  -void HTMLFrameSetElementImpl::detach()
  -{
  -    if(attached())
  -        // ### send the event when we actually get removed from the doc instead of here
  -        dispatchHTMLEvent(EventImpl::UNLOAD_EVENT,false,false);
  -
  -    HTMLElementImpl::detach();
  -}
  -
   void HTMLFrameSetElementImpl::recalcStyle( StyleChange ch )
   {
       if (changed() && m_render) {
  
  
  
  1.25.10.1 +2 -1      WebCore/khtml/html/html_baseimpl.h
  
  Index: html_baseimpl.h
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/html/html_baseimpl.h,v
  retrieving revision 1.25
  retrieving revision 1.25.10.1
  diff -u -r1.25 -r1.25.10.1
  --- html_baseimpl.h	19 Nov 2004 00:12:21 -0000	1.25
  +++ html_baseimpl.h	12 Nov 2005 01:24:32 -0000	1.25.10.1
  @@ -86,6 +86,8 @@
   
       virtual void parseHTMLAttribute(HTMLAttributeImpl *);
       virtual void attach();
  +    void close();
  +    virtual void willRemove();
       virtual void detach();
       virtual bool rendererIsNeeded(khtml::RenderStyle *);
       virtual khtml::RenderObject *createRenderer(RenderArena *, khtml::RenderStyle *);
  @@ -151,7 +153,6 @@
       int totalRows() const { return m_totalRows; }
       int totalCols() const { return m_totalCols; }
       int border() const { return m_border; }
  -    virtual void detach();
   
       virtual void recalcStyle( StyleChange ch );
       
  
  
  
  1.60.8.5  +0 -5      WebCore/khtml/html/html_objectimpl.cpp
  
  Index: html_objectimpl.cpp
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/html/html_objectimpl.cpp,v
  retrieving revision 1.60.8.4
  retrieving revision 1.60.8.5
  diff -u -r1.60.8.4 -r1.60.8.5
  --- html_objectimpl.cpp	10 Nov 2005 23:40:52 -0000	1.60.8.4
  +++ html_objectimpl.cpp	12 Nov 2005 01:24:32 -0000	1.60.8.5
  @@ -558,7 +558,6 @@
                   // this method or recalcStyle (which also calls updateWidget) to be called.
                   needWidgetUpdate = false;
                   static_cast<RenderPartObject*>(m_render)->updateWidget();
  -                dispatchHTMLEvent(EventImpl::LOAD_EVENT,false,false);
               } else {
                   needWidgetUpdate = true;
                   setChanged();
  @@ -588,11 +587,7 @@
   
   void HTMLObjectElementImpl::detach()
   {
  -    // Only bother with an unload event if we had a render object.  - dwh
       if (attached() && m_render && !m_useFallbackContent) {
  -        // ### do this when we are actualy removed from document instead
  -        dispatchHTMLEvent(EventImpl::UNLOAD_EVENT,false,false);
  -        
           // Update the widget the next time we attach (detaching destroys the plugin).
           needWidgetUpdate = true;
       }
  
  
  
  No                   revision
  
  
  No                   revision
  
  
  1.9.12.1  +12 -12    WebCore/khtml/xml/dom2_traversalimpl.cpp
  
  Index: dom2_traversalimpl.cpp
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/xml/dom2_traversalimpl.cpp,v
  retrieving revision 1.9
  retrieving revision 1.9.12.1
  diff -u -r1.9 -r1.9.12.1
  --- dom2_traversalimpl.cpp	28 Jul 2004 16:36:14 -0000	1.9
  +++ dom2_traversalimpl.cpp	12 Nov 2005 01:24:34 -0000	1.9.12.1
  @@ -187,36 +187,36 @@
           old->deref();
   }
   
  -void NodeIteratorImpl::notifyBeforeNodeRemoval(NodeImpl *willRemove)
  +void NodeIteratorImpl::notifyBeforeNodeRemoval(NodeImpl *removedNode)
   {
       // Iterator is not affected if the removed node is the reference node and is the root.
       // or if removed node is not the reference node, or the ancestor of the reference node.
  -    if (!willRemove || willRemove == root())
  +    if (!removedNode || removedNode == root())
           return;
  -    bool willRemoveReferenceNode = willRemove == referenceNode();
  -    bool willRemoveReferenceNodeAncestor = referenceNode() && referenceNode()->isAncestor(willRemove);
  +    bool willRemoveReferenceNode = removedNode == referenceNode();
  +    bool willRemoveReferenceNodeAncestor = referenceNode() && referenceNode()->isAncestor(removedNode);
       if (!willRemoveReferenceNode && !willRemoveReferenceNodeAncestor)
           return;
   
       if (pointerBeforeReferenceNode()) {
  -        NodeImpl *node = findNextNode(willRemove);
  +        NodeImpl *node = findNextNode(removedNode);
           if (node) {
               // Move out from under the node being removed if the reference node is
               // a descendant of the node being removed.
               if (willRemoveReferenceNodeAncestor) {
  -                while (node && node->isAncestor(willRemove))
  +                while (node && node->isAncestor(removedNode))
                       node = findNextNode(node);
               }
               if (node)
                   setReferenceNode(node);
           }
           else {
  -            node = findPreviousNode(willRemove);
  +            node = findPreviousNode(removedNode);
               if (node) {
                   // Move out from under the node being removed if the reference node is
                   // a descendant of the node being removed.
                   if (willRemoveReferenceNodeAncestor) {
  -                    while (node && node->isAncestor(willRemove))
  +                    while (node && node->isAncestor(removedNode))
                           node = findPreviousNode(node);
                   }
                   if (node) {
  @@ -230,23 +230,23 @@
           }
       }
       else {
  -        NodeImpl *node = findPreviousNode(willRemove);
  +        NodeImpl *node = findPreviousNode(removedNode);
           if (node) {
               // Move out from under the node being removed if the reference node is
               // a descendant of the node being removed.
               if (willRemoveReferenceNodeAncestor) {
  -                while (node && node->isAncestor(willRemove))
  +                while (node && node->isAncestor(removedNode))
                       node = findPreviousNode(node);
               }
               if (node)
                   setReferenceNode(node);
           }
           else {
  -            node = findNextNode(willRemove);
  +            node = findNextNode(removedNode);
                   // Move out from under the node being removed if the reference node is
                   // a descendant of the node being removed.
                   if (willRemoveReferenceNodeAncestor) {
  -                    while (node && node->isAncestor(willRemove))
  +                    while (node && node->isAncestor(removedNode))
                           node = findPreviousNode(node);
                   }
                   if (node)
  
  
  
  1.211.6.10 +21 -0     WebCore/khtml/xml/dom_docimpl.cpp
  
  Index: dom_docimpl.cpp
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/xml/dom_docimpl.cpp,v
  retrieving revision 1.211.6.9
  retrieving revision 1.211.6.10
  diff -u -r1.211.6.9 -r1.211.6.10
  --- dom_docimpl.cpp	10 Nov 2005 23:40:54 -0000	1.211.6.9
  +++ dom_docimpl.cpp	12 Nov 2005 01:24:34 -0000	1.211.6.10
  @@ -361,6 +361,7 @@
       resetVisitedLinkColor();
       resetActiveLinkColor();
   
  +    m_eventDispatchForbidden = 0;
       m_processingLoadEvent = false;
       m_startTime.restart();
       m_overMinimumLayoutThreshold = false;
  @@ -2690,8 +2691,28 @@
       return m_defaultView;
   }
   
  +void DocumentImpl::forbidEventDispatch()
  +{
  +    m_eventDispatchForbidden += 1;
  +}
  +
  +void DocumentImpl::allowEventDispatch()
  +{
  +    ASSERT(m_eventDispatchForbidden > 0);
  +    m_eventDispatchForbidden -= 1;
  +}
  +
  +bool DocumentImpl::eventDispatchForbidden()
  +{
  +    return m_eventDispatchForbidden > 0;
  +}
  +
   EventImpl *DocumentImpl::createEvent(const DOMString &eventType, int &exceptioncode)
   {
  +    // createEvent ought to be at a time completely separate from DOM modifications that forbidEventDispatch
  +    // (of course, the event _could_ be sent later, but this seems like a good bottleneck)
  +    ASSERT(!eventDispatchForbidden());
  +    
       if (eventType == "UIEvents")
           return new UIEventImpl();
       else if (eventType == "MouseEvents")
  
  
  
  1.104.6.6 +5 -1      WebCore/khtml/xml/dom_docimpl.h
  
  Index: dom_docimpl.h
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/xml/dom_docimpl.h,v
  retrieving revision 1.104.6.5
  retrieving revision 1.104.6.6
  diff -u -r1.104.6.5 -r1.104.6.6
  --- dom_docimpl.h	22 Jul 2005 03:09:51 -0000	1.104.6.5
  +++ dom_docimpl.h	12 Nov 2005 01:24:35 -0000	1.104.6.6
  @@ -437,6 +437,9 @@
       void detachNodeIterator(NodeIteratorImpl *ni);
       void notifyBeforeNodeRemoval(NodeImpl *n);
       AbstractViewImpl *defaultView() const;
  +    void forbidEventDispatch();
  +    void allowEventDispatch();
  +    bool eventDispatchForbidden();
       EventImpl *createEvent(const DOMString &eventType, int &exceptioncode);
   
       // keep track of what types of event listeners are registered, so we don't
  @@ -676,7 +679,7 @@
       bool m_closeAfterStyleRecalc;
       bool m_usesDescendantRules;
       bool m_usesSiblingRules;
  -
  +    
       DOMString m_title;
       bool m_titleSetExplicitly;
       NodeImpl *m_titleElement;
  @@ -689,6 +692,7 @@
       KWQAccObjectCache* m_accCache;
   #endif
       
  +    int m_eventDispatchForbidden;
       QPtrList<HTMLImageLoader> m_imageLoadEventDispatchSoonList;
       QPtrList<HTMLImageLoader> m_imageLoadEventDispatchingList;
       int m_imageLoadEventTimer;
  
  
  
  1.140.8.11 +81 -11    WebCore/khtml/xml/dom_nodeimpl.cpp
  
  Index: dom_nodeimpl.cpp
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/xml/dom_nodeimpl.cpp,v
  retrieving revision 1.140.8.10
  retrieving revision 1.140.8.11
  diff -u -r1.140.8.10 -r1.140.8.11
  --- dom_nodeimpl.cpp	28 Sep 2005 18:24:48 -0000	1.140.8.10
  +++ dom_nodeimpl.cpp	12 Nov 2005 01:24:35 -0000	1.140.8.11
  @@ -466,6 +466,7 @@
   
   bool NodeImpl::dispatchEvent(EventImpl *evt, int &exceptioncode, bool tempEvent)
   {
  +    assert(!getDocument()->eventDispatchForbidden());
       evt->ref();
   
       evt->setTarget(this);
  @@ -504,6 +505,7 @@
   
   bool NodeImpl::dispatchGenericEvent( EventImpl *evt, int &/*exceptioncode */)
   {
  +    assert(!getDocument()->eventDispatchForbidden());
       evt->ref();
   
       // ### check that type specified
  @@ -588,6 +590,7 @@
   
   bool NodeImpl::dispatchHTMLEvent(int _id, bool canBubbleArg, bool cancelableArg)
   {
  +    assert(!getDocument()->eventDispatchForbidden());
       int exceptioncode = 0;
       EventImpl *evt = new EventImpl(static_cast<EventImpl::EventId>(_id),canBubbleArg,cancelableArg);
       return dispatchEvent(evt,exceptioncode,true);
  @@ -595,6 +598,7 @@
   
   bool NodeImpl::dispatchWindowEvent(int _id, bool canBubbleArg, bool cancelableArg)
   {
  +    assert(!getDocument()->eventDispatchForbidden());
       int exceptioncode = 0;
       EventImpl *evt = new EventImpl(static_cast<EventImpl::EventId>(_id),canBubbleArg,cancelableArg);
       evt->setTarget( 0 );
  @@ -635,6 +639,7 @@
   
   bool NodeImpl::dispatchMouseEvent(QMouseEvent *_mouse, int overrideId, int overrideDetail)
   {
  +    assert(!getDocument()->eventDispatchForbidden());
       bool cancelable = true;
       int detail = overrideDetail; // defaults to 0
       EventImpl::EventId evtId = EventImpl::UNKNOWN_EVENT;
  @@ -786,6 +791,7 @@
   
   bool NodeImpl::dispatchUIEvent(int _id, int detail)
   {
  +    assert(!getDocument()->eventDispatchForbidden());
       assert (!( (_id != EventImpl::DOMFOCUSIN_EVENT &&
           _id != EventImpl::DOMFOCUSOUT_EVENT &&
                   _id != EventImpl::DOMACTIVATE_EVENT)));
  @@ -842,6 +848,10 @@
   
   bool NodeImpl::dispatchSubtreeModifiedEvent(bool sendChildrenChanged)
   {
  +    // forbidder will send this event later
  +    if (getDocument()->eventDispatchForbidden())
  +        return true;
  +
       notifyNodeListsSubtreeModified();
       if (sendChildrenChanged)
           childrenChanged();
  @@ -854,6 +864,7 @@
   
   bool NodeImpl::dispatchKeyEvent(QKeyEvent *key)
   {
  +    assert(!getDocument()->eventDispatchForbidden());
       int exceptioncode = 0;
       //kdDebug(6010) << "DOM::NodeImpl: dispatching keyboard event" << endl;
       KeyboardEventImpl *keyboardEventImpl = new KeyboardEventImpl(key, getDocument()->defaultView());
  @@ -874,10 +885,12 @@
   
       keyboardEventImpl->deref();
       return r;
  +
   }
   
   void NodeImpl::dispatchWheelEvent(QWheelEvent *e)
   {
  +    assert(!getDocument()->eventDispatchForbidden());
       if (e->delta() == 0)
           return;
   
  @@ -1170,6 +1183,10 @@
       m_attached = true;
   }
   
  +void NodeImpl::willRemove()
  +{
  +}
  +
   void NodeImpl::detach()
   {
   //    assert(m_attached);
  @@ -1705,6 +1722,7 @@
               return 0;
   
           // Add child in the correct position
  +        getDocument()->forbidEventDispatch();
           if (prev)
               prev->setNextSibling(child);
           else
  @@ -1718,7 +1736,8 @@
           // ### should we detach() it first if it's already attached?
           if (attached() && !child->attached())
               child->attach();
  -
  +        getDocument()->allowEventDispatch();
  +        
           // Dispatch the mutation events
           dispatchChildInsertedEvents(child,exceptioncode);
   
  @@ -1765,6 +1784,7 @@
   
       // Add the new child(ren)
       while (child) {
  +        getDocument()->forbidEventDispatch();
           nextChild = isFragment ? child->nextSibling() : 0;
   
           // If child is already present in the tree, first remove it
  @@ -1787,6 +1807,7 @@
           // ### should we detach() it first if it's already attached?
           if (attached() && !child->attached())
               child->attach();
  +        getDocument()->allowEventDispatch();
   
           // Dispatch the mutation events
           dispatchChildInsertedEvents(child,exceptioncode);
  @@ -1801,6 +1822,28 @@
       return oldChild;
   }
   
  +void NodeBaseImpl::willRemove()
  +{
  +    for (NodeImpl *n = _first; n != 0; n = n->nextSibling()) {
  +        n->willRemove();
  +    }
  +}
  +
  +int NodeBaseImpl::willRemoveChild(NodeImpl *child)
  +{
  +    int exceptionCode = 0;
  +
  +    // fire removed from document mutation events.
  +    dispatchChildRemovalEvents(child, exceptionCode);
  +    if (exceptionCode)
  +        return exceptionCode;
  +
  +    if (child->attached())
  +        child->willRemove();
  +    
  +    return 0;
  +}
  +
   NodeImpl *NodeBaseImpl::removeChild ( NodeImpl *oldChild, int &exceptioncode )
   {
       exceptioncode = 0;
  @@ -1816,9 +1859,12 @@
           exceptioncode = DOMException::NOT_FOUND_ERR;
           return 0;
       }
  +    
  +    // update auxiliary doc info (e.g. iterators) to note that node is being removed
  +    // FIX: This looks redundant with same call from dispatchChildRemovalEvents in willRemoveChild
  +//  getDocument()->notifyBeforeNodeRemoval(oldChild); // ### use events instead
   
  -    // Dispatch pre-removal mutation events
  -    getDocument()->notifyBeforeNodeRemoval(oldChild); // ### use events instead
  +    // dispatch pre-removal mutation events
       if (getDocument()->hasListenerType(DocumentImpl::DOMNODEREMOVED_LISTENER)) {
   	oldChild->dispatchEvent(new MutationEventImpl(EventImpl::DOMNODEREMOVED_EVENT,
   			     true,false,this,DOMString(),DOMString(),DOMString(),0),exceptioncode,true);
  @@ -1826,10 +1872,12 @@
   	    return 0;
       }
   
  -    dispatchChildRemovalEvents(oldChild,exceptioncode);
  +    exceptioncode = willRemoveChild(oldChild);
       if (exceptioncode)
           return 0;
   
  +    getDocument()->forbidEventDispatch();
  +
       // Remove from rendering tree
       if (oldChild->attached())
           oldChild->detach();
  @@ -1850,6 +1898,8 @@
   
       getDocument()->setDocumentChanged(true);
   
  +    getDocument()->allowEventDispatch();
  +
       // Dispatch post-removal mutation events
       dispatchSubtreeModifiedEvent();
   
  @@ -1859,17 +1909,26 @@
       return oldChild;
   }
   
  +// this differs from other remove functions because it forcibly removes all the children,
  +// regardless of read-only status or event exceptions, e.g.
   void NodeBaseImpl::removeChildren()
   {
  -    int exceptionCode;
  -    while (NodeImpl *n = _first) {
  +    NodeImpl *n;
  +    
  +    if (!_first)
  +        return;
  +
  +    // do any prep work needed before actually starting to detach
  +    // and remove... e.g. stop loading frames, fire unload events
  +    for (n = _first; n != 0; n = n->nextSibling())
  +        willRemoveChild(n);
  +    
  +    getDocument()->forbidEventDispatch();
  +    while ((n = _first) != 0) {
           NodeImpl *next = n->nextSibling();
           
           n->ref();
   
  -        // Fire removed from document mutation events.
  -        dispatchChildRemovalEvents(n, exceptionCode);
  -
           if (n->attached())
   	    n->detach();
           n->setPreviousSibling(0);
  @@ -1884,6 +1943,7 @@
           _first = next;
       }
       _last = 0;
  +    getDocument()->allowEventDispatch();
       
       // Dispatch a single post-removal mutation event denoting a modified subtree.
       dispatchSubtreeModifiedEvent();
  @@ -1916,6 +1976,7 @@
       NodeImpl *child = isFragment ? newChild->firstChild() : newChild;
   
       while (child) {
  +        getDocument()->forbidEventDispatch();
           nextChild = isFragment ? child->nextSibling() : 0;
   
           // If child is already present in the tree, first remove it
  @@ -1944,7 +2005,9 @@
           // ### should we detach() it first if it's already attached?
           if (attached() && !child->attached())
               child->attach();
  -          
  +        
  +        getDocument()->allowEventDispatch();
  +        
           // Dispatch the mutation events
           dispatchChildInsertedEvents(child,exceptioncode);
   
  @@ -2025,6 +2088,8 @@
           return 0;
       }
   
  +    getDocument()->forbidEventDispatch();
  +
       // just add it...
       newChild->setParent(this);
   
  @@ -2043,6 +2108,8 @@
           newChild->insertedIntoDocument();
       childrenChanged();
   
  +    getDocument()->allowEventDispatch();
  +    
       if(newChild->nodeType() == Node::ELEMENT_NODE)
           return newChild;
       return this;
  @@ -2279,6 +2346,7 @@
   
   void NodeBaseImpl::dispatchChildInsertedEvents( NodeImpl *child, int &exceptioncode )
   {
  +    assert(!getDocument()->eventDispatchForbidden());
       NodeImpl *p = this;
       while (p->parentNode())
           p = p->parentNode();
  @@ -2311,8 +2379,10 @@
   
   void NodeBaseImpl::dispatchChildRemovalEvents( NodeImpl *child, int &exceptioncode )
   {
  -    // Dispatch pre-removal mutation events
  +    // update auxiliary doc info (e.g. iterators) to note that node is being removed
       getDocument()->notifyBeforeNodeRemoval(child); // ### use events instead
  +
  +    // dispatch pre-removal mutation events
       if (getDocument()->hasListenerType(DocumentImpl::DOMNODEREMOVED_LISTENER)) {
   	child->dispatchEvent(new MutationEventImpl(EventImpl::DOMNODEREMOVED_EVENT,
   			     true,false,this,DOMString(),DOMString(),DOMString(),0),exceptioncode,true);
  
  
  
  1.75.8.6  +3 -0      WebCore/khtml/xml/dom_nodeimpl.h
  
  Index: dom_nodeimpl.h
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/xml/dom_nodeimpl.h,v
  retrieving revision 1.75.8.5
  retrieving revision 1.75.8.6
  diff -u -r1.75.8.5 -r1.75.8.6
  --- dom_nodeimpl.h	26 Jul 2005 22:45:33 -0000	1.75.8.5
  +++ dom_nodeimpl.h	12 Nov 2005 01:24:36 -0000	1.75.8.6
  @@ -392,6 +392,7 @@
        */
       virtual void detach();
   
  +    virtual void willRemove();
       void createRendererIfNeeded();
       virtual khtml::RenderStyle *styleForRenderer(khtml::RenderObject *parent);
       virtual bool rendererIsNeeded(khtml::RenderStyle *);
  @@ -515,6 +516,8 @@
       virtual bool hasChildNodes (  ) const;
   
       // Other methods (not part of DOM)
  +    void willRemove();
  +    int willRemoveChild(NodeImpl *child);
       void removeChildren();
       void cloneChildNodes(NodeImpl *clone);
   
  
  
  



More information about the webkit-changes mailing list