changeset 24:f418a6305f17

Allow moving multiple highlighted tabs Allow moving multiple highlighted tabs using the new multiselect feature available in Firefox 62.0.
author Guido Berhoerster <guido+tab-mover@berhoerster.name>
date Sun, 25 Nov 2018 13:53:02 +0100
parents 4704e5216412
children fa504a211b26
files README background.js
diffstat 2 files changed, 31 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/README	Sun Nov 25 13:27:47 2018 +0100
+++ b/README	Sun Nov 25 13:53:02 2018 +0100
@@ -14,17 +14,16 @@
 In order to move a tab between windows, open the tab context menu by clicking
 on the tab using the right mouse button, then open the submenu named
 "Tab Mover", and finally select a window from the submenu named "Move to
-Window".
+Window".  Multiple tabs can be moved by opening the context menu on a tab
+belonging to a group of highlighted tabs (highlighting multiple tabs is
+possible starting from Firefox 62 if the preference browser.tabs.multiselect
+is set to "true").
 
 In order to close a tab in a window in incognito mode and to reopen its URL
 in a normal window or vice versa, open the tab context menu by clicking the
 tab using the right mouse button, then open the submenu named "Tab Mover", and
 finally select a window from the submenu named "Close and Reopen in Window".
 
-When using Firefox version 52 or earlier the "Tab Mover" submenu is located in
-the page context menu instead of the tab context menu. The page context menu
-can be opened by clicking anywhere on a page using the right mouse button.
-
 Contact
 -------
 
--- a/background.js	Sun Nov 25 13:27:47 2018 +0100
+++ b/background.js	Sun Nov 25 13:53:02 2018 +0100
@@ -25,20 +25,36 @@
     });
 }
 
-async function moveTab(tab, targetWindowId) {
-    browser.tabs.move(tab.id, {windowId: targetWindowId, index: -1});
+async function moveTabs(tab, targetWindowId) {
+    // if the current tab is part of a highlighted group then move the whole
+    // group
+    let selectedTabs = (tab.highlighted) ? await browser.tabs.query({
+        highlighted: true,
+        windowId: tab.windowId
+    }) : [tab];
+    browser.tabs.move(selectedTabs.map(selectedTab => selectedTab.id),
+            {windowId: targetWindowId, index: -1});
 }
 
-async function reopenTab(tab, targetWindowId) {
-    if (!ALLOWED_PROTOCOLS.has(new URL(tab.url).protocol)) {
-        // privileged tab URL which cannot be reopened
+async function reopenTabs(tab, targetWindowId) {
+    // if the current tab is part of a highlighted group then reopen the whole
+    // group
+    let selectedTabs = (tab.highlighted) ? await browser.tabs.query({
+        highlighted: true,
+        windowId: tab.windowId
+    }) : [tab];
+    // filter out privileged tabs which cannot be reopened
+    selectedTabs = selectedTabs.filter(selectedTab =>
+            ALLOWED_PROTOCOLS.has(new URL(selectedTab.url).protocol));
+    if (selectedTabs.length === 0) {
         return;
     }
-    await browser.tabs.create({
-        url: tab.url,
+
+    await Promise.all(selectedTabs.map(selectedTab => browser.tabs.create({
+        url: selectedTab.url,
         windowId: targetWindowId
-    });
-    browser.tabs.remove(tab.id);
+    })));
+    browser.tabs.remove(selectedTabs.map(selectedTab => selectedTab.id));
 }
 
 async function onMenuShown(info, tab)  {
@@ -58,14 +74,14 @@
         }
         if (tab.incognito === targetWindow.incognito) {
             creatingMenus.push(createMenuItem({
-                onclick: (info, tab) => moveTab(tab, targetWindow.id),
+                onclick: (info, tab) => moveTabs(tab, targetWindow.id),
                 parentId: 'move-menu',
                 title: targetWindow.title
             }));
             moveMenuItems++;
         } else {
             creatingMenus.push(createMenuItem({
-                onclick: (info, tab) => reopenTab(tab, targetWindow.id),
+                onclick: (info, tab) => reopenTabs(tab, targetWindow.id),
                 parentId: 'reopen-menu',
                 title: targetWindow.title
             }));