Bug 1363419 - Unregister DevTools on Add-on disabling. r=jdescottes
MozReview-Commit-ID: 7ME0xBdjvle
--- a/devtools/bootstrap.js
+++ b/devtools/bootstrap.js
@@ -1,13 +1,13 @@
/* 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/. */
-/* global content */
+/* global content, APP_SHUTDOWN */
/* exported startup, shutdown, install, uninstall */
"use strict";
const Cu = Components.utils;
const Ci = Components.interfaces;
const {Services} = Cu.import("resource://gre/modules/Services.jsm", {});
const {NetUtil} = Cu.import("resource://gre/modules/NetUtil.jsm", {});
@@ -135,16 +135,52 @@ let getTopLevelWindow = function (window
return window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShellTreeItem)
.rootTreeItem
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindow);
};
+function unload(reason) {
+ // This frame script is going to be executed in all processes:
+ // parent and child
+ Services.ppmm.loadProcessScript("data:,(" + function (scriptReason) {
+ /* Flush message manager cached frame scripts as well as chrome locales */
+ let obs = Components.classes["@mozilla.org/observer-service;1"]
+ .getService(Components.interfaces.nsIObserverService);
+ obs.notifyObservers(null, "message-manager-flush-caches");
+
+ /* Also purge cached modules in child processes, we do it a few lines after
+ in the parent process */
+ if (Services.appinfo.processType == Services.appinfo.PROCESS_TYPE_CONTENT) {
+ Services.obs.notifyObservers(null, "devtools-unload", scriptReason);
+ }
+ } + ")(\"" + reason.replace(/"/g, '\\"') + "\")", false);
+
+ // As we can't get a reference to existing Loader.jsm instances, we send them
+ // an observer service notification to unload them.
+ Services.obs.notifyObservers(null, "devtools-unload", reason);
+
+ // Then spawn a brand new Loader.jsm instance and start the main module
+ Cu.unload("resource://devtools/shared/Loader.jsm");
+ // Also unload all resources loaded as jsm, hopefully all of them are going
+ // to be converted into regular modules
+ Cu.unload("resource://devtools/client/shared/browser-loader.js");
+ Cu.unload("resource://devtools/client/framework/ToolboxProcess.jsm");
+ Cu.unload("resource://devtools/shared/apps/Devices.jsm");
+ Cu.unload("resource://devtools/client/scratchpad/scratchpad-manager.jsm");
+ Cu.unload("resource://devtools/shared/Parser.jsm");
+ Cu.unload("resource://devtools/client/shared/DOMHelpers.jsm");
+ Cu.unload("resource://devtools/client/shared/widgets/VariablesView.jsm");
+ Cu.unload("resource://devtools/client/responsivedesign/responsivedesign.jsm");
+ Cu.unload("resource://devtools/client/shared/widgets/AbstractTreeItem.jsm");
+ Cu.unload("resource://devtools/shared/deprecated-sync-thenables.js");
+}
+
function reload(event) {
// We automatically reload the toolbox if we are on a browser tab
// with a toolbox already opened
let reloadToolbox = false;
if (event) {
let top = getTopLevelWindow(event.view);
let isBrowser = top.location.href.includes("/browser.xul");
if (isBrowser && top.gBrowser) {
@@ -167,49 +203,17 @@ function reload(event) {
reopenBrowserConsole = true;
}
dump("Reload DevTools. (reload-toolbox:" + reloadToolbox + ")\n");
// Invalidate xul cache in order to see changes made to chrome:// files
Services.obs.notifyObservers(null, "startupcache-invalidate");
- // This frame script is going to be executed in all processes:
- // parent and child
- Services.ppmm.loadProcessScript("data:,new " + function () {
- /* Flush message manager cached frame scripts as well as chrome locales */
- let obs = Components.classes["@mozilla.org/observer-service;1"]
- .getService(Components.interfaces.nsIObserverService);
- obs.notifyObservers(null, "message-manager-flush-caches");
-
- /* Also purge cached modules in child processes, we do it a few lines after
- in the parent process */
- if (Services.appinfo.processType == Services.appinfo.PROCESS_TYPE_CONTENT) {
- Services.obs.notifyObservers(null, "devtools-unload", "reload");
- }
- }, false);
-
- // As we can't get a reference to existing Loader.jsm instances, we send them
- // an observer service notification to unload them.
- Services.obs.notifyObservers(null, "devtools-unload", "reload");
-
- // Then spawn a brand new Loader.jsm instance and start the main module
- Cu.unload("resource://devtools/shared/Loader.jsm");
- // Also unload all resources loaded as jsm, hopefully all of them are going
- // to be converted into regular modules
- Cu.unload("resource://devtools/client/shared/browser-loader.js");
- Cu.unload("resource://devtools/client/framework/ToolboxProcess.jsm");
- Cu.unload("resource://devtools/shared/apps/Devices.jsm");
- Cu.unload("resource://devtools/client/scratchpad/scratchpad-manager.jsm");
- Cu.unload("resource://devtools/shared/Parser.jsm");
- Cu.unload("resource://devtools/client/shared/DOMHelpers.jsm");
- Cu.unload("resource://devtools/client/shared/widgets/VariablesView.jsm");
- Cu.unload("resource://devtools/client/responsivedesign/responsivedesign.jsm");
- Cu.unload("resource://devtools/client/shared/widgets/AbstractTreeItem.jsm");
- Cu.unload("resource://devtools/shared/deprecated-sync-thenables.js");
+ unload("reload");
// Update the preferences before starting new code
setPrefs();
const {devtools} = Cu.import("resource://devtools/shared/Loader.jsm", {});
devtools.require("devtools/client/framework/devtools-browser");
// Go over all top level windows to reload all devtools related things
@@ -288,28 +292,35 @@ function startup(data) {
if (userValue != value) {
Services.prefs.setBoolPref(name, value);
originalPrefValues[name] = userValue;
}
}
reload();
}
-function shutdown() {
+function shutdown(data, reason) {
+ // On browser shutdown, do not try to cleanup anything
+ if (reason == APP_SHUTDOWN) {
+ return;
+ }
+
listener.stop();
listener = null;
// Restore preferences that used to be before the addon was installed
for (let name in originalPrefValues) {
let userValue = Services.prefs.getBoolPref(name);
// Only reset the pref if it hasn't changed
if (userValue == prefs[name]) {
Services.prefs.setBoolPref(name, originalPrefValues[name]);
}
}
+
+ unload("disable");
}
function install() {
try {
actionOccurred("reloadAddonInstalled");
} catch (e) {
// When installing on Firefox builds without devtools, telemetry doesn't
// work yet and throws.
}