diff --git a/background_scripts/commands.js b/background_scripts/commands.js index 8fa8c29c4..1b278482e 100644 --- a/background_scripts/commands.js +++ b/background_scripts/commands.js @@ -346,6 +346,10 @@ const Commands = { "removeTab", "restoreTab", "moveTabToNewWindow", + "mergeTabToExistingWindowOnLeft", + "mergeTabToExistingWindowOnRight", + "mergeTabToExistingWindowAbove", + "mergeTabToExistingWindowBelow", "closeTabsOnLeft", "closeTabsOnRight", "closeOtherTabs", @@ -366,6 +370,10 @@ const Commands = { "scrollToLeft", "scrollToRight", "moveTabToNewWindow", + "mergeTabToExistingWindowOnLeft", + "mergeTabToExistingWindowOnRight", + "mergeTabToExistingWindowAbove", + "mergeTabToExistingWindowBelow", "goUp", "goToRoot", "LinkHints.activateModeWithQueue", @@ -459,6 +467,10 @@ const defaultKeyMappings = { "g0": "firstTab", "g$": "lastTab", "W": "moveTabToNewWindow", + "wh": "mergeTabToExistingWindowOnLeft", + "wl": "mergeTabToExistingWindowOnRight", + "wk": "mergeTabToExistingWindowAbove", + "wj": "mergeTabToExistingWindowBelow", "t": "createTab", "yt": "duplicateTab", "x": "removeTab", @@ -552,6 +564,12 @@ const commandDescriptions = { restoreTab: ["Restore closed tab", { background: true, repeatLimit: 20 }], moveTabToNewWindow: ["Move tab to new window", { background: true }], + + mergeTabToExistingWindowOnLeft : ["Move tab to an existing window on left, if exists", {background: true}], + mergeTabToExistingWindowOnRight : ["Move tab to an existing window on right, if exists", {background: true}], + mergeTabToExistingWindowAbove : ["Move tab to an existing window above, if exists", {background: true}], + mergeTabToExistingWindowBelow : ["Move tab to an existing window below, if exists", {background: true}], + togglePinTab: ["Pin or unpin current tab", { background: true }], toggleMuteTab: ["Mute or unmute current tab", { background: true, noRepeat: true }], diff --git a/background_scripts/main.js b/background_scripts/main.js index 823f50187..133fadf55 100644 --- a/background_scripts/main.js +++ b/background_scripts/main.js @@ -210,6 +210,35 @@ function nextZoomLevel(currentZoom, steps) { } } +const moveTabToExistingWindow = function(orientation, currentTab) { + chrome.windows.getCurrent({}, currentWindow => { + chrome.windows.getAll({populate: true}, windows => { + const filteredWindows = windows.filter(window => { + if (window.id !== currentWindow.id) { + if (orientation === 'left') { + return window.left < currentWindow.left; + } else if (orientation === 'right') { + return window.left > currentWindow.left; + } else if (orientation === 'top') { + return window.top < currentWindow.top; + } else if (orientation === 'bottom') { + return window.top > currentWindow.top; + } + } + }); + if (filteredWindows.length > 0) { + const destinationWindow = filteredWindows[0]; + chrome.tabs.move(currentTab.id, { windowId: destinationWindow.id, index: -1 }).then(() => { + chrome.windows.get(destinationWindow.id, {populate: true}, newWindow => { + const newTab = newWindow.tabs.slice(-1)[0]; + selectSpecificTab({ id: newTab.id }); + }); + }); + } + }); + }); +}; + // These are commands which are bound to keystrokes which must be handled by the background page. // They are mapped in commands.js. const BackgroundCommands = { @@ -291,6 +320,19 @@ const BackgroundCommands = { }); }, + mergeTabToExistingWindowOnLeft(request) { + moveTabToExistingWindow("left", request.tab); + }, + mergeTabToExistingWindowOnRight(request) { + moveTabToExistingWindow("right", request.tab); + }, + mergeTabToExistingWindowAbove(request) { + moveTabToExistingWindow("top", request.tab); + }, + mergeTabToExistingWindowBelow(request) { + moveTabToExistingWindow("bottom", request.tab); + }, + nextTab(request) { return selectTab("next", request); },