[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:31:05 PST 2005
thatcher 05/11/11 17:31:05
Modified: . Tag: Safari-1-3-branch ChangeLog
khtml/html Tag: Safari-1-3-branch html_baseimpl.cpp
html_baseimpl.h html_objectimpl.cpp
khtml/xml Tag: Safari-1-3-branch dom2_traversalimpl.cpp
dom_docimpl.cpp dom_docimpl.h dom_nodeimpl.cpp
dom_nodeimpl.h
Log:
Merged fix from TOT to Safari-1-3-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.335.2.15 +73 -0 WebCore/ChangeLog
Index: ChangeLog
===================================================================
RCS file: /cvs/root/WebCore/ChangeLog,v
retrieving revision 1.335.2.14
retrieving revision 1.335.2.15
diff -u -r1.335.2.14 -r1.335.2.15
--- ChangeLog 11 Nov 2005 19:40:21 -0000 1.335.2.14
+++ ChangeLog 12 Nov 2005 01:30:50 -0000 1.335.2.15
@@ -1,5 +1,78 @@
2005-11-11 Timothy Hatcher <timothy at apple.com>
+ Merged fix from TOT to Safari-1-3-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.6.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.6.2
retrieving revision 1.68.6.3
diff -u -r1.68.6.2 -r1.68.6.3
--- html_baseimpl.cpp 12 Jul 2005 20:58:48 -0000 1.68.6.2
+++ html_baseimpl.cpp 12 Nov 2005 01:30:56 -0000 1.68.6.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.8.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.8.1
diff -u -r1.25 -r1.25.8.1
--- html_baseimpl.h 19 Nov 2004 00:12:21 -0000 1.25
+++ html_baseimpl.h 12 Nov 2005 01:30:57 -0000 1.25.8.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.6.2 +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.6.1
retrieving revision 1.60.6.2
diff -u -r1.60.6.1 -r1.60.6.2
--- html_objectimpl.cpp 9 Nov 2005 22:51:32 -0000 1.60.6.1
+++ html_objectimpl.cpp 12 Nov 2005 01:30:57 -0000 1.60.6.2
@@ -553,7 +553,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();
@@ -564,11 +563,7 @@
void HTMLObjectElementImpl::detach()
{
- // Only bother with an unload event if we had a render object. - dwh
if (attached() && m_render) {
- // ### 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.10.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.10.1
diff -u -r1.9 -r1.9.10.1
--- dom2_traversalimpl.cpp 28 Jul 2004 16:36:14 -0000 1.9
+++ dom2_traversalimpl.cpp 12 Nov 2005 01:30:58 -0000 1.9.10.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.4.8 +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.4.7
retrieving revision 1.211.4.8
diff -u -r1.211.4.7 -r1.211.4.8
--- dom_docimpl.cpp 13 Jul 2005 04:52:02 -0000 1.211.4.7
+++ dom_docimpl.cpp 12 Nov 2005 01:30:59 -0000 1.211.4.8
@@ -361,6 +361,7 @@
resetVisitedLinkColor();
resetActiveLinkColor();
+ m_eventDispatchForbidden = 0;
m_processingLoadEvent = false;
m_startTime.restart();
m_overMinimumLayoutThreshold = false;
@@ -2686,8 +2687,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.4.5 +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.4.4
retrieving revision 1.104.4.5
diff -u -r1.104.4.4 -r1.104.4.5
--- dom_docimpl.h 13 Jul 2005 04:52:03 -0000 1.104.4.4
+++ dom_docimpl.h 12 Nov 2005 01:31:00 -0000 1.104.4.5
@@ -435,6 +435,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
@@ -674,7 +677,7 @@
bool m_closeAfterStyleRecalc;
bool m_usesDescendantRules;
bool m_usesSiblingRules;
-
+
DOMString m_title;
bool m_titleSetExplicitly;
NodeImpl *m_titleElement;
@@ -687,6 +690,7 @@
KWQAccObjectCache* m_accCache;
#endif
+ int m_eventDispatchForbidden;
QPtrList<HTMLImageLoader> m_imageLoadEventDispatchSoonList;
QPtrList<HTMLImageLoader> m_imageLoadEventDispatchingList;
int m_imageLoadEventTimer;
1.140.6.2 +80 -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.6.1
retrieving revision 1.140.6.2
diff -u -r1.140.6.1 -r1.140.6.2
--- dom_nodeimpl.cpp 12 Jul 2005 21:18:10 -0000 1.140.6.1
+++ dom_nodeimpl.cpp 12 Nov 2005 01:31:01 -0000 1.140.6.2
@@ -467,6 +467,7 @@
bool NodeImpl::dispatchEvent(EventImpl *evt, int &exceptioncode, bool tempEvent)
{
+ assert(!getDocument()->eventDispatchForbidden());
evt->ref();
evt->setTarget(this);
@@ -505,6 +506,7 @@
bool NodeImpl::dispatchGenericEvent( EventImpl *evt, int &/*exceptioncode */)
{
+ assert(!getDocument()->eventDispatchForbidden());
evt->ref();
// ### check that type specified
@@ -589,6 +591,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);
@@ -596,6 +599,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 );
@@ -636,6 +640,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;
@@ -787,6 +792,7 @@
bool NodeImpl::dispatchUIEvent(int _id, int detail)
{
+ assert(!getDocument()->eventDispatchForbidden());
assert (!( (_id != EventImpl::DOMFOCUSIN_EVENT &&
_id != EventImpl::DOMFOCUSOUT_EVENT &&
_id != EventImpl::DOMACTIVATE_EVENT)));
@@ -843,6 +849,10 @@
bool NodeImpl::dispatchSubtreeModifiedEvent(bool sendChildrenChanged)
{
+ // forbidder will send this event later
+ if (getDocument()->eventDispatchForbidden())
+ return true;
+
notifyNodeListsSubtreeModified();
if (sendChildrenChanged)
childrenChanged();
@@ -855,6 +865,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());
@@ -875,6 +886,7 @@
keyboardEventImpl->deref();
return r;
+
}
void NodeImpl::handleLocalEvents(EventImpl *evt, bool useCapture)
@@ -1143,6 +1155,10 @@
m_attached = true;
}
+void NodeImpl::willRemove()
+{
+}
+
void NodeImpl::detach()
{
// assert(m_attached);
@@ -1666,6 +1682,7 @@
return 0;
// Add child in the correct position
+ getDocument()->forbidEventDispatch();
if (prev)
prev->setNextSibling(child);
else
@@ -1679,7 +1696,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);
@@ -1726,6 +1744,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
@@ -1748,6 +1767,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);
@@ -1762,6 +1782,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;
@@ -1777,9 +1819,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);
@@ -1787,10 +1832,12 @@
return 0;
}
- dispatchChildRemovalEvents(oldChild,exceptioncode);
+ exceptioncode = willRemoveChild(oldChild);
if (exceptioncode)
return 0;
+ getDocument()->forbidEventDispatch();
+
// Remove from rendering tree
if (oldChild->attached())
oldChild->detach();
@@ -1811,6 +1858,8 @@
getDocument()->setDocumentChanged(true);
+ getDocument()->allowEventDispatch();
+
// Dispatch post-removal mutation events
dispatchSubtreeModifiedEvent();
@@ -1820,17 +1869,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);
@@ -1845,6 +1903,7 @@
_first = next;
}
_last = 0;
+ getDocument()->allowEventDispatch();
// Dispatch a single post-removal mutation event denoting a modified subtree.
dispatchSubtreeModifiedEvent();
@@ -1877,6 +1936,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
@@ -1905,7 +1965,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);
@@ -1985,6 +2047,8 @@
return 0;
}
+ getDocument()->forbidEventDispatch();
+
// just add it...
newChild->setParent(this);
@@ -2003,6 +2067,8 @@
newChild->insertedIntoDocument();
childrenChanged();
+ getDocument()->allowEventDispatch();
+
if(newChild->nodeType() == Node::ELEMENT_NODE)
return newChild;
return this;
@@ -2234,6 +2300,7 @@
void NodeBaseImpl::dispatchChildInsertedEvents( NodeImpl *child, int &exceptioncode )
{
+ assert(!getDocument()->eventDispatchForbidden());
NodeImpl *p = this;
while (p->parentNode())
p = p->parentNode();
@@ -2266,8 +2333,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.6.3 +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.6.2
retrieving revision 1.75.6.3
diff -u -r1.75.6.2 -r1.75.6.3
--- dom_nodeimpl.h 12 Jul 2005 21:18:10 -0000 1.75.6.2
+++ dom_nodeimpl.h 12 Nov 2005 01:31:01 -0000 1.75.6.3
@@ -386,6 +386,7 @@
*/
virtual void detach();
+ virtual void willRemove();
void createRendererIfNeeded();
virtual khtml::RenderStyle *styleForRenderer(khtml::RenderObject *parent);
virtual bool rendererIsNeeded(khtml::RenderStyle *);
@@ -509,6 +510,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