diff --git a/devtools/client/definitions.js b/devtools/client/definitions.js index 6c0796095c73..fc85bf43965f 100644 --- a/devtools/client/definitions.js +++ b/devtools/client/definitions.js @@ -12,6 +12,7 @@ loader.lazyGetter(this, "OptionsPanel", () => require("devtools/client/framework loader.lazyGetter(this, "InspectorPanel", () => require("devtools/client/inspector/panel").InspectorPanel); loader.lazyGetter(this, "WebConsolePanel", () => require("devtools/client/webconsole/panel").WebConsolePanel); loader.lazyGetter(this, "DebuggerPanel", () => require("devtools/client/debugger/panel").DebuggerPanel); +loader.lazyGetter(this, "NewDebuggerPanel", () => require("devtools/client/debugger/new/panel").DebuggerPanel); loader.lazyGetter(this, "StyleEditorPanel", () => require("devtools/client/styleeditor/styleeditor-panel").StyleEditorPanel); loader.lazyGetter(this, "ShaderEditorPanel", () => require("devtools/client/shadereditor/panel").ShaderEditorPanel); loader.lazyGetter(this, "CanvasDebuggerPanel", () => require("devtools/client/canvasdebugger/panel").CanvasDebuggerPanel); @@ -155,8 +156,6 @@ Tools.jsdebugger = { function switchDebugger() { if (Services.prefs.getBoolPref("devtools.debugger.new-debugger-frontend")) { - const NewDebuggerPanel = require("devtools/client/debugger/new/panel").DebuggerPanel; - Tools.jsdebugger.url = "chrome://devtools/content/debugger/new/index.html"; Tools.jsdebugger.build = function (iframeWindow, toolbox) { return new NewDebuggerPanel(iframeWindow, toolbox); diff --git a/devtools/client/framework/devtools-browser.js b/devtools/client/framework/devtools-browser.js index 385adc131b23..0fdc6f33c125 100644 --- a/devtools/client/framework/devtools-browser.js +++ b/devtools/client/framework/devtools-browser.js @@ -18,7 +18,6 @@ const promise = require("promise"); const defer = require("devtools/shared/defer"); const Telemetry = require("devtools/client/shared/telemetry"); const { gDevTools } = require("./devtools"); -const { when: unload } = require("sdk/system/unload"); // Load target and toolbox lazily as they need gDevTools to be fully initialized loader.lazyRequireGetter(this, "TargetFactory", "devtools/client/framework/target", true); @@ -142,6 +141,16 @@ var gDevToolsBrowser = exports.gDevToolsBrowser = { } } break; + case "quit-application": + gDevToolsBrowser.destroy({ shuttingDown: true }); + break; + case "sdk:loader:destroy": + // This event is fired when the devtools loader unloads, which happens + // only when the add-on workflow ask devtools to be reloaded. + if (subject.wrappedJSObject == require('@loader/unload')) { + gDevToolsBrowser.destroy({ shuttingDown: false }); + } + break; } }, @@ -730,12 +739,19 @@ var gDevToolsBrowser = exports.gDevToolsBrowser = { }, /** - * All browser windows have been closed, tidy up remaining objects. + * Either the SDK Loader has been destroyed by the add-on contribution + * workflow, or firefox is shutting down. + + * @param {boolean} shuttingDown + * True if firefox is currently shutting down. We may prevent doing + * some cleanups to speed it up. Otherwise everything need to be + * cleaned up in order to be able to load devtools again. */ - destroy: function () { + destroy: function ({ shuttingDown }) { Services.prefs.removeObserver("devtools.", gDevToolsBrowser); Services.obs.removeObserver(gDevToolsBrowser, "browser-delayed-startup-finished"); - Services.obs.removeObserver(gDevToolsBrowser.destroy, "quit-application"); + Services.obs.removeObserver(gDevToolsBrowser, "quit-application"); + Services.obs.removeObserver(gDevToolsBrowser, "sdk:loader:destroy"); gDevToolsBrowser._pingTelemetry(); gDevToolsBrowser._telemetry = null; @@ -743,6 +759,8 @@ var gDevToolsBrowser = exports.gDevToolsBrowser = { for (let win of gDevToolsBrowser._trackedBrowserWindows) { gDevToolsBrowser._forgetBrowserWindow(win); } + + gDevTools.destroy({ shuttingDown }); }, }; @@ -766,8 +784,10 @@ gDevTools.on("tool-unregistered", function (ev, toolId) { gDevTools.on("toolbox-ready", gDevToolsBrowser._updateMenuCheckbox); gDevTools.on("toolbox-destroyed", gDevToolsBrowser._updateMenuCheckbox); -Services.obs.addObserver(gDevToolsBrowser.destroy, "quit-application", false); +Services.obs.addObserver(gDevToolsBrowser, "quit-application", false); Services.obs.addObserver(gDevToolsBrowser, "browser-delayed-startup-finished", false); +// Watch for module loader unload. Fires when the tools are reloaded. +Services.obs.addObserver(gDevToolsBrowser, "sdk:loader:destroy", false); // Fake end of browser window load event for all already opened windows // that is already fully loaded. @@ -778,8 +798,3 @@ while (enumerator.hasMoreElements()) { gDevToolsBrowser._registerBrowserWindow(win); } } - -// Watch for module loader unload. Fires when the tools are reloaded. -unload(function () { - gDevToolsBrowser.destroy(); -}); diff --git a/devtools/client/framework/devtools.js b/devtools/client/framework/devtools.js index ff13f1f64459..3ec83cbdee87 100644 --- a/devtools/client/framework/devtools.js +++ b/devtools/client/framework/devtools.js @@ -18,7 +18,6 @@ const {defaultTools: DefaultTools, defaultThemes: DefaultThemes} = const EventEmitter = require("devtools/shared/event-emitter"); const {JsonView} = require("devtools/client/jsonview/main"); const AboutDevTools = require("devtools/client/framework/about-devtools-toolbox"); -const {when: unload} = require("sdk/system/unload"); const {Task} = require("devtools/shared/task"); const FORBIDDEN_IDS = new Set(["toolbox", ""]); @@ -35,9 +34,6 @@ function DevTools() { // List of toolboxes that are still in process of creation this._creatingToolboxes = new Map(); // Map - // destroy() is an observer's handler so we need to preserve context. - this.destroy = this.destroy.bind(this); - // JSON Viewer for 'application/json' documents. JsonView.initialize(); @@ -45,8 +41,6 @@ function DevTools() { EventEmitter.decorate(this); - Services.obs.addObserver(this.destroy, "quit-application", false); - // This is important step in initialization codepath where we are going to // start registering all default tools and themes: create menuitems, keys, emit // related events. @@ -480,20 +474,23 @@ DevTools.prototype = { }, /** - * Called to tear down a tools provider. - */ - _teardown: function DT_teardown() { - for (let [target, toolbox] of this._toolboxes) { - toolbox.destroy(); - } - AboutDevTools.unregister(); - }, + * Either the SDK Loader has been destroyed by the add-on contribution + * workflow, or firefox is shutting down. - /** - * All browser windows have been closed, tidy up remaining objects. + * @param {boolean} shuttingDown + * True if firefox is currently shutting down. We may prevent doing + * some cleanups to speed it up. Otherwise everything need to be + * cleaned up in order to be able to load devtools again. */ - destroy: function () { - Services.obs.removeObserver(this.destroy, "quit-application"); + destroy: function ({ shuttingDown }) { + // Do not cleanup everything during firefox shutdown, but only when + // devtools are reloaded via the add-on contribution workflow. + if (!shuttingDown) { + for (let [target, toolbox] of this._toolboxes) { + toolbox.destroy(); + } + AboutDevTools.unregister(); + } for (let [key, tool] of this.getToolDefinitionMap()) { this.unregisterTool(key, true); @@ -519,8 +516,3 @@ DevTools.prototype = { }; const gDevTools = exports.gDevTools = new DevTools(); - -// Watch for module loader unload. Fires when the tools are reloaded. -unload(function () { - gDevTools._teardown(); -});