Bug 1211269 - Store the information whether the channel is LOAD_REPLACE into history entry. r=bz ba=lizzard, a=lizzard
authorDragana Damjanovic <dd.mozilla@gmail.com>
Mon, 05 Oct 2015 12:33:00 +0200
changeset 296694 23d25d9a94d7
parent 296693 8b8a66145292
child 296695 d8c7509ddad0
push id5293
push usercbook@mozilla.com
push date2015-11-11 10:29 +0000
treeherdermozilla-beta@d8c7509ddad0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz, lizzard
bugs1211269
milestone43.0
Bug 1211269 - Store the information whether the channel is LOAD_REPLACE into history entry. r=bz ba=lizzard, a=lizzard
docshell/base/nsDocShell.cpp
docshell/base/nsDocShell.h
docshell/base/nsDocShellLoadInfo.cpp
docshell/base/nsDocShellLoadInfo.h
docshell/base/nsIDocShell.idl
docshell/base/nsIDocShellLoadInfo.idl
docshell/shistory/nsISHEntry.idl
docshell/shistory/nsSHEntry.cpp
docshell/shistory/nsSHEntry.h
docshell/shistory/nsSHistory.cpp
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -1262,16 +1262,17 @@ nsDocShell::LoadURI(nsIURI* aURI,
   }
 
   if (DoAppRedirectIfNeeded(aURI, aLoadInfo, aFirstParty)) {
     return NS_OK;
   }
 
   nsCOMPtr<nsIURI> referrer;
   nsCOMPtr<nsIURI> originalURI;
+  bool loadReplace = false;
   nsCOMPtr<nsIInputStream> postStream;
   nsCOMPtr<nsIInputStream> headersStream;
   nsCOMPtr<nsISupports> owner;
   bool inheritOwner = false;
   bool ownerIsExplicit = false;
   bool sendReferrer = true;
   uint32_t referrerPolicy = mozilla::net::RP_Default;
   bool isSrcdoc = false;
@@ -1289,17 +1290,17 @@ nsDocShell::LoadURI(nsIURI* aURI,
       mItemType == typeContent && !NS_IsAboutBlank(aURI)) {
     StartupTimeline::RecordOnce(StartupTimeline::FIRST_LOAD_URI);
   }
 
   // Extract the info from the DocShellLoadInfo struct...
   if (aLoadInfo) {
     aLoadInfo->GetReferrer(getter_AddRefs(referrer));
     aLoadInfo->GetOriginalURI(getter_AddRefs(originalURI));
-
+    aLoadInfo->GetLoadReplace(&loadReplace);
     nsDocShellInfoLoadType lt = nsIDocShellLoadInfo::loadNormal;
     aLoadInfo->GetLoadType(&lt);
     // Get the appropriate loadType from nsIDocShellLoadInfo type
     loadType = ConvertDocShellLoadInfoToLoadType(lt);
 
     aLoadInfo->GetOwner(getter_AddRefs(owner));
     aLoadInfo->GetInheritOwner(&inheritOwner);
     aLoadInfo->GetOwnerIsExplicit(&ownerIsExplicit);
@@ -1544,16 +1545,17 @@ nsDocShell::LoadURI(nsIURI* aURI,
   }
 
   if (isSrcdoc) {
     flags |= INTERNAL_LOAD_FLAGS_IS_SRCDOC;
   }
 
   return InternalLoad(aURI,
                       originalURI,
+                      loadReplace,
                       referrer,
                       referrerPolicy,
                       owner,
                       flags,
                       target.get(),
                       nullptr,      // No type hint
                       NullString(), // No forced download
                       postStream,
@@ -5209,17 +5211,18 @@ nsDocShell::LoadErrorPage(nsIURI* aURI, 
   // end of the URL, so append it last.
   errorPageUrl.AppendLiteral("&d=");
   errorPageUrl.AppendASCII(escapedDescription.get());
 
   nsCOMPtr<nsIURI> errorPageURI;
   rv = NS_NewURI(getter_AddRefs(errorPageURI), errorPageUrl);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  return InternalLoad(errorPageURI, nullptr, nullptr, mozilla::net::RP_Default,
+  return InternalLoad(errorPageURI, nullptr, false, nullptr,
+                      mozilla::net::RP_Default,
                       nullptr, INTERNAL_LOAD_FLAGS_INHERIT_OWNER, nullptr,
                       nullptr, NullString(), nullptr, nullptr, LOAD_ERROR_PAGE,
                       nullptr, true, NullString(), this, nullptr, nullptr,
                       nullptr);
 }
 
 NS_IMETHODIMP
 nsDocShell::Reload(uint32_t aReloadFlags)
@@ -5260,36 +5263,41 @@ nsDocShell::Reload(uint32_t aReloadFlags
 
     // Do not inherit owner from document
     uint32_t flags = INTERNAL_LOAD_FLAGS_NONE;
     nsAutoString srcdoc;
     nsIPrincipal* principal = nullptr;
     nsAutoString contentTypeHint;
     nsCOMPtr<nsIURI> baseURI;
     nsCOMPtr<nsIURI> originalURI;
+    bool loadReplace = false;
     if (doc) {
       principal = doc->NodePrincipal();
       doc->GetContentType(contentTypeHint);
 
       if (doc->IsSrcdocDocument()) {
         doc->GetSrcdocData(srcdoc);
         flags |= INTERNAL_LOAD_FLAGS_IS_SRCDOC;
         baseURI = doc->GetBaseURI();
       }
       nsCOMPtr<nsIChannel> chan = doc->GetChannel();
       if (chan) {
+        uint32_t loadFlags;
+        chan->GetLoadFlags(&loadFlags);
+        loadReplace = loadFlags & nsIChannel::LOAD_REPLACE;
         nsCOMPtr<nsIHttpChannel> httpChan(do_QueryInterface(chan));
         if (httpChan) {
           httpChan->GetOriginalURI(getter_AddRefs(originalURI));
         }
-      } 
+      }
     }
 
     rv = InternalLoad(mCurrentURI,
                       originalURI,
+                      loadReplace,
                       mReferrerURI,
                       mReferrerPolicy,
                       principal,
                       flags,
                       nullptr,         // No window target
                       NS_LossyConvertUTF16toASCII(contentTypeHint).get(),
                       NullString(),    // No forced download
                       nullptr,         // No post data
@@ -9312,28 +9320,30 @@ nsDocShell::CopyFavicon(nsIURI* aOldURI,
     favSvc->GetFaviconURLForPage(aOldURI, callback);
   }
 #endif
 }
 
 class InternalLoadEvent : public nsRunnable
 {
 public:
-  InternalLoadEvent(nsDocShell* aDocShell, nsIURI* aURI, nsIURI* aOriginalURI,
+  InternalLoadEvent(nsDocShell* aDocShell, nsIURI* aURI,
+                    nsIURI* aOriginalURI, bool aLoadReplace,
                     nsIURI* aReferrer, uint32_t aReferrerPolicy,
                     nsISupports* aOwner, uint32_t aFlags,
                     const char* aTypeHint, nsIInputStream* aPostData,
                     nsIInputStream* aHeadersData, uint32_t aLoadType,
                     nsISHEntry* aSHEntry, bool aFirstParty,
                     const nsAString& aSrcdoc, nsIDocShell* aSourceDocShell,
                     nsIURI* aBaseURI)
     : mSrcdoc(aSrcdoc)
     , mDocShell(aDocShell)
     , mURI(aURI)
     , mOriginalURI(aOriginalURI)
+    , mLoadReplace(aLoadReplace)
     , mReferrer(aReferrer)
     , mReferrerPolicy(aReferrerPolicy)
     , mOwner(aOwner)
     , mPostData(aPostData)
     , mHeadersData(aHeadersData)
     , mSHEntry(aSHEntry)
     , mFlags(aFlags)
     , mLoadType(aLoadType)
@@ -9346,16 +9356,17 @@ public:
       mTypeHint = aTypeHint;
     }
   }
 
   NS_IMETHOD
   Run()
   {
     return mDocShell->InternalLoad(mURI, mOriginalURI,
+                                   mLoadReplace,
                                    mReferrer,
                                    mReferrerPolicy,
                                    mOwner, mFlags,
                                    nullptr, mTypeHint.get(),
                                    NullString(), mPostData, mHeadersData,
                                    mLoadType, mSHEntry, mFirstParty,
                                    mSrcdoc, mSourceDocShell, mBaseURI,
                                    nullptr, nullptr);
@@ -9365,16 +9376,17 @@ private:
   // Use IDL strings so .get() returns null by default
   nsXPIDLString mWindowTarget;
   nsXPIDLCString mTypeHint;
   nsString mSrcdoc;
 
   nsRefPtr<nsDocShell> mDocShell;
   nsCOMPtr<nsIURI> mURI;
   nsCOMPtr<nsIURI> mOriginalURI;
+  bool mLoadReplace;
   nsCOMPtr<nsIURI> mReferrer;
   uint32_t mReferrerPolicy;
   nsCOMPtr<nsISupports> mOwner;
   nsCOMPtr<nsIInputStream> mPostData;
   nsCOMPtr<nsIInputStream> mHeadersData;
   nsCOMPtr<nsISHEntry> mSHEntry;
   uint32_t mFlags;
   uint32_t mLoadType;
@@ -9419,16 +9431,17 @@ nsDocShell::CreatePrincipalFromReferrer(
   prin.forget(aResult);
 
   return *aResult ? NS_OK : NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
 nsDocShell::InternalLoad(nsIURI* aURI,
                          nsIURI* aOriginalURI,
+                         bool aLoadReplace,
                          nsIURI* aReferrer,
                          uint32_t aReferrerPolicy,
                          nsISupports* aOwner,
                          uint32_t aFlags,
                          const char16_t* aWindowTarget,
                          const char* aTypeHint,
                          const nsAString& aFileName,
                          nsIInputStream* aPostData,
@@ -9681,16 +9694,17 @@ nsDocShell::InternalLoad(nsIURI* aURI,
 
     //
     // Transfer the load to the target DocShell...  Pass nullptr as the
     // window target name from to prevent recursive retargeting!
     //
     if (NS_SUCCEEDED(rv) && targetDocShell) {
       rv = targetDocShell->InternalLoad(aURI,
                                         aOriginalURI,
+                                        aLoadReplace,
                                         aReferrer,
                                         aReferrerPolicy,
                                         owner,
                                         aFlags,
                                         nullptr,         // No window target
                                         aTypeHint,
                                         NullString(),    // No forced download
                                         aPostData,
@@ -9762,18 +9776,18 @@ nsDocShell::InternalLoad(nsIURI* aURI,
       // the unload event also a replace load, so we don't
       // create extra history entries.
       if (LOAD_TYPE_HAS_FLAGS(aLoadType, LOAD_FLAGS_REPLACE_HISTORY)) {
         mLoadType = LOAD_NORMAL_REPLACE;
       }
 
       // Do this asynchronously
       nsCOMPtr<nsIRunnable> ev =
-        new InternalLoadEvent(this, aURI, aOriginalURI, aReferrer,
-                              aReferrerPolicy, aOwner, aFlags,
+        new InternalLoadEvent(this, aURI, aOriginalURI, aLoadReplace,
+                              aReferrer, aReferrerPolicy, aOwner, aFlags,
                               aTypeHint, aPostData, aHeadersData,
                               aLoadType, aSHEntry, aFirstParty, aSrcdoc,
                               aSourceDocShell, aBaseURI);
       return NS_DispatchToCurrentThread(ev);
     }
 
     // Just ignore this load attempt
     return NS_OK;
@@ -10243,17 +10257,17 @@ nsDocShell::InternalLoad(nsIURI* aURI,
   }
 
   net::PredictorLearn(aURI, nullptr,
                       nsINetworkPredictor::LEARN_LOAD_TOPLEVEL, this);
   net::PredictorPredict(aURI, nullptr,
                         nsINetworkPredictor::PREDICT_LOAD, this, nullptr);
 
   nsCOMPtr<nsIRequest> req;
-  rv = DoURILoad(aURI, aOriginalURI, aReferrer,
+  rv = DoURILoad(aURI, aOriginalURI, aLoadReplace, aReferrer,
                  !(aFlags & INTERNAL_LOAD_FLAGS_DONT_SEND_REFERRER),
                  aReferrerPolicy,
                  owner, aTypeHint, aFileName, aPostData, aHeadersData,
                  aFirstParty, aDocShell, getter_AddRefs(req),
                  (aFlags & INTERNAL_LOAD_FLAGS_FIRST_LOAD) != 0,
                  (aFlags & INTERNAL_LOAD_FLAGS_BYPASS_CLASSIFIER) != 0,
                  (aFlags & INTERNAL_LOAD_FLAGS_FORCE_ALLOW_COOKIES) != 0,
                  srcdoc, aBaseURI, contentType);
@@ -10318,16 +10332,17 @@ nsDocShell::GetInheritedPrincipal(bool a
   }
 
   return nullptr;
 }
 
 nsresult
 nsDocShell::DoURILoad(nsIURI* aURI,
                       nsIURI* aOriginalURI,
+                      bool aLoadReplace,
                       nsIURI* aReferrerURI,
                       bool aSendReferrer,
                       uint32_t aReferrerPolicy,
                       nsISupports* aOwner,
                       const char* aTypeHint,
                       const nsAString& aFileName,
                       nsIInputStream* aPostData,
                       nsIInputStream* aHeadersData,
@@ -10554,16 +10569,22 @@ nsDocShell::DoURILoad(nsIURI* aURI,
   // Make sure to give the caller a channel if we managed to create one
   // This is important for correct error page/session history interaction
   if (aRequest) {
     NS_ADDREF(*aRequest = channel);
   }
 
   if (aOriginalURI) {
     channel->SetOriginalURI(aOriginalURI);
+    if (aLoadReplace) {
+      uint32_t loadFlags;
+      channel->GetLoadFlags(&loadFlags);
+      NS_ENSURE_SUCCESS(rv, rv);
+      channel->SetLoadFlags(loadFlags | nsIChannel::LOAD_REPLACE);
+    }
   } else {
     channel->SetOriginalURI(aURI);
   }
 
   if (aTypeHint && *aTypeHint) {
     channel->SetContentType(nsDependentCString(aTypeHint));
     mContentTypeHint = aTypeHint;
   } else {
@@ -11534,16 +11555,17 @@ nsDocShell::AddState(JS::Handle<JS::Valu
     // AddToSessionHistory may not modify mOSHE.  In case it doesn't,
     // we'll just set mOSHE here.
     mOSHE = newSHEntry;
 
   } else {
     newSHEntry = mOSHE;
     newSHEntry->SetURI(newURI);
     newSHEntry->SetOriginalURI(newURI);
+    newSHEntry->SetLoadReplace(false);
   }
 
   // Step 4: Modify new/original session history entry and clear its POST
   // data, if there is any.
   newSHEntry->SetStateData(scContainer);
   newSHEntry->SetPostData(nullptr);
 
   // If this push/replaceState changed the document's current URI and the new
@@ -11718,16 +11740,17 @@ nsDocShell::AddToSessionHistory(nsIURI* 
     if (!entry) {
       return NS_ERROR_OUT_OF_MEMORY;
     }
   }
 
   // Get the post data & referrer
   nsCOMPtr<nsIInputStream> inputStream;
   nsCOMPtr<nsIURI> originalURI;
+  bool loadReplace = false;
   nsCOMPtr<nsIURI> referrerURI;
   uint32_t referrerPolicy = mozilla::net::RP_Default;
   nsCOMPtr<nsISupports> cacheKey;
   nsCOMPtr<nsISupports> owner = aOwner;
   bool expired = false;
   bool discardLayoutState = false;
   nsCOMPtr<nsICacheInfoChannel> cacheChannel;
   if (aChannel) {
@@ -11746,16 +11769,19 @@ nsDocShell::AddToSessionHistory(nsIURI* 
       GetHttpChannel(aChannel, getter_AddRefs(httpChannel));
     }
     if (httpChannel) {
       nsCOMPtr<nsIUploadChannel> uploadChannel(do_QueryInterface(httpChannel));
       if (uploadChannel) {
         uploadChannel->GetUploadStream(getter_AddRefs(inputStream));
       }
       httpChannel->GetOriginalURI(getter_AddRefs(originalURI));
+      uint32_t loadFlags;
+      aChannel->GetLoadFlags(&loadFlags);
+      loadReplace = loadFlags & nsIChannel::LOAD_REPLACE;
       httpChannel->GetReferrer(getter_AddRefs(referrerURI));
       httpChannel->GetReferrerPolicy(&referrerPolicy);
 
       discardLayoutState = ShouldDiscardLayoutState(httpChannel);
     }
     aChannel->GetOwner(getter_AddRefs(owner));
     if (!owner) {
       nsCOMPtr<nsILoadInfo> loadInfo;
@@ -11780,16 +11806,17 @@ nsDocShell::AddToSessionHistory(nsIURI* 
                 nullptr,           // LayoutHistory state
                 cacheKey,          // CacheKey
                 mContentTypeHint,  // Content-type
                 owner,             // Channel or provided owner
                 mHistoryID,
                 mDynamicallyCreated);
 
   entry->SetOriginalURI(originalURI);
+  entry->SetLoadReplace(loadReplace);
   entry->SetReferrerURI(referrerURI);
   entry->SetReferrerPolicy(referrerPolicy);
   nsCOMPtr<nsIInputStreamChannel> inStrmChan = do_QueryInterface(aChannel);
   if (inStrmChan) {
     bool isSrcdocChannel;
     inStrmChan->GetIsSrcdocChannel(&isSrcdocChannel);
     if (isSrcdocChannel) {
       nsAutoString srcdoc;
@@ -11881,27 +11908,30 @@ nsresult
 nsDocShell::LoadHistoryEntry(nsISHEntry* aEntry, uint32_t aLoadType)
 {
   if (!IsNavigationAllowed()) {
     return NS_OK;
   }
 
   nsCOMPtr<nsIURI> uri;
   nsCOMPtr<nsIURI> originalURI;
+  bool loadReplace = false;
   nsCOMPtr<nsIInputStream> postData;
   nsCOMPtr<nsIURI> referrerURI;
   uint32_t referrerPolicy;
   nsAutoCString contentType;
   nsCOMPtr<nsISupports> owner;
 
   NS_ENSURE_TRUE(aEntry, NS_ERROR_FAILURE);
 
   NS_ENSURE_SUCCESS(aEntry->GetURI(getter_AddRefs(uri)), NS_ERROR_FAILURE);
   NS_ENSURE_SUCCESS(aEntry->GetOriginalURI(getter_AddRefs(originalURI)),
                     NS_ERROR_FAILURE);
+  NS_ENSURE_SUCCESS(aEntry->GetLoadReplace(&loadReplace),
+                    NS_ERROR_FAILURE);
   NS_ENSURE_SUCCESS(aEntry->GetReferrerURI(getter_AddRefs(referrerURI)),
                     NS_ERROR_FAILURE);
   NS_ENSURE_SUCCESS(aEntry->GetReferrerPolicy(&referrerPolicy),
                     NS_ERROR_FAILURE);
   NS_ENSURE_SUCCESS(aEntry->GetPostData(getter_AddRefs(postData)),
                     NS_ERROR_FAILURE);
   NS_ENSURE_SUCCESS(aEntry->GetContentType(contentType), NS_ERROR_FAILURE);
   NS_ENSURE_SUCCESS(aEntry->GetOwner(getter_AddRefs(owner)), NS_ERROR_FAILURE);
@@ -11973,16 +12003,17 @@ nsDocShell::LoadHistoryEntry(nsISHEntry*
   }
 
   // Passing nullptr as aSourceDocShell gives the same behaviour as before
   // aSourceDocShell was introduced. According to spec we should be passing
   // the source browsing context that was used when the history entry was
   // first created. bug 947716 has been created to address this issue.
   rv = InternalLoad(uri,
                     originalURI,
+                    loadReplace,
                     referrerURI,
                     referrerPolicy,
                     owner,
                     flags,
                     nullptr,            // No window target
                     contentType.get(),  // Type hint
                     NullString(),       // No forced file download
                     postData,           // Post data stream
@@ -13432,16 +13463,17 @@ nsDocShell::OnLinkClickSync(nsIContent* 
   nsCOMPtr<nsIURI> clonedURI;
   aURI->Clone(getter_AddRefs(clonedURI));
   if (!clonedURI) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   nsresult rv = InternalLoad(clonedURI,                 // New URI
                              nullptr,                   // Original URI
+                             false,                     // LoadReplace
                              referer,                   // Referer URI
                              refererPolicy,             // Referer policy
                              aContent->NodePrincipal(), // Owner is our node's
                                                         // principal
                              flags,
                              target.get(),              // Window target
                              NS_LossyConvertUTF16toASCII(typeHint).get(),
                              aFileName,                 // Download as file
--- a/docshell/base/nsDocShell.h
+++ b/docshell/base/nsDocShell.h
@@ -326,18 +326,20 @@ protected:
 
   // Actually open a channel and perform a URI load. Note: whatever owner is
   // passed to this function will be set on the channel. Callers who wish to
   // not have an owner on the channel should just pass null.
   // If aSrcdoc is not void, the load will be considered as a srcdoc load,
   // and the contents of aSrcdoc will be loaded instead of aURI.
   // aOriginalURI will be set as the originalURI on the channel that does the
   // load. If aOriginalURI is null, aURI will be set as the originalURI.
+  // If aLoadReplace is true, OLOAD_REPLACE flag will be set to the nsIChannel.
   nsresult DoURILoad(nsIURI* aURI,
                      nsIURI* aOriginalURI,
+                     bool aLoadReplace,
                      nsIURI* aReferrer,
                      bool aSendReferrer,
                      uint32_t aReferrerPolicy,
                      nsISupports* aOwner,
                      const char* aTypeHint,
                      const nsAString& aFileName,
                      nsIInputStream* aPostData,
                      nsIInputStream* aHeadersData,
--- a/docshell/base/nsDocShellLoadInfo.cpp
+++ b/docshell/base/nsDocShellLoadInfo.cpp
@@ -63,16 +63,30 @@ nsDocShellLoadInfo::GetOriginalURI(nsIUR
 NS_IMETHODIMP
 nsDocShellLoadInfo::SetOriginalURI(nsIURI* aOriginalURI)
 {
   mOriginalURI = aOriginalURI;
   return NS_OK;
 }
 
 NS_IMETHODIMP
+nsDocShellLoadInfo::GetLoadReplace(bool* aLoadReplace)
+{
+  *aLoadReplace = mLoadReplace;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDocShellLoadInfo::SetLoadReplace(bool aLoadReplace)
+{
+  mLoadReplace = aLoadReplace;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
 nsDocShellLoadInfo::GetOwner(nsISupports** aOwner)
 {
   NS_ENSURE_ARG_POINTER(aOwner);
 
   *aOwner = mOwner;
   NS_IF_ADDREF(*aOwner);
   return NS_OK;
 }
--- a/docshell/base/nsDocShellLoadInfo.h
+++ b/docshell/base/nsDocShellLoadInfo.h
@@ -28,16 +28,17 @@ public:
   NS_DECL_NSIDOCSHELLLOADINFO
 
 protected:
   virtual ~nsDocShellLoadInfo();
 
 protected:
   nsCOMPtr<nsIURI> mReferrer;
   nsCOMPtr<nsIURI> mOriginalURI;
+  bool mLoadReplace;
   nsCOMPtr<nsISupports> mOwner;
   bool mInheritOwner;
   bool mOwnerIsExplicit;
   bool mSendReferrer;
   nsDocShellInfoReferrerPolicy mReferrerPolicy;
   nsDocShellInfoLoadType mLoadType;
   nsCOMPtr<nsISHEntry> mSHEntry;
   nsString mTarget;
--- a/docshell/base/nsIDocShell.idl
+++ b/docshell/base/nsIDocShell.idl
@@ -41,17 +41,17 @@ interface nsIWebBrowserPrint;
 interface nsIVariant;
 interface nsIPrivacyTransitionObserver;
 interface nsIReflowObserver;
 interface nsIScrollObserver;
 interface nsITabParent;
 
 typedef unsigned long nsLoadFlags;
 
-[scriptable, builtinclass, uuid(df834cfd-5073-4053-96e4-4e5a4e508696)]
+[scriptable, builtinclass, uuid(539bce70-8261-462f-bbd0-40ee90b7d636)]
 interface nsIDocShell : nsIDocShellTreeItem
 {
   /**
    * Loads a given URI.  This will give priority to loading the requested URI
    * in the object implementing	this interface.  If it can't be loaded here
    * however, the URL dispatcher will go through its normal process of content
    * loading.
    *
@@ -121,16 +121,19 @@ interface nsIDocShell : nsIDocShellTreeI
    * Loads the given URI.  This method is identical to loadURI(...) except
    * that its parameter list is broken out instead of being packaged inside
    * of an nsIDocShellLoadInfo object...
    *
    * @param aURI            - The URI to load.
    * @param aOriginalURI    - The URI to set as the originalURI on the channel
    *                          that does the load. If null, aURI will be set as
    *                          the originalURI.
+   * @param aLoadReplace    - If set LOAD_REPLACE flag will be set on the
+   *                          channel. aOriginalURI is null, this argument is
+   *                          ignored.
    * @param aReferrer       - Referring URI
    * @param aReferrerPolicy - Referrer policy
    * @param aOwner          - Owner (security principal)
    * @param aInheritOwner   - Flag indicating whether the owner of the current
    *                          document should be inherited if aOwner is null.
    * @param aStopActiveDoc  - Flag indicating whether loading the current
    *                          document should be stopped.
    * @param aWindowTarget   - Window target for the load.
@@ -148,16 +151,17 @@ interface nsIDocShell : nsIDocShellTreeI
    *                          of aURI.
    * @param aSourceDocShell - The source browsing context for the navigation.
    * @param aBaseURI        - The base URI to be used for the load.  Set in
    *                          srcdoc loads as it cannot otherwise be inferred
    *                          in certain situations such as view-source.
    */
   [noscript]void internalLoad(in nsIURI aURI,
                               in nsIURI aOriginalURI,
+                              in boolean aLoadReplace,
                               in nsIURI aReferrer,
                               in unsigned long aReferrerPolicy,
                               in nsISupports aOwner,
                               in uint32_t aFlags,
                               in wstring aWindowTarget,
                               in string aTypeHint,
                               in AString aFileName,
                               in nsIInputStream aPostDataStream,
--- a/docshell/base/nsIDocShellLoadInfo.idl
+++ b/docshell/base/nsIDocShellLoadInfo.idl
@@ -14,27 +14,32 @@
 interface nsIURI;
 interface nsIInputStream;
 interface nsISHEntry;
 interface nsIDocShell;
 
 typedef long nsDocShellInfoLoadType;
 typedef unsigned long nsDocShellInfoReferrerPolicy;
 
-[scriptable, uuid(9d3bc466-5efe-414d-ae8b-3830b45877bb)]
+[scriptable, uuid(e7570e5a-f1d6-452d-b4f8-b35fdc63aa03)]
 interface nsIDocShellLoadInfo : nsISupports
 {
     /** This is the referrer for the load. */
     attribute nsIURI referrer;
 
     /**
      * The originalURI to be passed to nsIDocShell.internalLoad. May be null.
-     */ 
+     */
     attribute nsIURI originalURI;
 
+    /**
+     * loadReplace flag to be passed to nsIDocShell.internalLoad.
+     */
+    attribute boolean loadReplace;
+
     /** The owner of the load, that is, the entity responsible for 
      *  causing the load to occur. This should be a nsIPrincipal typically.
      */
     attribute nsISupports owner;
 
     /** If this attribute is true and no owner is specified, copy
      *  the owner from the referring document.
      */
--- a/docshell/shistory/nsISHEntry.idl
+++ b/docshell/shistory/nsISHEntry.idl
@@ -25,17 +25,17 @@ interface nsIBFCacheEntry;
 #include "nsRect.h"
 class nsDocShellEditorData;
 class nsSHEntryShared;
 %}
 [ref] native nsIntRect(nsIntRect);
 [ptr] native nsDocShellEditorDataPtr(nsDocShellEditorData);
 [ptr] native nsSHEntryShared(nsSHEntryShared);
 
-[scriptable, uuid(e45ab6ef-3485-449c-b91c-0846b2bf6faf)]
+[scriptable, uuid(3a5e5fa0-5364-4fbb-a87a-3f12a6b51903)]
 interface nsISHEntry : nsISupports
 {
     /**
      * A readonly property that returns the URI
      * of the current entry. The object returned is
      * of type nsIURI
      */
     readonly attribute nsIURI URI;
@@ -43,16 +43,21 @@ interface nsISHEntry : nsISupports
     /**
      * A readonly property that returns the original URI of the current entry.
      * If an entry is the result of a redirect this attribute holds original
      * URI. The object returned is of type nsIURI
      */
     attribute nsIURI originalURI;
 
     /**
+     *  This flag remembers whether channel has LOAD_REPLACE set.
+     */
+    attribute boolean loadReplace;
+
+    /**
      * A readonly property that returns the title
      * of the current entry.  The object returned
      * is a encoded string
      */
     readonly attribute wstring title;
 
     /**
      * A readonly property that returns a boolean
--- a/docshell/shistory/nsSHEntry.cpp
+++ b/docshell/shistory/nsSHEntry.cpp
@@ -34,16 +34,17 @@ nsSHEntry::nsSHEntry()
   , mIsSrcdocEntry(false)
 {
 }
 
 nsSHEntry::nsSHEntry(const nsSHEntry& aOther)
   : mShared(aOther.mShared)
   , mURI(aOther.mURI)
   , mOriginalURI(aOther.mOriginalURI)
+  , mLoadReplace(aOther.mLoadReplace)
   , mReferrerURI(aOther.mReferrerURI)
   , mReferrerPolicy(aOther.mReferrerPolicy)
   , mTitle(aOther.mTitle)
   , mPostData(aOther.mPostData)
   , mLoadType(0)         // XXX why not copy?
   , mID(aOther.mID)
   , mScrollPositionX(0)  // XXX why not copy?
   , mScrollPositionY(0)  // XXX why not copy?
@@ -129,16 +130,30 @@ nsSHEntry::GetOriginalURI(nsIURI** aOrig
 NS_IMETHODIMP
 nsSHEntry::SetOriginalURI(nsIURI* aOriginalURI)
 {
   mOriginalURI = aOriginalURI;
   return NS_OK;
 }
 
 NS_IMETHODIMP
+nsSHEntry::GetLoadReplace(bool* aLoadReplace)
+{
+  *aLoadReplace = mLoadReplace;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSHEntry::SetLoadReplace(bool aLoadReplace)
+{
+  mLoadReplace = aLoadReplace;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
 nsSHEntry::GetReferrerURI(nsIURI** aReferrerURI)
 {
   *aReferrerURI = mReferrerURI;
   NS_IF_ADDREF(*aReferrerURI);
   return NS_OK;
 }
 
 NS_IMETHODIMP
--- a/docshell/shistory/nsSHEntry.h
+++ b/docshell/shistory/nsSHEntry.h
@@ -45,16 +45,17 @@ private:
 
   // We share the state in here with other SHEntries which correspond to the
   // same document.
   nsRefPtr<nsSHEntryShared> mShared;
 
   // See nsSHEntry.idl for comments on these members.
   nsCOMPtr<nsIURI> mURI;
   nsCOMPtr<nsIURI> mOriginalURI;
+  bool mLoadReplace;
   nsCOMPtr<nsIURI> mReferrerURI;
   uint32_t mReferrerPolicy;
   nsString mTitle;
   nsCOMPtr<nsIInputStream> mPostData;
   uint32_t mLoadType;
   uint32_t mID;
   int32_t mScrollPositionX;
   int32_t mScrollPositionY;
--- a/docshell/shistory/nsSHistory.cpp
+++ b/docshell/shistory/nsSHistory.cpp
@@ -1770,16 +1770,20 @@ nsSHistory::InitiateLoad(nsISHEntry* aFr
 
   loadInfo->SetLoadType(aLoadType);
   loadInfo->SetSHEntry(aFrameEntry);
 
   nsCOMPtr<nsIURI> originalURI;
   aFrameEntry->GetOriginalURI(getter_AddRefs(originalURI));
   loadInfo->SetOriginalURI(originalURI);
 
+  bool loadReplace;
+  aFrameEntry->GetLoadReplace(&loadReplace);
+  loadInfo->SetLoadReplace(loadReplace);
+
   nsCOMPtr<nsIURI> nextURI;
   aFrameEntry->GetURI(getter_AddRefs(nextURI));
   // Time   to initiate a document load
   return aFrameDS->LoadURI(nextURI, loadInfo,
                            nsIWebNavigation::LOAD_FLAGS_NONE, false);
 
 }