/** * @license * Copyright Google LLC All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ /// import {Events, MessageBus, Parameters} from 'protocol'; interface ChromeMessage { topic: K; args: Parameters; } type AnyEventCallback = (topic: E, args: Parameters) => void; export class ChromeMessageBus extends MessageBus { private _disconnected = false; private _listeners: any[] = []; constructor(private _port: chrome.runtime.Port) { super(); _port.onDisconnect.addListener(() => { // console.log('Disconnected the port'); this._disconnected = true; }); } onAny(cb: AnyEventCallback): () => void { const listener = (msg: ChromeMessage): void => { cb(msg.topic, msg.args); }; this._port.onMessage.addListener(listener); this._listeners.push(listener); return () => { this._listeners.splice(this._listeners.indexOf(listener), 1); this._port.onMessage.removeListener(listener); }; } on(topic: E, cb: Events[E]): () => void { const listener = (msg: ChromeMessage): void => { if (msg.topic === topic) { cb.apply(null, msg.args); } }; this._port.onMessage.addListener(listener); this._listeners.push(listener); return () => { this._listeners.splice(this._listeners.indexOf(listener), 1); this._port.onMessage.removeListener(listener); }; } once(topic: E, cb: Events[E]): void { const listener = (msg: ChromeMessage) => { if (msg.topic === topic) { cb.apply(null, msg.args); this._port.onMessage.removeListener(listener); } }; this._port.onMessage.addListener(listener); } emit(topic: E, args?: Parameters): boolean { if (this._disconnected) { return false; } this._port.postMessage({ topic, args, }); return true; } destroy(): void { this._listeners.forEach((l) => window.removeEventListener('message', l)); this._listeners = []; } }