зеркало из https://github.com/mozilla/gecko-dev.git
Fix stuck designMode when using fastback by making sure the DOM window still contains the old document when the STATE_START notification is sent. Bug 300411, r+sr=darin, a=asa.
This commit is contained in:
Родитель
b85cfbfdc5
Коммит
0e7ee4a645
|
@ -4955,18 +4955,23 @@ RestorePresentationEvent::RestorePresentationEvent(nsDocShell *aShell)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::BeginRestore(PRBool aTop)
|
||||
nsDocShell::BeginRestore(nsIContentViewer *aContentViewer, PRBool aTop)
|
||||
{
|
||||
nsresult rv;
|
||||
if (!aContentViewer) {
|
||||
rv = EnsureContentViewer();
|
||||
NS_ENSURE_TRUE(rv, rv);
|
||||
|
||||
aContentViewer = mContentViewer;
|
||||
}
|
||||
|
||||
// Dispatch events for restoring the presentation. We try to simulate
|
||||
// the progress notifications loading the document would cause, so we add
|
||||
// the document's channel to the loadgroup to initiate stateChange
|
||||
// notifications.
|
||||
|
||||
nsresult rv = EnsureContentViewer();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIDOMDocument> domDoc;
|
||||
mContentViewer->GetDOMDocument(getter_AddRefs(domDoc));
|
||||
aContentViewer->GetDOMDocument(getter_AddRefs(domDoc));
|
||||
nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
|
||||
if (doc) {
|
||||
nsIChannel *channel = doc->GetChannel();
|
||||
|
@ -4977,22 +4982,10 @@ nsDocShell::BeginRestore(PRBool aTop)
|
|||
}
|
||||
}
|
||||
|
||||
// These events start from the top-down and finish from the bottom-up.
|
||||
// So, next we tell all of our children to call AddRequest, then post
|
||||
// a PLEvent, which will cause us to call finishRestore() on our children.
|
||||
|
||||
PRInt32 n = mChildList.Count();
|
||||
for (PRInt32 i = 0; i < n; ++i) {
|
||||
nsCOMPtr<nsIDocShell> child = do_QueryInterface(ChildAt(i));
|
||||
if (child) {
|
||||
rv = child->BeginRestore(PR_FALSE);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
}
|
||||
|
||||
if (aTop) {
|
||||
// We finish up the restore processing on a PLEvent to mimic the way
|
||||
// RemoveRequest is called by nsIChannel implementations.
|
||||
// Post a PLEvent that will remove the request after we've returned
|
||||
// to the event loop. This mimics the way it is called by nsIChannel
|
||||
// implementations.
|
||||
|
||||
nsCOMPtr<nsIEventQueue> uiThreadQueue;
|
||||
NS_GetMainEventQ(getter_AddRefs(uiThreadQueue));
|
||||
|
@ -5005,9 +4998,30 @@ nsDocShell::BeginRestore(PRBool aTop)
|
|||
if (NS_FAILED(rv)) {
|
||||
PL_DestroyEvent(evt);
|
||||
}
|
||||
} else {
|
||||
// For non-top frames, there is no notion of making sure that the
|
||||
// previous document is in the domwindow when STATE_START notifications
|
||||
// happen. We can just call BeginRestore for all of the child shells
|
||||
// now.
|
||||
rv = BeginRestoreChildren();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
return rv;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDocShell::BeginRestoreChildren()
|
||||
{
|
||||
PRInt32 n = mChildList.Count();
|
||||
for (PRInt32 i = 0; i < n; ++i) {
|
||||
nsCOMPtr<nsIDocShell> child = do_QueryInterface(ChildAt(i));
|
||||
if (child) {
|
||||
nsresult rv = child->BeginRestore(nsnull, PR_FALSE);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -5136,6 +5150,14 @@ nsDocShell::RestorePresentation(nsISHEntry *aSHEntry, PRBool aSavePresentation,
|
|||
FirePageHideNotification(!aSavePresentation);
|
||||
mFiredUnloadEvent = PR_FALSE;
|
||||
|
||||
// Add the request to our load group. We do this before swapping out
|
||||
// the content viewers so that consumers of STATE_START can access
|
||||
// the old document. We only deal with the toplevel load at this time --
|
||||
// to be consistent with normal document loading, subframes cannot start
|
||||
// loading until after data arrives, which is after STATE_START completes.
|
||||
|
||||
BeginRestore(viewer, PR_TRUE);
|
||||
|
||||
// Save off the root view's parent and sibling so that we can insert the
|
||||
// new content viewer's root view at the same position. Also save the
|
||||
// bounds of the root view's widget.
|
||||
|
@ -5224,6 +5246,10 @@ nsDocShell::RestorePresentation(nsISHEntry *aSHEntry, PRBool aSavePresentation,
|
|||
// And release the references in the history entry.
|
||||
aSHEntry->ClearChildShells();
|
||||
|
||||
// Dispatch STATE_START notifications for the new child shells.
|
||||
rv = BeginRestoreChildren();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// 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.
|
||||
|
@ -5345,13 +5371,6 @@ nsDocShell::RestorePresentation(nsISHEntry *aSHEntry, PRBool aSavePresentation,
|
|||
nsDoc->SetTitle(title);
|
||||
}
|
||||
|
||||
// Dispatch DOMPageShow and other events.
|
||||
rv = BeginRestore(PR_TRUE);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = mContentViewer->Show();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Restart plugins, and paint the content.
|
||||
if (shell)
|
||||
shell->Thaw();
|
||||
|
|
|
@ -445,6 +445,9 @@ protected:
|
|||
PRBool aSavePresentation,
|
||||
PRBool *aRestored);
|
||||
|
||||
// Call BeginRestore(nsnull, PR_FALSE) for each child of this shell.
|
||||
nsresult BeginRestoreChildren();
|
||||
|
||||
protected:
|
||||
// Override the parent setter from nsDocLoader
|
||||
virtual nsresult SetDocLoaderParent(nsDocLoader * aLoader);
|
||||
|
|
|
@ -66,7 +66,7 @@ interface nsISHEntry;
|
|||
interface nsILayoutHistoryState;
|
||||
interface nsISecureBrowserUI;
|
||||
|
||||
[scriptable, uuid(1c9bcef6-98ef-4a3e-9df2-beda50fce980)]
|
||||
[scriptable, uuid(cfe93f8d-bd92-4e77-a9b7-c37296fe0986)]
|
||||
interface nsIDocShell : nsISupports
|
||||
{
|
||||
/**
|
||||
|
@ -366,12 +366,14 @@ interface nsIDocShell : nsISupports
|
|||
|
||||
/**
|
||||
* Begin firing WebProgressListener notifications and DOM events for
|
||||
* restoring a page presentation. |top| should be true for the toplevel
|
||||
* docshell that is being restored; it will be set to false when this method
|
||||
* is called for child docshells. This method will post an event to call
|
||||
* finishRestore() after returning to the event loop.
|
||||
* restoring a page presentation. |viewer| is the content viewer whose
|
||||
* document we are starting to load. If null, it defaults to the docshell's
|
||||
* current content viewer, creating one if necessary. |top| should be true
|
||||
* for the toplevel docshell that is being restored; it will be set to false
|
||||
* when this method is called for child docshells. This method will post an
|
||||
* event to call finishRestore() after returning to the event loop.
|
||||
*/
|
||||
void beginRestore(in boolean top);
|
||||
void beginRestore(in nsIContentViewer viewer, in boolean top);
|
||||
|
||||
/**
|
||||
* Finish firing WebProgressListener notifications and DOM events for
|
||||
|
|
Загрузка…
Ссылка в новой задаче