зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1214007 - Implement chrome.tabs.move. r=billm
This commit is contained in:
Родитель
9981852508
Коммит
5847404799
|
@ -536,6 +536,82 @@ extensions.registerSchemaAPI("tabs", null, (extension, context) => {
|
|||
}
|
||||
return context.messenger.sendMessage(mm, message, recipient, responseCallback);
|
||||
},
|
||||
|
||||
move: function(tabIds, moveProperties, callback) {
|
||||
let index = moveProperties.index;
|
||||
let tabsMoved = [];
|
||||
if (!Array.isArray(tabIds)) {
|
||||
tabIds = [tabIds];
|
||||
}
|
||||
|
||||
let destinationWindow = null;
|
||||
if (moveProperties.windowId !== null) {
|
||||
destinationWindow = WindowManager.getWindow(moveProperties.windowId);
|
||||
// Ignore invalid window.
|
||||
if (!destinationWindow) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Indexes are maintained on a per window basis so that a call to
|
||||
move([tabA, tabB], {index: 0})
|
||||
-> tabA to 0, tabB to 1 if tabA and tabB are in the same window
|
||||
move([tabA, tabB], {index: 0})
|
||||
-> tabA to 0, tabB to 0 if tabA and tabB are in different windows
|
||||
*/
|
||||
let indexMap = new Map();
|
||||
|
||||
for (let tabId of tabIds) {
|
||||
let tab = TabManager.getTab(tabId);
|
||||
// Ignore invalid tab ids.
|
||||
if (!tab) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If the window is not specified, use the window from the tab.
|
||||
let window = destinationWindow || tab.ownerDocument.defaultView;
|
||||
let windowId = WindowManager.getId(window);
|
||||
let gBrowser = window.gBrowser;
|
||||
|
||||
let getInsertionPoint = () => {
|
||||
let point = indexMap.get(window) || index;
|
||||
// If the index is -1 it should go to the end of the tabs.
|
||||
if (point == -1) {
|
||||
point = gBrowser.tabs.length;
|
||||
}
|
||||
indexMap.set(window, point + 1);
|
||||
return point;
|
||||
};
|
||||
|
||||
if (WindowManager.getId(tab.ownerDocument.defaultView) !== windowId) {
|
||||
// If the window we are moving the tab in is different, then move the tab
|
||||
// to the new window.
|
||||
let newTab = gBrowser.addTab('about:blank');
|
||||
let newBrowser = gBrowser.getBrowserForTab(newTab);
|
||||
gBrowser.updateBrowserRemotenessByURL(newBrowser, tab.linkedBrowser.currentURI.spec);
|
||||
newBrowser.stop();
|
||||
newBrowser.docShell;
|
||||
|
||||
if (tab.pinned) {
|
||||
gBrowser.pinTab(newTab);
|
||||
}
|
||||
|
||||
gBrowser.moveTabTo(newTab, getInsertionPoint());
|
||||
|
||||
tab.parentNode._finishAnimateTabMove();
|
||||
gBrowser.swapBrowsersAndCloseOther(newTab, tab);
|
||||
} else {
|
||||
// If the window we are moving is the same, just move the tab.
|
||||
gBrowser.moveTabTo(tab, getInsertionPoint());
|
||||
}
|
||||
tabsMoved.push(tab);
|
||||
}
|
||||
|
||||
if (callback) {
|
||||
runSafe(context, callback, tabsMoved.map(tab => TabManager.convert(extension, tab)));
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
return self;
|
||||
|
|
|
@ -27,6 +27,8 @@ support-files =
|
|||
[browser_ext_tabs_update.js]
|
||||
[browser_ext_tabs_onUpdated.js]
|
||||
[browser_ext_tabs_sendMessage.js]
|
||||
[browser_ext_tabs_move.js]
|
||||
[browser_ext_tabs_move_window.js]
|
||||
[browser_ext_windows_update.js]
|
||||
[browser_ext_contentscript_connect.js]
|
||||
[browser_ext_tab_runtimeConnect.js]
|
||||
|
|
|
@ -0,0 +1,117 @@
|
|||
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set sts=2 sw=2 et tw=80: */
|
||||
"use strict";
|
||||
|
||||
add_task(function* () {
|
||||
let tab1 = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:robots");
|
||||
let tab2 = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:config");
|
||||
|
||||
gBrowser.selectedTab = tab1
|
||||
|
||||
let extension = ExtensionTestUtils.loadExtension({
|
||||
manifest: {
|
||||
"permissions": ["tabs"]
|
||||
},
|
||||
|
||||
background: function() {
|
||||
browser.tabs.query({
|
||||
lastFocusedWindow: true,
|
||||
}, function(tabs) {
|
||||
var tab = tabs[0];
|
||||
chrome.tabs.move(tab.id, {index: 0});
|
||||
browser.tabs.query({
|
||||
lastFocusedWindow: true,
|
||||
}, function(tabs) {
|
||||
browser.test.assertEq(tabs[0].url, tab.url, "should be first tab");
|
||||
browser.test.notifyPass("tabs.move.single");
|
||||
});
|
||||
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
yield extension.startup();
|
||||
yield extension.awaitFinish("tabs.move.single");
|
||||
yield extension.unload();
|
||||
|
||||
extension = ExtensionTestUtils.loadExtension({
|
||||
manifest: {
|
||||
"permissions": ["tabs"]
|
||||
},
|
||||
|
||||
background: function() {
|
||||
browser.tabs.query({
|
||||
lastFocusedWindow: true,
|
||||
}, function(tabs) {
|
||||
tabs.sort(function(a, b) { return a.url > b.url; });
|
||||
chrome.tabs.move(tabs.map(tab => tab.id), {index: 0});
|
||||
chrome.tabs.query({
|
||||
lastFocusedWindow: true,
|
||||
}, function(tabs) {
|
||||
browser.test.assertEq(tabs[0].url, "about:blank", "should be first tab");
|
||||
browser.test.assertEq(tabs[1].url, "about:config", "should be second tab");
|
||||
browser.test.assertEq(tabs[2].url, "about:robots", "should be third tab");
|
||||
browser.test.notifyPass("tabs.move.multiple");
|
||||
});
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
yield extension.startup();
|
||||
yield extension.awaitFinish("tabs.move.multiple");
|
||||
yield extension.unload();
|
||||
|
||||
extension = ExtensionTestUtils.loadExtension({
|
||||
manifest: {
|
||||
"permissions": ["tabs"]
|
||||
},
|
||||
|
||||
background: function() {
|
||||
browser.tabs.query({
|
||||
lastFocusedWindow: true,
|
||||
}, function(tabs) {
|
||||
var tab = tabs[0];
|
||||
// Assuming that tab.id of 12345 does not exist.
|
||||
chrome.tabs.move([12345, tab.id], {index: 0});
|
||||
chrome.tabs.query({
|
||||
lastFocusedWindow: true,
|
||||
}, function(tabs) {
|
||||
browser.test.assertEq(tabs[0].url, tab.url, "should be first tab");
|
||||
browser.test.notifyPass("tabs.move.invalid");
|
||||
});
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
yield extension.startup();
|
||||
yield extension.awaitFinish("tabs.move.invalid");
|
||||
yield extension.unload();
|
||||
|
||||
extension = ExtensionTestUtils.loadExtension({
|
||||
manifest: {
|
||||
"permissions": ["tabs"]
|
||||
},
|
||||
|
||||
background: function() {
|
||||
browser.tabs.query({
|
||||
lastFocusedWindow: true,
|
||||
}, function(tabs) {
|
||||
var tab = tabs[0];
|
||||
chrome.tabs.move(tab.id, {index: -1});
|
||||
chrome.tabs.query({
|
||||
lastFocusedWindow: true,
|
||||
}, function(tabs) {
|
||||
browser.test.assertEq(tabs[2].url, tab.url, "should be last tab");
|
||||
browser.test.notifyPass("tabs.move.last");
|
||||
});
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
yield extension.startup();
|
||||
yield extension.awaitFinish("tabs.move.last");
|
||||
yield extension.unload();
|
||||
|
||||
yield BrowserTestUtils.removeTab(tab1);
|
||||
yield BrowserTestUtils.removeTab(tab2);
|
||||
});
|
|
@ -0,0 +1,123 @@
|
|||
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set sts=2 sw=2 et tw=80: */
|
||||
"use strict";
|
||||
|
||||
add_task(function* () {
|
||||
let tab0 = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "http://example.net/");
|
||||
let window1 = yield BrowserTestUtils.openNewBrowserWindow();
|
||||
let tab1 = yield BrowserTestUtils.openNewForegroundTab(window1.gBrowser, "http://example.com/");
|
||||
|
||||
let extension = ExtensionTestUtils.loadExtension({
|
||||
manifest: {
|
||||
"permissions": ["tabs"]
|
||||
},
|
||||
|
||||
background: function() {
|
||||
chrome.tabs.query({
|
||||
url: '<all_urls>',
|
||||
}, function(tabs) {
|
||||
let destination = tabs[0];
|
||||
let source = tabs[1]; // skip over about:blank in window1
|
||||
chrome.tabs.move(source.id, {windowId: destination.windowId, index: 0});
|
||||
|
||||
chrome.tabs.query({
|
||||
url: '<all_urls>',
|
||||
}, function(tabs) {
|
||||
browser.test.assertEq(tabs[0].url, "http://example.com/");
|
||||
browser.test.assertEq(tabs[0].windowId, destination.windowId);
|
||||
browser.test.notifyPass("tabs.move.window");
|
||||
});
|
||||
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
yield extension.startup();
|
||||
yield extension.awaitFinish("tabs.move.window");
|
||||
yield extension.unload();
|
||||
|
||||
for (let tab of window.gBrowser.tabs) {
|
||||
yield BrowserTestUtils.removeTab(tab);
|
||||
}
|
||||
yield BrowserTestUtils.closeWindow(window1);
|
||||
});
|
||||
|
||||
add_task(function* () {
|
||||
let tab0 = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "http://example.net/");
|
||||
let window1 = yield BrowserTestUtils.openNewBrowserWindow();
|
||||
let tab1 = yield BrowserTestUtils.openNewForegroundTab(window1.gBrowser, "http://example.com/");
|
||||
window1.gBrowser.pinTab(tab1);
|
||||
|
||||
let extension = ExtensionTestUtils.loadExtension({
|
||||
manifest: {
|
||||
"permissions": ["tabs"]
|
||||
},
|
||||
|
||||
background: function() {
|
||||
chrome.tabs.query({
|
||||
url: '<all_urls>',
|
||||
}, function(tabs) {
|
||||
let destination = tabs[0];
|
||||
let source = tabs[1]; // remember, pinning moves it to the left.
|
||||
chrome.tabs.move(source.id, {windowId: destination.windowId, index: 0});
|
||||
|
||||
chrome.tabs.query({
|
||||
url: '<all_urls>',
|
||||
}, function(tabs) {
|
||||
browser.test.assertEq(true, tabs[0].pinned);
|
||||
browser.test.notifyPass("tabs.move.pin");
|
||||
});
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
yield extension.startup();
|
||||
yield extension.awaitFinish("tabs.move.pin");
|
||||
yield extension.unload();
|
||||
|
||||
for (let tab of window.gBrowser.tabs) {
|
||||
yield BrowserTestUtils.removeTab(tab);
|
||||
}
|
||||
yield BrowserTestUtils.closeWindow(window1);
|
||||
});
|
||||
|
||||
add_task(function* () {
|
||||
let window1 = yield BrowserTestUtils.openNewBrowserWindow();
|
||||
let tab0 = yield BrowserTestUtils.openNewForegroundTab(window.gBrowser, "http://example.net/");
|
||||
let tab1 = yield BrowserTestUtils.openNewForegroundTab(window.gBrowser, "http://example.com/");
|
||||
let tab2 = yield BrowserTestUtils.openNewForegroundTab(window1.gBrowser, "http://example.net/");
|
||||
let tab3 = yield BrowserTestUtils.openNewForegroundTab(window1.gBrowser, "http://example.com/");
|
||||
|
||||
let extension = ExtensionTestUtils.loadExtension({
|
||||
manifest: {
|
||||
"permissions": ["tabs"]
|
||||
},
|
||||
|
||||
background: function() {
|
||||
chrome.tabs.query({
|
||||
url: '<all_urls>',
|
||||
}, function(tabs) {
|
||||
let move1 = tabs[1];
|
||||
let move3 = tabs[3];
|
||||
chrome.tabs.move([move1.id, move3.id], {index: 0});
|
||||
chrome.tabs.query({
|
||||
url: '<all_urls>',
|
||||
}, function(tabs) {
|
||||
browser.test.assertEq(tabs[0].url, move1.url);
|
||||
browser.test.assertEq(tabs[2].url, move3.url);
|
||||
browser.test.notifyPass("tabs.move.multiple");
|
||||
});
|
||||
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
yield extension.startup();
|
||||
yield extension.awaitFinish("tabs.move.multiple");
|
||||
yield extension.unload();
|
||||
|
||||
for (let tab of window.gBrowser.tabs) {
|
||||
yield BrowserTestUtils.removeTab(tab);
|
||||
}
|
||||
yield BrowserTestUtils.closeWindow(window1);
|
||||
});
|
Загрузка…
Ссылка в новой задаче