UNPKG

electron-devtools-vendor

Version:

<div align="center"> <h2>electron-devtools-vendor</h2> <img alt="MIT" src="https://img.shields.io/github/license/BlackHole1/electron-devtools-vendor?color=9cf&style=flat-square"> <img alt="GitHub repo size" src="https://img.shields.io/github/r

208 lines (186 loc) 6.62 kB
/*global chrome*/ /** * Long lived background script running in the browser, works in tandem with the * client-script to coordinate messaging between EmberDebug, EmberInspector and the * ClientApp. The background.js script serves as a proxy between the EmberInspector * and the content-script. * * It is also responsible for showing the Ember icon and tooltip in the url bar. * * See: * https://developer.chrome.com/extensions/background_pages * https://developer.chrome.com/extensions/messaging */ (function() { "use strict"; var activeTabs = {}, activeTabId, contextMenuAdded = false, emberInspectorChromePorts = {}; /** * Creates the tooltip string to show the version of libraries used in the ClientApp * @param {Array} versions - array of library objects * @return {String} - string of library names and versions */ function generateVersionsTooltip(versions) { return versions.map(function(lib) { return lib.name + " " + lib.version; }).join("\n"); } /** * Creates the title for the action for the current ClientApp * @param {Number} tabId - the current tab */ function setActionTitle(tabId) { void chrome.action.setTitle({ tabId: tabId, title: generateVersionsTooltip(activeTabs[tabId]) }); } /** * Update the tab's action: https://developer.chrome.com/extensions/pageAction * If the user has choosen to display it, the icon is shown and the title * is updated to display the ClientApp's information in the tooltip. * @param {Number} tabId - the current tab */ function updateTabAction(tabId) { chrome.storage.sync.get("options", async function(data) { void chrome.action.enable(tabId); void chrome.action.setIcon({ tabId, path: { 19: 'panes-3-16-0/assets/images/icon19.png', 38: 'panes-3-16-0/assets/images/icon38.png', } }); setActionTitle(tabId); }); } /** * Remove the curent tab's Ember icon. * Typically used to clearout the icon after reload. * @param {Number} tabId - the current tab */ function hideAction(tabId) { if (!activeTabs[tabId]) { return; } void chrome.action.disable(tabId); void chrome.action.setIcon({ tabId, path: { 19: 'panes-3-16-0/assets/images/icon19_grey.png', 38: 'panes-3-16-0/assets/images/icon38_grey.png', } }); } function genericOnClick(info) { if (info.menuItemId !== 'inspect-ember-component') return; void chrome.tabs.sendMessage(activeTabId, { from: 'devtools', type: 'view:contextMenu' }); } chrome.contextMenus.onClicked.addListener(genericOnClick); /** * Update the tab's contextMenu: https://developer.chrome.com/extensions/contextMenus * Add a menu item called "Inspect Ember Component" that shows info * about the component in the inspector. * @param {Boolean} force don't use the activeTabs array to check for an existing context menu */ function updateContextMenu(force) { // The Chromium that Electron runs does not have a chrome.contextMenus, // so make sure this doesn't throw an error in Electron if (!chrome.contextMenus) { return; } // Only add context menu item when an Ember app has been detected var isEmberApp = !!activeTabs[activeTabId] || force; if (!isEmberApp && contextMenuAdded) { chrome.contextMenus.remove('inspect-ember-component'); contextMenuAdded = false; } if (isEmberApp && !contextMenuAdded) { chrome.contextMenus.create({ id: 'inspect-ember-component', title: 'Inspect Ember Component', contexts: ['all'], }); contextMenuAdded = true; } } /** * Listen for a connection request from the EmberInspector. * When the EmberInspector connects to the extension a messageListener * is added for the specific EmberInspector instance, and saved into * an array, keyed by appId. * * @param {Port} emberInspectorChromePort */ chrome.runtime.onConnect.addListener(function(emberInspectorChromePort) { var appId; /** * Listen for messages from the EmberInspector. * The first message is used to save the port, all others are forwarded * to the content-script. * @param {Message} message */ emberInspectorChromePort.onMessage.addListener(function(message) { // if the message contains the appId, this is the first // message and the appId is used to map the port for this app. if (message.appId) { appId = message.appId; emberInspectorChromePorts[appId] = emberInspectorChromePort; emberInspectorChromePort.onDisconnect.addListener(function() { delete emberInspectorChromePorts[appId]; }); } else if (message.from === 'devtools') { // all other messages from EmberInspector are forwarded to the content-script // https://developer.chrome.com/extensions/tabs#method-sendMessage chrome.tabs.sendMessage(message.tabId || appId, message, { frameId: message.frameId }); } }); }); /** * Listen for messages from the content-script. * A few events trigger specfic behavior, all others are forwarded to EmberInspector. * @param {Object} request * @param {MessageSender} sender */ chrome.runtime.onMessage.addListener(function(request, sender) { // only listen to messages from the content-script if (!sender.tab) { // noop } else if (request && request.type === 'emberVersion') { // set the version info and update title activeTabs[sender.tab.id] = request.versions; updateTabAction(sender.tab.id); updateContextMenu(); } else if (request && request.type === 'resetEmberIcon') { // hide the Ember icon hideAction(sender.tab.id); } else if (request && request.type === 'inspectorLoaded') { updateContextMenu(true); } else { // forward the message to EmberInspector var emberInspectorChromePort = emberInspectorChromePorts[sender.tab.id]; if (emberInspectorChromePort) { emberInspectorChromePort.postMessage(request); } } }); /** * Keep track of which browser tab is active and update the context menu. */ chrome.tabs.onActivated.addListener(({ tabId }) => { activeTabId = tabId; if (activeTabs[tabId]) { updateTabAction(tabId); } updateContextMenu(); }); /** * Only keep track of active tabs */ chrome.tabs.onRemoved.addListener(({ tabId }) => { delete activeTabs[tabId]; }); }());