const internals = { promisesSupported: !!(window.browser), 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.joinAudioCall(); }, onConnect(port) { internals.port = port; port.onDisconnect.addListener(internals.onDisconnect); port.onMessage.addListener(internals.onMessage); port.postMessage({ action: 'joinAudioCall', data: { currentUrl: internals.currentUrl, tada: internals.getRoot().runtime.getURL('sounds/tada.wav') } }); internals.getRoot().browserAction.enable(); internals.setIcon('hangUp'); }, 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 joinAudioCall() { internals.getRoot().browserAction.disable(); const activeTabs = await internals.getActiveTabs(); internals.currentUrl = activeTabs[0].url; const execution = await internals.getRoot().tabs.executeScript(activeTabs[0].id, { file: '/build/content_script.js' }, () => { if (internals.getRoot().runtime.lastError) { internals.onDisconnect(); } }); if (execution && !execution[0]) { internals.onDisconnect(); } } , 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, reject) => { internals.getRoot().tabs.query(query, (tabs) => { return resolve(tabs); }); }); }, }; internals.getRoot().browserAction.onClicked.addListener(internals.onClick); internals.getRoot().runtime.onConnect.addListener(internals.onConnect);