/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* eslint-env browser */ /* global AddonsComponent, DebuggerClient, DebuggerServer, React, RuntimesComponent, WorkersComponent */ "use strict"; const { classes: Cc, interfaces: Ci, utils: Cu } = Components; const { loader } = Components.utils.import( "resource://devtools/shared/Loader.jsm", {}); loader.lazyRequireGetter(this, "AddonsComponent", "devtools/client/aboutdebugging/components/addons", true); loader.lazyRequireGetter(this, "DebuggerClient", "devtools/shared/client/main", true); loader.lazyRequireGetter(this, "DebuggerServer", "devtools/server/main", true); loader.lazyRequireGetter(this, "Telemetry", "devtools/client/shared/telemetry"); loader.lazyRequireGetter(this, "WorkersComponent", "devtools/client/aboutdebugging/components/workers", true); loader.lazyRequireGetter(this, "Services"); loader.lazyImporter(this, "AddonManager", "resource://gre/modules/AddonManager.jsm"); const Strings = Services.strings.createBundle( "chrome://devtools/locale/aboutdebugging.properties"); var AboutDebugging = { _prefListeners: [], _categories: null, get categories() { // If needed, initialize the list of available categories. if (!this._categories) { let elements = document.querySelectorAll(".category"); this._categories = Array.map(elements, element => { let value = element.getAttribute("value"); element.addEventListener("click", this.showTab.bind(this, value)); return value; }); } return this._categories; }, showTab(category) { // If no category was specified, try the URL hash. if (!category) { category = location.hash.substr(1); } // If no corresponding category can be found, use the first available. let categories = this.categories; if (categories.indexOf(category) < 0) { category = categories[0]; } // Show the corresponding tab and hide the others. document.querySelector(".tab.active").classList.remove("active"); document.querySelector("#tab-" + category).classList.add("active"); document.querySelector(".category[selected]").removeAttribute("selected"); document.querySelector(".category[value=" + category + "]") .setAttribute("selected", "true"); location.hash = "#" + category; if (category == "addons") { React.render(React.createElement(AddonsComponent, { client: this.client }), document.querySelector("#addons")); } else if (category == "workers") { React.render(React.createElement(WorkersComponent, { client: this.client }), document.querySelector("#workers")); } }, init() { let telemetry = this._telemetry = new Telemetry(); telemetry.toolOpened("aboutdebugging"); // Link checkboxes to prefs. let elements = document.querySelectorAll("input[type=checkbox][data-pref]"); Array.map(elements, element => { let pref = element.dataset.pref; let updatePref = () => { Services.prefs.setBoolPref(pref, element.checked); }; element.addEventListener("change", updatePref, false); let updateCheckbox = () => { element.checked = Services.prefs.getBoolPref(pref); }; Services.prefs.addObserver(pref, updateCheckbox, false); this._prefListeners.push([pref, updateCheckbox]); updateCheckbox(); }); // Link buttons to their associated actions. let loadAddonButton = document.getElementById("load-addon-from-file"); loadAddonButton.addEventListener("click", this.loadAddonFromFile); if (!DebuggerServer.initialized) { DebuggerServer.init(); DebuggerServer.addBrowserActors(); } DebuggerServer.allowChromeProcess = true; this.client = new DebuggerClient(DebuggerServer.connectPipe()); this.client.connect(() => { // Show the first available tab. this.showTab(); window.addEventListener("hashchange", () => this.showTab()); }); }, loadAddonFromFile() { let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker); fp.init(window, Strings.GetStringFromName("selectAddonFromFile"), Ci.nsIFilePicker.modeOpen); let res = fp.show(); if (res == Ci.nsIFilePicker.returnCancel || !fp.file) { return; } let file = fp.file; // AddonManager.installTemporaryAddon accepts either // addon directory or final xpi file. if (!file.isDirectory() && !file.leafName.endsWith(".xpi")) { file = file.parent; } try { AddonManager.installTemporaryAddon(file); } catch(e) { alert("Error while installing the addon:\n" + e.message + "\n"); throw e; } }, destroy() { let telemetry = this._telemetry; telemetry.toolClosed("aboutdebugging"); telemetry.destroy(); this._prefListeners.forEach(([pref, listener]) => { Services.prefs.removeObserver(pref, listener); }); this._prefListeners = []; React.unmountComponentAtNode(document.querySelector("#addons")); React.unmountComponentAtNode(document.querySelector("#workers")); this.client.close(); this.client = null; }, }; window.addEventListener("DOMContentLoaded", function load() { window.removeEventListener("DOMContentLoaded", load); AboutDebugging.init(); }); window.addEventListener("unload", function unload() { window.removeEventListener("unload", unload); AboutDebugging.destroy(); });