Bug 329982: Give nsXULElement::RemoveChildAt some lovin' to make it deal better with mutationevent handlers mutating the DOM
This commit is contained in:
@@ -2371,7 +2371,9 @@ nsGenericElement::AppendChildTo(nsIContent* aKid, PRBool aNotify)
|
||||
nsresult
|
||||
nsGenericElement::RemoveChildAt(PRUint32 aIndex, PRBool aNotify)
|
||||
{
|
||||
nsCOMPtr<nsIContent> oldKid = GetChildAt(aIndex);
|
||||
nsCOMPtr<nsIContent> oldKid = mAttrsAndChildren.GetSafeChildAt(aIndex);
|
||||
NS_ASSERTION(oldKid == GetChildAt(aIndex), "Unexpected child in RemoveChildAt");
|
||||
|
||||
if (oldKid) {
|
||||
return doRemoveChildAt(aIndex, aNotify, oldKid, this, GetCurrentDoc(),
|
||||
mAttrsAndChildren);
|
||||
@@ -2399,38 +2401,41 @@ nsGenericElement::doRemoveChildAt(PRUint32 aIndex, PRBool aNotify,
|
||||
}
|
||||
|
||||
NS_PRECONDITION(aKid && aKid->GetParent() == aParent &&
|
||||
aKid == container->GetChildAt(aIndex), "Bogus aKid");
|
||||
aKid == container->GetChildAt(aIndex) &&
|
||||
container->IndexOf(aKid) == aIndex, "Bogus aKid");
|
||||
|
||||
mozAutoDocUpdate updateBatch(aDocument, UPDATE_CONTENT_MODEL, aNotify);
|
||||
|
||||
PRBool hasListeners =
|
||||
aParent &&
|
||||
nsGenericElement::HasMutationListeners(aParent,
|
||||
NS_EVENT_BITS_MUTATION_NODEREMOVED);
|
||||
nsMutationGuard guard;
|
||||
|
||||
if (hasListeners) {
|
||||
if (aParent && nsGenericElement::HasMutationListeners(aParent,
|
||||
NS_EVENT_BITS_MUTATION_NODEREMOVED)) {
|
||||
nsMutationEvent mutation(PR_TRUE, NS_MUTATION_NODEREMOVED);
|
||||
mutation.mRelatedNode = do_QueryInterface(aParent);
|
||||
nsEventDispatcher::Dispatch(aKid, nsnull, &mutation);
|
||||
}
|
||||
|
||||
// Someone may have removed the kid while that event was processing...
|
||||
if (!hasListeners ||
|
||||
(aKid->GetParent() == aParent &&
|
||||
aKid == container->GetChildAt(aIndex))) {
|
||||
if (aParent) {
|
||||
nsRange::OwnerChildRemoved(aParent, aIndex, aKid);
|
||||
// Someone may have removed the kid or any of its siblings while that event
|
||||
// was processing.
|
||||
if (guard.Mutated(0)) {
|
||||
aIndex = container->IndexOf(aKid);
|
||||
if (aIndex < 0) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
aChildArray.RemoveChildAt(aIndex);
|
||||
|
||||
if (aNotify && aDocument) {
|
||||
aDocument->ContentRemoved(aParent, aKid, aIndex);
|
||||
}
|
||||
|
||||
aKid->UnbindFromTree();
|
||||
}
|
||||
|
||||
if (aParent) {
|
||||
nsRange::OwnerChildRemoved(aParent, aIndex, aKid);
|
||||
}
|
||||
|
||||
aChildArray.RemoveChildAt(aIndex);
|
||||
|
||||
if (aNotify && aDocument) {
|
||||
aDocument->ContentRemoved(aParent, aKid, aIndex);
|
||||
}
|
||||
|
||||
aKid->UnbindFromTree();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user