UNPKG

ember-inspector-prebuilt

Version:

A pre-built set of distributable assets from the ember.js ember-inspector project.

175 lines (149 loc) 5.29 kB
const { Class } = require('sdk/core/heritage'); const { data } = require("sdk/self"); const { PageMod } = require("sdk/page-mod"); const { emit, on, off, once } = require("sdk/event/core"); const { EventTarget } = require("sdk/event/target"); const tabs = require("sdk/tabs"); const emberVersions = require('./ember-versions'); const previousVersions = emberVersions.previous; const supportedVersions = emberVersions.supported; // route open/active/ready events (needed by tomster-locationbar-button) let emitTomsterTabsOpen = (tab) => emit(tomsterTabs, 'open', tab); let emitTomsterTabsActivate = (tab) => emit(tomsterTabs, 'activate', tab); let emitTomsterTabsReady = (tab) => emit(tomsterTabs, 'ready', tab); tabs.on('open', emitTomsterTabsOpen); tabs.on('activate', emitTomsterTabsActivate); tabs.on('ready', emitTomsterTabsReady); // track attached workers and ember libraries detected by tab.id let workers = new Set(); let workersByTabId = new Map(); let libraries = new Map(); // simplified tabs tracker class const Tabs = Class({ extends: EventTarget, get activeTab() tabs.activeTab, attachExistentWorkersByTabId: function (tabId) { var selectedWorkers = workersByTabId.get(tabId); if (selectedWorkers) { selectedWorkers.forEach((w) => { emit(this, "emberAttach", { tabId: tabId, worker: w }); }); } }, hasWorkersByTabId: function (tabId) { let selectedWorkers = workersByTabId.get(tabId); if (!!selectedWorkers && selectedWorkers.size) { return true; } else { return false; } }, sendToWorkersByTabId: function (tabId, name, msg) { var selectedWorkers = workersByTabId.get(tabId); if (selectedWorkers) { selectedWorkers.forEach((w) => { try { w.port.emit(name, msg); } catch(e) { console.error("EXCEPTION", e); } }); } }, getLibrariesByTabId: function (tabId) { return libraries.get(tabId); }, destroy: function () { // NOTE: prevents leaks ("can't access dead object" exceptions // from "sdk/tabs/tab-firefox:104" after disabling the addon [...workers]. map((w) => w.tab). filter((tab) => !!tab). sort(). filter((tab, i, a) => (i == a.indexOf(tab))). forEach((tab) => { tab.destroy(); }); } }); // exports tab tracker instance let tomsterTabs = Tabs(); module.exports = tomsterTabs; let contentScriptOptions = { emberInPageScript: data.load("scripts/in-page-script.js") }; previousVersions.concat([supportedVersions[0]]).forEach((version) => { let dashedVersion = version.replace(/\./g, '-'); contentScriptOptions['emberDebugScript-' + dashedVersion] = data.load('panes-' + dashedVersion + '/ember_debug.js'); }); // create a page monitor to check ember versions and route // ember debug messages when needed let pageMod = PageMod({ include: "*", include: ["*", "file://*"], attachTo: ["top", "frame", "existing"], contentScriptFile: data.url('content-script.js'), contentScriptOptions: contentScriptOptions, contentScriptWhen: "start", onAttach: (worker) => { console.debug("ON ATTACH WORKER", worker); workers.add(worker); let tabId = worker.tab.id; let workersSet = workersByTabId.get(tabId); if (!workersSet) { workersSet = new Set(); workersByTabId.set(tabId, workersSet); } workersSet.add(worker); attachWorker(worker); worker.on('pagehide', () => { workersSet.delete(worker); }); worker.on('pageshow', () => { workersSet.add(worker); }); worker.once('detach', () => { console.debug("DETACH WORKER", worker); workersSet.delete(worker); workers.delete(worker); libraries.delete(tabId); emit(tomsterTabs, "emberDetach", { tabId: tabId, worker: worker }); console.debug("NUMBER OF ATTACHED WORKERS", workers.size); }); emit(tomsterTabs, "emberAttach", { tabId: tabId, worker: worker }); } }); function attachWorker(worker) { worker.port.on("emberVersion", routeEmberVersion); worker.port.on("emberDebug", routeEmberDebug); worker.once('detach', () => { console.debug("CLEANUP WORKER PORT LISTENERS", worker); worker.port.removeListener("emberVersion", routeEmberVersion); worker.port.removeListener("emberDebug", routeEmberDebug); }); function routeEmberVersion(msg) { if (worker.tab) { let previousLibrary = libraries.get(worker.tab.id); // NOTE: filter iframe if we have already libraries from the parent window if ((worker.url !== worker.tab.url) && !!previousLibrary && previousLibrary.versions.length > 0) { return; } msg.url = worker.tab.url; msg.realUrl = worker.url; console.debug("DETECTED EMBER VERSION", msg); libraries.set(worker.tab.id, msg); emit(tomsterTabs, "emberVersion", worker.tab); } } function routeEmberDebug(msg) { // filter workers without an associated tab if (!worker.tab) { return null; } emit(tomsterTabs, "emberDebug", { tabId: worker.tab.id, worker: worker, url: worker.url, data: msg }); } }