зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1342207 - chrome.tabs.onActivated does not fire for new windows, r=kmag
MozReview-Commit-ID: D9Nwd9lc57x --HG-- extra : rebase_source : 76d2ff62574469ca1b0d82f4415d9fdfd6a2b8d4
This commit is contained in:
Родитель
b8d1d42a17
Коммит
948af6e263
|
@ -103,11 +103,15 @@ this.tabs = class extends ExtensionAPI {
|
|||
|
||||
let self = {
|
||||
tabs: {
|
||||
onActivated: new WindowEventManager(context, "tabs.onActivated", "TabSelect", (fire, event) => {
|
||||
let nativeTab = event.originalTarget;
|
||||
let tabId = tabTracker.getId(nativeTab);
|
||||
let windowId = windowTracker.getId(nativeTab.ownerGlobal);
|
||||
fire.async({tabId, windowId});
|
||||
onActivated: new SingletonEventManager(context, "tabs.onActivated", fire => {
|
||||
let listener = (eventName, event) => {
|
||||
fire.async(event);
|
||||
};
|
||||
|
||||
tabTracker.on("tab-activated", listener);
|
||||
return () => {
|
||||
tabTracker.off("tab-activated", listener);
|
||||
};
|
||||
}).api(),
|
||||
|
||||
onCreated: new SingletonEventManager(context, "tabs.onCreated", fire => {
|
||||
|
@ -127,11 +131,15 @@ this.tabs = class extends ExtensionAPI {
|
|||
* 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 nativeTab = event.originalTarget;
|
||||
let tabIds = [tabTracker.getId(nativeTab)];
|
||||
let windowId = windowTracker.getId(nativeTab.ownerGlobal);
|
||||
fire.async({tabIds, windowId});
|
||||
onHighlighted: new SingletonEventManager(context, "tabs.onHighlighted", fire => {
|
||||
let listener = (eventName, event) => {
|
||||
fire.async({tabIds: [event.tabId], windowId: event.windowId});
|
||||
};
|
||||
|
||||
tabTracker.on("tab-activated", listener);
|
||||
return () => {
|
||||
tabTracker.off("tab-activated", listener);
|
||||
};
|
||||
}).api(),
|
||||
|
||||
onAttached: new SingletonEventManager(context, "tabs.onAttached", fire => {
|
||||
|
|
|
@ -156,6 +156,7 @@ class TabTracker extends TabTrackerBase {
|
|||
|
||||
windowTracker.addListener("TabClose", this);
|
||||
windowTracker.addListener("TabOpen", this);
|
||||
windowTracker.addListener("TabSelect", this);
|
||||
windowTracker.addOpenListener(this._handleWindowOpen);
|
||||
windowTracker.addCloseListener(this._handleWindowClose);
|
||||
|
||||
|
@ -263,6 +264,14 @@ class TabTracker extends TabTrackerBase {
|
|||
this.emitRemoved(nativeTab, false);
|
||||
}
|
||||
break;
|
||||
|
||||
case "TabSelect":
|
||||
// Because we are delaying calling emitCreated above, we also need to
|
||||
// delay sending this event because it shouldn't fire before onCreated.
|
||||
Promise.resolve().then(() => {
|
||||
this.emitActivated(nativeTab);
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -308,6 +317,9 @@ class TabTracker extends TabTrackerBase {
|
|||
for (let nativeTab of window.gBrowser.tabs) {
|
||||
this.emitCreated(nativeTab);
|
||||
}
|
||||
|
||||
// emitActivated to trigger tab.onActivated/tab.onHighlighted for a newly opened window.
|
||||
this.emitActivated(window.gBrowser.tabs[0]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -329,6 +341,19 @@ class TabTracker extends TabTrackerBase {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Emits a "tab-activated" event for the given tab element.
|
||||
*
|
||||
* @param {NativeTab} nativeTab
|
||||
* The tab element which has been activated.
|
||||
* @private
|
||||
*/
|
||||
emitActivated(nativeTab) {
|
||||
this.emit("tab-activated", {
|
||||
tabId: this.getId(nativeTab),
|
||||
windowId: windowTracker.getId(nativeTab.ownerGlobal)});
|
||||
}
|
||||
|
||||
/**
|
||||
* Emits a "tab-attached" event for the given tab element.
|
||||
*
|
||||
|
|
|
@ -25,6 +25,14 @@ add_task(function* testTabEvents() {
|
|||
}
|
||||
});
|
||||
|
||||
browser.tabs.onCreated.addListener((info) => {
|
||||
if (info.id in events) {
|
||||
events[info.id].push("onCreated");
|
||||
} else {
|
||||
events[info.id] = ["onCreated"];
|
||||
}
|
||||
});
|
||||
|
||||
browser.tabs.onHighlighted.addListener((info) => {
|
||||
if (info.tabIds[0] in events) {
|
||||
events[info.tabIds[0]].push("onHighlighted");
|
||||
|
@ -43,7 +51,10 @@ add_task(function* testTabEvents() {
|
|||
async function expectEvents(tabId, expectedEvents) {
|
||||
browser.test.log(`Expecting events: ${expectedEvents.join(", ")}`);
|
||||
|
||||
await new Promise(resolve => setTimeout(resolve, 0));
|
||||
// Wait up to 5 ticks for the expected number of events.
|
||||
for (let i = 0; i < 5 && (!events[tabId] || events[tabId].length < expectedEvents.length); i++) {
|
||||
await new Promise(resolve => setTimeout(resolve, 0));
|
||||
}
|
||||
|
||||
browser.test.assertEq(expectedEvents.length, events[tabId].length,
|
||||
`Got expected number of events for ${tabId}`);
|
||||
|
@ -61,23 +72,58 @@ add_task(function* testTabEvents() {
|
|||
* @param {number} windowId
|
||||
*/
|
||||
async function openTab(windowId) {
|
||||
browser.test.assertEq(0, Object.keys(events).length,
|
||||
"No events remaining before testing openTab.");
|
||||
|
||||
let tab = await browser.tabs.create({windowId});
|
||||
|
||||
tabIds.push(tab.id);
|
||||
browser.test.log(`Opened tab ${tab.id}`);
|
||||
|
||||
await expectEvents(tab.id, [
|
||||
"onCreated",
|
||||
"onActivated",
|
||||
"onHighlighted",
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a new window and asserts that the correct events are fired.
|
||||
*
|
||||
* @param {Array} urls A list of urls for which to open tabs in the new window.
|
||||
*/
|
||||
async function openWindow(urls) {
|
||||
browser.test.assertEq(0, Object.keys(events).length,
|
||||
"No events remaining before testing openWindow.");
|
||||
|
||||
let window = await browser.windows.create({url: urls});
|
||||
browser.test.log(`Opened new window ${window.id}`);
|
||||
|
||||
for (let [i] of urls.entries()) {
|
||||
let tab = window.tabs[i];
|
||||
tabIds.push(tab.id);
|
||||
|
||||
let expectedEvents = [
|
||||
"onCreated",
|
||||
"onActivated",
|
||||
"onHighlighted",
|
||||
];
|
||||
if (i !== 0) {
|
||||
expectedEvents.splice(1);
|
||||
}
|
||||
await expectEvents(window.tabs[i].id, expectedEvents);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Highlights an existing tab and asserts that the correct events are fired.
|
||||
*
|
||||
* @param {number} tabId
|
||||
*/
|
||||
async function highlightTab(tabId) {
|
||||
browser.test.assertEq(0, Object.keys(events).length,
|
||||
"No events remaining before testing highlightTab.");
|
||||
|
||||
browser.test.log(`Highlighting tab ${tabId}`);
|
||||
let tab = await browser.tabs.update(tabId, {active: true});
|
||||
|
||||
|
@ -107,6 +153,15 @@ add_task(function* testTabEvents() {
|
|||
highlightTab(tabIds[2]),
|
||||
]);
|
||||
|
||||
await Promise.all([
|
||||
openWindow(["http://example.com"]),
|
||||
openWindow(["http://example.com", "http://example.org"]),
|
||||
openWindow(["http://example.com", "http://example.org", "http://example.net"]),
|
||||
]);
|
||||
|
||||
browser.test.assertEq(0, Object.keys(events).length,
|
||||
"No events remaining after tests.");
|
||||
|
||||
await Promise.all(tabIds.map(id => browser.tabs.remove(id)));
|
||||
|
||||
browser.test.notifyPass("tabs.highlight");
|
||||
|
|
Загрузка…
Ссылка в новой задаче