Bug 1058116 - Pass referrer and isPrivate to openURIInFrame instead of nullptr as aOpener. r=mconley, r=smaug, r=Margaret, r=ally
authorTomasz Kołodziejski <tkolodziejski@mozilla.com>
Thu, 06 Nov 2014 09:41:00 -0500
changeset 214472 5caf99f630593a318543c943c29aabb8dafffab6
parent 214471 3e45eeacb23162e7c1ce1f08f4f1de334fce0c80
child 214473 ebb8c73555a128ae7e3d4723254bfde7ef27dce4
push id51494
push userkwierso@gmail.com
push dateFri, 07 Nov 2014 03:08:20 +0000
treeherdermozilla-inbound@c4b831696f15 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmconley, smaug, Margaret, ally
bugs1058116
milestone36.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 1058116 - Pass referrer and isPrivate to openURIInFrame instead of nullptr as aOpener. r=mconley, r=smaug, r=Margaret, r=ally
browser/base/content/browser.js
browser/base/content/chatWindow.xul
browser/metro/base/content/browser.js
dom/base/moz.build
dom/base/nsOpenURIInFrameParams.cpp
dom/base/nsOpenURIInFrameParams.h
dom/interfaces/base/nsIBrowserDOMWindow.idl
dom/ipc/TabParent.cpp
mobile/android/chrome/content/browser.js
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -4546,44 +4546,42 @@ var TabsProgressListener = {
   }
 }
 
 function nsBrowserAccess() { }
 
 nsBrowserAccess.prototype = {
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIBrowserDOMWindow, Ci.nsISupports]),
 
-  _openURIInNewTab: function(aURI, aOpener, aIsExternal) {
+  _openURIInNewTab: function(aURI, aReferrer, aIsPrivate, aIsExternal) {
     let win, needToFocusWin;
 
     // try the current window.  if we're in a popup, fall back on the most recent browser window
     if (window.toolbar.visible)
       win = window;
     else {
-      let isPrivate = PrivateBrowsingUtils.isWindowPrivate(aOpener || window);
-      win = RecentWindow.getMostRecentBrowserWindow({private: isPrivate});
+      win = RecentWindow.getMostRecentBrowserWindow({private: aIsPrivate});
       needToFocusWin = true;
     }
 
     if (!win) {
       // we couldn't find a suitable window, a new one needs to be opened.
       return null;
     }
 
     if (aIsExternal && (!aURI || aURI.spec == "about:blank")) {
       win.BrowserOpenTab(); // this also focuses the location bar
       win.focus();
       return win.gBrowser.selectedBrowser;
     }
 
     let loadInBackground = gPrefService.getBoolPref("browser.tabs.loadDivertedInBackground");
-    let referrer = aOpener ? makeURI(aOpener.location.href) : null;
 
     let tab = win.gBrowser.loadOneTab(aURI ? aURI.spec : "about:blank", {
-                                      referrerURI: referrer,
+                                      referrerURI: aReferrer,
                                       fromExternal: aIsExternal,
                                       inBackground: loadInBackground});
     let browser = win.gBrowser.getBrowserForTab(tab);
 
     if (needToFocusWin || (!loadInBackground && aIsExternal))
       win.focus();
 
     return browser;
@@ -4610,17 +4608,19 @@ nsBrowserAccess.prototype = {
         // FIXME: Bug 408379. So how come this doesn't send the
         // referrer like the other loads do?
         var url = aURI ? aURI.spec : "about:blank";
         // Pass all params to openDialog to ensure that "url" isn't passed through
         // loadOneOrMoreURIs, which splits based on "|"
         newWindow = openDialog(getBrowserURL(), "_blank", "all,dialog=no", url, null, null, null);
         break;
       case Ci.nsIBrowserDOMWindow.OPEN_NEWTAB :
-        let browser = this._openURIInNewTab(aURI, aOpener, isExternal);
+        let referrer = aOpener ? makeURI(aOpener.location.href) : null;
+        let isPrivate = PrivateBrowsingUtils.isWindowPrivate(aOpener || window);
+        let browser = this._openURIInNewTab(aURI, referrer, isPrivate, isExternal);
         if (browser)
           newWindow = browser.contentWindow;
         break;
       default : // OPEN_CURRENTWINDOW or an illegal value
         newWindow = content;
         if (aURI) {
           let referrer = aOpener ? makeURI(aOpener.location.href) : null;
           let loadflags = isExternal ?
@@ -4629,24 +4629,24 @@ nsBrowserAccess.prototype = {
           gBrowser.loadURIWithFlags(aURI.spec, loadflags, referrer, null, null);
         }
         if (!gPrefService.getBoolPref("browser.tabs.loadDivertedInBackground"))
           window.focus();
     }
     return newWindow;
   },
 
-  openURIInFrame: function browser_openURIInFrame(aURI, aOpener, aWhere, aContext) {
+  openURIInFrame: function browser_openURIInFrame(aURI, aParams, aWhere, aContext) {
     if (aWhere != Ci.nsIBrowserDOMWindow.OPEN_NEWTAB) {
       dump("Error: openURIInFrame can only open in new tabs");
       return null;
     }
 
     var isExternal = (aContext == Ci.nsIBrowserDOMWindow.OPEN_EXTERNAL);
-    let browser = this._openURIInNewTab(aURI, aOpener, isExternal);
+    let browser = this._openURIInNewTab(aURI, aParams.referrer, aParams.isPrivate, isExternal);
     if (browser)
       return browser.QueryInterface(Ci.nsIFrameLoaderOwner);
 
     return null;
   },
 
   isTabContentWindow: function (aWindow) {
     return gBrowser.browsers.some(function (browser) browser.contentWindow == aWindow);
--- a/browser/base/content/chatWindow.xul
+++ b/browser/base/content/chatWindow.xul
@@ -118,17 +118,17 @@ chatBrowserAccess.prototype = {
     return browser;
   },
 
   openURI: function (aURI, aOpener, aWhere, aContext) {
     let browser = this._openURIInNewTab(aURI, aWhere);
     return browser ? browser.contentWindow : null;
   },
 
-  openURIInFrame: function browser_openURIInFrame(aURI, aOpener, aWhere, aContext) {
+  openURIInFrame: function browser_openURIInFrame(aURI, aParams, aWhere, aContext) {
     let browser = this._openURIInNewTab(aURI, aWhere);
     return browser ? browser.QueryInterface(Ci.nsIFrameLoaderOwner) : null;
   },
 
   isTabContentWindow: function (aWindow) this.contentWindow == aWindow,
 };
 
 </script>
--- a/browser/metro/base/content/browser.js
+++ b/browser/metro/base/content/browser.js
@@ -1074,18 +1074,18 @@ nsBrowserAccess.prototype = {
     return browser;
   },
 
   openURI: function browser_openURI(aURI, aOpener, aWhere, aContext) {
     let browser = this._getBrowser(aURI, aOpener, aWhere, aContext);
     return browser ? browser.contentWindow : null;
   },
 
-  openURIInFrame: function browser_openURIInFrame(aURI, aOpener, aWhere, aContext) {
-    let browser = this._getBrowser(aURI, aOpener, aWhere, aContext);
+  openURIInFrame: function browser_openURIInFrame(aURI, aParams, aWhere, aContext) {
+    let browser = this._getBrowser(aURI, null, aWhere, aContext);
     return browser ? browser.QueryInterface(Ci.nsIFrameLoaderOwner) : null;
   },
 
   isTabContentWindow: function(aWindow) {
     return Browser.browsers.some(function (browser) browser.contentWindow == aWindow);
   },
 };
 
--- a/dom/base/moz.build
+++ b/dom/base/moz.build
@@ -288,16 +288,17 @@ UNIFIED_SOURCES += [
     'nsMappedAttributeElement.cpp',
     'nsMappedAttributes.cpp',
     'nsMimeTypeArray.cpp',
     'nsMixedContentBlocker.cpp',
     'nsNameSpaceManager.cpp',
     'nsNoDataProtocolContentPolicy.cpp',
     'nsNodeInfoManager.cpp',
     'nsNodeUtils.cpp',
+    'nsOpenURIInFrameParams.cpp',
     'nsPerformance.cpp',
     'nsPlainTextSerializer.cpp',
     'nsPropertyTable.cpp',
     'nsQueryContentEventResult.cpp',
     'nsRange.cpp',
     'nsReferencedElement.cpp',
     'nsScreen.cpp',
     'nsScriptElement.cpp',
new file mode 100644
--- /dev/null
+++ b/dom/base/nsOpenURIInFrameParams.cpp
@@ -0,0 +1,45 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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/. */
+
+#include "nsOpenURIInFrameParams.h"
+
+NS_IMPL_ISUPPORTS(nsOpenURIInFrameParams, nsIOpenURIInFrameParams)
+
+nsOpenURIInFrameParams::nsOpenURIInFrameParams() :
+  mIsPrivate(false)
+{
+}
+
+nsOpenURIInFrameParams::~nsOpenURIInFrameParams() {
+}
+
+/* attribute DOMString referrer; */
+NS_IMETHODIMP
+nsOpenURIInFrameParams::GetReferrer(nsAString& aReferrer)
+{
+  aReferrer = mReferrer;
+  return NS_OK;
+}
+NS_IMETHODIMP
+nsOpenURIInFrameParams::SetReferrer(const nsAString& aReferrer)
+{
+  mReferrer = aReferrer;
+  return NS_OK;
+}
+
+/* attribute boolean isPrivate; */
+NS_IMETHODIMP
+nsOpenURIInFrameParams::GetIsPrivate(bool* aIsPrivate)
+{
+  NS_ENSURE_ARG_POINTER(aIsPrivate);
+  *aIsPrivate = mIsPrivate;
+  return NS_OK;
+}
+NS_IMETHODIMP
+nsOpenURIInFrameParams::SetIsPrivate(bool aIsPrivate)
+{
+  mIsPrivate = aIsPrivate;
+  return NS_OK;
+}
new file mode 100644
--- /dev/null
+++ b/dom/base/nsOpenURIInFrameParams.h
@@ -0,0 +1,21 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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/. */
+
+#include "nsIBrowserDOMWindow.h"
+#include "nsString.h"
+
+class nsOpenURIInFrameParams MOZ_FINAL : public nsIOpenURIInFrameParams
+{
+public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIOPENURIINFRAMEPARAMS
+
+  nsOpenURIInFrameParams();
+
+private:
+  ~nsOpenURIInFrameParams();
+  nsString mReferrer;
+  bool mIsPrivate;
+};
--- a/dom/interfaces/base/nsIBrowserDOMWindow.idl
+++ b/dom/interfaces/base/nsIBrowserDOMWindow.idl
@@ -4,17 +4,25 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsISupports.idl"
 
 interface nsIDOMWindow;
 interface nsIURI;
 interface nsIFrameLoaderOwner;
 
-[scriptable, uuid(699b8f60-2898-11e4-8c21-0800200c9a66)]
+[scriptable, uuid(e774db14-79ac-4156-a7a3-aa3fd0a22c10)]
+
+interface nsIOpenURIInFrameParams : nsISupports
+{
+  attribute DOMString referrer;
+  attribute boolean isPrivate;
+};
+
+[scriptable, uuid(99f5a347-722c-4337-bd38-f14ec94801b3)]
 
 /**
  * The C++ source has access to the browser script source through
  * nsIBrowserDOMWindow. It is intended to be attached to the chrome DOMWindow
  * of a toplevel browser window (a XUL window). A DOMWindow that does not
  * happen to be a browser chrome window will simply have no access to any such
  * interface.
  */
@@ -75,20 +83,20 @@ interface nsIBrowserDOMWindow : nsISuppo
    *                 is used only when aWhere == OPEN_DEFAULTWINDOW.
    * @return the window into which the URI was opened.
   */
   nsIDOMWindow openURI(in nsIURI aURI, in nsIDOMWindow aOpener,
                        in short aWhere, in short aContext);
 
   /**
    * As above, but return the nsIFrameLoaderOwner for the new window.
-   // XXXbz is this the right API? Do we really need the opener here?
+   // XXXbz is this the right API?
    // See bug 537428
    */
-  nsIFrameLoaderOwner openURIInFrame(in nsIURI aURI, in nsIDOMWindow aOpener,
+  nsIFrameLoaderOwner openURIInFrame(in nsIURI aURI, in nsIOpenURIInFrameParams params,
                                      in short aWhere, in short aContext);
 
   /**
    * @param  aWindow the window to test.
    * @return whether the window is the main content window for any
    *         currently open tab in this toplevel browser window.
    */
   boolean      isTabContentWindow(in nsIDOMWindow aWindow);
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -45,16 +45,17 @@
 #include "nsIURI.h"
 #include "nsIWebBrowserChrome.h"
 #include "nsIWindowCreator2.h"
 #include "nsIXULBrowserWindow.h"
 #include "nsIXULWindow.h"
 #include "nsViewManager.h"
 #include "nsIWidget.h"
 #include "nsIWindowWatcher.h"
+#include "nsOpenURIInFrameParams.h"
 #include "nsPIDOMWindow.h"
 #include "nsPIWindowWatcher.h"
 #include "nsPresShell.h"
 #include "nsPrintfCString.h"
 #include "nsServiceManagerUtils.h"
 #include "nsThreadUtils.h"
 #include "nsWindowWatcher.h"
 #include "private/pprio.h"
@@ -436,18 +437,26 @@ TabParent::AnswerCreateWindow(const uint
              openLocation == nsIBrowserDOMWindow::OPEN_NEWWINDOW);
 
   *aWindowIsNew = true;
 
   // Opening new tabs is the easy case...
   if (openLocation == nsIBrowserDOMWindow::OPEN_NEWTAB) {
     NS_ENSURE_TRUE(mBrowserDOMWindow, false);
 
+    bool isPrivate;
+    nsCOMPtr<nsILoadContext> loadContext = GetLoadContext();
+    loadContext->GetUsePrivateBrowsing(&isPrivate);
+
+    nsCOMPtr<nsIOpenURIInFrameParams> params = new nsOpenURIInFrameParams();
+    params->SetReferrer(aBaseURI);
+    params->SetIsPrivate(isPrivate);
+
     nsCOMPtr<nsIFrameLoaderOwner> frameLoaderOwner;
-    mBrowserDOMWindow->OpenURIInFrame(nullptr, nullptr,
+    mBrowserDOMWindow->OpenURIInFrame(nullptr, params,
                                       nsIBrowserDOMWindow::OPEN_NEWTAB,
                                       nsIBrowserDOMWindow::OPEN_NEW,
                                       getter_AddRefs(frameLoaderOwner));
     NS_ENSURE_TRUE(frameLoaderOwner, false);
 
     nsRefPtr<nsFrameLoader> frameLoader = frameLoaderOwner->GetFrameLoader();
     NS_ENSURE_TRUE(frameLoader, false);
 
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -3110,18 +3110,18 @@ nsBrowserAccess.prototype = {
     return browser;
   },
 
   openURI: function browser_openURI(aURI, aOpener, aWhere, aContext) {
     let browser = this._getBrowser(aURI, aOpener, aWhere, aContext);
     return browser ? browser.contentWindow : null;
   },
 
-  openURIInFrame: function browser_openURIInFrame(aURI, aOpener, aWhere, aContext) {
-    let browser = this._getBrowser(aURI, aOpener, aWhere, aContext);
+  openURIInFrame: function browser_openURIInFrame(aURI, aParams, aWhere, aContext) {
+    let browser = this._getBrowser(aURI, null, aWhere, aContext);
     return browser ? browser.QueryInterface(Ci.nsIFrameLoaderOwner) : null;
   },
 
   isTabContentWindow: function(aWindow) {
     return BrowserApp.getBrowserForWindow(aWindow) != null;
   },
 };