const internals = { promisesSupported: !!window.browser, injectedScript: {}, port: null, currentUrl: null, icons: { call: { 16: "icons/action-16.png", 32: "icons/action-32.png", }, hangUp: { 16: "icons/hang_up-16.png", 32: "icons/hang_up-32.png", }, }, onClick() { if (internals.isInCall()) { return internals.hangUp(); } return internals.initializeContentScript(); }, joinAudioCall() { internals.port.postMessage({ action: "joinAudioCall", data: { currentUrl: internals.currentUrl, tada: internals.getRoot().runtime.getURL("sounds/tada.wav"), }, }); internals.getRoot().browserAction.enable(); internals.setIcon("hangUp"); }, onConnect(port) { internals.port = port; port.onDisconnect.addListener(internals.onDisconnect); port.onMessage.addListener(internals.onMessage); internals.joinAudioCall(); }, onMessage(message) { if (message.action === "error") { internals.getRoot().browserAction.setBadgeText({ text: "x" }, () => {}); } }, onDisconnect() { internals.getRoot().browserAction.setBadgeText({ text: "" }, () => {}); internals.setIcon("call"); internals.currentUrl = null; internals.port = null; internals.getRoot().browserAction.enable(); }, async initializeContentScript() { internals.getRoot().browserAction.disable(); const activeTabs = await internals.getActiveTabs(); internals.currentUrl = activeTabs[0].url; const id = activeTabs[0].id; if (!internals.injectedScript[id]) { const execution = await internals.getRoot().tabs.executeScript( activeTabs[0].id, { file: "/build/content_script.js", }, () => { internals.injectedScript[id] = true; }, ); if (execution && !execution[0]) { internals.onDisconnect(); } } else { internals.getRoot().tabs.connect(activeTabs[0].id); } }, hangUp() { internals.getRoot().browserAction.disable(); internals.port.postMessage({ action: "hangUp", }); }, isInCall() { return !!internals.port; }, setIcon(iconSet) { internals.getRoot().browserAction.setIcon({ path: internals.icons[iconSet], }); }, getRoot() { return window.browser || window.chrome; }, // Chrome doesn't yet implement the promise based tabs.query :'( getActiveTabs() { const query = { currentWindow: true, active: true, }; if (internals.promisesSupported) { return internals.getRoot().tabs.query(query); } return new Promise((resolve) => { internals.getRoot().tabs.query(query, (tabs) => { return resolve(tabs); }); }); }, }; internals.getRoot().browserAction.onClicked.addListener(internals.onClick); internals.getRoot().runtime.onConnect.addListener(internals.onConnect);