Bug 37639. Be sure to send notifications about document change down to anonymous content elements. r=hyatt

This commit is contained in:
waterson%netscape.com 2000-05-04 04:25:50 +00:00
Родитель a15ebee0dc
Коммит 6af30c5a92
8 изменённых файлов: 90 добавлений и 72 удалений

Просмотреть файл

@ -35,6 +35,7 @@
#include "nsISupports.h"
class nsIContent;
class nsIDocument;
class nsISupportsArray;
class nsIScriptContext;
@ -67,7 +68,7 @@ public:
// Called when an attribute changes on a binding.
NS_IMETHOD AttributeChanged(nsIAtom* aAttribute, PRInt32 aNameSpaceID, PRBool aRemoveFlag) = 0;
NS_IMETHOD RemoveScriptReferences(nsIScriptContext* aContext) = 0;
NS_IMETHOD ChangeDocument(nsIDocument* aOldDocument, nsIDocument* aNewDocument) = 0;
NS_IMETHOD GetBindingURI(nsString& aResult) = 0;
};

Просмотреть файл

@ -153,7 +153,7 @@ class nsXBLBinding: public nsIXBLBinding, public nsIScriptObjectOwner
NS_IMETHOD AttributeChanged(nsIAtom* aAttribute, PRInt32 aNameSpaceID, PRBool aRemoveFlag);
NS_IMETHOD RemoveScriptReferences(nsIScriptContext* aContext);
NS_IMETHOD ChangeDocument(nsIDocument* aOldDocument, nsIDocument* aNewDocument);
NS_IMETHOD GetBindingURI(nsString& aResult);
@ -354,29 +354,8 @@ nsXBLBinding::nsXBLBinding(void)
}
// Error code that ensures the binding clears
// out its script object, even in cases where it should
// have done so earlier.
static nsresult RemoveRoot(void* aSlot)
{
const char kJSRuntimeServiceProgID[] = "nsJSRuntimeService";
nsresult rv;
NS_WITH_SERVICE(nsIJSRuntimeService, runtimeService, kJSRuntimeServiceProgID, &rv);
if (NS_FAILED(rv)) return rv;
JSRuntime* rt;
rv = runtimeService->GetRuntime(&rt);
if (NS_FAILED(rv)) return rv;
return (JS_RemoveRootRT(rt, aSlot) ? NS_OK : NS_ERROR_FAILURE);
}
nsXBLBinding::~nsXBLBinding(void)
{
NS_ASSERTION(!mScriptObject, "XBL binding hasn't properly cleared its script object out.");
if (mScriptObject) {
RemoveRoot(&mScriptObject);
mScriptObject = nsnull;
}
delete mAttributeTable;
gRefCnt--;
@ -1036,14 +1015,40 @@ nsXBLBinding::AttributeChanged(nsIAtom* aAttribute, PRInt32 aNameSpaceID, PRBool
}
NS_IMETHODIMP
nsXBLBinding::RemoveScriptReferences(nsIScriptContext* aContext)
nsXBLBinding::ChangeDocument(nsIDocument* aOldDocument, nsIDocument* aNewDocument)
{
if (mNextBinding)
mNextBinding->RemoveScriptReferences(aContext);
if (aOldDocument != aNewDocument) {
if (mNextBinding)
mNextBinding->ChangeDocument(aOldDocument, aNewDocument);
if (mScriptObject) {
aContext->RemoveReference((void*) &mScriptObject, mScriptObject);
mScriptObject = nsnull;
if (mScriptObject) {
if (aOldDocument) {
nsCOMPtr<nsIScriptGlobalObject> global;
aOldDocument->GetScriptGlobalObject(getter_AddRefs(global));
if (global) {
nsCOMPtr<nsIScriptContext> context;
global->GetContext(getter_AddRefs(context));
if (context)
context->RemoveReference((void*) &mScriptObject, mScriptObject);
}
}
if (aNewDocument) {
nsCOMPtr<nsIScriptGlobalObject> global;
aNewDocument->GetScriptGlobalObject(getter_AddRefs(global));
if (global) {
nsCOMPtr<nsIScriptContext> context;
global->GetContext(getter_AddRefs(context));
if (context)
context->AddNamedReference((void*) &mScriptObject, mScriptObject, "nsXBLBinding::mScriptObject");
}
}
}
nsCOMPtr<nsIContent> anonymous;
GetAnonymousContent(getter_AddRefs(anonymous));
if (anonymous)
anonymous->SetDocument(aNewDocument, PR_TRUE);
}
return NS_OK;

Просмотреть файл

@ -339,11 +339,7 @@ nsXBLService::FlushBindings(nsIContent* aContent)
// Clear out the script references.
nsCOMPtr<nsIDocument> document;
aContent->GetDocument(*getter_AddRefs(document));
nsCOMPtr<nsIScriptGlobalObject> global;
document->GetScriptGlobalObject(getter_AddRefs(global));
nsCOMPtr<nsIScriptContext> context;
global->GetContext(getter_AddRefs(context));
binding->RemoveScriptReferences(context);
binding->ChangeDocument(document, nsnull);
}
bindable->SetBinding(nsnull); // Flush old bindings

Просмотреть файл

@ -2211,13 +2211,14 @@ nsXULElement::SetDocument(nsIDocument* aDocument, PRBool aDeep)
global->GetContext(getter_AddRefs(context));
if (context) {
context->RemoveReference((void*) &mScriptObject, mScriptObject);
if (Binding())
Binding()->RemoveScriptReferences(context);
}
}
}
}
if (Binding())
Binding()->ChangeDocument(mDocument, aDocument);
mDocument = aDocument; // not refcounted
if (mDocument) {
@ -2234,6 +2235,12 @@ nsXULElement::SetDocument(nsIDocument* aDocument, PRBool aDeep)
}
}
// When we SetDocument(), we're either adding an element
// into the document that wasn't there before, or we're
// moving the element from one document to
// another. Regardless, we need to (re-)initialize several
// attributes that are dependant on the document. Do that
// now.
PRInt32 count;
GetAttributeCount(count);

Просмотреть файл

@ -35,6 +35,7 @@
#include "nsISupports.h"
class nsIContent;
class nsIDocument;
class nsISupportsArray;
class nsIScriptContext;
@ -67,7 +68,7 @@ public:
// Called when an attribute changes on a binding.
NS_IMETHOD AttributeChanged(nsIAtom* aAttribute, PRInt32 aNameSpaceID, PRBool aRemoveFlag) = 0;
NS_IMETHOD RemoveScriptReferences(nsIScriptContext* aContext) = 0;
NS_IMETHOD ChangeDocument(nsIDocument* aOldDocument, nsIDocument* aNewDocument) = 0;
NS_IMETHOD GetBindingURI(nsString& aResult) = 0;
};

Просмотреть файл

@ -153,7 +153,7 @@ class nsXBLBinding: public nsIXBLBinding, public nsIScriptObjectOwner
NS_IMETHOD AttributeChanged(nsIAtom* aAttribute, PRInt32 aNameSpaceID, PRBool aRemoveFlag);
NS_IMETHOD RemoveScriptReferences(nsIScriptContext* aContext);
NS_IMETHOD ChangeDocument(nsIDocument* aOldDocument, nsIDocument* aNewDocument);
NS_IMETHOD GetBindingURI(nsString& aResult);
@ -354,29 +354,8 @@ nsXBLBinding::nsXBLBinding(void)
}
// Error code that ensures the binding clears
// out its script object, even in cases where it should
// have done so earlier.
static nsresult RemoveRoot(void* aSlot)
{
const char kJSRuntimeServiceProgID[] = "nsJSRuntimeService";
nsresult rv;
NS_WITH_SERVICE(nsIJSRuntimeService, runtimeService, kJSRuntimeServiceProgID, &rv);
if (NS_FAILED(rv)) return rv;
JSRuntime* rt;
rv = runtimeService->GetRuntime(&rt);
if (NS_FAILED(rv)) return rv;
return (JS_RemoveRootRT(rt, aSlot) ? NS_OK : NS_ERROR_FAILURE);
}
nsXBLBinding::~nsXBLBinding(void)
{
NS_ASSERTION(!mScriptObject, "XBL binding hasn't properly cleared its script object out.");
if (mScriptObject) {
RemoveRoot(&mScriptObject);
mScriptObject = nsnull;
}
delete mAttributeTable;
gRefCnt--;
@ -1036,14 +1015,40 @@ nsXBLBinding::AttributeChanged(nsIAtom* aAttribute, PRInt32 aNameSpaceID, PRBool
}
NS_IMETHODIMP
nsXBLBinding::RemoveScriptReferences(nsIScriptContext* aContext)
nsXBLBinding::ChangeDocument(nsIDocument* aOldDocument, nsIDocument* aNewDocument)
{
if (mNextBinding)
mNextBinding->RemoveScriptReferences(aContext);
if (aOldDocument != aNewDocument) {
if (mNextBinding)
mNextBinding->ChangeDocument(aOldDocument, aNewDocument);
if (mScriptObject) {
aContext->RemoveReference((void*) &mScriptObject, mScriptObject);
mScriptObject = nsnull;
if (mScriptObject) {
if (aOldDocument) {
nsCOMPtr<nsIScriptGlobalObject> global;
aOldDocument->GetScriptGlobalObject(getter_AddRefs(global));
if (global) {
nsCOMPtr<nsIScriptContext> context;
global->GetContext(getter_AddRefs(context));
if (context)
context->RemoveReference((void*) &mScriptObject, mScriptObject);
}
}
if (aNewDocument) {
nsCOMPtr<nsIScriptGlobalObject> global;
aNewDocument->GetScriptGlobalObject(getter_AddRefs(global));
if (global) {
nsCOMPtr<nsIScriptContext> context;
global->GetContext(getter_AddRefs(context));
if (context)
context->AddNamedReference((void*) &mScriptObject, mScriptObject, "nsXBLBinding::mScriptObject");
}
}
}
nsCOMPtr<nsIContent> anonymous;
GetAnonymousContent(getter_AddRefs(anonymous));
if (anonymous)
anonymous->SetDocument(aNewDocument, PR_TRUE);
}
return NS_OK;

Просмотреть файл

@ -339,11 +339,7 @@ nsXBLService::FlushBindings(nsIContent* aContent)
// Clear out the script references.
nsCOMPtr<nsIDocument> document;
aContent->GetDocument(*getter_AddRefs(document));
nsCOMPtr<nsIScriptGlobalObject> global;
document->GetScriptGlobalObject(getter_AddRefs(global));
nsCOMPtr<nsIScriptContext> context;
global->GetContext(getter_AddRefs(context));
binding->RemoveScriptReferences(context);
binding->ChangeDocument(document, nsnull);
}
bindable->SetBinding(nsnull); // Flush old bindings

Просмотреть файл

@ -2211,13 +2211,14 @@ nsXULElement::SetDocument(nsIDocument* aDocument, PRBool aDeep)
global->GetContext(getter_AddRefs(context));
if (context) {
context->RemoveReference((void*) &mScriptObject, mScriptObject);
if (Binding())
Binding()->RemoveScriptReferences(context);
}
}
}
}
if (Binding())
Binding()->ChangeDocument(mDocument, aDocument);
mDocument = aDocument; // not refcounted
if (mDocument) {
@ -2234,6 +2235,12 @@ nsXULElement::SetDocument(nsIDocument* aDocument, PRBool aDeep)
}
}
// When we SetDocument(), we're either adding an element
// into the document that wasn't there before, or we're
// moving the element from one document to
// another. Regardless, we need to (re-)initialize several
// attributes that are dependant on the document. Do that
// now.
PRInt32 count;
GetAttributeCount(count);