diff --git a/lib/bus.ts b/lib/bus.ts index 0c580db..e132f6a 100644 --- a/lib/bus.ts +++ b/lib/bus.ts @@ -8,32 +8,35 @@ import {runtime, tabs, RawPort, MessageSender} from "./browser"; export class Port extends EventEmitter { private port: RawPort | null; + private disconnected = false; + constructor(port: RawPort) { super(); this.port = port; - let disconnected = false; - const disconnect = () => { - if (disconnected) { - return; - } - disconnected = true; - this.port = null; // Break the cycle - this.emit("disconnect", this, port); - }; // Nasty firefox bug, thus listen for tab removal explicitly if (port.sender && port.sender.tab && port.sender.tab.id) { const otherTabId = port.sender.tab.id; - const tabListener = function(tabId: number) { + const tabListener = (tabId: number) => { if (tabId !== otherTabId) { return; } - disconnect(); + this.disconnect(); }; tabs.onRemoved.addListener(tabListener); } port.onMessage.addListener(this.onMessage.bind(this)); - port.onDisconnect.addListener(disconnect); + port.onDisconnect.addListener(this.disconnect.bind(this)); + } + + disconnect() { + if (this.disconnected) { + return; + } + this.disconnected = true; + const {port} = this; + this.port = null; // Break the cycle + this.emit("disconnect", this, port); } get name() { @@ -120,6 +123,9 @@ export const Bus = new class extends EventEmitter { port.disconnect(); return; } - this.ports.emit(port.name, new Port(port)); + const wrapped = new Port(port); + if (!this.ports.emit(port.name, wrapped)) { + wrapped.disconnect(); + } } }(); diff --git a/lib/manager/man.ts b/lib/manager/man.ts index 6bac439..032579e 100644 --- a/lib/manager/man.ts +++ b/lib/manager/man.ts @@ -93,6 +93,7 @@ export class Manager extends EventEmitter { this.ports.delete(mport); }); this.ports.add(mport); + return true; }); Limits.on("changed", () => { this.resetScheduler(); diff --git a/lib/select.ts b/lib/select.ts index 77ffba6..bfc1bc5 100644 --- a/lib/select.ts +++ b/lib/select.ts @@ -101,7 +101,10 @@ export async function select(links: BaseItem[], media: BaseItem[]) { tracker.track(window.id, null); try { const port = await Promise.race([ - new Promise(resolve => Bus.oncePort("select", resolve)), + new Promise(resolve => Bus.oncePort("select", port => { + resolve(port); + return true; + })), timeout(5 * 1000)]); if (!port.isSelf) { throw Error("Invalid sender connected"); diff --git a/lib/single.ts b/lib/single.ts index 26b2712..4488715 100644 --- a/lib/single.ts +++ b/lib/single.ts @@ -24,7 +24,10 @@ export async function single(item: BaseItem | null) { tracker.track(window.id, null); try { const port: Port = await Promise.race([ - new Promise(resolve => Bus.oncePort("single", resolve)), + new Promise(resolve => Bus.oncePort("single", port => { + resolve(port); + return true; + })), timeout(5 * 1000)]); if (!port.isSelf) { throw Error("Invalid sender connected");