Bug 1220124 - Add support for chrome.tabs.onhighlight. r=kmag
MozReview-Commit-ID: BB6vJl8qV4l
--- a/browser/components/extensions/ext-tabs.js
+++ b/browser/components/extensions/ext-tabs.js
@@ -149,16 +149,29 @@ extensions.registerSchemaAPI("tabs", nul
WindowListManager.addOpenListener(windowListener);
AllWindowEvents.addListener("TabOpen", listener);
return () => {
WindowListManager.removeOpenListener(windowListener);
AllWindowEvents.removeListener("TabOpen", listener);
};
}).api(),
+ /**
+ * Since multiple tabs currently can't be highlighted, onHighlighted
+ * essentially acts an alias for self.tabs.onActivated but returns
+ * the tabId in an array to match the API.
+ * @see https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/Tabs/onHighlighted
+ */
+ onHighlighted: new WindowEventManager(context, "tabs.onHighlighted", "TabSelect", (fire, event) => {
+ let tab = event.originalTarget;
+ let tabIds = [TabManager.getId(tab)];
+ let windowId = WindowManager.getId(tab.ownerDocument.defaultView);
+ fire({tabIds, windowId});
+ }).api(),
+
onAttached: new EventManager(context, "tabs.onAttached", fire => {
let fireForTab = tab => {
let newWindowId = WindowManager.getId(tab.ownerDocument.defaultView);
fire(TabManager.getId(tab), {newWindowId, newPosition: tab._tPos});
};
let listener = event => {
if (event.detail.adoptedTab) {
--- a/browser/components/extensions/test/browser/browser.ini
+++ b/browser/components/extensions/test/browser/browser.ini
@@ -39,13 +39,14 @@ support-files =
[browser_ext_tabs_create_invalid_url.js]
[browser_ext_tabs_duplicate.js]
[browser_ext_tabs_update.js]
[browser_ext_tabs_update_url.js]
[browser_ext_tabs_onUpdated.js]
[browser_ext_tabs_sendMessage.js]
[browser_ext_tabs_move.js]
[browser_ext_tabs_move_window.js]
+[browser_ext_tabs_onHighlighted.js]
[browser_ext_windows_create_tabId.js]
[browser_ext_windows_update.js]
[browser_ext_contentscript_connect.js]
[browser_ext_tab_runtimeConnect.js]
[browser_ext_webNavigation_getFrames.js]
new file mode 100644
--- /dev/null
+++ b/browser/components/extensions/test/browser/browser_ext_tabs_onHighlighted.js
@@ -0,0 +1,118 @@
+/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* vim: set sts=2 sw=2 et tw=80: */
+"use strict";
+
+add_task(function* testTabEvents() {
+ function background() {
+ /** The list of active tab ID's */
+ let tabIds = [];
+
+ /**
+ * Stores the events that fire for each tab.
+ *
+ * events {
+ * tabId1: [event1, event2, ...],
+ * tabId2: [event1, event2, ...],
+ * }
+ */
+ let events = {};
+
+ browser.tabs.onActivated.addListener((info) => {
+ if (info.tabId in events) {
+ events[info.tabId].push("onActivated");
+ } else {
+ events[info.tabId] = ["onActivated"];
+ }
+ });
+
+ browser.tabs.onHighlighted.addListener((info) => {
+ if (info.tabIds[0] in events) {
+ events[info.tabIds[0]].push("onHighlighted");
+ } else {
+ events[info.tabIds[0]] = ["onHighlighted"];
+ }
+ });
+
+ /**
+ * Asserts that the expected events are fired for the tab with id = tabId.
+ * The events associated to the specified tab are removed after this check is made.
+ */
+ function expectEvents(tabId, expectedEvents) {
+ browser.test.log(`Expecting events: ${expectedEvents.join(", ")}`);
+
+ return new Promise(resolve => {
+ setTimeout(resolve, 0);
+ }).then(() => {
+ browser.test.assertEq(expectedEvents.length, events[tabId].length,
+ `Got expected number of events for ${tabId}`);
+ for (let [i, name] of expectedEvents.entries()) {
+ browser.test.assertEq(name, i in events[tabId] && events[tabId][i],
+ `Got expected ${name} event`);
+ }
+ delete events[tabId];
+ });
+ }
+
+ /**
+ * Opens a new tab and asserts that the correct events are fired.
+ */
+ function openTab(windowId) {
+ return browser.tabs.create({windowId}).then(tab => {
+ tabIds.push(tab.id);
+ browser.test.log(`Opened tab ${tab.id}`);
+ return expectEvents(tab.id, [
+ "onActivated",
+ "onHighlighted",
+ ]);
+ });
+ }
+
+ /**
+ * Highlights an existing tab and asserts that the correct events are fired.
+ */
+ function highlightTab(tabId) {
+ browser.test.log(`Highlighting tab ${tabId}`);
+ return browser.tabs.update(tabId, {active: true}).then(tab => {
+ browser.test.assertEq(tab.id, tabId, `Tab ${tab.id} highlighted`);
+ return expectEvents(tab.id, [
+ "onActivated",
+ "onHighlighted",
+ ]);
+ });
+ }
+
+ /**
+ * The main entry point to the tests.
+ */
+ browser.tabs.query({active: true, currentWindow: true}, tabs => {
+ let activeWindow = tabs[0].windowId;
+ Promise.all([
+ openTab(activeWindow),
+ openTab(activeWindow),
+ openTab(activeWindow),
+ ]).then(() => {
+ return Promise.all([
+ highlightTab(tabIds[0]),
+ highlightTab(tabIds[1]),
+ highlightTab(tabIds[2]),
+ ]);
+ }).then(() => {
+ return Promise.all(tabIds.map(id => browser.tabs.remove(id)));
+ }).then(() => {
+ browser.test.notifyPass("tabs.highlight");
+ });
+ });
+ }
+
+ let extension = ExtensionTestUtils.loadExtension({
+ manifest: {
+ "permissions": ["tabs"],
+ },
+
+ background,
+ });
+
+ yield extension.startup();
+ yield extension.awaitFinish("tabs.highlight");
+ yield extension.unload();
+});