Mozilla Home
Privacy
Cookies
Legal
Bugzilla
Browse
Advanced Search
New Bug
Reports
Documentation
Log In
Log In with GitHub
or
Remember me
Browse
Advanced Search
New Bug
Reports
Documentation
Attachment 192450 Details for
Bug 303267
[patch]
hold onto inner windows
temp.diff (text/plain), 53.30 KB, created by
Blake Kaplan (:mrbkap) (inactive)
(
hide
)
Description:
hold onto inner windows
Filename:
MIME Type:
Creator:
Blake Kaplan (:mrbkap) (inactive)
Size:
53.30 KB
patch
obsolete
>Index: content/html/document/src/nsHTMLDocument.cpp >=================================================================== >RCS file: /cvsroot/mozilla/content/html/document/src/nsHTMLDocument.cpp,v >retrieving revision 3.614 >diff -p -U10 -r3.614 nsHTMLDocument.cpp >--- content/html/document/src/nsHTMLDocument.cpp 8 Aug 2005 03:15:56 -0000 3.614 >+++ content/html/document/src/nsHTMLDocument.cpp 12 Aug 2005 00:28:27 -0000 >@@ -1908,21 +1908,21 @@ nsHTMLDocument::OpenCommon(const nsACStr > } > > // Before we reset the doc notify the globalwindow of the change. > > if (mScriptGlobalObject) { > // Hold onto ourselves on the offchance that we're down to one ref > > nsCOMPtr<nsIDOMDocument> kungFuDeathGrip = > do_QueryInterface((nsIHTMLDocument*)this); > >- rv = mScriptGlobalObject->SetNewDocument(kungFuDeathGrip, PR_FALSE, >+ rv = mScriptGlobalObject->SetNewDocument(kungFuDeathGrip, nsnull, PR_FALSE, > PR_FALSE); > > if (NS_FAILED(rv)) { > return rv; > } > } > > // XXX This is a nasty workaround for a scrollbar code bug > // (http://bugzilla.mozilla.org/show_bug.cgi?id=55334). > >Index: content/xbl/src/nsXBLDocumentInfo.cpp >=================================================================== >RCS file: /cvsroot/mozilla/content/xbl/src/nsXBLDocumentInfo.cpp,v >retrieving revision 1.29 >diff -p -U10 -r1.29 nsXBLDocumentInfo.cpp >--- content/xbl/src/nsXBLDocumentInfo.cpp 30 Jul 2005 20:57:03 -0000 1.29 >+++ content/xbl/src/nsXBLDocumentInfo.cpp 12 Aug 2005 00:28:27 -0000 >@@ -60,20 +60,21 @@ class nsXBLDocGlobalObject : public nsIS > public: > nsXBLDocGlobalObject(); > > // nsISupports interface > NS_DECL_ISUPPORTS > > // nsIScriptGlobalObject methods > virtual void SetContext(nsIScriptContext *aContext); > virtual nsIScriptContext *GetContext(); > virtual nsresult SetNewDocument(nsIDOMDocument *aDocument, >+ nsISupports *aState, > PRBool aRemoveEventListeners, > PRBool aClearScope); > virtual void SetDocShell(nsIDocShell *aDocShell); > virtual nsIDocShell *GetDocShell(); > virtual void SetOpenerWindow(nsIDOMWindowInternal *aOpener); > virtual void SetGlobalObjectOwner(nsIScriptGlobalObjectOwner* aOwner); > virtual nsIScriptGlobalObjectOwner *GetGlobalObjectOwner(); > virtual nsresult HandleDOMEvent(nsPresContext* aPresContext, > nsEvent* aEvent, > nsIDOMEvent** aDOMEvent, >@@ -213,20 +214,21 @@ nsXBLDocGlobalObject::GetContext() > ::JS_SetPrivate(cx, mJSObject, this); > NS_ADDREF(this); > } > > return mScriptContext; > } > > > nsresult > nsXBLDocGlobalObject::SetNewDocument(nsIDOMDocument *aDocument, >+ nsISupports *aState, > PRBool aRemoveEventListeners, > PRBool aClearScope) > { > NS_NOTREACHED("waaah!"); > return NS_ERROR_UNEXPECTED; > } > > > void > nsXBLDocGlobalObject::SetDocShell(nsIDocShell *aDocShell) >Index: content/xul/document/src/nsXULPrototypeDocument.cpp >=================================================================== >RCS file: /cvsroot/mozilla/content/xul/document/src/nsXULPrototypeDocument.cpp,v >retrieving revision 1.64 >diff -p -U10 -r1.64 nsXULPrototypeDocument.cpp >--- content/xul/document/src/nsXULPrototypeDocument.cpp 30 Jul 2005 20:57:04 -0000 1.64 >+++ content/xul/document/src/nsXULPrototypeDocument.cpp 12 Aug 2005 00:28:27 -0000 >@@ -82,20 +82,21 @@ class nsXULPDGlobalObject : public nsISc > public: > nsXULPDGlobalObject(); > > // nsISupports interface > NS_DECL_ISUPPORTS > > // nsIScriptGlobalObject methods > virtual void SetContext(nsIScriptContext *aContext); > virtual nsIScriptContext *GetContext(); > virtual nsresult SetNewDocument(nsIDOMDocument *aDocument, >+ nsISupports *aState, > PRBool aRemoveEventListeners, > PRBool aClearScope); > virtual void SetDocShell(nsIDocShell *aDocShell); > virtual nsIDocShell *GetDocShell(); > virtual void SetOpenerWindow(nsIDOMWindowInternal *aOpener); > virtual void SetGlobalObjectOwner(nsIScriptGlobalObjectOwner* aOwner); > virtual nsIScriptGlobalObjectOwner *GetGlobalObjectOwner(); > virtual nsresult HandleDOMEvent(nsPresContext* aPresContext, > nsEvent* aEvent, > nsIDOMEvent** aDOMEvent, >@@ -839,20 +840,21 @@ nsXULPDGlobalObject::GetContext() > ::JS_SetPrivate(cx, mJSObject, this); > NS_ADDREF(this); > } > > return mScriptContext; > } > > > nsresult > nsXULPDGlobalObject::SetNewDocument(nsIDOMDocument *aDocument, >+ nsISupports *aState, > PRBool aRemoveEventListeners, > PRBool aClearScope) > { > NS_NOTREACHED("waaah!"); > return NS_ERROR_UNEXPECTED; > } > > > void > nsXULPDGlobalObject::SetDocShell(nsIDocShell *aDocShell) >Index: docshell/base/nsDocShell.cpp >=================================================================== >RCS file: /cvsroot/mozilla/docshell/base/nsDocShell.cpp,v >retrieving revision 1.719 >diff -p -U10 -r1.719 nsDocShell.cpp >--- docshell/base/nsDocShell.cpp 11 Aug 2005 20:14:00 -0000 1.719 >+++ docshell/base/nsDocShell.cpp 12 Aug 2005 00:28:29 -0000 >@@ -5220,22 +5220,26 @@ nsDocShell::RestoreFromHistory() > // Destroy() is called. > > if (mContentViewer) { > mContentViewer->Close(mSavingOldViewer ? mOSHE.get() : nsnull); > mContentViewer->Destroy(); > } > > mContentViewer.swap(viewer); > viewer = nsnull; // force a release to complete ownership transfer > >+ // Grab the window state up here so we can pass it to Open. >+ nsCOMPtr<nsISupports> windowState; >+ mLSHE->GetWindowState(getter_AddRefs(windowState)); >+ > // Reattach to the window object. >- rv = mContentViewer->Open(); >+ rv = mContentViewer->Open(windowState); > > // Now remove it from the cached presentation. > mLSHE->SetContentViewer(nsnull); > mEODForCurrentDocument = PR_FALSE; > > // Restore the sticky state of the viewer. The viewer has set this state > // on the history entry in Destroy() just before marking itself non-sticky, > // to avoid teardown of the presentation. > PRBool sticky; > mLSHE->GetSticky(&sticky); >@@ -5268,23 +5272,20 @@ nsDocShell::RestoreFromHistory() > document->GetChannel(), PR_TRUE); > } > > // This is the end of our CreateContentViewer() replacement. > // Now we simulate a load. First, we restore the state of the javascript > // window object. > nsCOMPtr<nsPIDOMWindow> privWin = > do_GetInterface(NS_STATIC_CAST(nsIInterfaceRequestor*, this)); > NS_ASSERTION(privWin, "could not get nsPIDOMWindow interface"); > >- nsCOMPtr<nsISupports> windowState; >- mLSHE->GetWindowState(getter_AddRefs(windowState)); >- > rv = privWin->RestoreWindowState(windowState); > NS_ENSURE_SUCCESS(rv, rv); > > mLSHE->SetWindowState(nsnull); > > // Now, dispatch a title change event which would happed as the > // <head> is parsed. > nsCOMPtr<nsIDOMNSDocument> nsDoc = do_QueryInterface(document); > if (nsDoc) { > const nsAFlatString &title = document->GetDocumentTitle(); >Index: docshell/base/nsIContentViewer.idl >=================================================================== >RCS file: /cvsroot/mozilla/docshell/base/nsIContentViewer.idl,v >retrieving revision 1.17 >diff -p -U10 -r1.17 nsIContentViewer.idl >--- docshell/base/nsIContentViewer.idl 15 Jun 2005 23:52:36 -0000 1.17 >+++ docshell/base/nsIContentViewer.idl 12 Aug 2005 00:28:29 -0000 >@@ -7,21 +7,21 @@ interface nsISHEntry; > %{ C++ > class nsIWidget; > class nsIDeviceContext; > struct nsRect; > %} > > [ptr] native nsIWidgetPtr(nsIWidget); > [ptr] native nsIDeviceContextPtr(nsIDeviceContext); > [ref] native nsRectRef(nsRect); > >-[scriptable, uuid(62d0e866-e608-4b1a-9ab0-467142b3e3bd)] >+[scriptable, uuid(6a7ddb40-8a9e-4576-8ad1-71c5641d8780)] > interface nsIContentViewer : nsISupports > { > > [noscript] void init(in nsIWidgetPtr aParentWidget, > in nsIDeviceContextPtr aDeviceContext, > [const] in nsRectRef aBounds); > > attribute nsISupports container; > > void loadStart(in nsISupports aDoc); >@@ -79,18 +79,18 @@ interface nsIContentViewer : nsISupports > * This is called when the DOM window wants to be closed. Returns true > * if the window can close immediately. Otherwise, returns false and will > * close the DOM window as soon as practical. > */ > > boolean requestWindowClose(); > > /** > * Attach the content viewer to its DOM window and docshell. > */ >- void open(); >+ void open(in nsISupports aState); > > /** > * Clears the current history entry. This is used if we need to clear out > * the saved presentation state. > */ > void clearHistoryEntry(); > }; >Index: dom/public/nsIScriptGlobalObject.h >=================================================================== >RCS file: /cvsroot/mozilla/dom/public/nsIScriptGlobalObject.h,v >retrieving revision 3.26 >diff -p -U10 -r3.26 nsIScriptGlobalObject.h >--- dom/public/nsIScriptGlobalObject.h 30 Jul 2005 20:57:05 -0000 3.26 >+++ dom/public/nsIScriptGlobalObject.h 12 Aug 2005 00:28:29 -0000 >@@ -1,11 +1,12 @@ > /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ >+/* vim: set ts=2 sw=2 et tw=80: */ > /* ***** BEGIN LICENSE BLOCK ***** > * Version: MPL 1.1/GPL 2.0/LGPL 2.1 > * > * The contents of this file are subject to the Mozilla Public License Version > * 1.1 (the "License"); you may not use this file except in compliance with > * the License. You may obtain a copy of the License at > * http://www.mozilla.org/MPL/ > * > * Software distributed under the License is distributed on an "AS IS" basis, > * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License >@@ -60,20 +61,21 @@ struct JSObject; > */ > > class nsIScriptGlobalObject : public nsISupports > { > public: > NS_DEFINE_STATIC_IID_ACCESSOR(NS_ISCRIPTGLOBALOBJECT_IID) > > virtual void SetContext(nsIScriptContext *aContext) = 0; > virtual nsIScriptContext *GetContext() = 0; > virtual nsresult SetNewDocument(nsIDOMDocument *aDocument, >+ nsISupports *aState, > PRBool aRemoveEventListeners, > PRBool aClearScope) = 0; > virtual void SetDocShell(nsIDocShell *aDocShell) = 0; > virtual nsIDocShell *GetDocShell() = 0; > virtual void SetOpenerWindow(nsIDOMWindowInternal *aOpener)=0; > > /** > * Let the script global object know who its owner is. > * The script global object should not addref the owner. It > * will be told when the owner goes away. >Index: dom/src/base/nsGlobalWindow.cpp >=================================================================== >RCS file: /cvsroot/mozilla/dom/src/base/nsGlobalWindow.cpp,v >retrieving revision 1.760 >diff -p -U10 -r1.760 nsGlobalWindow.cpp >--- dom/src/base/nsGlobalWindow.cpp 10 Aug 2005 20:10:18 -0000 1.760 >+++ dom/src/base/nsGlobalWindow.cpp 12 Aug 2005 00:28:30 -0000 >@@ -1,11 +1,12 @@ > /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ >+/* vim: set sw=2 ts=2 et tw=80: */ > /* ***** BEGIN LICENSE BLOCK ***** > * Version: MPL 1.1/GPL 2.0/LGPL 2.1 > * > * The contents of this file are subject to the Mozilla Public License Version > * 1.1 (the "License"); you may not use this file except in compliance with > * the License. You may obtain a copy of the License at > * http://www.mozilla.org/MPL/ > * > * Software distributed under the License is distributed on an "AS IS" basis, > * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License >@@ -242,20 +243,21 @@ static const char kPkcs11ContractID[] = > //*** nsGlobalWindow: Object Management > //***************************************************************************** > > nsGlobalWindow::nsGlobalWindow(nsGlobalWindow *aOuterWindow) > : nsPIDOMWindow(aOuterWindow), > mFullScreen(PR_FALSE), > mIsClosed(PR_FALSE), > mInClose(PR_FALSE), > mOpenerWasCleared(PR_FALSE), > mIsPopupSpam(PR_FALSE), >+ mIsFrozen(PR_FALSE), > mJSObject(nsnull), > mArguments(nsnull), > mTimeouts(nsnull), > mTimeoutInsertionPoint(&mTimeouts), > mTimeoutPublicIdCounter(1), > mTimeoutFiringDepth(0), > mGlobalObjectOwner(nsnull), > mDocShell(nsnull) > { > // Window object's are also PRCList's, the list is for keeping all >@@ -503,40 +505,137 @@ nsGlobalWindow::PopPopupControlState(Pop > { > ::PopPopupControlState(aState); > } > > PopupControlState > nsGlobalWindow::GetPopupControlState() const > { > return gPopupControlState; > } > >+#define WINDOWSTATEHOLDER_IID \ >+{0x2aa29291, 0x3ac9, 0x4d37, {0xa4, 0x3d, 0x45, 0x15, 0x2f, 0x16, 0x23, 0x04 }} >+ >+class WindowStateHolder : public nsISupports >+{ >+public: >+ NS_DEFINE_STATIC_IID_ACCESSOR(WINDOWSTATEHOLDER_IID) >+ NS_DECL_ISUPPORTS >+ >+ WindowStateHolder(nsGlobalWindow *aWindow, >+ nsIXPConnectJSObjectHolder *aHolder, >+ nsNavigator *aNavigator); >+ >+ // Get the listener manager, which holds all event handlers for the window. >+ nsIEventListenerManager* GetListenerManager() { return mListenerManager; } >+ >+ // Get the contents of focus memory when the state was saved >+ // (if the focus was inside of this window). >+ nsIDOMElement* GetFocusedElement() { return mFocusedElement; } >+ nsIDOMWindowInternal* GetFocusedWindow() { return mFocusedWindow; } >+ >+ nsGlobalWindow* GetInnerWindow() { return mInnerWindow; } >+ nsIXPConnectJSObjectHolder* GetInnerWindowHolder() >+ { return mInnerWindowHolder; } >+ >+ nsNavigator* GetNavigator() { return mNavigator; } >+ >+protected: >+ ~WindowStateHolder(); >+ >+ nsGlobalWindow *mInnerWindow; >+ // We hold onto this to make sure the inner window doesn't go away. The outer >+ // window ends up recalculating it anyway. >+ nsCOMPtr<nsIXPConnectJSObjectHolder> mInnerWindowHolder; >+ nsRefPtr<nsNavigator> mNavigator; >+ nsCOMPtr<nsIEventListenerManager> mListenerManager; >+ nsCOMPtr<nsIDOMElement> mFocusedElement; >+ nsCOMPtr<nsIDOMWindowInternal> mFocusedWindow; >+}; >+ >+WindowStateHolder::WindowStateHolder(nsGlobalWindow *aWindow, >+ nsIXPConnectJSObjectHolder *aHolder, >+ nsNavigator *aNavigator) >+ : mInnerWindow(aWindow), >+ mInnerWindowHolder(aHolder), >+ mNavigator(aNavigator) >+{ >+ NS_PRECONDITION(aWindow, "null window"); >+ NS_PRECONDITION(aWindow->IsInnerWindow(), "Saving an outer window"); >+ >+ // Keep the listener manager around, but not on the window. >+ aWindow->GetListenerManager(getter_AddRefs(mListenerManager)); >+ >+ // Clear the window's EventListenerManager pointer so that it can't have >+ // listeners removed from it later. >+ aWindow->mListenerManager = nsnull; >+ >+ nsIFocusController *fc = aWindow->GetRootFocusController(); >+ NS_ASSERTION(fc, "null focus controller"); >+ >+ // We want to save the focused element/window only if they are inside of >+ // this window. >+ >+ nsCOMPtr<nsIDOMWindowInternal> focusWinInternal; >+ fc->GetFocusedWindow(getter_AddRefs(focusWinInternal)); >+ >+ nsCOMPtr<nsPIDOMWindow> focusedWindow = do_QueryInterface(focusWinInternal); >+ >+ // The outer window is used for focus purposes, so make sure that's what >+ // we're looking for. >+ nsPIDOMWindow *targetWindow = aWindow->GetOuterWindow(); >+ >+ while (focusedWindow) { >+ if (focusedWindow == targetWindow) { >+ fc->GetFocusedWindow(getter_AddRefs(mFocusedWindow)); >+ fc->GetFocusedElement(getter_AddRefs(mFocusedElement)); >+ break; >+ } >+ >+ focusedWindow = >+ NS_STATIC_CAST(nsGlobalWindow*, >+ NS_STATIC_CAST(nsPIDOMWindow*, >+ focusedWindow))->GetPrivateParent(); >+ } >+ >+ aWindow->SuspendTimeouts(); >+} >+ >+WindowStateHolder::~WindowStateHolder() >+{ >+} >+ >+NS_IMPL_ISUPPORTS1(WindowStateHolder, WindowStateHolder) >+ > nsresult > nsGlobalWindow::SetNewDocument(nsIDOMDocument* aDocument, >+ nsISupports* aState, > PRBool aRemoveEventListeners, > PRBool aClearScopeHint) > { >- return SetNewDocument(aDocument, aRemoveEventListeners, aClearScopeHint, >- PR_FALSE); >+ return SetNewDocument(aDocument, aState, aRemoveEventListeners, >+ aClearScopeHint, PR_FALSE); > } > > nsresult > nsGlobalWindow::SetNewDocument(nsIDOMDocument* aDocument, >+ nsISupports* aState, > PRBool aRemoveEventListeners, > PRBool aClearScopeHint, > PRBool aIsInternalCall) > { > NS_WARN_IF_FALSE(mDocumentPrincipal == nsnull, > "mDocumentPrincipal prematurely set!"); > > if (!aIsInternalCall && IsInnerWindow()) { > return GetOuterWindowInternal()->SetNewDocument(aDocument, >+ aState, > aRemoveEventListeners, > aClearScopeHint, PR_TRUE); > } > > if (!aDocument) { > NS_ERROR("SetNewDocument(null) called!"); > > return NS_ERROR_INVALID_ARG; > } > >@@ -592,21 +691,21 @@ nsGlobalWindow::SetNewDocument(nsIDOMDoc > xblService->AttachGlobalKeyHandler(rec); > > // for now, the only way to get drag/drop is to use the XUL > // wrapper. There are just too many things that need to be > // added to hookup DnD with XBL (pinkerton) > //xblService->AttachGlobalDragHandler(rec); > } > } > } > >- /* No mDocShell means we've either an inner window or we're already >+ /* No mDocShell means we're either an inner window or we're already > been partially closed down. When that happens, setting status > isn't a big requirement, so don't. (Doesn't happen under normal > circumstances, but bug 49615 describes a case.) */ > /* We only want to do this when we're setting a new document rather > than going away. See bug 61840. */ > > if (mDocShell) { > SetStatus(EmptyString()); > SetDefaultStatus(EmptyString()); > } >@@ -667,20 +766,22 @@ nsGlobalWindow::SetNewDocument(nsIDOMDoc > } > } > > // Remember the old document's principal. > nsIPrincipal *oldPrincipal = nsnull; > > if (oldDoc) { > oldPrincipal = oldDoc->GetPrincipal(); > } > >+ nsGlobalWindow *currentInner = GetCurrentInnerWindowInternal(); >+ > // Drop our reference to the navigator object unless we're reusing > // the existing inner window or the new document is from the same > // origin as the old document. > if (!reUseInnerWindow && mNavigator && oldPrincipal) { > nsIPrincipal *newPrincipal = newDoc->GetPrincipal(); > rv = NS_ERROR_FAILURE; > > if (newPrincipal) { > rv = sSecMan->CheckSameOriginPrincipal(oldPrincipal, newPrincipal); > } >@@ -708,27 +809,25 @@ nsGlobalWindow::SetNewDocument(nsIDOMDoc > // having to *always* reach into the inner window to find the > // document. > > mDocument = aDocument; > > if (IsOuterWindow()) { > scx->WillInitializeContext(); > } > > if (xpc && IsOuterWindow()) { >- nsGlobalWindow *currentInner = GetCurrentInnerWindowInternal(); >- > // In case we're not removing event listeners, move the event > // listener manager over to the new inner window. > nsCOMPtr<nsIEventListenerManager> listenerManager; > >- if (currentInner) { >+ if (currentInner && !currentInner->IsFrozen()) { > if (!reUseInnerWindow) { > currentInner->ClearAllTimeouts(); > > currentInner->mChromeEventHandler = nsnull; > } > > if (aRemoveEventListeners && currentInner->mListenerManager) { > currentInner->mListenerManager->RemoveAllListeners(PR_FALSE); > currentInner->mListenerManager = nsnull; > } else { >@@ -739,49 +838,61 @@ nsGlobalWindow::SetNewDocument(nsIDOMDoc > } > > nsRefPtr<nsGlobalWindow> newInnerWindow; > > nsCOMPtr<nsIDOMChromeWindow> thisChrome = > do_QueryInterface(NS_STATIC_CAST(nsIDOMWindow *, this)); > nsCOMPtr<nsIXPConnectJSObjectHolder> navigatorHolder; > > PRUint32 flags = 0; > >- if (reUseInnerWindow) { >+ if (reUseInnerWindow && !currentInner->IsFrozen()) { > // We're reusing the current inner window. > newInnerWindow = currentInner; > } else { >- if (thisChrome) { >- newInnerWindow = new nsGlobalChromeWindow(this); >+ if (!aState) { >+ if (thisChrome) { >+ newInnerWindow = new nsGlobalChromeWindow(this); > >- flags = nsIXPConnect::FLAG_SYSTEM_GLOBAL_OBJECT; >+ flags = nsIXPConnect::FLAG_SYSTEM_GLOBAL_OBJECT; >+ } else { >+ newInnerWindow = new nsGlobalWindow(this); >+ } > } else { >- newInnerWindow = new nsGlobalWindow(this); >+ nsCOMPtr<WindowStateHolder> wsh = do_QueryInterface(aState); >+ NS_ASSERTION(wsh, "What kind of weird state are you giving me here?"); >+ >+ newInnerWindow = wsh->GetInnerWindow(); >+ mInnerWindowHolder = wsh->GetInnerWindowHolder(); >+ mNavigator = wsh->GetNavigator(); // This assignment addrefs. > } > > if (!newInnerWindow) { > return NS_ERROR_OUT_OF_MEMORY; > } > >- nsIScriptGlobalObject *sgo = >- (nsIScriptGlobalObject *)newInnerWindow.get(); >- >- nsresult rv = xpc-> >- InitClassesWithNewWrappedGlobal(cx, sgo, NS_GET_IID(nsISupports), >- flags, >- getter_AddRefs(mInnerWindowHolder)); >- NS_ENSURE_SUCCESS(rv, rv); >+ if (!aState) { >+ // This is redundant if we're restoring from a previous inner window. >+ nsIScriptGlobalObject *sgo = >+ (nsIScriptGlobalObject *)newInnerWindow.get(); >+ >+ nsresult rv = xpc-> >+ InitClassesWithNewWrappedGlobal(cx, sgo, NS_GET_IID(nsISupports), >+ flags, >+ getter_AddRefs(mInnerWindowHolder)); >+ NS_ENSURE_SUCCESS(rv, rv); > >- mInnerWindowHolder->GetJSObject(&newInnerWindow->mJSObject); >+ mInnerWindowHolder->GetJSObject(&newInnerWindow->mJSObject); >+ } > > if (currentInner && currentInner->mJSObject) { >- if (mNavigator) { >+ if (mNavigator && !aState) { > // Hold on to the navigator wrapper so that we can set > // window.navigator in the new window to point to the same > // object (assuming we didn't change origins etc). See bug > // 163645 for more on why we need this. > > nsIDOMNavigator* navigator = > NS_STATIC_CAST(nsIDOMNavigator*, mNavigator.get()); > xpc->WrapNative(cx, currentInner->mJSObject, navigator, > NS_GET_IID(nsIDOMNavigator), > getter_AddRefs(navigatorHolder)); >@@ -793,108 +904,116 @@ nsGlobalWindow::SetNewDocument(nsIDOMDoc > nsCOMPtr<nsIJSContextStack> stack = > do_GetService(sJSStackContractID); > > JSContext *cx = nsnull; > > if (stack) { > stack->Peek(&cx); > } > > nsIScriptContext *callerScx; >- if (cx && (callerScx = GetScriptContextFromJSContext(cx))) { >+ if (cx && (callerScx = GetScriptContextFromJSContext(cx)) && >+ !currentInner->IsFrozen()) { > // We're called from document.open() (and document.open() is > // called from JS), clear the scope etc in a termination > // function on the calling context to prevent clearing the > // calling scope. > callerScx->SetTerminationFunction(ClearWindowScope, > NS_STATIC_CAST(nsIDOMWindow *, > currentInner)); > > termFuncSet = PR_TRUE; > } > } > > // Clear scope on the outer window > ::JS_ClearScope(cx, mJSObject); > ::JS_ClearWatchPointsForObject(cx, mJSObject); > > // Re-initialize the outer window. > scx->InitContext(this); > >- if (!termFuncSet) { >- ::JS_ClearScope(cx, currentInner->mJSObject); >- ::JS_ClearWatchPointsForObject(cx, currentInner->mJSObject); >- ::JS_ClearRegExpStatics(cx); >- } >+ // Don't clear scope on our current inner window if it's going to be >+ // held in the bfcache. >+ if (!currentInner->IsFrozen()) { >+ if (!termFuncSet) { >+ ::JS_ClearScope(cx, currentInner->mJSObject); >+ ::JS_ClearWatchPointsForObject(cx, currentInner->mJSObject); >+ ::JS_ClearRegExpStatics(cx); >+ } > >- // Make the current inner window release its strong references >- // to the document to prevent it from keeping everything >- // around. But remember the document's principal. >- currentInner->mDocument = nsnull; >- currentInner->mDocumentPrincipal = oldPrincipal; >+ // Make the current inner window release its strong references >+ // to the document to prevent it from keeping everything >+ // around. But remember the document's principal. >+ currentInner->mDocument = nsnull; >+ currentInner->mDocumentPrincipal = oldPrincipal; >+ } > } > > mInnerWindow = newInnerWindow; > > // InitClassesWithNewWrappedGlobal() sets the global object in > // cx to be the new wrapped global. We don't want that, so set > // it back to our own JS object. > > ::JS_SetGlobalObject(cx, mJSObject); > >- if (newDoc != oldDoc) { >+ if (newDoc != oldDoc && !aState) { > nsCOMPtr<nsIHTMLDocument> html_doc(do_QueryInterface(mDocument)); > nsWindowSH::InstallGlobalScopePolluter(cx, newInnerWindow->mJSObject, > html_doc); > } > } > > if (newDoc) { > newDoc->SetScriptGlobalObject(newInnerWindow); > } > >- if (reUseInnerWindow) { >- newInnerWindow->mDocument = aDocument; >- } else { >- rv = newInnerWindow->SetNewDocument(aDocument, aRemoveEventListeners, >- aClearScopeHint, PR_TRUE); >- NS_ENSURE_SUCCESS(rv, rv); >+ if (!aState) { >+ if (reUseInnerWindow) { >+ newInnerWindow->mDocument = aDocument; >+ } else { >+ rv = newInnerWindow->SetNewDocument(aDocument, nsnull, >+ aRemoveEventListeners, >+ aClearScopeHint, PR_TRUE); >+ NS_ENSURE_SUCCESS(rv, rv); > >- // Initialize DOM classes etc on the inner window. >- rv = scx->InitClasses(newInnerWindow->mJSObject); >- NS_ENSURE_SUCCESS(rv, rv); >+ // Initialize DOM classes etc on the inner window. >+ rv = scx->InitClasses(newInnerWindow->mJSObject); >+ NS_ENSURE_SUCCESS(rv, rv); > >- if (navigatorHolder) { >- // Restore window.navigator onto the new inner window. >- JSObject *nav; >- navigatorHolder->GetJSObject(&nav); >+ if (navigatorHolder) { >+ // Restore window.navigator onto the new inner window. >+ JSObject *nav; >+ navigatorHolder->GetJSObject(&nav); > >- jsval navVal = OBJECT_TO_JSVAL(nav); >- ::JS_SetProperty(cx, newInnerWindow->mJSObject, "navigator", &navVal); >+ jsval navVal = OBJECT_TO_JSVAL(nav); >+ ::JS_SetProperty(cx, newInnerWindow->mJSObject, "navigator", &navVal); >+ } >+ >+ newInnerWindow->mListenerManager = listenerManager; > } > >- newInnerWindow->mListenerManager = listenerManager; >- } >+ if (mArguments) { >+ jsval args = OBJECT_TO_JSVAL(mArguments); > >- if (mArguments) { >- jsval args = OBJECT_TO_JSVAL(mArguments); >+ ::JS_SetProperty(cx, newInnerWindow->mJSObject, "arguments", >+ &args); > >- ::JS_SetProperty(cx, newInnerWindow->mJSObject, "arguments", >- &args); >+ ::JS_UnlockGCThing(cx, mArguments); >+ mArguments = nsnull; >+ } > >- ::JS_UnlockGCThing(cx, mArguments); >- mArguments = nsnull; >+ // Give the new inner window our chrome event handler (since it >+ // doesn't have one). >+ newInnerWindow->mChromeEventHandler = mChromeEventHandler; > } >- >- // Give the new inner window our chrome event handler (since it >- // doesn't have one). >- newInnerWindow->mChromeEventHandler = mChromeEventHandler; > } > > if (scx && IsOuterWindow()) { > // Add an extra ref in case we release mContext during GC. > nsCOMPtr<nsIScriptContext> kungFuDeathGrip = scx; > scx->GC(); > > scx->DidInitializeContext(); > } > >@@ -6369,317 +6488,89 @@ nsGlobalWindow::EnsureSizeUpToDate() > // If we're a subframe, make sure our size is up to date. It's OK that this > // crosses the content/chrome boundary, since chrome can have pending reflows > // too. > nsGlobalWindow *parent = > NS_STATIC_CAST(nsGlobalWindow *, GetPrivateParent()); > if (parent) { > parent->FlushPendingNotifications(Flush_Layout); > } > } > >-#define WINDOWSTATEHOLDER_IID \ >-{0xae1c7401, 0xcdee, 0x404a, {0xbd, 0x63, 0x05, 0xc0, 0x35, 0x0d, 0xa7, 0x72}} >- >-class WindowStateHolder : public nsISupports >-{ >-public: >- NS_DEFINE_STATIC_IID_ACCESSOR(WINDOWSTATEHOLDER_IID) >- NS_DECL_ISUPPORTS >- >- WindowStateHolder(JSContext *cx, // The JSContext for the window >- JSObject *aObject, // An object to save the properties onto >- nsGlobalWindow *aWindow); // The window to operate on >- >- // This is the property store object that holds the window properties. >- JSObject* GetObject() { return mJSObj; } >- >- // Get the listener manager, which holds all event handlers for the window. >- nsIEventListenerManager* GetListenerManager() { return mListenerManager; } >- >- // Get the saved value of the mMutationBits field. >- PRUint32 GetMutationBits() { return mMutationBits; } >- >- // Get the contents of focus memory when the state was saved >- // (if the focus was inside of this window). >- nsIDOMElement* GetFocusedElement() { return mFocusedElement; } >- nsIDOMWindowInternal* GetFocusedWindow() { return mFocusedWindow; } >- >- // Manage the list of saved timeouts for the window. >- nsTimeout* GetSavedTimeouts() { return mSavedTimeouts; } >- nsTimeout** GetTimeoutInsertionPoint() { return mTimeoutInsertionPoint; } >- void ClearSavedTimeouts() { mSavedTimeouts = nsnull; } >- >-protected: >- ~WindowStateHolder(); >- >- JSRuntime *mRuntime; >- JSObject *mJSObj; >- nsCOMPtr<nsIEventListenerManager> mListenerManager; >- nsCOMPtr<nsIDOMElement> mFocusedElement; >- nsCOMPtr<nsIDOMWindowInternal> mFocusedWindow; >- nsTimeout *mSavedTimeouts; >- nsTimeout **mTimeoutInsertionPoint; >- PRUint32 mMutationBits; >-}; >- >-WindowStateHolder::WindowStateHolder(JSContext *cx, JSObject *aObject, >- nsGlobalWindow *aWindow) >- : mRuntime(::JS_GetRuntime(cx)), mJSObj(aObject) >-{ >- NS_ASSERTION(aWindow, "null window"); >- >- // Prevent mJSObj from being gc'd for the lifetime of this object. >- ::JS_AddNamedRoot(cx, &mJSObj, "WindowStateHolder::mJSObj"); >- >- aWindow->GetListenerManager(getter_AddRefs(mListenerManager)); >- mMutationBits = aWindow->mMutationBits; >- >- // Clear the window's EventListenerManager pointer so that it can't have >- // listeners removed from it later. >- aWindow->mListenerManager = nsnull; >- >- nsIFocusController *fc = aWindow->GetRootFocusController(); >- NS_ASSERTION(fc, "null focus controller"); >- >- // We want to save the focused element/window only if they are inside of >- // this window. >- >- nsCOMPtr<nsIDOMWindowInternal> focusWinInternal; >- fc->GetFocusedWindow(getter_AddRefs(focusWinInternal)); >- >- nsCOMPtr<nsPIDOMWindow> focusedWindow = do_QueryInterface(focusWinInternal); >- >- // The outer window is used for focus purposes, so make sure that's what >- // we're looking for. >- nsPIDOMWindow *targetWindow = aWindow->GetOuterWindow(); >- >- while (focusedWindow) { >- if (focusedWindow == targetWindow) { >- fc->GetFocusedWindow(getter_AddRefs(mFocusedWindow)); >- fc->GetFocusedElement(getter_AddRefs(mFocusedElement)); >- break; >- } >- >- focusedWindow = >- NS_STATIC_CAST(nsGlobalWindow*, >- NS_STATIC_CAST(nsPIDOMWindow*, >- focusedWindow))->GetPrivateParent(); >- } >- >- aWindow->SuspendTimeouts(); >- >- // Clear the timeout list for aWindow (but we don't need to for children) >- mSavedTimeouts = aWindow->mTimeouts; >- mTimeoutInsertionPoint = aWindow->mTimeoutInsertionPoint; >- >- aWindow->mTimeouts = nsnull; >- aWindow->mTimeoutInsertionPoint = &aWindow->mTimeouts; >-} >- >-WindowStateHolder::~WindowStateHolder() >-{ >- // Release the timeouts, if we still have any. >- nsTimeout *timeout = mSavedTimeouts; >- while (timeout) { >- nsTimeout *next = timeout->mNext; >- NS_ASSERTION(!timeout->mTimer, "live timer in a saved window state"); >- timeout->Release(nsnull); >- timeout = next; >- } >- >- ::JS_RemoveRootRT(mRuntime, &mJSObj); >-} >- >-NS_IMPL_ISUPPORTS1(WindowStateHolder, WindowStateHolder) >- >-static JSClass sWindowStateClass = { >- "window state", 0, >- JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, >- JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub, >- JSCLASS_NO_OPTIONAL_MEMBERS >-}; >- >-static nsresult >-CopyJSPropertyArray(JSContext *cx, JSObject *aSource, JSObject *aDest, >- JSIdArray *props) >-{ >- jsint length = props->length; >- for (jsint i = 0; i < length; ++i) { >- jsval propname_value; >- >- if (!::JS_IdToValue(cx, props->vector[i], &propname_value) || >- !JSVAL_IS_STRING(propname_value)) { >- NS_WARNING("Failed to copy non-string-named window property"); >- return NS_ERROR_FAILURE; >- } >- >- JSString *propname = JSVAL_TO_STRING(propname_value); >- jschar *propname_str = ::JS_GetStringChars(propname); >- NS_ENSURE_TRUE(propname_str, NS_ERROR_FAILURE); >- >- // We exclude the "location" property because restoring it this way is >- // problematic. It will "just work" without us explicitly saving or >- // restoring the value. >- >- if (!nsCRT::strcmp(NS_REINTERPRET_CAST(PRUnichar*, propname_str), >- NS_LITERAL_STRING("location").get())) { >- continue; >- } >- >- size_t propname_len = ::JS_GetStringLength(propname); >- >- JSPropertyOp getter, setter; >- uintN attrs; >- JSBool found; >- if (!::JS_GetUCPropertyAttrsGetterAndSetter(cx, aSource, propname_str, >- propname_len, &attrs, &found, >- &getter, &setter)) >- return NS_ERROR_FAILURE; >- >- NS_ENSURE_TRUE(found, NS_ERROR_UNEXPECTED); >- >- jsval propvalue; >- if (!::JS_LookupUCProperty(cx, aSource, propname_str, >- propname_len, &propvalue)) >- return NS_ERROR_FAILURE; >- >- PRBool res = ::JS_DefineUCProperty(cx, aDest, propname_str, propname_len, >- propvalue, getter, setter, attrs); >-#ifdef DEBUG_PAGE_CACHE >- if (res) >- printf("Copied window property: %s\n", >- NS_ConvertUTF16toUTF8(NS_REINTERPRET_CAST(PRUnichar*, >- propname_str)).get()); >-#endif >- >- if (!res) { >-#ifdef DEBUG >- printf("failed to copy property: %s\n", >- NS_ConvertUTF16toUTF8(NS_REINTERPRET_CAST(PRUnichar*, >- propname_str)).get()); >-#endif >- return NS_ERROR_FAILURE; >- } >- } >- >- return NS_OK; >-} >- >-static nsresult >-CopyJSProperties(JSContext *cx, JSObject *aSource, JSObject *aDest) >-{ >- // Enumerate all of the properties on aSource and install them on aDest. >- >- JSIdArray *props = ::JS_Enumerate(cx, aSource); >- if (props) { >- props = ::JS_EnumerateResolvedStandardClasses(cx, aSource, props); >- } >- if (!props) { >-#ifdef DEBUG_PAGE_CACHE >- printf("failed to enumerate JS properties\n"); >-#endif >- return NS_ERROR_FAILURE; >- } >- >-#ifdef DEBUG_PAGE_CACHE >- printf("props length = %d\n", props->length); >-#endif >- >- nsresult rv = CopyJSPropertyArray(cx, aSource, aDest, props); >- ::JS_DestroyIdArray(cx, props); >- return rv; >-} >- > nsresult > nsGlobalWindow::SaveWindowState(nsISupports **aState) > { >+ NS_PRECONDITION(IsOuterWindow(), "Can't save the inner window's state"); >+ > *aState = nsnull; > >- if (IsOuterWindow() && (!mContext || !mJSObject)) { >+ if (!mContext || !mJSObject) { > // The window may be getting torn down; don't bother saving state. > return NS_OK; > } > >- FORWARD_TO_INNER(SaveWindowState, (aState)); >- >- JSContext *cx = NS_STATIC_CAST(JSContext*, >- GetContextInternal()->GetNativeContext()); >- NS_ENSURE_TRUE(cx, NS_ERROR_FAILURE); >- >- JSObject *stateObj = ::JS_NewObject(cx, &sWindowStateClass, NULL, NULL); >- NS_ENSURE_TRUE(stateObj, NS_ERROR_OUT_OF_MEMORY); >+ nsGlobalWindow *inner = GetCurrentInnerWindowInternal(); >+ NS_ASSERTION(inner, "No inner window to save"); > >- // The window state object will root the JSObject. >- nsCOMPtr<nsISupports> state = new WindowStateHolder(cx, stateObj, this); >+ nsCOMPtr<nsISupports> state = new WindowStateHolder(inner, >+ mInnerWindowHolder, >+ mNavigator); > NS_ENSURE_TRUE(state, NS_ERROR_OUT_OF_MEMORY); > > #ifdef DEBUG_PAGE_CACHE > printf("saving window state, stateObj = %p\n", (void*)stateObj); > #endif >- nsresult rv = CopyJSProperties(cx, mJSObject, stateObj); >- NS_ENSURE_SUCCESS(rv, rv); >+ >+ // Don't do anything else to this inner window! >+ inner->Freeze(); > > state.swap(*aState); > return NS_OK; > } > > nsresult > nsGlobalWindow::RestoreWindowState(nsISupports *aState) > { >- // SetNewDocument() has already been called so we should have a >- // new clean inner window to restore stat into here. >+ NS_ASSERTION(IsOuterWindow(), "Cannot restore an inner window"); > >- if (IsOuterWindow() && (!mContext || !mJSObject)) { >+ if (!mContext || !mJSObject) { > // The window may be getting torn down; don't bother restoring state. > return NS_OK; > } > >- FORWARD_TO_INNER(RestoreWindowState, (aState)); >- >- JSContext *cx = NS_STATIC_CAST(JSContext*, >- GetContextInternal()->GetNativeContext()); >- NS_ENSURE_TRUE(cx, NS_ERROR_FAILURE); >- >- // Note that we don't need to call JS_ClearScope here. The scope is already >- // cleared by SetNewDocument(), and calling it again here would remove the >- // XPConnect properties. >- > nsCOMPtr<WindowStateHolder> holder = do_QueryInterface(aState); > NS_ENSURE_TRUE(holder, NS_ERROR_FAILURE); > > #ifdef DEBUG_PAGE_CACHE > printf("restoring window state, stateObj = %p\n", (void*)holder->GetObject()); > #endif >- nsresult rv = CopyJSProperties(cx, holder->GetObject(), mJSObject); >- NS_ENSURE_SUCCESS(rv, rv); > >- mListenerManager = holder->GetListenerManager(); >- mMutationBits = holder->GetMutationBits(); >+ nsGlobalWindow *inner = GetCurrentInnerWindowInternal(); >+ >+ inner->mListenerManager = holder->GetListenerManager(); > > nsIDOMElement *focusedElement = holder->GetFocusedElement(); > nsIDOMWindowInternal *focusedWindow = holder->GetFocusedWindow(); > > // If the toplevel window isn't focused, just update the focus controller. > nsIFocusController *fc = nsGlobalWindow::GetRootFocusController(); > NS_ENSURE_TRUE(fc, NS_ERROR_UNEXPECTED); > > PRBool active; > fc->GetActive(&active); > if (active) { > PRBool didFocusContent = PR_FALSE; > nsCOMPtr<nsIContent> focusedContent = do_QueryInterface(focusedElement); > > if (focusedContent) { > // We don't bother checking whether the element or frame is focusable. > // If it was focusable when we stored the presentation, it must be > // focusable now. >- PRBool didFocusContent = PR_FALSE; > nsIDocument *doc = focusedContent->GetCurrentDoc(); > if (doc) { > nsIPresShell *shell = doc->GetShellAt(0); > if (shell) { > nsPresContext *pc = shell->GetPresContext(); > if (pc) { > pc->EventStateManager()->SetContentState(focusedContent, > NS_EVENT_STATE_FOCUS); > didFocusContent = PR_TRUE; > } >@@ -6688,30 +6579,24 @@ nsGlobalWindow::RestoreWindowState(nsISu > } > > if (!didFocusContent && focusedWindow) > focusedWindow->Focus(); > } else if (focusedWindow) { > // Just update the saved focus memory. > fc->SetFocusedWindow(focusedWindow); > fc->SetFocusedElement(focusedElement); > } > >- mTimeouts = holder->GetSavedTimeouts(); >- mTimeoutInsertionPoint = holder->GetTimeoutInsertionPoint(); >- >- holder->ClearSavedTimeouts(); >- >- // If our state is being restored from history, we won't be getting an onload >- // event. Make sure we're marked as being completely loaded. >- mIsDocumentLoaded = PR_TRUE; >+ // And we're ready to go! >+ inner->Thaw(); > >- return ResumeTimeouts(); >+ return inner->ResumeTimeouts(); > } > > void > nsGlobalWindow::SuspendTimeouts() > { > FORWARD_TO_INNER_VOID(SuspendTimeouts, ()); > > nsInt64 now = PR_IntervalNow(); > for (nsTimeout *t = mTimeouts; t; t = t->mNext) { > // Change mWhen to be the time remaining for this timer. >Index: dom/src/base/nsGlobalWindow.h >=================================================================== >RCS file: /cvsroot/mozilla/dom/src/base/nsGlobalWindow.h,v >retrieving revision 1.249 >diff -p -U10 -r1.249 nsGlobalWindow.h >--- dom/src/base/nsGlobalWindow.h 31 Jul 2005 19:43:27 -0000 1.249 >+++ dom/src/base/nsGlobalWindow.h 12 Aug 2005 00:28:30 -0000 >@@ -1,11 +1,12 @@ > /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ >+/* vim: set ts=2 sw=2 et tw=80: */ > /* ***** BEGIN LICENSE BLOCK ***** > * Version: MPL 1.1/GPL 2.0/LGPL 2.1 > * > * The contents of this file are subject to the Mozilla Public License Version > * 1.1 (the "License"); you may not use this file except in compliance with > * the License. You may obtain a copy of the License at > * http://www.mozilla.org/MPL/ > * > * Software distributed under the License is distributed on an "AS IS" basis, > * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License >@@ -137,20 +138,21 @@ public: > // callback for close event > void ReallyCloseWindow(); > > // nsISupports > NS_DECL_ISUPPORTS > > // nsIScriptGlobalObject > virtual void SetContext(nsIScriptContext *aContext); > virtual nsIScriptContext *GetContext(); > virtual nsresult SetNewDocument(nsIDOMDocument *aDocument, >+ nsISupports *aState, > PRBool aRemoveEventListeners, > PRBool aClearScopeHint); > virtual void SetDocShell(nsIDocShell* aDocShell); > virtual nsIDocShell *GetDocShell(); > virtual void SetOpenerWindow(nsIDOMWindowInternal *aOpener); > virtual void SetGlobalObjectOwner(nsIScriptGlobalObjectOwner* aOwner); > virtual nsIScriptGlobalObjectOwner *GetGlobalObjectOwner(); > virtual nsresult HandleDOMEvent(nsPresContext* aPresContext, > nsEvent* aEvent, nsIDOMEvent** aDOMEvent, > PRUint32 aFlags, >@@ -258,20 +260,21 @@ public: > > friend class WindowStateHolder; > > protected: > // Object Management > virtual ~nsGlobalWindow(); > void CleanUp(); > void ClearControllers(); > > nsresult SetNewDocument(nsIDOMDocument *aDocument, >+ nsISupports *aState, > PRBool aRemoveEventListeners, > PRBool aClearScopeHint, > PRBool aIsInternalCall); > > // Get the parent, returns null if this is a toplevel window > nsIDOMWindowInternal *GetParentInternal(); > > // popup tracking > PRBool IsPopupSpamWindow() > { >@@ -352,35 +355,58 @@ protected: > > PRBool DispatchCustomEvent(const char *aEventName); > > PRBool WindowExists(const nsAString& aName); > > already_AddRefed<nsIWidget> GetMainWidget(); > > void SuspendTimeouts(); > nsresult ResumeTimeouts(); > >+ void Freeze() >+ { >+ NS_ASSERTION(IsInnerWindow(), "Freeze called on an outer window"); >+ mIsFrozen = PR_TRUE; >+ } >+ >+ void Thaw() >+ { >+ NS_ASSERTION(IsInnerWindow(), "Freeze called on an outer window"); >+ mIsFrozen = PR_FALSE; >+ } >+ >+ PRBool IsFrozen() >+ { >+ NS_ASSERTION(IsInnerWindow(), >+ "Why do you care if an outer window is frozen?"); >+ return mIsFrozen; >+ } >+ > // 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 > // objects will keep the global object (this object) alive. To prevent > // these cycles, ownership of such members must be released in > // |CleanUp| and |SetDocShell|. > > // These members are only used on outer window objects. Make sure > // you never set any of these on an inner object! > PRPackedBool mFullScreen; > PRPackedBool mIsClosed; > PRPackedBool mInClose; > PRPackedBool mOpenerWasCleared; > PRPackedBool mIsPopupSpam; > >+ // This member is only used on inner window objects. It should not >+ // be set on an outer object. >+ PRPackedBool mIsFrozen; >+ > nsCOMPtr<nsIScriptContext> mContext; > nsCOMPtr<nsIDOMWindowInternal> mOpener; > nsCOMPtr<nsIControllers> mControllers; > JSObject* mJSObject; > JSObject* mArguments; > nsRefPtr<nsNavigator> mNavigator; > nsRefPtr<nsScreen> mScreen; > nsRefPtr<nsHistory> mHistory; > nsRefPtr<nsDOMWindowList> mFrames; > nsRefPtr<nsLocation> mLocation; >Index: layout/base/nsCaret.cpp >=================================================================== >RCS file: /cvsroot/mozilla/layout/base/nsCaret.cpp,v >retrieving revision 1.144 >diff -p -U10 -r1.144 nsCaret.cpp >--- layout/base/nsCaret.cpp 11 Aug 2005 03:44:16 -0000 1.144 >+++ layout/base/nsCaret.cpp 12 Aug 2005 00:28:36 -0000 >@@ -500,22 +500,28 @@ nsCaret::DrawAtPositionWithHint(nsIDOMNo > nsIFrameSelection::HINT aFrameHint) > { > nsCOMPtr<nsIContent> contentNode = do_QueryInterface(aNode); > if (!contentNode) > return PR_FALSE; > > //get frame selection and find out what frame to use... > nsCOMPtr<nsIPresShell> presShell = do_QueryReferent(mPresShell); > if (!presShell) > return PR_FALSE; >- >- nsIFrameSelection *frameSelection = presShell->FrameSelection(); >+ >+ nsCOMPtr<nsISelectionPrivate> privateSelection(do_QueryReferent(mDomSelectionWeak)); >+ if (!privateSelection) >+ return PR_FALSE; >+ >+ nsIFrameSelection* frameSelection; >+ privateSelection->GetFrameSelection(&frameSelection); >+ > nsIFrame* theFrame = nsnull; > PRInt32 theFrameOffset = 0; > > nsresult rv = frameSelection->GetFrameForNodeOffset(contentNode, aOffset, aFrameHint, &theFrame, &theFrameOffset); > if (NS_FAILED(rv) || !theFrame) > return PR_FALSE; > > #ifdef IBMBIDI > PRUint8 bidiLevel=0; > // Mamdouh : modification of the caret to work at rtl and ltr with Bidi >Index: layout/base/nsDocumentViewer.cpp >=================================================================== >RCS file: /cvsroot/mozilla/layout/base/nsDocumentViewer.cpp,v >retrieving revision 1.442 >diff -p -U10 -r1.442 nsDocumentViewer.cpp >--- layout/base/nsDocumentViewer.cpp 2 Aug 2005 20:19:19 -0000 1.442 >+++ layout/base/nsDocumentViewer.cpp 12 Aug 2005 00:28:36 -0000 >@@ -1,11 +1,12 @@ > /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ >+/* vim: set ts=2 sw=2 et tw=80: */ > /* ***** BEGIN LICENSE BLOCK ***** > * Version: MPL 1.1/GPL 2.0/LGPL 2.1 > * > * The contents of this file are subject to the Mozilla Public License Version > * 1.1 (the "License"); you may not use this file except in compliance with > * the License. You may obtain a copy of the License at > * http://www.mozilla.org/MPL/ > * > * Software distributed under the License is distributed on an "AS IS" basis, > * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License >@@ -347,20 +348,21 @@ public: > // nsIDocumentViewerPrint Printing Methods > NS_DECL_NSIDOCUMENTVIEWERPRINT > > protected: > virtual ~DocumentViewerImpl(); > > private: > nsresult MakeWindow(nsIWidget* aParentWidget, > const nsRect& aBounds); > nsresult InitInternal(nsIWidget* aParentWidget, >+ nsISupports *aState, > nsIDeviceContext* aDeviceContext, > const nsRect& aBounds, > PRBool aDoCreation, > PRBool aInPrintPreview); > nsresult InitPresentationStuff(PRBool aDoInitialReflow); > > nsresult GetPopupNode(nsIDOMNode** aNode); > nsresult GetPopupLinkNode(nsIDOMNode** aNode); > nsresult GetPopupImageNode(nsIImageLoadingContent** aNode); > >@@ -620,21 +622,21 @@ DocumentViewerImpl::GetContainer(nsISupp > nsCOMPtr<nsISupports> container = do_QueryReferent(mContainer); > container.swap(*aResult); > return NS_OK; > } > > NS_IMETHODIMP > DocumentViewerImpl::Init(nsIWidget* aParentWidget, > nsIDeviceContext* aDeviceContext, > const nsRect& aBounds) > { >- return InitInternal(aParentWidget, aDeviceContext, aBounds, PR_TRUE, PR_FALSE); >+ return InitInternal(aParentWidget, nsnull, aDeviceContext, aBounds, PR_TRUE, PR_FALSE); > } > > nsresult > DocumentViewerImpl::InitPresentationStuff(PRBool aDoInitialReflow) > { > // Create the style set... > nsStyleSet *styleSet; > nsresult rv = CreateStyleSet(mDocument, &styleSet); > NS_ENSURE_SUCCESS(rv, rv); > >@@ -758,20 +760,21 @@ DocumentViewerImpl::InitPresentationStuf > > return NS_OK; > } > > //----------------------------------------------- > // This method can be used to initial the "presentation" > // The aDoCreation indicates whether it should create > // all the new objects or just initialize the existing ones > nsresult > DocumentViewerImpl::InitInternal(nsIWidget* aParentWidget, >+ nsISupports *aState, > nsIDeviceContext* aDeviceContext, > const nsRect& aBounds, > PRBool aDoCreation, > PRBool aInPrintPreview) > { > mParentWidget = aParentWidget; // not ref counted > > nsresult rv = NS_OK; > NS_ENSURE_TRUE(mDocument, NS_ERROR_NULL_POINTER); > >@@ -836,21 +839,21 @@ DocumentViewerImpl::InitInternal(nsIWidg > // Set script-context-owner in the document > > nsCOMPtr<nsIScriptGlobalObject> global; > requestor->GetInterface(NS_GET_IID(nsIScriptGlobalObject), > getter_AddRefs(global)); > > if (global) { > nsCOMPtr<nsIDOMDocument> domdoc(do_QueryInterface(mDocument)); > > if (domdoc) { >- global->SetNewDocument(domdoc, PR_TRUE, PR_TRUE); >+ global->SetNewDocument(domdoc, aState, PR_TRUE, PR_TRUE); > } > } > } > } > > if (aDoCreation && mPresContext) { > // The ViewManager and Root View was created above (in > // MakeWindow())... > > rv = InitPresentationStuff(!makeCX); >@@ -1196,34 +1199,34 @@ DocumentViewerImpl::PageHide(PRBool aIsU > > // Never permit popups from the unload handler, no matter how we get > // here. > nsAutoPopupStatePusher popupStatePusher(openAbused, PR_TRUE); > > return global->HandleDOMEvent(mPresContext, &event, nsnull, > NS_EVENT_FLAG_INIT, &status); > } > > NS_IMETHODIMP >-DocumentViewerImpl::Open() >+DocumentViewerImpl::Open(nsISupports *aState) > { > NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_INITIALIZED); > > // Our container might have gone away while we were closed. > // If this is the case, we must fail to open so we don't crash. > nsCOMPtr<nsISupports> container = do_QueryReferent(mContainer); > if (!container) > return NS_ERROR_NOT_AVAILABLE; > > nsRect bounds; > mWindow->GetBounds(bounds); > >- nsresult rv = InitInternal(mParentWidget, mDeviceContext, bounds, >+ nsresult rv = InitInternal(mParentWidget, aState, mDeviceContext, bounds, > PR_FALSE, PR_FALSE); > NS_ENSURE_SUCCESS(rv, rv); > > if (mDocument) > mDocument->SetContainer(nsCOMPtr<nsISupports>(do_QueryReferent(mContainer))); > > SyncParentSubDocMap(); > > // XXX re-enable image animations once that works correctly > >@@ -1503,21 +1506,21 @@ DocumentViewerImpl::SetDOMDocument(nsIDO > newDoc->SetContainer(container); > > if (mDocument != newDoc) { > // Replace the old document with the new one. Do this only when > // the new document really is a new document. > mDocument = newDoc; > > // Set the script global object on the new document > nsCOMPtr<nsIScriptGlobalObject> global = do_GetInterface(container); > if (global) { >- global->SetNewDocument(aDocument, PR_TRUE, PR_TRUE); >+ global->SetNewDocument(aDocument, nsnull, PR_TRUE, PR_TRUE); > } > } > > rv = SyncParentSubDocMap(); > NS_ENSURE_SUCCESS(rv, rv); > > // Replace the current pres shell with a new shell for the new document > > nsCOMPtr<nsILinkHandler> linkHandler; > if (mPresShell) { >@@ -3929,21 +3932,21 @@ DocumentViewerImpl::ReturnToGalleyPresen > if (mPrintEngine) { > // Very important! Turn On scripting > mPrintEngine->TurnScriptingOn(PR_TRUE); > > if (wasCached) { > mPrintEngine->Destroy(); > NS_RELEASE(mPrintEngine); > } > } > >- InitInternal(mParentWidget, mDeviceContext, bounds, !wasCached, PR_TRUE); >+ InitInternal(mParentWidget, nsnull, mDeviceContext, bounds, !wasCached, PR_TRUE); > > if (mPrintEngine && !wasCached) { > mPrintEngine->Destroy(); > NS_RELEASE(mPrintEngine); > } > > // this needs to be set here not earlier, > // because it is needing when re-constructing the Galley Mode) > SetIsPrintPreview(PR_FALSE); > >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
Flags:
bryner
: review+
Actions:
View
|
Diff
|
Review
Attachments on
bug 303267
:
191925
|
191999
|
192450
|
192553
|
192640
|
387025
|
387212
|
387671