Bug 1375833 - Part 2: Set mHistoryID to aSHEntry->DocshellID() in both reload and history navigation. r?smaug draft
authorSamael Wang <freesamael@gmail.com>
Fri, 11 Aug 2017 14:49:09 +0800
changeset 645844 0b5fa59ef4b1a8ce4bc27ef1687ef1adbe83457a
parent 645843 f61e349010e39b9a0741ffc68206d59a5237619e
child 645845 2a478b6dbe7285c7bb307a6bcfb774ef756e7f22
child 647204 b4e171efb5be126461be78bdd3d1ae1a916a8dac
push id73909
push userbmo:sawang@mozilla.com
push dateMon, 14 Aug 2017 10:45:52 +0000
reviewerssmaug
bugs1375833, 1326845
milestone57.0a1
Bug 1375833 - Part 2: Set mHistoryID to aSHEntry->DocshellID() in both reload and history navigation. r?smaug The root cause of bug 1326845 is that reloading would apply frame history entries without setting new child docshells' mHistoryID to the entrys' DocshellID. So SHistory can not find corresponding entries for subframes in a consequent GoBack(), and cause history navigation being broken (it would return NS_ERROR_FAILURE). MozReview-Commit-ID: 6syGYkoP1eZ
docshell/base/nsDocShell.cpp
docshell/base/nsDocShell.h
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -9914,18 +9914,19 @@ nsDocShell::InternalLoad(nsIURI* aURI,
       // an iframe since that's more common.
       contentType = nsIContentPolicy::TYPE_INTERNAL_IFRAME;
     }
   } else {
     contentType = nsIContentPolicy::TYPE_DOCUMENT;
     isTargetTopLevelDocShell = true;
   }
 
-  // If there's no targetDocShell, that means we are about to create a new window,
-  // perform a content policy check before creating the window.
+  // If there's no targetDocShell, that means we are about to create a new
+  // window (or aWindowTarget is empty). Perform a content policy check before
+  // creating the window.
   if (!targetDocShell) {
     nsCOMPtr<Element> requestingElement;
     nsISupports* requestingContext = nullptr;
 
     if (contentType == nsIContentPolicy::TYPE_DOCUMENT) {
       if (XRE_IsContentProcess()) {
         // In e10s the child process doesn't have access to the element that
         // contains the browsing context (because that element is in the chrome
@@ -10727,26 +10728,27 @@ nsDocShell::InternalLoad(nsIURI* aURI,
 
   mLoadType = aLoadType;
 
   // mLSHE should be assigned to aSHEntry, only after Stop() has
   // been called. But when loading an error page, do not clear the
   // mLSHE for the real page.
   if (mLoadType != LOAD_ERROR_PAGE) {
     SetHistoryEntry(&mLSHE, aSHEntry);
+    if (aSHEntry) {
+      // We're making history navigation or a reload. Make sure our history ID
+      // points to the same ID as SHEntry's docshell ID.
+      mHistoryID = aSHEntry->DocshellID();
+    }
   }
 
   mSavingOldViewer = savePresentation;
 
   // If we have a saved content viewer in history, restore and show it now.
   if (aSHEntry && (mLoadType & LOAD_CMD_HISTORY)) {
-    // Make sure our history ID points to the same ID as
-    // SHEntry's docshell ID.
-    mHistoryID = aSHEntry->DocshellID();
-
     // It's possible that the previous viewer of mContentViewer is the
     // viewer that will end up in aSHEntry when it gets closed.  If that's
     // the case, we need to go ahead and force it into its shentry so we
     // can restore it.
     if (mContentViewer) {
       nsCOMPtr<nsIContentViewer> prevViewer;
       mContentViewer->GetPreviousViewer(getter_AddRefs(prevViewer));
       if (prevViewer) {
--- a/docshell/base/nsDocShell.h
+++ b/docshell/base/nsDocShell.h
@@ -920,17 +920,18 @@ protected:
   int32_t mMarginWidth;
   int32_t mMarginHeight;
 
   // This can either be a content docshell or a chrome docshell. After
   // Create() is called, the type is not expected to change.
   int32_t mItemType;
 
   // Index into the SHTransaction list, indicating the previous and current
-  // transaction at the time that this DocShell begins to load
+  // transaction at the time that this DocShell begins to load. Consequently
+  // root docshell's indices can differ from child docshells'.
   int32_t mPreviousTransIndex;
   int32_t mLoadedTransIndex;
 
   uint32_t mSandboxFlags;
   nsWeakPtr mOnePermittedSandboxedNavigator;
 
   // The orientation lock as described by
   // https://w3c.github.io/screen-orientation/