Bug 514232, r=bzbarsky
authorHonza Bambas <honzab.moz@firemni.cz>
Wed, 11 Nov 2009 23:15:05 +0100
changeset 32876 8467ea52b569237f2e545a91d1491c0498f2e1f5
parent 32875 3fe53fb62d4308f930c4e4462e4fbff0b8efe82e
child 32877 da88c8220c15f8c318a628e9c0564a6ed0fc4fc8
push id656
push userhonzab.moz@firemni.cz
push dateWed, 11 Nov 2009 22:15:30 +0000
reviewersbzbarsky
bugs514232
milestone1.9.2b3pre
Bug 514232, r=bzbarsky
docshell/base/nsDocShell.cpp
docshell/base/nsDocShell.h
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -3790,24 +3790,20 @@ nsDocShell::LoadErrorPage(nsIURI *aURI, 
         else
             chanName.AssignLiteral("<no channel>");
 
         PR_LOG(gDocShellLog, PR_LOG_DEBUG,
                ("nsDocShell[%p]::LoadErrorPage(\"%s\", \"%s\", {...}, [%s])\n", this,
                 spec.get(), NS_ConvertUTF16toUTF8(aURL).get(), chanName.get()));
     }
 #endif
-    // Create an shistory entry for the old load, if we have a channel
-    if (aFailedChannel) {
-        mURIResultedInDocument = PR_TRUE;
-        OnLoadingSite(aFailedChannel, PR_TRUE, PR_FALSE);
-    } else if (aURI) {
-        mURIResultedInDocument = PR_TRUE;
-        OnNewURI(aURI, nsnull, nsnull, mLoadType, PR_TRUE, PR_FALSE);
-    }
+    mFailedChannel = aFailedChannel;
+    mFailedURI = aURI;
+    mFailedLoadType = mLoadType;
+
     // Be sure to have a correct mLSHE, it may have been cleared by
     // EndPageLoad. See bug 302115.
     if (mSessionHistory && !mLSHE) {
         PRInt32 idx;
         mSessionHistory->GetRequestedIndex(&idx);
         if (idx == -1)
             mSessionHistory->GetIndex(&idx);
 
@@ -3816,19 +3812,16 @@ nsDocShell::LoadErrorPage(nsIURI *aURI, 
                                          getter_AddRefs(entry));
         mLSHE = do_QueryInterface(entry);
     }
 
     nsCAutoString url;
     nsCAutoString charset;
     if (aURI)
     {
-        // Set our current URI
-        SetCurrentURI(aURI);
-
         nsresult rv = aURI->GetSpec(url);
         rv |= aURI->GetOriginCharset(charset);
         NS_ENSURE_SUCCESS(rv, rv);
     }
     else if (aURL)
     {
         CopyUTF16toUTF8(aURL, url);
     }
@@ -3947,20 +3940,25 @@ nsDocShell::Reload(PRUint32 aReloadFlags
 }
 
 NS_IMETHODIMP
 nsDocShell::Stop(PRUint32 aStopFlags)
 {
     // Revoke any pending event related to content viewer restoration
     mRestorePresentationEvent.Revoke();
 
-    if (mLoadType == LOAD_ERROR_PAGE && mLSHE) {
-        // Since error page loads never unset mLSHE, do so now
-        SetHistoryEntry(&mOSHE, mLSHE);
-        SetHistoryEntry(&mLSHE, nsnull);
+    if (mLoadType == LOAD_ERROR_PAGE) {
+        if (mLSHE) {
+            // Since error page loads never unset mLSHE, do so now
+            SetHistoryEntry(&mOSHE, mLSHE);
+            SetHistoryEntry(&mLSHE, nsnull);
+        }
+
+        mFailedChannel = nsnull;
+        mFailedURI = nsnull;
     }
 
     if (nsIWebNavigation::STOP_CONTENT & aStopFlags) {
         // Stop the document loading
         if (mContentViewer)
             mContentViewer->Stop();
     }
 
@@ -7008,16 +7006,45 @@ nsDocShell::CreateContentViewer(const ch
     // *new* document will fire.
     mFiredUnloadEvent = PR_FALSE;
 
     // we've created a new document so go ahead and call
     // OnLoadingSite(), but don't fire OnLocationChange()
     // notifications before we've called Embed(). See bug 284993.
     mURIResultedInDocument = PR_TRUE;
 
+    if (mLoadType == LOAD_ERROR_PAGE) {
+        // We need to set the SH entry and our current URI here and not
+        // at the moment we load the page. We want the same behavior 
+        // of Stop() as for a normal page load. See bug 514232 for details.
+
+        // Revert mLoadType to load type to state the page load failed,
+        // following function calls need it.
+        mLoadType = mFailedLoadType;
+
+        nsCOMPtr<nsIChannel> failedChannel = mFailedChannel;
+        nsCOMPtr<nsIURI> failedURI = mFailedURI;
+        mFailedChannel = nsnull;
+        mFailedURI = nsnull;
+
+        // Create an shistory entry for the old load, if we have a channel
+        if (failedChannel) {
+            mURIResultedInDocument = PR_TRUE;
+            OnLoadingSite(failedChannel, PR_TRUE, PR_FALSE);
+        } else if (failedURI) {
+            mURIResultedInDocument = PR_TRUE;
+            OnNewURI(failedURI, nsnull, nsnull, mLoadType, PR_TRUE, PR_FALSE);
+        }
+
+        // Set our current URI
+        SetCurrentURI(failedURI);
+
+        mLoadType = LOAD_ERROR_PAGE;
+    }
+
     PRBool onLocationChangeNeeded = OnLoadingSite(aOpenedChannel, PR_FALSE);
 
     // let's try resetting the load group if we need to...
     nsCOMPtr<nsILoadGroup> currentLoadGroup;
     NS_ENSURE_SUCCESS(aOpenedChannel->
                       GetLoadGroup(getter_AddRefs(currentLoadGroup)),
                       NS_ERROR_FAILURE);
 
--- a/docshell/base/nsDocShell.h
+++ b/docshell/base/nsDocShell.h
@@ -692,16 +692,23 @@ protected:
 
     // The URI we're currently loading.  This is only relevant during the
     // firing of a pagehide/unload.  The caller of FirePageHideNotification()
     // is responsible for setting it and unsetting it.  It may be null if the
     // pagehide/unload is happening for some reason other than just loading a
     // new URI.
     nsCOMPtr<nsIURI>           mLoadingURI;
 
+    // Set in LoadErrorPage from the method argument and used later
+    // in CreateContentViewer. We have to delay an shistory entry creation
+    // for which these objects are needed.
+    nsCOMPtr<nsIURI>           mFailedURI;
+    nsCOMPtr<nsIChannel>       mFailedChannel;
+    PRUint32                   mFailedLoadType;
+
     // WEAK REFERENCES BELOW HERE.
     // Note these are intentionally not addrefd.  Doing so will create a cycle.
     // For that reasons don't use nsCOMPtr.
 
     nsIDocShellTreeOwner *     mTreeOwner; // Weak Reference
     nsPIDOMEventTarget *       mChromeEventHandler; //Weak Reference
 
     eCharsetReloadState        mCharsetReloadState;