mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 416939 - "Broadcast the destruction of DOM windows". r+sr=jst, a=blocking1.9+.
This commit is contained in:
parent
18f47ac952
commit
566b83da67
@ -70,6 +70,7 @@
|
||||
#include "nsBindingManager.h"
|
||||
#include "nsIDOMNodeList.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsIRDFCompositeDataSource.h"
|
||||
#include "nsIRDFInferDataSource.h"
|
||||
#include "nsIRDFContainerUtils.h"
|
||||
@ -98,6 +99,7 @@
|
||||
#include "pldhash.h"
|
||||
#include "plhash.h"
|
||||
#include "nsIDOMClassInfo.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsXULTemplateBuilder.h"
|
||||
@ -120,6 +122,7 @@ nsIRDFService* nsXULTemplateBuilder::gRDFService;
|
||||
nsIRDFContainerUtils* nsXULTemplateBuilder::gRDFContainerUtils;
|
||||
nsIScriptSecurityManager* nsXULTemplateBuilder::gScriptSecurityManager;
|
||||
nsIPrincipal* nsXULTemplateBuilder::gSystemPrincipal;
|
||||
nsIObserverService* nsXULTemplateBuilder::gObserverService;
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
PRLogModuleInfo* gXULTemplateLog;
|
||||
@ -135,7 +138,8 @@ PRLogModuleInfo* gXULTemplateLog;
|
||||
nsXULTemplateBuilder::nsXULTemplateBuilder(void)
|
||||
: mQueriesCompiled(PR_FALSE),
|
||||
mFlags(0),
|
||||
mTop(nsnull)
|
||||
mTop(nsnull),
|
||||
mObservedDocument(nsnull)
|
||||
{
|
||||
}
|
||||
|
||||
@ -161,6 +165,7 @@ nsXULTemplateBuilder::~nsXULTemplateBuilder(void)
|
||||
NS_IF_RELEASE(gRDFContainerUtils);
|
||||
NS_IF_RELEASE(gSystemPrincipal);
|
||||
NS_IF_RELEASE(gScriptSecurityManager);
|
||||
NS_IF_RELEASE(gObserverService);
|
||||
}
|
||||
|
||||
Uninit(PR_TRUE);
|
||||
@ -191,6 +196,10 @@ nsXULTemplateBuilder::InitGlobals()
|
||||
rv = gScriptSecurityManager->GetSystemPrincipal(&gSystemPrincipal);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
rv = CallGetService(NS_OBSERVERSERVICE_CONTRACTID, &gObserverService);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
}
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
@ -227,6 +236,8 @@ nsXULTemplateBuilder::Uninit(PRBool aIsFinal)
|
||||
mMemberVariable = nsnull;
|
||||
|
||||
mQueriesCompiled = PR_FALSE;
|
||||
|
||||
NS_ASSERTION(!mObservedDocument, "Shouldn't be observing anymore!");
|
||||
}
|
||||
|
||||
static PLDHashOperator
|
||||
@ -286,6 +297,7 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsXULTemplateBuilder)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIXULTemplateBuilder)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDocumentObserver)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIMutationObserver)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIObserver)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXULTemplateBuilder)
|
||||
NS_INTERFACE_MAP_ENTRY_DOM_CLASSINFO(XULTemplateBuilder)
|
||||
NS_INTERFACE_MAP_END
|
||||
@ -409,6 +421,10 @@ nsXULTemplateBuilder::Init(nsIContent* aElement)
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// Add ourselves as a document observer
|
||||
doc->AddObserver(this);
|
||||
|
||||
mObservedDocument = doc;
|
||||
gObserverService->AddObserver(this, DOM_WINDOW_DESTROYED_TOPIC,
|
||||
PR_FALSE);
|
||||
}
|
||||
|
||||
return rv;
|
||||
@ -1029,6 +1045,26 @@ nsXULTemplateBuilder::RemoveListener(nsIXULBuilderListener* aListener)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULTemplateBuilder::Observe(nsISupports* aSubject,
|
||||
const char* aTopic,
|
||||
const PRUnichar* aData)
|
||||
{
|
||||
// Uuuuber hack to clean up circular references that the cycle collector
|
||||
// doesn't know about. See bug 394514.
|
||||
if (!strcmp(aTopic, DOM_WINDOW_DESTROYED_TOPIC)) {
|
||||
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aSubject);
|
||||
if (window) {
|
||||
nsCOMPtr<nsIDocument> doc =
|
||||
do_QueryInterface(window->GetExtantDocument());
|
||||
NS_ASSERTION(doc, "Null document, notification came too late?");
|
||||
|
||||
if (doc == mObservedDocument)
|
||||
NodeWillBeDestroyed(doc);
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
//----------------------------------------------------------------------
|
||||
//
|
||||
// nsIDocumentOberver interface
|
||||
@ -1069,6 +1105,11 @@ nsXULTemplateBuilder::ContentRemoved(nsIDocument* aDocument,
|
||||
if (mRoot && nsContentUtils::ContentIsDescendantOf(mRoot, aChild)) {
|
||||
nsRefPtr<nsXULTemplateBuilder> kungFuDeathGrip(this);
|
||||
|
||||
if (mObservedDocument) {
|
||||
gObserverService->RemoveObserver(this, DOM_WINDOW_DESTROYED_TOPIC);
|
||||
mObservedDocument = nsnull;
|
||||
}
|
||||
|
||||
if (mQueryProcessor)
|
||||
mQueryProcessor->Done();
|
||||
|
||||
@ -1103,6 +1144,11 @@ nsXULTemplateBuilder::NodeWillBeDestroyed(const nsINode* aNode)
|
||||
// |this|, so hold another reference.
|
||||
nsRefPtr<nsXULTemplateBuilder> kungFuDeathGrip(this);
|
||||
|
||||
if (mObservedDocument) {
|
||||
gObserverService->RemoveObserver(this, DOM_WINDOW_DESTROYED_TOPIC);
|
||||
mObservedDocument = nsnull;
|
||||
}
|
||||
|
||||
// Break circular references
|
||||
if (mQueryProcessor)
|
||||
mQueryProcessor->Done();
|
||||
|
@ -46,6 +46,7 @@
|
||||
#include "nsStubDocumentObserver.h"
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "nsIRDFCompositeDataSource.h"
|
||||
#include "nsIRDFContainer.h"
|
||||
#include "nsIRDFContainerUtils.h"
|
||||
@ -71,12 +72,14 @@ extern PRLogModuleInfo* gXULTemplateLog;
|
||||
|
||||
class nsIXULDocument;
|
||||
class nsIRDFCompositeDataSource;
|
||||
class nsIObserverService;
|
||||
|
||||
/**
|
||||
* An object that translates an RDF graph into a presentation using a
|
||||
* set of rules.
|
||||
*/
|
||||
class nsXULTemplateBuilder : public nsIXULTemplateBuilder,
|
||||
public nsIObserver,
|
||||
public nsStubDocumentObserver
|
||||
{
|
||||
public:
|
||||
@ -99,6 +102,9 @@ public:
|
||||
// nsIXULTemplateBuilder interface
|
||||
NS_DECL_NSIXULTEMPLATEBUILDER
|
||||
|
||||
// nsIObserver Interface
|
||||
NS_DECL_NSIOBSERVER
|
||||
|
||||
// nsIMutationObserver
|
||||
NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED
|
||||
NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
|
||||
@ -410,6 +416,7 @@ protected:
|
||||
static nsIRDFContainerUtils* gRDFContainerUtils;
|
||||
static nsIScriptSecurityManager* gScriptSecurityManager;
|
||||
static nsIPrincipal* gSystemPrincipal;
|
||||
static nsIObserverService* gObserverService;
|
||||
|
||||
enum {
|
||||
eDontTestEmpty = (1 << 0),
|
||||
@ -488,6 +495,11 @@ protected:
|
||||
virtual void Traverse(nsCycleCollectionTraversalCallback &cb) const
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Document that we're observing. Weak ref!
|
||||
*/
|
||||
nsIDocument* mObservedDocument;
|
||||
};
|
||||
|
||||
#endif // nsXULTemplateBuilder_h__
|
||||
|
@ -50,6 +50,8 @@
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsEvent.h"
|
||||
|
||||
#define DOM_WINDOW_DESTROYED_TOPIC "dom-window-destroyed"
|
||||
|
||||
class nsIPrincipal;
|
||||
|
||||
// Popup control state enum. The values in this enum must go from most
|
||||
|
@ -209,6 +209,7 @@ nsIFactory *nsGlobalWindow::sComputedDOMStyleFactory = nsnull;
|
||||
|
||||
static nsIEntropyCollector *gEntropyCollector = nsnull;
|
||||
static PRInt32 gRefCnt = 0;
|
||||
static PRUint32 gSerialCounter = 0;
|
||||
static PRInt32 gOpenPopupSpamCount = 0;
|
||||
static PopupControlState gPopupControlState = openAbused;
|
||||
static PRInt32 gRunningTimeoutDepth = 0;
|
||||
@ -654,7 +655,10 @@ nsGlobalWindow::nsGlobalWindow(nsGlobalWindow *aOuterWindow)
|
||||
CallGetService(NS_ENTROPYCOLLECTOR_CONTRACTID, &gEntropyCollector);
|
||||
}
|
||||
#ifdef DEBUG
|
||||
printf("++DOMWINDOW == %d\n", gRefCnt);
|
||||
printf("++DOMWINDOW == %d (%p) [serial = %d] [Outer = %p]\n", gRefCnt,
|
||||
static_cast<nsIScriptGlobalObject*>(this), ++gSerialCounter,
|
||||
aOuterWindow);
|
||||
mSerial = gSerialCounter;
|
||||
#endif
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
@ -673,7 +677,8 @@ nsGlobalWindow::~nsGlobalWindow()
|
||||
NS_IF_RELEASE(gEntropyCollector);
|
||||
}
|
||||
#ifdef DEBUG
|
||||
printf("--DOMWINDOW == %d\n", gRefCnt);
|
||||
printf("--DOMWINDOW == %d (%p) [serial = %d] [Outer = %p]\n", gRefCnt,
|
||||
static_cast<nsIScriptGlobalObject*>(this), mSerial, mOuterWindow);
|
||||
#endif
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
@ -867,6 +872,9 @@ nsGlobalWindow::FreeInnerObjects(PRBool aClearScope)
|
||||
nsCycleCollector_DEBUG_shouldBeFreed(nsCOMPtr<nsISupports>(do_QueryInterface(mDocument)));
|
||||
#endif
|
||||
|
||||
// Make sure that this is called before we null out the document.
|
||||
NotifyDOMWindowDestroyed(this);
|
||||
|
||||
// Remove our reference to the document and the document principal.
|
||||
mDocument = nsnull;
|
||||
mDoc = nsnull;
|
||||
@ -1965,6 +1973,9 @@ nsGlobalWindow::SetDocShell(nsIDocShell* aDocShell)
|
||||
inner->FreeInnerObjects(PR_TRUE);
|
||||
}
|
||||
|
||||
// Make sure that this is called before we null out the document.
|
||||
NotifyDOMWindowDestroyed(this);
|
||||
|
||||
nsGlobalWindow *currentInner = GetCurrentInnerWindowInternal();
|
||||
|
||||
if (currentInner) {
|
||||
@ -5507,6 +5518,18 @@ nsGlobalWindow::IsInModalState()
|
||||
(top.get()))->mModalStateDepth != 0;
|
||||
}
|
||||
|
||||
// static
|
||||
void
|
||||
nsGlobalWindow::NotifyDOMWindowDestroyed(nsGlobalWindow* aWindow) {
|
||||
nsCOMPtr<nsIObserverService> observerService =
|
||||
do_GetService(NS_OBSERVERSERVICE_CONTRACTID);
|
||||
if (observerService) {
|
||||
observerService->
|
||||
NotifyObservers(static_cast<nsIScriptGlobalObject*>(aWindow),
|
||||
DOM_WINDOW_DESTROYED_TOPIC, nsnull);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsGlobalWindow::InitJavaProperties()
|
||||
{
|
||||
|
@ -628,6 +628,8 @@ protected:
|
||||
return aList != &mTimeouts;
|
||||
}
|
||||
|
||||
static void NotifyDOMWindowDestroyed(nsGlobalWindow* aWindow);
|
||||
|
||||
// When adding new member variables, be careful not to create cycles
|
||||
// through JavaScript. If there is any chance that a member variable
|
||||
// could own objects that are implemented in JavaScript, then those
|
||||
@ -728,6 +730,7 @@ protected:
|
||||
|
||||
#ifdef DEBUG
|
||||
PRBool mSetOpenerWindowCalled;
|
||||
PRUint32 mSerial;
|
||||
#endif
|
||||
|
||||
nsCOMPtr<nsIDOMOfflineResourceList> mApplicationCache;
|
||||
|
Loading…
Reference in New Issue
Block a user