Bug 1406371 - Add preference to inherit the previous container when opening a tab without a container. r?baku r?Gijs draft
authorJonathan Kingston <jkt@mozilla.com>
Tue, 05 Dec 2017 20:28:37 +0000
changeset 707762 2219d725165e501a6347c37e00437f5d4ea73ee6
parent 705606 ba283baf4e98aa3a5f45a17981077b98697aa73a
child 743034 57d37527f0e5058476b78fa7f8c9e9efabfa4967
push id92216
push userbmo:jkt@mozilla.com
push dateTue, 05 Dec 2017 20:31:47 +0000
reviewersbaku, Gijs
bugs1406371
milestone59.0a1
Bug 1406371 - Add preference to inherit the previous container when opening a tab without a container. r?baku r?Gijs MozReview-Commit-ID: 18dfJCprcy2
browser/app/profile/firefox.js
browser/base/content/utilityOverlay.js
browser/components/contextualidentity/test/browser/browser_newtabButton.js
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1552,16 +1552,17 @@ pref("privacy.userContext.longPressBehav
 pref("privacy.userContext.enabled", false);
 pref("privacy.userContext.ui.enabled", false);
 pref("privacy.usercontext.about_newtab_segregation.enabled", false);
 
 // 0 disables long press, 1 when clicked, the menu is shown, 2 the menu is shown after X milliseconds.
 pref("privacy.userContext.longPressBehavior", 0);
 #endif
 pref("privacy.userContext.extension", "");
+pref("privacy.userContext.newTabInheritContext", false);
 
 // Start the browser in e10s mode
 pref("browser.tabs.remote.autostart", true);
 pref("browser.tabs.remote.desktopbehavior", true);
 
 // For speculatively warming up tabs to improve perceived
 // performance while using the async tab switcher.
 // Disabled until bug 1397426 is fixed.
--- a/browser/base/content/utilityOverlay.js
+++ b/browser/base/content/utilityOverlay.js
@@ -266,16 +266,21 @@ function openLinkIn(url, where, params) 
   // We don't want to open tabs in popups, so try to find a non-popup window in
   // that case.
   if ((where == "tab" || where == "tabshifted") &&
       w && !w.toolbar.visible) {
     w = getTopWin(true);
     aRelatedToCurrent = false;
   }
 
+  if (!aIsPrivate && isNaN(aUserContextId) && getBoolPref("privacy.userContext.newTabInheritContext", false)) {
+    let currentTargetBrowser = params.targetBrowser || w.gBrowser.selectedBrowser;
+    aUserContextId = w.gBrowser.getTabForBrowser(currentTargetBrowser).userContextId;
+  }
+
   // Teach the principal about the right OA to use, e.g. in case when
   // opening a link in a new private window, or in a new container tab.
   // Please note we do not have to do that for SystemPrincipals and we
   // can not do it for NullPrincipals since NullPrincipals are only
   // identical if they actually are the same object (See Bug: 1346759)
   function useOAForPrincipal(principal) {
     if (principal && principal.isCodebasePrincipal) {
       let attrs = {
--- a/browser/components/contextualidentity/test/browser/browser_newtabButton.js
+++ b/browser/components/contextualidentity/test/browser/browser_newtabButton.js
@@ -33,17 +33,18 @@ add_task(async function test_menu_with_t
     is(tab.getAttribute("usercontextid"), i, `New tab has UCI equal ${i}`);
     await BrowserTestUtils.removeTab(tab);
   }
 });
 
 add_task(async function test_menu_without_timeout() {
   await SpecialPowers.pushPrefEnv({"set": [
       ["privacy.userContext.enabled", true],
-      ["privacy.userContext.longPressBehavior", 1]
+      ["privacy.userContext.longPressBehavior", 1],
+      ["privacy.userContext.newTabInheritContext", true],
   ]});
 
   let newTab = document.getElementById("tabbrowser-tabs");
   let newTabButton = document.getAnonymousElementByAttribute(newTab, "anonid", "tabs-newtab-button");
   ok(newTabButton, "New tab button exists");
   ok(!newTabButton.hidden, "New tab button is visible");
   await BrowserTestUtils.waitForCondition(() => !!document.getAnonymousElementByAttribute(newTab, "anonid", "newtab-popup"), "Wait for popup to exist");
   let popup = document.getAnonymousElementByAttribute(newTab, "anonid", "newtab-popup");
@@ -52,39 +53,53 @@ add_task(async function test_menu_withou
   let popupHiddenPromise = BrowserTestUtils.waitForEvent(popup, "popuphidden");
   EventUtils.synthesizeMouseAtCenter(newTabButton, {type: "mousedown"});
   await popupShownPromise;
   let contextIdItems = popup.querySelectorAll("menuitem");
   // 4 + default + manage containers
   is(contextIdItems.length, 6, "Has 6 menu items");
   popup.hidePopup();
   await popupHiddenPromise;
-
-  for (let i = 0; i <= 4; i++) {
+  async function showMenuAndClickItem(i, expectedUCI = i) {
     popupShownPromise = BrowserTestUtils.waitForEvent(popup, "popupshown");
     EventUtils.synthesizeMouseAtCenter(newTabButton, {type: "mousedown"});
 
     await popupShownPromise;
     let contextIdItem = popup.querySelector(`menuitem[data-usercontextid="${i}"]`);
 
     ok(contextIdItem, `User context id ${i} exists`);
 
     // waitForNewTab doesn't work for default tabs due to a different code path that doesn't cause a load event
     let waitForTabPromise = BrowserTestUtils.waitForEvent(gBrowser.tabContainer, "TabOpen");
     EventUtils.synthesizeMouseAtCenter(contextIdItem, {});
 
     let tabEvent = await waitForTabPromise;
     let tab = tabEvent.target;
-    if (i > 0) {
-      is(tab.getAttribute("usercontextid"), i, `New tab has UCI equal ${i}`);
+    if (expectedUCI > 0) {
+      is(tab.getAttribute("usercontextid"), expectedUCI, `New tab has UCI equal ${expectedUCI}`);
     } else {
       ok(!tab.hasAttribute("usercontextid"), `New tab has no UCI`);
     }
+    return tab;
+  }
+  let tab;
+  for (let i = 0; i <= 4; i++) {
+    tab = await showMenuAndClickItem(i);
     await BrowserTestUtils.removeTab(tab);
   }
+  // Try sequence to inherit tab
+  const inheritedUCI = 2;
+  tab = await showMenuAndClickItem(inheritedUCI);
+
+  /* the UCI menu item for longPressBehavior=1 has an explicit UCI=0 which won't inherit, so lets create a new tab without a UCI like the normal new tab will do */
+  let tab2 = await BrowserTestUtils.openNewForegroundTab(gBrowser);
+  is(tab.getAttribute("usercontextid"), inheritedUCI, `New tab has UCI equal ${inheritedUCI}`);
+  await BrowserTestUtils.removeTab(tab2);
+
+  await BrowserTestUtils.removeTab(tab);
 });
 
 add_task(async function test_no_menu() {
   await SpecialPowers.pushPrefEnv({"set": [
       ["privacy.userContext.enabled", true],
       ["privacy.userContext.longPressBehavior", 0]
   ]});
 
@@ -92,16 +107,19 @@ add_task(async function test_no_menu() {
   let newTabButton = document.getAnonymousElementByAttribute(newTab, "anonid", "tabs-newtab-button");
   ok(newTabButton, "New tab button exists");
   ok(!newTabButton.hidden, "New tab button is visible");
   let popup = document.getAnonymousElementByAttribute(newTab, "anonid", "newtab-popup");
   ok(!popup, "new tab should not have a popup");
 });
 
 add_task(async function test_private_mode() {
+  await SpecialPowers.pushPrefEnv({"set": [
+    ["privacy.userContext.enabled", true]
+  ]});
   let privateWindow = await BrowserTestUtils.openNewBrowserWindow({private: true});
   let privateDocument = privateWindow.document;
   let {tabContainer} = privateWindow.gBrowser;
   let newTab = privateDocument.getAnonymousElementByAttribute(tabContainer, "anonid", "tabs-newtab-button");
   let newTab2 = privateDocument.getElementById("new-tab-button");
   // Check to ensure we are talking about the right button
   ok(!!newTab.clientWidth, "new tab button should not be hidden");
   ok(!newTab2.clientWidth, "overflow new tab button should be hidden");