Bug 1513241: Update loadURI interface and pass a loadURIOptions dictionary from frontend to docshell loads. r=bz
authorChristoph Kerschbaumer <ckerschb@christophkerschbaumer.com>
Fri, 11 Jan 2019 12:43:39 +0100
changeset 453414 6ae543902cdaaec070a77dd5f554db6b02fde2b1
parent 453413 2cf71aa80108d6fb25feb576f17c08d2342e94c7
child 453415 71cb45922e3474b96c93cf736299e4e8b2e2db34
push id35355
push userrmaries@mozilla.com
push dateFri, 11 Jan 2019 15:31:02 +0000
treeherdermozilla-central@2a99e348fde3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs1513241
milestone66.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1513241: Update loadURI interface and pass a loadURIOptions dictionary from frontend to docshell loads. r=bz
docshell/base/nsDocShell.cpp
docshell/base/nsDocShellTreeOwner.cpp
docshell/base/nsIWebNavigation.idl
dom/ipc/TabChild.cpp
dom/security/FramingChecker.cpp
dom/webidl/LoadURIOptions.webidl
dom/webidl/moz.build
editor/composer/nsEditingSession.cpp
toolkit/components/browser/nsWebBrowser.cpp
xpfe/appshell/nsWebShellWindow.cpp
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -53,16 +53,17 @@
 #include "mozilla/dom/ScriptSettings.h"
 #include "mozilla/dom/ServiceWorkerInterceptController.h"
 #include "mozilla/dom/ServiceWorkerUtils.h"
 #include "mozilla/dom/SessionStorageManager.h"
 #include "mozilla/dom/TabChild.h"
 #include "mozilla/dom/TabGroup.h"
 #include "mozilla/dom/ToJSValue.h"
 #include "mozilla/dom/ChildSHistory.h"
+#include "mozilla/dom/LoadURIOptionsBinding.h"
 
 #include "mozilla/net/ReferrerPolicy.h"
 
 #include "nsIApplicationCacheChannel.h"
 #include "nsIApplicationCacheContainer.h"
 #include "nsIAppShell.h"
 #include "nsIAsyncVerifyRedirectCallback.h"
 #include "nsIAuthPrompt.h"
@@ -3797,155 +3798,141 @@ nsDocShell::GotoIndex(int32_t aIndex) {
   if (!IsNavigationAllowed()) {
     return NS_OK;  // JS may not handle returning of an error code
   }
   RefPtr<ChildSHistory> rootSH = GetRootSessionHistory();
   NS_ENSURE_TRUE(rootSH, NS_ERROR_FAILURE);
   return rootSH->LegacySHistory()->GotoIndex(aIndex);
 }
 
-NS_IMETHODIMP
-nsDocShell::LoadURI(const nsAString& aURI, uint32_t aLoadFlags,
-                    nsIURI* aReferringURI, nsIInputStream* aPostStream,
-                    nsIInputStream* aHeaderStream,
-                    nsIPrincipal* aTriggeringPrincipal) {
-  if (mUseStrictSecurityChecks && !aTriggeringPrincipal) {
-    return NS_ERROR_FAILURE;
-  }
-  return LoadURIWithOptions(aURI, aLoadFlags, aReferringURI, RP_Unset,
-                            aPostStream, aHeaderStream, nullptr,
-                            aTriggeringPrincipal);
-}
-
-NS_IMETHODIMP
-nsDocShell::LoadURIWithOptions(const nsAString& aURI, uint32_t aLoadFlags,
-                               nsIURI* aReferringURI, uint32_t aReferrerPolicy,
-                               nsIInputStream* aPostStream,
-                               nsIInputStream* aHeaderStream, nsIURI* aBaseURI,
-                               nsIPrincipal* aTriggeringPrincipal) {
-  NS_ASSERTION((aLoadFlags & INTERNAL_LOAD_FLAGS_LOADURI_SETUP_FLAGS) == 0,
+nsresult nsDocShell::LoadURI(const nsAString& aURI,
+                             const LoadURIOptions& aLoadURIOptions) {
+  uint32_t loadFlags = aLoadURIOptions.mLoadFlags;
+
+  NS_ASSERTION((loadFlags & INTERNAL_LOAD_FLAGS_LOADURI_SETUP_FLAGS) == 0,
                "Unexpected flags");
 
   if (!IsNavigationAllowed()) {
     return NS_OK;  // JS may not handle returning of an error code
   }
   nsCOMPtr<nsIURI> uri;
-  nsCOMPtr<nsIInputStream> postStream(aPostStream);
+  nsCOMPtr<nsIInputStream> postData(aLoadURIOptions.mPostData);
   nsresult rv = NS_OK;
 
   // Create a URI from our string; if that succeeds, we want to
-  // change aLoadFlags to not include the ALLOW_THIRD_PARTY_FIXUP
+  // change loadFlags to not include the ALLOW_THIRD_PARTY_FIXUP
   // flag.
 
   NS_ConvertUTF16toUTF8 uriString(aURI);
   // Cleanup the empty spaces that might be on each end.
   uriString.Trim(" ");
   // Eliminate embedded newlines, which single-line text fields now allow:
   uriString.StripCRLF();
   NS_ENSURE_TRUE(!uriString.IsEmpty(), NS_ERROR_FAILURE);
 
-  if (mUseStrictSecurityChecks && !aTriggeringPrincipal) {
+  if (mUseStrictSecurityChecks && !aLoadURIOptions.mTriggeringPrincipal) {
     return NS_ERROR_FAILURE;
   }
 
   rv = NS_NewURI(getter_AddRefs(uri), uriString);
   if (uri) {
-    aLoadFlags &= ~LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP;
+    loadFlags &= ~LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP;
   }
 
   nsCOMPtr<nsIURIFixupInfo> fixupInfo;
   if (sURIFixup) {
     // Call the fixup object.  This will clobber the rv from NS_NewURI
     // above, but that's fine with us.  Note that we need to do this even
     // if NS_NewURI returned a URI, because fixup handles nested URIs, etc
     // (things like view-source:mozilla.org for example).
     uint32_t fixupFlags = 0;
-    if (aLoadFlags & LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP) {
+    if (loadFlags & LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP) {
       fixupFlags |= nsIURIFixup::FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP;
     }
-    if (aLoadFlags & LOAD_FLAGS_FIXUP_SCHEME_TYPOS) {
+    if (loadFlags & LOAD_FLAGS_FIXUP_SCHEME_TYPOS) {
       fixupFlags |= nsIURIFixup::FIXUP_FLAG_FIX_SCHEME_TYPOS;
     }
     nsCOMPtr<nsIInputStream> fixupStream;
     rv = sURIFixup->GetFixupURIInfo(uriString, fixupFlags,
                                     getter_AddRefs(fixupStream),
                                     getter_AddRefs(fixupInfo));
 
     if (NS_SUCCEEDED(rv)) {
       fixupInfo->GetPreferredURI(getter_AddRefs(uri));
       fixupInfo->SetConsumer(GetAsSupports(this));
     }
 
     if (fixupStream) {
       // GetFixupURIInfo only returns a post data stream if it succeeded
       // and changed the URI, in which case we should override the
       // passed-in post data.
-      postStream = fixupStream;
-    }
-
-    if (aLoadFlags & LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP) {
+      postData = fixupStream;
+    }
+
+    if (loadFlags & LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP) {
       nsCOMPtr<nsIObserverService> serv = services::GetObserverService();
       if (serv) {
         serv->NotifyObservers(fixupInfo, "keyword-uri-fixup",
                               PromiseFlatString(aURI).get());
       }
     }
   }
   // else no fixup service so just use the URI we created and see
   // what happens
 
   if (NS_ERROR_MALFORMED_URI == rv) {
     if (DisplayLoadError(rv, uri, PromiseFlatString(aURI).get(), nullptr) &&
-        (aLoadFlags & LOAD_FLAGS_ERROR_LOAD_CHANGES_RV) != 0) {
+        (loadFlags & LOAD_FLAGS_ERROR_LOAD_CHANGES_RV) != 0) {
       return NS_ERROR_LOAD_SHOWED_ERRORPAGE;
     }
   }
 
   if (NS_FAILED(rv) || !uri) {
     return NS_ERROR_FAILURE;
   }
 
   PopupBlocker::PopupControlState popupState;
-  if (aLoadFlags & LOAD_FLAGS_ALLOW_POPUPS) {
+  if (loadFlags & LOAD_FLAGS_ALLOW_POPUPS) {
     popupState = PopupBlocker::openAllowed;
-    aLoadFlags &= ~LOAD_FLAGS_ALLOW_POPUPS;
+    loadFlags &= ~LOAD_FLAGS_ALLOW_POPUPS;
   } else {
     popupState = PopupBlocker::openOverridden;
   }
   nsAutoPopupStatePusher statePusher(popupState);
 
-  bool forceAllowDataURI = aLoadFlags & LOAD_FLAGS_FORCE_ALLOW_DATA_URI;
+  bool forceAllowDataURI = loadFlags & LOAD_FLAGS_FORCE_ALLOW_DATA_URI;
 
   // Don't pass certain flags that aren't needed and end up confusing
   // ConvertLoadTypeToDocShellInfoLoadType.  We do need to ensure that they are
   // passed to LoadURI though, since it uses them.
-  uint32_t extraFlags = (aLoadFlags & EXTRA_LOAD_FLAGS);
-  aLoadFlags &= ~EXTRA_LOAD_FLAGS;
+  uint32_t extraFlags = (loadFlags & EXTRA_LOAD_FLAGS);
+  loadFlags &= ~EXTRA_LOAD_FLAGS;
 
   RefPtr<nsDocShellLoadState> loadState = new nsDocShellLoadState(uri);
 
   /*
    * If the user "Disables Protection on This Page", we have to make sure to
    * remember the users decision when opening links in child tabs [Bug 906190]
    */
-  if (aLoadFlags & LOAD_FLAGS_ALLOW_MIXED_CONTENT) {
+  if (loadFlags & LOAD_FLAGS_ALLOW_MIXED_CONTENT) {
     loadState->SetLoadType(
-        MAKE_LOAD_TYPE(LOAD_NORMAL_ALLOW_MIXED_CONTENT, aLoadFlags));
+        MAKE_LOAD_TYPE(LOAD_NORMAL_ALLOW_MIXED_CONTENT, loadFlags));
   } else {
-    loadState->SetLoadType(MAKE_LOAD_TYPE(LOAD_NORMAL, aLoadFlags));
+    loadState->SetLoadType(MAKE_LOAD_TYPE(LOAD_NORMAL, loadFlags));
   }
 
   loadState->SetLoadFlags(extraFlags);
   loadState->SetFirstParty(true);
-  loadState->SetPostDataStream(postStream);
-  loadState->SetReferrer(aReferringURI);
-  loadState->SetReferrerPolicy((mozilla::net::ReferrerPolicy)aReferrerPolicy);
-  loadState->SetHeadersStream(aHeaderStream);
-  loadState->SetBaseURI(aBaseURI);
-  loadState->SetTriggeringPrincipal(aTriggeringPrincipal);
+  loadState->SetPostDataStream(postData);
+  loadState->SetReferrer(aLoadURIOptions.mReferrerURI);
+  loadState->SetReferrerPolicy(
+      (mozilla::net::ReferrerPolicy)aLoadURIOptions.mReferrerPolicy);
+  loadState->SetHeadersStream(aLoadURIOptions.mHeaders);
+  loadState->SetBaseURI(aLoadURIOptions.mBaseURI);
+  loadState->SetTriggeringPrincipal(aLoadURIOptions.mTriggeringPrincipal);
   loadState->SetForceAllowDataURI(forceAllowDataURI);
 
   if (fixupInfo) {
     nsAutoString searchProvider, keyword;
     fixupInfo->GetKeywordProviderName(searchProvider);
     fixupInfo->GetKeywordAsSent(keyword);
     MaybeNotifyKeywordSearchLoading(searchProvider, keyword);
   }
@@ -3955,16 +3942,28 @@ nsDocShell::LoadURIWithOptions(const nsA
   // Save URI string in case it's needed later when
   // sending to search engine service in EndPageLoad()
   mOriginalUriString = uriString;
 
   return rv;
 }
 
 NS_IMETHODIMP
+nsDocShell::LoadURIFromScript(const nsAString& aURI,
+                              JS::Handle<JS::Value> aLoadURIOptions,
+                              JSContext* aCx) {
+  // generate dictionary for aLoadURIOptions and forward call
+  LoadURIOptions loadURIOptions;
+  if (!loadURIOptions.Init(aCx, aLoadURIOptions)) {
+    return NS_ERROR_INVALID_ARG;
+  }
+  return LoadURI(aURI, loadURIOptions);
+}
+
+NS_IMETHODIMP
 nsDocShell::DisplayLoadError(nsresult aError, nsIURI* aURI,
                              const char16_t* aURL, nsIChannel* aFailedChannel,
                              bool* aDisplayedErrorPage) {
   *aDisplayedErrorPage = false;
   // Get prompt and string bundle services
   nsCOMPtr<nsIPrompt> prompter;
   nsCOMPtr<nsIStringBundle> stringBundle;
   GetPromptAndStringBundle(getter_AddRefs(prompter),
@@ -6905,22 +6904,21 @@ nsresult nsDocShell::EndPageLoad(nsIWebP
           // This notification is meant for Firefox Health Report so it
           // can increment counts from the search engine
           MaybeNotifyKeywordSearchLoading(keywordProviderName, keywordAsSent);
 
           nsCOMPtr<nsILoadInfo> loadInfo = aChannel->GetLoadInfo();
           MOZ_ASSERT(loadInfo, "loadInfo is required on all channels");
           nsCOMPtr<nsIPrincipal> triggeringPrincipal =
               loadInfo->TriggeringPrincipal();
-          return LoadURI(newSpecW,              // URI string
-                         LOAD_FLAGS_NONE,       // Load flags
-                         nullptr,               // Referring URI
-                         newPostData,           // Post data stream
-                         nullptr,               // Headers stream
-                         triggeringPrincipal);  // TriggeringPrincipal
+
+          LoadURIOptions loadURIOptions;
+          loadURIOptions.mTriggeringPrincipal = triggeringPrincipal;
+          loadURIOptions.mPostData = newPostData;
+          return LoadURI(newSpecW, loadURIOptions);
         }
       }
     }
 
     // Well, fixup didn't work :-(
     // It is time to throw an error dialog box, and be done with it...
 
     // Errors to be shown only on top-level frames
--- a/docshell/base/nsDocShellTreeOwner.cpp
+++ b/docshell/base/nsDocShellTreeOwner.cpp
@@ -51,16 +51,17 @@
 #include "nsView.h"
 #include "nsIConstraintValidation.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/EventListenerManager.h"
 #include "mozilla/dom/DragEvent.h"
 #include "mozilla/dom/Event.h"     // for Event
 #include "mozilla/dom/File.h"      // for input type=file
 #include "mozilla/dom/FileList.h"  // for input type=file
+#include "mozilla/dom/LoadURIOptionsBinding.h"
 #include "mozilla/TextEvents.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 // A helper routine that navigates the tricky path from a |nsWebBrowser| to
 // a |EventTarget| via the window root and chrome event handler.
 static nsresult GetDOMEventTarget(nsWebBrowser* aInBrowser,
@@ -891,18 +892,19 @@ nsDocShellTreeOwner::HandleEvent(Event* 
           nsAutoString url;
           if (NS_SUCCEEDED(links[0]->GetUrl(url))) {
             if (!url.IsEmpty()) {
 #ifndef ANDROID
               MOZ_ASSERT(triggeringPrincipal,
                          "nsDocShellTreeOwner::HandleEvent: Need a valid "
                          "triggeringPrincipal");
 #endif
-              webnav->LoadURI(url, 0, nullptr, nullptr, nullptr,
-                              triggeringPrincipal);
+              LoadURIOptions loadURIOptions;
+              loadURIOptions.mTriggeringPrincipal = triggeringPrincipal;
+              webnav->LoadURI(url, loadURIOptions);
             }
           }
 
           for (uint32_t i = 0; i < linksCount; i++) {
             NS_RELEASE(links[i]);
           }
           free(links);
         }
--- a/docshell/base/nsIWebNavigation.idl
+++ b/docshell/base/nsIWebNavigation.idl
@@ -9,18 +9,25 @@ interface nsIInputStream;
 interface nsISHistory;
 interface nsIURI;
 interface nsIPrincipal;
 interface nsIChildSHistory;
 webidl Document;
 
 %{ C++
 #include "mozilla/dom/ChildSHistory.h"
+namespace mozilla {
+namespace dom {
+struct LoadURIOptions;
+} // namespace dom
+} // namespace mozilla
 %}
 
+[ref] native LoadURIOptionsRef(const mozilla::dom::LoadURIOptions);
+
 /**
  * The nsIWebNavigation interface defines an interface for navigating the web.
  * It provides methods and attributes to direct an object to navigate to a new
  * location, stop or restart an in process load, or determine where the object
  * has previously gone.
  */
 [scriptable, uuid(3ade79d4-8cb9-4952-b18d-4f9b63ca0d31)]
 interface nsIWebNavigation : nsISupports
@@ -216,111 +223,38 @@ interface nsIWebNavigation : nsISupports
 
   /**
    * This load is the result of an HTTP redirect.
    */
   const unsigned long LOAD_FLAGS_IS_REDIRECT = 0x800000;
 
   /**
    * 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
+   * in the object implementing this interface.  If it can't be loaded here
    * however, the URI dispatcher will go through its normal process of content
    * loading.
    *
    * @param aURI
    *        The URI string to load.  For HTTP and FTP URLs and possibly others,
    *        characters above U+007F will be converted to UTF-8 and then URL-
    *        escaped per the rules of RFC 2396.
-   * @param aLoadFlags
-   *        Flags modifying load behaviour.  This parameter is a bitwise
-   *        combination of the load flags defined above.  (Undefined bits are
-   *        reserved for future use.)  Generally you will pass LOAD_FLAGS_NONE
-   *        for this parameter.
-   * @param aReferrer
-   *        The referring URI.  If this argument is null, then the referring
-   *        URI will be inferred internally.
-   * @param aPostData
-   *        If the URI corresponds to a HTTP request, then this stream is
-   *        appended directly to the HTTP request headers.  It may be prefixed
-   *        with additional HTTP headers.  This stream must contain a "\r\n"
-   *        sequence separating any HTTP headers from the HTTP request body.
-   *        This parameter is optional and may be null.
-   * @param aHeaders
-   *        If the URI corresponds to a HTTP request, then any HTTP headers
-   *        contained in this stream are set on the HTTP request.  The HTTP
-   *        header stream is formatted as:
-   *            ( HEADER "\r\n" )*
-   *        This parameter is optional and may be null.
-   * @param aTriggeringPrincipal
-   *        The principal that initiated the load of aURI. If omitted docShell
-   *        tries to create a codeBasePrincipal from aReferrer if not null. If
-   *        aReferrer is also null docShell peforms a load using the
-   *        SystemPrincipal as the triggeringPrincipal.
+   * @param aLoadURIOptions
+   *        A JSObject defined in LoadURIOptions.webidl holding info like e.g.
+   *        the triggeringPrincipal, the referrer URI, the referrer policy.
    */
-  void loadURI(in AString                  aURI,
-               in unsigned long            aLoadFlags,
-               in nsIURI                   aReferrer,
-               in nsIInputStream           aPostData,
-               in nsIInputStream           aHeaders,
-               [optional] in nsIPrincipal  aTriggeringPrincipal);
+  [implicit_jscontext, binaryname(LoadURIFromScript)]
+  void loadURI(in AString aURI,
+               in jsval   aLoadURIOptions);
 
   /**
-   * 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 URI dispatcher will go through its normal process of content
-   * loading.
-   *
-   * Behaves like loadURI, but allows passing of additional parameters.
-   *
-   * @param aURI
-   *        The URI string to load.  For HTTP and FTP URLs and possibly others,
-   *        characters above U+007F will be converted to UTF-8 and then URL-
-   *        escaped per the rules of RFC 2396.
-   * @param aLoadFlags
-   *        Flags modifying load behaviour.  This parameter is a bitwise
-   *        combination of the load flags defined above.  (Undefined bits are
-   *        reserved for future use.)  Generally you will pass LOAD_FLAGS_NONE
-   *        for this parameter.
-   * @param aReferrer
-   *        The referring URI.  If this argument is null, then the referring
-   *        URI will be inferred internally.
-   * @param aReferrerPolicy
-   *        One of the REFERRER_POLICY_* constants from nsIHttpChannel.
-   *        Normal case is REFERRER_POLICY_NO_REFERRER_WHEN_DOWNGRADE.
-   * @param aPostData
-   *        If the URI corresponds to a HTTP request, then this stream is
-   *        appended directly to the HTTP request headers.  It may be prefixed
-   *        with additional HTTP headers.  This stream must contain a "\r\n"
-   *        sequence separating any HTTP headers from the HTTP request body.
-   *        This parameter is optional and may be null.
-   * @param aHeaders
-   *        If the URI corresponds to a HTTP request, then any HTTP headers
-   *        contained in this stream are set on the HTTP request.  The HTTP
-   *        header stream is formatted as:
-   *            ( HEADER "\r\n" )*
-   *        This parameter is optional and may be null.
-   * @param aBaseURI
-   *        Set to indicate a base URI to be associated with the load. Note
-   *        that at present this argument is only used with view-source aURIs
-   *        and cannot be used to resolve aURI.
-   *        This parameter is optional and may be null.
-   * @param aTriggeringPrincipal
-   *        The principal that initiated the load of aURI. If omitted docShell
-   *        tries to create a codeBasePrincipal from aReferrer if not null. If
-   *        aReferrer is also null docShell peforms a load using the
-   *        SystemPrincipal as the triggeringPrincipal.
+   * A C++ friendly version of loadURI
    */
-  void loadURIWithOptions(in AString                  aURI,
-                          in unsigned long            aLoadFlags,
-                          in nsIURI                   aReferrer,
-                          in unsigned long            aReferrerPolicy,
-                          in nsIInputStream           aPostData,
-                          in nsIInputStream           aHeaders,
-                          in nsIURI                   aBaseURI,
-                          [optional] in nsIPrincipal  aTriggeringPrincipal);
+  [nostdcall, binaryname(LoadURI)]
+  void binaryLoadURI(in AString           aURI,
+                     in LoadURIOptionsRef aLoadURIOptions);
 
   /**
    * Tells the Object to reload the current page.  There may be cases where the
    * user will be asked to confirm the reload (for example, when it is
    * determined that the request is non-idempotent).
    *
    * @param aReloadFlags
    *        Flags modifying load behaviour.  This parameter is a bitwise
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -18,16 +18,17 @@
 #include "js/JSON.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/BrowserElementParent.h"
 #include "mozilla/ClearOnShutdown.h"
 #include "mozilla/EventListenerManager.h"
 #include "mozilla/dom/DataTransfer.h"
 #include "mozilla/dom/Event.h"
 #include "mozilla/dom/indexedDB/PIndexedDBPermissionRequestChild.h"
+#include "mozilla/dom/LoadURIOptionsBinding.h"
 #include "mozilla/dom/MessageManagerBinding.h"
 #include "mozilla/dom/MouseEventBinding.h"
 #include "mozilla/dom/Nullable.h"
 #include "mozilla/dom/PaymentRequestChild.h"
 #include "mozilla/dom/WindowProxyHolder.h"
 #include "mozilla/gfx/CrossProcessPaint.h"
 #include "mozilla/IMEStateManager.h"
 #include "mozilla/ipc/URIUtils.h"
@@ -1002,21 +1003,24 @@ mozilla::ipc::IPCResult TabChild::RecvLo
     mDidLoadURLInit = true;
     if (!InitTabChildMessageManager()) {
       return IPC_FAIL_NO_REASON(this);
     }
 
     ApplyShowInfo(aInfo);
   }
 
-  nsresult rv = WebNavigation()->LoadURI(
-      NS_ConvertUTF8toUTF16(aURI),
+  LoadURIOptions loadURIOptions;
+  loadURIOptions.mTriggeringPrincipal = nsContentUtils::GetSystemPrincipal();
+  loadURIOptions.mLoadFlags =
       nsIWebNavigation::LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP |
-          nsIWebNavigation::LOAD_FLAGS_DISALLOW_INHERIT_PRINCIPAL,
-      nullptr, nullptr, nullptr, nsContentUtils::GetSystemPrincipal());
+      nsIWebNavigation::LOAD_FLAGS_DISALLOW_INHERIT_PRINCIPAL;
+
+  nsresult rv =
+      WebNavigation()->LoadURI(NS_ConvertUTF8toUTF16(aURI), loadURIOptions);
   if (NS_FAILED(rv)) {
     NS_WARNING(
         "WebNavigation()->LoadURI failed. Eating exception, what else can I "
         "do?");
   }
 
   CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::URL, aURI);
 
--- a/dom/security/FramingChecker.cpp
+++ b/dom/security/FramingChecker.cpp
@@ -10,16 +10,17 @@
 #include "nsDocShell.h"
 #include "nsIChannel.h"
 #include "nsIConsoleService.h"
 #include "nsIContentSecurityPolicy.h"
 #include "nsIScriptError.h"
 #include "nsNetUtil.h"
 #include "nsQueryObject.h"
 #include "mozilla/dom/nsCSPUtils.h"
+#include "mozilla/dom/LoadURIOptionsBinding.h"
 #include "mozilla/NullPrincipal.h"
 
 using namespace mozilla;
 
 /* static */ bool FramingChecker::CheckOneFrameOptionsPolicy(
     nsIHttpChannel* aHttpChannel, const nsAString& aPolicy,
     nsIDocShell* aDocShell) {
   static const char allowFrom[] = "allow-from";
@@ -252,18 +253,20 @@ static bool ShouldIgnoreFrameOptions(nsI
         nsCOMPtr<nsIWebNavigation> webNav(do_QueryObject(aDocShell));
         if (webNav) {
           nsCOMPtr<nsILoadInfo> loadInfo = httpChannel->GetLoadInfo();
           MOZ_ASSERT(loadInfo);
 
           RefPtr<NullPrincipal> principal =
               NullPrincipal::CreateWithInheritedAttributes(
                   loadInfo->TriggeringPrincipal());
-          webNav->LoadURI(NS_LITERAL_STRING("about:blank"), 0, nullptr, nullptr,
-                          nullptr, principal);
+
+          LoadURIOptions loadURIOptions;
+          loadURIOptions.mTriggeringPrincipal = principal;
+          webNav->LoadURI(NS_LITERAL_STRING("about:blank"), loadURIOptions);
         }
       }
       return false;
     }
   }
 
   return true;
 }
new file mode 100644
--- /dev/null
+++ b/dom/webidl/LoadURIOptions.webidl
@@ -0,0 +1,60 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+interface Principal;
+interface URI;
+interface InputStream;
+
+/**
+ * This dictionary holds load arguments for docshell loads.
+ */
+
+dictionary LoadURIOptions {
+  /**
+   * The principal that initiated the load.
+   */
+  Principal? triggeringPrincipal = null;
+
+  /**
+   * Flags modifying load behaviour.  This parameter is a bitwise
+   * combination of the load flags defined in nsIWebNavigation.idl.
+   */
+   long loadFlags = 0;
+
+  /**
+   * The referring URI.  If this argument is null, then the referring
+   * URI will be inferred internally.
+   */
+  URI? referrerURI = null;
+
+  /**
+   * Referrer Policy for the load, defaults to REFERRER_POLICY_UNSET.
+   * Alternatively use one of REFERRER_POLICY_* constants from
+   * nsIHttpChannel.
+   */
+  long referrerPolicy = 0;
+
+  /**
+   * If the URI to be loaded corresponds to a HTTP request, then this stream is
+   * appended directly to the HTTP request headers.  It may be prefixed
+   * with additional HTTP headers.  This stream must contain a "\r\n"
+   * sequence separating any HTTP headers from the HTTP request body.
+   */
+  InputStream? postData = null;
+
+  /**
+   * If the URI corresponds to a HTTP request, then any HTTP headers
+   * contained in this stream are set on the HTTP request.  The HTTP
+   * header stream is formatted as:
+   *     ( HEADER "\r\n" )*
+   */
+   InputStream? headers = null;
+
+  /**
+   * Set to indicate a base URI to be associated with the load. Note
+   * that at present this argument is only used with view-source aURIs
+   * and cannot be used to resolve aURI.
+   */
+  URI? baseURI = null;
+};
\ No newline at end of file
--- a/dom/webidl/moz.build
+++ b/dom/webidl/moz.build
@@ -627,16 +627,17 @@ WEBIDL_FILES = [
     'KeyboardEvent.webidl',
     'KeyEvent.webidl',
     'KeyframeAnimationOptions.webidl',
     'KeyframeEffect.webidl',
     'KeyIdsInitData.webidl',
     'L10nUtils.webidl',
     'LegacyQueryInterface.webidl',
     'LinkStyle.webidl',
+    'LoadURIOptions.webidl',
     'Location.webidl',
     'MediaCapabilities.webidl',
     'MediaDeviceInfo.webidl',
     'MediaDevices.webidl',
     'MediaElementAudioSourceNode.webidl',
     'MediaEncryptedEvent.webidl',
     'MediaError.webidl',
     'MediaKeyError.webidl',
--- a/editor/composer/nsEditingSession.cpp
+++ b/editor/composer/nsEditingSession.cpp
@@ -45,16 +45,17 @@
 #include "nsPICommandUpdater.h"          // for nsPICommandUpdater
 #include "nsPIDOMWindow.h"               // for nsPIDOMWindow
 #include "nsPresContext.h"               // for nsPresContext
 #include "nsReadableUtils.h"             // for AppendUTF16toUTF8
 #include "nsStringFwd.h"                 // for nsString
 #include "mozilla/dom/Selection.h"       // for AutoHideSelectionChanges, etc
 #include "nsFrameSelection.h"            // for nsFrameSelection
 #include "nsBaseCommandController.h"     // for nsBaseCommandController
+#include "mozilla/dom/LoadURIOptionsBinding.h"
 
 class nsISupports;
 class nsIURI;
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 /*---------------------------------------------------------------------------
@@ -935,18 +936,20 @@ nsresult nsEditingSession::EndDocumentLo
 }
 
 void nsEditingSession::TimerCallback(nsITimer* aTimer, void* aClosure) {
   nsCOMPtr<nsIDocShell> docShell =
       do_QueryReferent(static_cast<nsIWeakReference*>(aClosure));
   if (docShell) {
     nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(docShell));
     if (webNav) {
-      webNav->LoadURI(NS_LITERAL_STRING("about:blank"), 0, nullptr, nullptr,
-                      nullptr, nsContentUtils::GetSystemPrincipal());
+      LoadURIOptions loadURIOptions;
+      loadURIOptions.mTriggeringPrincipal =
+          nsContentUtils::GetSystemPrincipal();
+      webNav->LoadURI(NS_LITERAL_STRING("about:blank"), loadURIOptions);
     }
   }
 }
 
 /*---------------------------------------------------------------------------
 
   StartPageLoad
 
--- a/toolkit/components/browser/nsWebBrowser.cpp
+++ b/toolkit/components/browser/nsWebBrowser.cpp
@@ -33,16 +33,17 @@
 #include "nsIServiceManager.h"
 #include "nsFocusManager.h"
 #include "Layers.h"
 #include "nsILoadContext.h"
 #include "nsDocShell.h"
 
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/BrowsingContext.h"
+#include "mozilla/dom/LoadURIOptionsBinding.h"
 
 // for painting the background window
 #include "mozilla/LookAndFeel.h"
 
 // Printing Includes
 #ifdef NS_PRINTING
 #include "nsIWebBrowserPrint.h"
 #include "nsIContentViewer.h"
@@ -542,60 +543,47 @@ nsWebBrowser::GoBack() {
 
 NS_IMETHODIMP
 nsWebBrowser::GoForward() {
   NS_ENSURE_STATE(mDocShell);
 
   return mDocShellAsNav->GoForward();
 }
 
-NS_IMETHODIMP
-nsWebBrowser::LoadURIWithOptions(const nsAString& aURI, uint32_t aLoadFlags,
-                                 nsIURI* aReferringURI,
-                                 uint32_t aReferrerPolicy,
-                                 nsIInputStream* aPostDataStream,
-                                 nsIInputStream* aExtraHeaderStream,
-                                 nsIURI* aBaseURI,
-                                 nsIPrincipal* aTriggeringPrincipal) {
+nsresult nsWebBrowser::LoadURI(const nsAString& aURI,
+                               const dom::LoadURIOptions& aLoadURIOptions) {
 #ifndef ANDROID
-  MOZ_ASSERT(
-      aTriggeringPrincipal,
-      "nsWebBrowser::LoadURIWithOptions - Need a valid triggeringPrincipal");
+  MOZ_ASSERT(aLoadURIOptions.mTriggeringPrincipal,
+             "nsWebBrowser::LoadURI - Need a valid triggeringPrincipal");
 #endif
   NS_ENSURE_STATE(mDocShell);
 
-  return mDocShellAsNav->LoadURIWithOptions(
-      aURI, aLoadFlags, aReferringURI, aReferrerPolicy, aPostDataStream,
-      aExtraHeaderStream, aBaseURI, aTriggeringPrincipal);
+  return mDocShellAsNav->LoadURI(aURI, aLoadURIOptions);
+}
+
+NS_IMETHODIMP
+nsWebBrowser::LoadURIFromScript(const nsAString& aURI,
+                                JS::Handle<JS::Value> aLoadURIOptions,
+                                JSContext* aCx) {
+  // generate dictionary for loadURIOptions and forward call
+  dom::LoadURIOptions loadURIOptions;
+  if (!loadURIOptions.Init(aCx, aLoadURIOptions)) {
+    return NS_ERROR_INVALID_ARG;
+  }
+  return LoadURI(aURI, loadURIOptions);
 }
 
 NS_IMETHODIMP
 nsWebBrowser::SetOriginAttributesBeforeLoading(
     JS::Handle<JS::Value> aOriginAttributes, JSContext* aCx) {
   return mDocShellAsNav->SetOriginAttributesBeforeLoading(aOriginAttributes,
                                                           aCx);
 }
 
 NS_IMETHODIMP
-nsWebBrowser::LoadURI(const nsAString& aURI, uint32_t aLoadFlags,
-                      nsIURI* aReferringURI, nsIInputStream* aPostDataStream,
-                      nsIInputStream* aExtraHeaderStream,
-                      nsIPrincipal* aTriggeringPrincipal) {
-#ifndef ANDROID
-  MOZ_ASSERT(aTriggeringPrincipal,
-             "nsWebBrowser::LoadURI - Need a valid triggeringPrincipal");
-#endif
-  NS_ENSURE_STATE(mDocShell);
-
-  return mDocShellAsNav->LoadURI(aURI, aLoadFlags, aReferringURI,
-                                 aPostDataStream, aExtraHeaderStream,
-                                 aTriggeringPrincipal);
-}
-
-NS_IMETHODIMP
 nsWebBrowser::Reload(uint32_t aReloadFlags) {
   NS_ENSURE_STATE(mDocShell);
 
   return mDocShellAsNav->Reload(aReloadFlags);
 }
 
 NS_IMETHODIMP
 nsWebBrowser::GotoIndex(int32_t aIndex) {
--- a/xpfe/appshell/nsWebShellWindow.cpp
+++ b/xpfe/appshell/nsWebShellWindow.cpp
@@ -59,16 +59,17 @@
 #include "nsDocShell.h"
 
 #include "mozilla/Attributes.h"
 #include "mozilla/DebugOnly.h"
 #include "mozilla/EventDispatcher.h"
 #include "mozilla/MouseEvents.h"
 
 #include "mozilla/dom/BrowsingContext.h"
+#include "mozilla/dom/LoadURIOptionsBinding.h"
 
 #include "nsPIWindowRoot.h"
 
 #include "gfxPlatform.h"
 
 #ifdef XP_MACOSX
 #include "nsINativeMenuService.h"
 #define USE_NATIVE_MENUS
@@ -240,19 +241,21 @@ nsresult nsWebShellWindow::Initialize(
     nsCString tmpStr;
 
     rv = aUrl->GetSpec(tmpStr);
     if (NS_FAILED(rv)) return rv;
 
     NS_ConvertUTF8toUTF16 urlString(tmpStr);
     nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(mDocShell));
     NS_ENSURE_TRUE(webNav, NS_ERROR_FAILURE);
-    rv =
-        webNav->LoadURI(urlString, nsIWebNavigation::LOAD_FLAGS_NONE, nullptr,
-                        nullptr, nullptr, nsContentUtils::GetSystemPrincipal());
+
+    LoadURIOptions loadURIOptions;
+    loadURIOptions.mTriggeringPrincipal = nsContentUtils::GetSystemPrincipal();
+
+    rv = webNav->LoadURI(urlString, loadURIOptions);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   return rv;
 }
 
 nsIPresShell* nsWebShellWindow::GetPresShell() {
   if (!mDocShell) return nullptr;