Bug 1500218 - Set 'Move to Start' and 'Move to End' disabled state according to contextTab and contextTab position r=dao,jaws
authorMichael Kohler <me@michaelkohler.info>
Wed, 21 Nov 2018 11:30:33 +0000
changeset 503896 f5db5f1b269099e7900bebb64470aaf0e2213b58
parent 503895 824bcd08c85e70d98109b04715b26f139e099ce8
child 503897 a6d6337f6bada016703226a4d127bdef8936aca9
push id10290
push userffxbld-merge
push dateMon, 03 Dec 2018 16:23:23 +0000
treeherdermozilla-beta@700bed2445e6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdao, jaws
bugs1500218
milestone65.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 1500218 - Set 'Move to Start' and 'Move to End' disabled state according to contextTab and contextTab position r=dao,jaws Differential Revision: https://phabricator.services.mozilla.com/D9598
browser/base/content/tabbrowser.js
browser/base/content/test/tabs/browser.ini
browser/base/content/test/tabs/browser_multiselect_tabs_move.js
--- a/browser/base/content/tabbrowser.js
+++ b/browser/base/content/tabbrowser.js
@@ -5474,20 +5474,29 @@ var TabContextMenu = {
     let moveTabOptionsAccessKey = contextMoveTabOptions.getAttribute(moveTabOptionsStringPrefix + "accesskey");
     contextMoveTabOptions.setAttribute("label", moveTabOptionsLabel);
     contextMoveTabOptions.setAttribute("accesskey", moveTabOptionsAccessKey);
     let selectedTabs = gBrowser.selectedTabs;
     let contextMoveTabToEnd = document.getElementById("context_moveToEnd");
     let allSelectedTabsAdjacent = selectedTabs.every((element, index, array) => {
       return array.length > index + 1 ? element._tPos + 1 == array[index + 1]._tPos : true;
     });
-    contextMoveTabToEnd.disabled = selectedTabs[selectedTabs.length - 1]._tPos == gBrowser.visibleTabs.length - 1 &&
+    let contextTabIsSelected = this.contextTab.multiselected;
+    let visibleTabs = gBrowser.visibleTabs;
+    let lastVisibleTab = visibleTabs[visibleTabs.length - 1];
+    let tabsToMove = contextTabIsSelected ? selectedTabs : [this.contextTab];
+    let lastTabToMove = tabsToMove[tabsToMove.length - 1];
+    let isLastPinnedTab = lastTabToMove.pinned &&
+      (!lastTabToMove.nextElementSibling || !lastTabToMove.nextElementSibling.pinned);
+    contextMoveTabToEnd.disabled = (lastTabToMove == lastVisibleTab || isLastPinnedTab) &&
                                    allSelectedTabsAdjacent;
     let contextMoveTabToStart = document.getElementById("context_moveToStart");
-    contextMoveTabToStart.disabled = selectedTabs[0]._tPos == 0 && allSelectedTabsAdjacent;
+    let isFirstTab = tabsToMove[0] == visibleTabs[0] ||
+                     tabsToMove[0] == visibleTabs[gBrowser._numPinnedTabs];
+    contextMoveTabToStart.disabled = isFirstTab && allSelectedTabsAdjacent;
 
     // Only one of "Duplicate Tab"/"Duplicate Tabs" should be visible.
     document.getElementById("context_duplicateTab").hidden = multiselectionContext;
     document.getElementById("context_duplicateTabs").hidden = !multiselectionContext;
 
     // Disable "Close Tabs to the Right" if there are no tabs
     // following it.
     document.getElementById("context_closeTabsToTheEnd").disabled =
--- a/browser/base/content/test/tabs/browser.ini
+++ b/browser/base/content/test/tabs/browser.ini
@@ -27,16 +27,17 @@ support-files =
 [browser_multiselect_tabs_close_using_shortcuts.js]
 [browser_multiselect_tabs_close.js]
 [browser_multiselect_tabs_copy_through_drag_and_drop.js]
 [browser_multiselect_tabs_drag_to_bookmarks_toolbar.js]
 [browser_multiselect_tabs_duplicate.js]
 [browser_multiselect_tabs_event.js]
 [browser_multiselect_tabs_move_to_another_window_drag.js]
 [browser_multiselect_tabs_move_to_new_window_contextmenu.js]
+[browser_multiselect_tabs_move.js]
 [browser_multiselect_tabs_mute_unmute.js]
 [browser_multiselect_tabs_open_related.js]
 [browser_multiselect_tabs_pin_unpin.js]
 [browser_multiselect_tabs_positional_attrs.js]
 [browser_multiselect_tabs_reload.js]
 [browser_multiselect_tabs_reopen_in_container.js]
 [browser_multiselect_tabs_reorder.js]
 [browser_multiselect_tabs_using_Ctrl.js]
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/tabs/browser_multiselect_tabs_move.js
@@ -0,0 +1,200 @@
+const PREF_MULTISELECT_TABS = "browser.tabs.multiselect";
+
+add_task(async function setPref() {
+  await SpecialPowers.pushPrefEnv({
+    set: [[PREF_MULTISELECT_TABS, true]],
+  });
+});
+
+add_task(async function testMoveStartEnabledClickedFromNonSelectedTab() {
+  let tab = gBrowser.selectedTab;
+  let tab2 = await addTab();
+  let tab3 = await addTab();
+
+  let tabs = [tab2, tab3];
+
+  let menuItemMoveStartTab = document.getElementById("context_moveToStart");
+
+  await triggerClickOn(tab, {});
+  await triggerClickOn(tab2, { ctrlKey: true });
+
+  ok(tab.multiselected, "Tab is multiselected");
+  ok(tab2.multiselected, "Tab2 is multiselected");
+
+  updateTabContextMenu(tab3);
+  is(menuItemMoveStartTab.disabled, false, "Move Tab to Start is enabled");
+
+  for (let tabToRemove of tabs) {
+    BrowserTestUtils.removeTab(tabToRemove);
+  }
+});
+
+add_task(async function testMoveStartDisabledFromFirstUnpinnedTab() {
+  let tab = gBrowser.selectedTab;
+  let tab2 = await addTab();
+
+  let menuItemMoveStartTab = document.getElementById("context_moveToStart");
+
+  gBrowser.pinTab(tab);
+
+  updateTabContextMenu(tab2);
+  is(menuItemMoveStartTab.disabled, true, "Move Tab to Start is disabled");
+
+  BrowserTestUtils.removeTab(tab2);
+  gBrowser.unpinTab(tab);
+});
+
+add_task(async function testMoveStartDisabledFromFirstPinnedTab() {
+  let tab = gBrowser.selectedTab;
+  let tab2 = await addTab();
+
+  let menuItemMoveStartTab = document.getElementById("context_moveToStart");
+
+  gBrowser.pinTab(tab);
+
+  updateTabContextMenu(tab);
+  is(menuItemMoveStartTab.disabled, true, "Move Tab to Start is disabled");
+
+  BrowserTestUtils.removeTab(tab2);
+  gBrowser.unpinTab(tab);
+});
+
+add_task(async function testMoveStartDisabledFromOnlyTab() {
+  let tab = gBrowser.selectedTab;
+
+  let menuItemMoveStartTab = document.getElementById("context_moveToStart");
+
+  updateTabContextMenu(tab);
+  is(menuItemMoveStartTab.disabled, true, "Move Tab to Start is disabled");
+});
+
+add_task(async function testMoveStartDisabledFromOnlyPinnedTab() {
+  let tab = gBrowser.selectedTab;
+
+  let menuItemMoveStartTab = document.getElementById("context_moveToStart");
+
+  gBrowser.pinTab(tab);
+
+  updateTabContextMenu(tab);
+  is(menuItemMoveStartTab.disabled, true, "Move Tab to Start is disabled");
+
+  gBrowser.unpinTab(tab);
+});
+
+add_task(async function testMoveStartEnabledFromLastPinnedTab() {
+  let tab = gBrowser.selectedTab;
+  let tab2 = await addTab();
+  let tab3 = await addTab();
+
+  let tabs = [tab2, tab3];
+
+  let menuItemMoveStartTab = document.getElementById("context_moveToStart");
+
+  gBrowser.pinTab(tab);
+  gBrowser.pinTab(tab2);
+
+  updateTabContextMenu(tab2);
+  is(menuItemMoveStartTab.disabled, false, "Move Tab to Start is enabled");
+
+  for (let tabToRemove of tabs) {
+    BrowserTestUtils.removeTab(tabToRemove);
+  }
+
+  gBrowser.unpinTab(tab);
+});
+
+add_task(async function testMoveStartDisabledFromFirstVisibleTab() {
+  let tab = gBrowser.selectedTab;
+  let tab2 = await addTab();
+
+  let menuItemMoveStartTab = document.getElementById("context_moveToStart");
+
+  gBrowser.selectTabAtIndex(1);
+  gBrowser.hideTab(tab);
+
+  updateTabContextMenu(tab2);
+  is(menuItemMoveStartTab.disabled, true, "Move Tab to Start is disabled");
+
+  BrowserTestUtils.removeTab(tab2);
+  gBrowser.showTab(tab);
+});
+
+add_task(async function testMoveEndEnabledClickedFromNonSelectedTab() {
+  let tab = gBrowser.selectedTab;
+  let tab2 = await addTab();
+  let tab3 = await addTab();
+
+  let tabs = [tab2, tab3];
+
+  let menuItemMoveEndTab = document.getElementById("context_moveToEnd");
+
+  await triggerClickOn(tab2, {});
+  await triggerClickOn(tab3, { ctrlKey: true });
+
+  ok(tab2.multiselected, "Tab2 is multiselected");
+  ok(tab3.multiselected, "Tab3 is multiselected");
+
+  updateTabContextMenu(tab);
+  is(menuItemMoveEndTab.disabled, false, "Move Tab to End is enabled");
+
+  for (let tabToRemove of tabs) {
+    BrowserTestUtils.removeTab(tabToRemove);
+  }
+});
+
+add_task(async function testMoveEndDisabledFromLastPinnedTab() {
+  let tab = gBrowser.selectedTab;
+  let tab2 = await addTab();
+  let tab3 = await addTab();
+
+  let tabs = [tab2, tab3];
+
+  let menuItemMoveEndTab = document.getElementById("context_moveToEnd");
+
+  gBrowser.pinTab(tab);
+  gBrowser.pinTab(tab2);
+
+  updateTabContextMenu(tab2);
+  is(menuItemMoveEndTab.disabled, true, "Move Tab to End is disabled");
+
+  for (let tabToRemove of tabs) {
+    BrowserTestUtils.removeTab(tabToRemove);
+  }
+});
+
+add_task(async function testMoveEndDisabledFromLastVisibleTab() {
+  let tab = gBrowser.selectedTab;
+  let tab2 = await addTab();
+
+  let menuItemMoveEndTab = document.getElementById("context_moveToEnd");
+
+  gBrowser.hideTab(tab2);
+
+  updateTabContextMenu(tab);
+  is(menuItemMoveEndTab.disabled, true, "Move Tab to End is disabled");
+
+  BrowserTestUtils.removeTab(tab2);
+  gBrowser.showTab(tab);
+});
+
+add_task(async function testMoveEndDisabledFromOnlyTab() {
+  let tab = gBrowser.selectedTab;
+
+  let menuItemMoveEndTab = document.getElementById("context_moveToEnd");
+
+  updateTabContextMenu(tab);
+  is(menuItemMoveEndTab.disabled, true, "Move Tab to End is disabled");
+});
+
+add_task(async function testMoveEndDisabledFromOnlyPinnedTab() {
+  let tab = gBrowser.selectedTab;
+
+  let menuItemMoveEndTab = document.getElementById("context_moveToEnd");
+
+  gBrowser.pinTab(tab);
+
+  updateTabContextMenu(tab);
+  is(menuItemMoveEndTab.disabled, true, "Move Tab to End is disabled");
+
+  gBrowser.unpinTab(tab);
+});