Bug 1344749 - about:config pref to open new tab next to current, includes WE browserSetting draft
authorKevin Jones <kevinhowjones@gmail.com>
Tue, 12 Dec 2017 16:40:50 -0700
changeset 710995 57b4956568f7fce32a698c11da252a498d79bf6e
parent 710925 ea27ee04a78a3badcb013935876f61a71da4a266
child 743716 118bcc38f04ecacf2448c45133880c265366ca2d
push id92967
push userallassopraise@gmail.com
push dateTue, 12 Dec 2017 23:42:00 +0000
bugs1344749
milestone59.0a1
Bug 1344749 - about:config pref to open new tab next to current, includes WE browserSetting MozReview-Commit-ID: 5nlNrEJvRK3
browser/app/profile/firefox.js
browser/base/content/browser.js
browser/components/sessionstore/test/browser.ini
browser/components/sessionstore/test/browser_1344749_new_tab_after_current.js
toolkit/components/extensions/ext-browserSettings.js
toolkit/components/extensions/schemas/browser_settings.json
toolkit/components/extensions/test/xpcshell/test_ext_browserSettings.js
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -450,16 +450,17 @@ pref("browser.link.open_newwindow.restri
 pref("browser.link.open_newwindow.disabled_in_fullscreen", true);
 #else
 pref("browser.link.open_newwindow.disabled_in_fullscreen", false);
 #endif
 
 // Tabbed browser
 pref("browser.tabs.closeWindowWithLastTab", true);
 pref("browser.tabs.insertRelatedAfterCurrent", true);
+pref("browser.tabs.insertNewTabAfterCurrent", false);
 pref("browser.tabs.warnOnClose", true);
 pref("browser.tabs.warnOnCloseOtherTabs", true);
 pref("browser.tabs.warnOnOpen", true);
 pref("browser.tabs.maxOpenBeforeWarn", 15);
 pref("browser.tabs.loadInBackground", true);
 pref("browser.tabs.opentabfor.middleclick", true);
 pref("browser.tabs.loadDivertedInBackground", false);
 pref("browser.tabs.loadBookmarksInBackground", false);
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -2261,17 +2261,17 @@ function BrowserOpenTab(event) {
   // A notification intended to be useful for modular peformance tracking
   // starting as close as is reasonably possible to the time when the user
   // expressed the intent to open a new tab.  Since there are a lot of
   // entry points, this won't catch every single tab created, but most
   // initiated by the user should go through here.
   Services.obs.notifyObservers(null, "browser-open-newtab-start");
 
   let where = "tab";
-  let relatedToCurrent = false;
+  let relatedToCurrent = gPrefService.getBoolPref("browser.tabs.insertNewTabAfterCurrent");
 
   if (event) {
     where = whereToOpenLink(event, false, true);
 
     switch (where) {
       case "tab":
       case "tabshifted":
         // When accel-click or middle-click are used, open the new tab as
--- a/browser/components/sessionstore/test/browser.ini
+++ b/browser/components/sessionstore/test/browser.ini
@@ -244,16 +244,17 @@ run-if = e10s
 [browser_forget_async_closings.js]
 [browser_newtab_userTypedValue.js]
 [browser_parentProcessRestoreHash.js]
 run-if = e10s
 [browser_sessionStoreContainer.js]
 [browser_windowStateContainer.js]
 skip-if = os == "linux" && !debug
 [browser_1234021.js]
+[browser_1344749_new_tab_after_current.js]
 [browser_remoteness_flip_on_restore.js]
 run-if = e10s
 [browser_background_tab_crash.js]
 run-if = e10s && crashreporter
 
 # Disabled on debug for frequent intermittent failures:
 [browser_undoCloseById.js]
 skip-if = debug
new file mode 100644
--- /dev/null
+++ b/browser/components/sessionstore/test/browser_1344749_new_tab_after_current.js
@@ -0,0 +1,39 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+add_task(async function test_discarded() {
+  async function awaitBrowserOpenTab(tabbrowser) {
+    return new Promise(resolve => {
+      tabbrowser.tabContainer.addEventListener("TabOpen", function tabOpenListener(e) {
+        resolve(e.target);
+      }, { once: true });
+      BrowserOpenTab();
+    });
+  }
+
+  BrowserTestUtils.loadURI(gBrowser.browsers[0], "http://example.com");
+  await BrowserTestUtils.browserLoaded(gBrowser.browsers[0]);
+  await BrowserTestUtils.openNewForegroundTab(gBrowser, "http://example.com");
+  await BrowserTestUtils.openNewForegroundTab(gBrowser, "http://example.com");
+
+  await BrowserTestUtils.switchTab(gBrowser, gBrowser.tabs[0]);
+
+  let newTab = await awaitBrowserOpenTab(gBrowser);
+  is(newTab._tPos, 3, "The position of the newly opened tab.");
+
+  await BrowserTestUtils.switchTab(gBrowser, gBrowser.tabs[0]);
+
+  await SpecialPowers.pushPrefEnv({
+    "set": [
+      ["browser.tabs.insertNewTabAfterCurrent", true],
+    ],
+  });
+
+  newTab = await awaitBrowserOpenTab(gBrowser);
+  is(newTab._tPos, 1, "The position of the newly opened tab.");
+
+  while (gBrowser.tabs.length > 1) {
+    await BrowserTestUtils.removeTab(gBrowser.tabs[1]);
+  }
+});
+
--- a/toolkit/components/extensions/ext-browserSettings.js
+++ b/toolkit/components/extensions/ext-browserSettings.js
@@ -100,16 +100,26 @@ ExtensionPreferencesManager.addSetting("
     "image.animation_mode",
   ],
 
   setCallback(value) {
     return {[this.prefNames[0]]: value};
   },
 });
 
+ExtensionPreferencesManager.addSetting("newTabAfterCurrent", {
+  prefNames: [
+    "browser.tabs.insertNewTabAfterCurrent",
+  ],
+
+  setCallback(value) {
+    return {[this.prefNames[0]]: value};
+  },
+});
+
 ExtensionPreferencesManager.addSetting("openBookmarksInNewTabs", {
   prefNames: [
     "browser.tabs.loadBookmarksInTabs",
   ],
 
   setCallback(value) {
     return {[this.prefNames[0]]: value};
   },
@@ -185,16 +195,21 @@ this.browserSettings = class extends Ext
             return Services.prefs.getComplexValue(
               HOMEPAGE_URL_PREF, Ci.nsIPrefLocalizedString).data;
           }, undefined, true),
         imageAnimationBehavior: getSettingsAPI(
           extension, "imageAnimationBehavior",
           () => {
             return Services.prefs.getCharPref("image.animation_mode");
           }),
+        newTabAfterCurrent: getSettingsAPI(
+          extension, "newTabAfterCurrent",
+          () => {
+            return Services.prefs.getBoolPref("browser.tabs.insertNewTabAfterCurrent");
+          }),
         newTabPageOverride: getSettingsAPI(
           extension, NEW_TAB_OVERRIDE_SETTING,
           () => {
             return aboutNewTabService.newTabURL;
           }, URL_STORE_TYPE, true),
         openBookmarksInNewTabs: getSettingsAPI(
           extension, "openBookmarksInNewTabs",
           () => {
--- a/toolkit/components/extensions/schemas/browser_settings.json
+++ b/toolkit/components/extensions/schemas/browser_settings.json
@@ -51,16 +51,20 @@
       "homepageOverride": {
         "$ref": "types.Setting",
         "description": "Returns the value of the overridden home page. Read-only."
       },
       "imageAnimationBehavior": {
         "$ref": "types.Setting",
         "description": "Controls the behaviour of image animation in the browser. This setting's value is of type ImageAnimationBehavior, defaulting to <code>normal</code>."
       },
+      "newTabAfterCurrent": {
+        "$ref": "types.Setting",
+        "description": "Determines whether new tab opens after the current tab or at the end of the tabstrip.  Defaults to opening at end of tabstrip."
+      },
       "newTabPageOverride": {
         "$ref": "types.Setting",
         "description": "Returns the value of the overridden new tab page. Read-only."
       },
       "openBookmarksInNewTabs": {
         "$ref": "types.Setting",
         "description": "This boolean setting controls whether bookmarks are opened in the current tab or in a new tab."
       },
--- a/toolkit/components/extensions/test/xpcshell/test_ext_browserSettings.js
+++ b/toolkit/components/extensions/test/xpcshell/test_ext_browserSettings.js
@@ -24,16 +24,17 @@ add_task(async function test_browser_set
   // Create an object to hold the values to which we will initialize the prefs.
   const PREFS = {
     "browser.cache.disk.enable": true,
     "browser.cache.memory.enable": true,
     "dom.popup_allowed_events": Preferences.get("dom.popup_allowed_events"),
     "image.animation_mode": "none",
     "permissions.default.desktop-notification": PERM_UNKNOWN_ACTION,
     "ui.context_menus.after_mouseup": false,
+    "browser.tabs.insertNewTabAfterCurrent": false,
     "browser.tabs.loadBookmarksInTabs": false,
     "browser.search.openintab": false,
   };
 
   async function background() {
     browser.test.onMessage.addListener(async (msg, apiName, value) => {
       let apiObj = browser.browserSettings[apiName];
       let result = await apiObj.set({value});
@@ -144,16 +145,23 @@ add_task(async function test_browser_set
       {"ui.context_menus.after_mouseup": AppConstants.platform === "win"});
   } else {
     await testSetting(
       "contextMenuShowEvent", "mousedown",
       {"ui.context_menus.after_mouseup": false});
   }
 
   await testSetting(
+    "newTabAfterCurrent", true,
+    {"browser.tabs.insertNewTabAfterCurrent": true});
+  await testSetting(
+    "newTabAfterCurrent", false,
+    {"browser.tabs.insertNewTabAfterCurrent": false});
+
+  await testSetting(
     "openBookmarksInNewTabs", true,
     {"browser.tabs.loadBookmarksInTabs": true});
   await testSetting(
     "openBookmarksInNewTabs", false,
     {"browser.tabs.loadBookmarksInTabs": false});
 
   await testSetting(
     "openSearchResultsInNewTabs", true,