зеркало из https://github.com/mozilla/pjs.git
Bug 402982, r=jst, sr=sicking
This commit is contained in:
Родитель
17544b3970
Коммит
b8363a260c
|
@ -93,11 +93,12 @@ class nsBindingManager;
|
|||
class nsIDOMNodeList;
|
||||
class mozAutoSubtreeModified;
|
||||
struct JSObject;
|
||||
class nsFrameLoader;
|
||||
|
||||
// IID for the nsIDocument interface
|
||||
#define NS_IDOCUMENT_IID \
|
||||
{ 0x626d86d2, 0x615f, 0x4a12, \
|
||||
{ 0x94, 0xd8, 0xe3, 0xdb, 0x3a, 0x29, 0x83, 0x72 } }
|
||||
{ 0x3c441ae9, 0xaa82, 0x4102, \
|
||||
{ 0xa3, 0x16, 0x3b, 0x97, 0x2b, 0x60, 0x2b, 0x05 } }
|
||||
|
||||
// Flag for AddStyleSheet().
|
||||
#define NS_STYLESHEET_FROM_CATALOG (1 << 0)
|
||||
|
@ -951,6 +952,7 @@ public:
|
|||
// Do nothing.
|
||||
}
|
||||
|
||||
virtual nsresult FinalizeFrameLoader(nsFrameLoader* aLoader) = 0;
|
||||
protected:
|
||||
~nsIDocument()
|
||||
{
|
||||
|
|
|
@ -158,6 +158,8 @@ static NS_DEFINE_CID(kDOMEventGroupCID, NS_DOMEVENTGROUP_CID);
|
|||
#include "nsCCUncollectableMarker.h"
|
||||
#include "nsIContentPolicy.h"
|
||||
|
||||
#include "nsFrameLoader.h"
|
||||
|
||||
#ifdef MOZ_LOGGING
|
||||
// so we can get logging even in release builds
|
||||
#define FORCE_PR_LOG 1
|
||||
|
@ -2719,6 +2721,17 @@ nsDocument::EndUpdate(nsUpdateType aUpdateType)
|
|||
if (mScriptLoader) {
|
||||
mScriptLoader->RemoveExecuteBlocker();
|
||||
}
|
||||
|
||||
if (mUpdateNestLevel == 0) {
|
||||
PRUint32 length = mFinalizableFrameLoaders.Length();
|
||||
if (length > 0) {
|
||||
nsTArray<nsRefPtr<nsFrameLoader> > loaders;
|
||||
mFinalizableFrameLoaders.SwapElements(loaders);
|
||||
for (PRInt32 i = 0; i < length; ++i) {
|
||||
loaders[i]->Finalize();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -3825,6 +3838,21 @@ nsDocument::FlushSkinBindings()
|
|||
mBindingManager->FlushSkinBindings();
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDocument::FinalizeFrameLoader(nsFrameLoader* aLoader)
|
||||
{
|
||||
if (mInDestructor) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
if (mUpdateNestLevel == 0) {
|
||||
nsRefPtr<nsFrameLoader> loader = aLoader;
|
||||
loader->Finalize();
|
||||
} else {
|
||||
mFinalizableFrameLoaders.AppendElement(aLoader);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
struct DirTable {
|
||||
const char* mName;
|
||||
PRUint8 mValue;
|
||||
|
|
|
@ -647,6 +647,8 @@ public:
|
|||
virtual NS_HIDDEN_(nsresult) GetContentListFor(nsIContent* aContent,
|
||||
nsIDOMNodeList** aResult);
|
||||
virtual NS_HIDDEN_(void) FlushSkinBindings();
|
||||
|
||||
virtual NS_HIDDEN_(nsresult) FinalizeFrameLoader(nsFrameLoader* aLoader);
|
||||
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsDocument, nsIDocument)
|
||||
|
||||
|
@ -839,6 +841,8 @@ private:
|
|||
|
||||
// Member to store out last-selected stylesheet set.
|
||||
nsString mLastStyleSheetSet;
|
||||
|
||||
nsTArray<nsRefPtr<nsFrameLoader> > mFinalizableFrameLoaders;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -73,6 +73,26 @@
|
|||
#include "nsGkAtoms.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
class nsAsyncDocShellDestroyer : public nsRunnable
|
||||
{
|
||||
public:
|
||||
nsAsyncDocShellDestroyer(nsIDocShell* aDocShell)
|
||||
: mDocShell(aDocShell)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
nsCOMPtr<nsIBaseWindow> base_win(do_QueryInterface(mDocShell));
|
||||
if (base_win) {
|
||||
base_win->Destroy();
|
||||
}
|
||||
}
|
||||
nsRefPtr<nsIDocShell> mDocShell;
|
||||
};
|
||||
|
||||
// Bug 136580: Limit to the number of nested content frames that can have the
|
||||
// same URL. This is to stop content that is recursively loading
|
||||
// itself. Note that "#foo" on the end of URL doesn't affect
|
||||
|
@ -140,6 +160,7 @@ NS_IMETHODIMP
|
|||
nsFrameLoader::LoadURI(nsIURI* aURI)
|
||||
{
|
||||
NS_PRECONDITION(aURI, "Null URI?");
|
||||
NS_ENSURE_STATE(!mDestroyCalled);
|
||||
if (!aURI)
|
||||
return NS_ERROR_INVALID_POINTER;
|
||||
|
||||
|
@ -227,11 +248,27 @@ nsFrameLoader::GetDocShell(nsIDocShell **aDocShell)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsFrameLoader::Finalize()
|
||||
{
|
||||
nsCOMPtr<nsIBaseWindow> base_win(do_QueryInterface(mDocShell));
|
||||
if (base_win) {
|
||||
base_win->Destroy();
|
||||
}
|
||||
mDocShell = nsnull;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFrameLoader::Destroy()
|
||||
{
|
||||
if (mDestroyCalled) {
|
||||
return NS_OK;
|
||||
}
|
||||
mDestroyCalled = PR_TRUE;
|
||||
|
||||
nsCOMPtr<nsIDocument> doc;
|
||||
if (mOwnerContent) {
|
||||
nsCOMPtr<nsIDocument> doc = mOwnerContent->GetDocument();
|
||||
doc = mOwnerContent->GetOwnerDoc();
|
||||
|
||||
if (doc) {
|
||||
doc->SetSubDocumentFor(mOwnerContent, nsnull);
|
||||
|
@ -258,14 +295,21 @@ nsFrameLoader::Destroy()
|
|||
if (win_private) {
|
||||
win_private->SetFrameElementInternal(nsnull);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIBaseWindow> base_win(do_QueryInterface(mDocShell));
|
||||
|
||||
if (base_win) {
|
||||
base_win->Destroy();
|
||||
if ((mInDestructor || !doc ||
|
||||
NS_FAILED(doc->FinalizeFrameLoader(this))) && mDocShell) {
|
||||
nsCOMPtr<nsIRunnable> event = new nsAsyncDocShellDestroyer(mDocShell);
|
||||
NS_ENSURE_TRUE(event, NS_ERROR_OUT_OF_MEMORY);
|
||||
NS_DispatchToCurrentThread(event);
|
||||
|
||||
// Let go of our docshell now that the async destroyer holds on to
|
||||
// the docshell.
|
||||
|
||||
mDocShell = nsnull;
|
||||
}
|
||||
|
||||
mDocShell = nsnull;
|
||||
// NOTE: 'this' may very well be gone by now.
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -282,6 +326,7 @@ nsFrameLoader::EnsureDocShell()
|
|||
if (mDocShell) {
|
||||
return NS_OK;
|
||||
}
|
||||
NS_ENSURE_STATE(!mDestroyCalled);
|
||||
|
||||
// Get our parent docshell off the document of mOwnerContent
|
||||
// XXXbz this is such a total hack.... We really need to have a
|
||||
|
|
|
@ -57,15 +57,21 @@ public:
|
|||
nsFrameLoader(nsIContent *aOwner) :
|
||||
mOwnerContent(aOwner),
|
||||
mDepthTooGreat(PR_FALSE),
|
||||
mIsTopLevelContent(PR_FALSE)
|
||||
mIsTopLevelContent(PR_FALSE),
|
||||
mDestroyCalled(PR_FALSE),
|
||||
mInDestructor(PR_FALSE)
|
||||
{}
|
||||
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS(nsFrameLoader)
|
||||
NS_DECL_NSIFRAMELOADER
|
||||
NS_HIDDEN_(nsresult) CheckForRecursiveLoad(nsIURI* aURI);
|
||||
void Finalize();
|
||||
private:
|
||||
~nsFrameLoader() { nsFrameLoader::Destroy(); }
|
||||
~nsFrameLoader() {
|
||||
mInDestructor = PR_TRUE;
|
||||
nsFrameLoader::Destroy();
|
||||
}
|
||||
|
||||
NS_HIDDEN_(nsresult) EnsureDocShell();
|
||||
NS_HIDDEN_(void) GetURL(nsString& aURL);
|
||||
|
@ -75,6 +81,8 @@ private:
|
|||
nsIContent *mOwnerContent; // WEAK
|
||||
PRPackedBool mDepthTooGreat;
|
||||
PRPackedBool mIsTopLevelContent;
|
||||
PRPackedBool mDestroyCalled;
|
||||
PRPackedBool mInDestructor;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Загрузка…
Ссылка в новой задаче