[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