Fix for bug 357453 (ASSERTION: Already have a document. Unbind first!: "!GetCurrentDoc() && !IsInDoc()", file m:/trunk/mozilla/content/base/src/nsGenericDOMDataNode.cpp, line 588). r/sr=bz.

This commit is contained in:
peterv%propagandism.org 2006-10-31 13:25:40 +00:00
parent 621d5e29e4
commit bd97030a46
4 changed files with 25 additions and 21 deletions

View File

@ -73,6 +73,8 @@ REQUIRES = xpcom \
prefetch \
xuldoc \
uriloader \
rdf \
xultmpl \
$(NULL)
EXPORTS = \

View File

@ -50,6 +50,7 @@
#include "pldhash.h"
#include "nsIDOMAttr.h"
#include "nsCOMArray.h"
#include "nsXULElement.h"
#define IMPL_MUTATION_NOTIFICATION(func_, content_, params_) \
PR_BEGIN_MACRO \
@ -466,6 +467,24 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNode, PRBool aClone, PRBool aDeep,
}
}
// XXX setting document on some nodes not in a document so XBL will bind
// and chrome won't break. Make XBL bind to document-less nodes!
// XXXbz Once this is fixed, fix up the asserts in all implementations of
// BindToTree to assert what they would like to assert, and fix the
// ChangeDocumentFor() call in nsXULElement::BindToTree as well. Also,
// remove the UnbindFromTree call in ~nsXULElement, and add back in the
// precondition in nsXULElement::UnbindFromTree and remove the line in
// nsXULElement.h that makes nsNodeUtils a friend of nsXULElement.
// Note: Make sure to do this witchery _after_ we've done any deep
// cloning, so kids of the new node aren't confused about whether they're
// in a document.
if (aClone && !aParent && aNode->IsNodeOfType(nsINode::eXUL)) {
nsXULElement *xulElem = NS_STATIC_CAST(nsXULElement*, elem);
if (!xulElem->mPrototype || xulElem->IsInDoc()) {
clone->mParentPtrBits |= nsINode::PARENT_BIT_INDOCUMENT;
}
}
if (aNode->HasProperties()) {
PRBool ok = aNodesWithProperties.AppendObject(aNode);
if (aClone) {

View File

@ -465,27 +465,12 @@ nsXULElement::Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const
{
*aResult = nsnull;
// XXX setting document on some nodes not in a document so XBL will bind
// and chrome won't break. Make XBL bind to document-less nodes!
// XXXbz Once this is fixed, fix up the asserts in all implementations of
// BindToTree to assert what they would like to assert, and fix the
// ChangeDocumentFor() call in nsXULElement::BindToTree as well. Also,
// remove the UnbindFromTree call in ~nsXULElement, and add back in the
// precondition in nsXULElement::UnbindFromTree.
// Note: Make sure to do this witchery _after_ we've done any deep
// cloning, so kids of the new node aren't confused about whether they're
// in a document.
PRBool fakeBeingInDocument = PR_TRUE;
// If we have a prototype, so will our clone.
nsRefPtr<nsXULElement> element;
if (mPrototype) {
element = nsXULElement::Create(mPrototype, aNodeInfo, PR_TRUE);
NS_ASSERTION(GetScriptTypeID() == mPrototype->mScriptTypeID,
"Didn't get the default language from proto?");
fakeBeingInDocument = IsInDoc();
}
else {
element = new nsXULElement(aNodeInfo);
@ -512,12 +497,6 @@ nsXULElement::Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const
NS_ADDREF(*aResult = element);
}
if (fakeBeingInDocument) {
// Don't use BindToTree here so we don't confuse the descendant
// non-XUL nodes.
element->mParentPtrBits |= PARENT_BIT_INDOCUMENT;
}
return rv;
}

View File

@ -576,6 +576,10 @@ public:
virtual void RecompileScriptEventListeners();
protected:
// XXX This can be removed when nsNodeUtils::CloneAndAdopt doesn't need
// access to mPrototype anymore.
friend class nsNodeUtils;
nsXULElement(nsINodeInfo* aNodeInfo);
virtual ~nsXULElement(void);