gecko-dev/devtools/shared/Loader.jsm

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

246 lines
8.0 KiB
JavaScript
Raw Normal View History

/* 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/. */
"use strict";
/**
* Manages the base loader (base-loader.js) instance used to load the developer tools.
*/
Bug 1514594: Part 3 - Change ChromeUtils.import API. *** Bug 1514594: Part 3a - Change ChromeUtils.import to return an exports object; not pollute global. r=mccr8 This changes the behavior of ChromeUtils.import() to return an exports object, rather than a module global, in all cases except when `null` is passed as a second argument, and changes the default behavior not to pollute the global scope with the module's exports. Thus, the following code written for the old model: ChromeUtils.import("resource://gre/modules/Services.jsm"); is approximately the same as the following, in the new model: var {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm"); Since the two behaviors are mutually incompatible, this patch will land with a scripted rewrite to update all existing callers to use the new model rather than the old. *** Bug 1514594: Part 3b - Mass rewrite all JS code to use the new ChromeUtils.import API. rs=Gijs This was done using the followng script: https://bitbucket.org/kmaglione/m-c-rewrites/src/tip/processors/cu-import-exports.jsm *** Bug 1514594: Part 3c - Update ESLint plugin for ChromeUtils.import API changes. r=Standard8 Differential Revision: https://phabricator.services.mozilla.com/D16747 *** Bug 1514594: Part 3d - Remove/fix hundreds of duplicate imports from sync tests. r=Gijs Differential Revision: https://phabricator.services.mozilla.com/D16748 *** Bug 1514594: Part 3e - Remove no-op ChromeUtils.import() calls. r=Gijs Differential Revision: https://phabricator.services.mozilla.com/D16749 *** Bug 1514594: Part 3f.1 - Cleanup various test corner cases after mass rewrite. r=Gijs *** Bug 1514594: Part 3f.2 - Cleanup various non-test corner cases after mass rewrite. r=Gijs Differential Revision: https://phabricator.services.mozilla.com/D16750 --HG-- extra : rebase_source : 359574ee3064c90f33bf36c2ebe3159a24cc8895 extra : histedit_source : b93c8f42808b1599f9122d7842d2c0b3e656a594%2C64a3a4e3359dc889e2ab2b49461bab9e27fc10a7
2019-01-17 18:18:31 +00:00
var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
var { Loader, Require, resolveURI, unload } =
Bug 1514594: Part 3 - Change ChromeUtils.import API. *** Bug 1514594: Part 3a - Change ChromeUtils.import to return an exports object; not pollute global. r=mccr8 This changes the behavior of ChromeUtils.import() to return an exports object, rather than a module global, in all cases except when `null` is passed as a second argument, and changes the default behavior not to pollute the global scope with the module's exports. Thus, the following code written for the old model: ChromeUtils.import("resource://gre/modules/Services.jsm"); is approximately the same as the following, in the new model: var {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm"); Since the two behaviors are mutually incompatible, this patch will land with a scripted rewrite to update all existing callers to use the new model rather than the old. *** Bug 1514594: Part 3b - Mass rewrite all JS code to use the new ChromeUtils.import API. rs=Gijs This was done using the followng script: https://bitbucket.org/kmaglione/m-c-rewrites/src/tip/processors/cu-import-exports.jsm *** Bug 1514594: Part 3c - Update ESLint plugin for ChromeUtils.import API changes. r=Standard8 Differential Revision: https://phabricator.services.mozilla.com/D16747 *** Bug 1514594: Part 3d - Remove/fix hundreds of duplicate imports from sync tests. r=Gijs Differential Revision: https://phabricator.services.mozilla.com/D16748 *** Bug 1514594: Part 3e - Remove no-op ChromeUtils.import() calls. r=Gijs Differential Revision: https://phabricator.services.mozilla.com/D16749 *** Bug 1514594: Part 3f.1 - Cleanup various test corner cases after mass rewrite. r=Gijs *** Bug 1514594: Part 3f.2 - Cleanup various non-test corner cases after mass rewrite. r=Gijs Differential Revision: https://phabricator.services.mozilla.com/D16750 --HG-- extra : rebase_source : 359574ee3064c90f33bf36c2ebe3159a24cc8895 extra : histedit_source : b93c8f42808b1599f9122d7842d2c0b3e656a594%2C64a3a4e3359dc889e2ab2b49461bab9e27fc10a7
2019-01-17 18:18:31 +00:00
ChromeUtils.import("resource://devtools/shared/base-loader.js");
var { requireRawId } = ChromeUtils.import("resource://devtools/shared/loader-plugin-raw.jsm");
this.EXPORTED_SYMBOLS = ["DevToolsLoader", "devtools", "BuiltinProvider",
"require", "loader",
// Export StructuredCloneHolder for its use from builtin-modules
"StructuredCloneHolder"];
/**
* Providers are different strategies for loading the devtools.
*/
/**
* Used when the tools should be loaded from the Firefox package itself.
* This is the default case.
*/
function BuiltinProvider() {}
BuiltinProvider.prototype = {
load: function() {
const paths = {
// ⚠ DISCUSSION ON DEV-DEVELOPER-TOOLS REQUIRED BEFORE MODIFYING ⚠
"devtools": "resource://devtools",
// ⚠ DISCUSSION ON DEV-DEVELOPER-TOOLS REQUIRED BEFORE MODIFYING ⚠
"acorn": "resource://devtools/shared/acorn",
// ⚠ DISCUSSION ON DEV-DEVELOPER-TOOLS REQUIRED BEFORE MODIFYING ⚠
"acorn/util/walk": "resource://devtools/shared/acorn/walk.js",
// ⚠ DISCUSSION ON DEV-DEVELOPER-TOOLS REQUIRED BEFORE MODIFYING ⚠
// Allow access to xpcshell test items from the loader.
"xpcshell-test": "resource://test",
// ⚠ DISCUSSION ON DEV-DEVELOPER-TOOLS REQUIRED BEFORE MODIFYING ⚠
// Allow access to locale data using paths closer to what is
// used in the source tree.
"devtools/client/locales": "chrome://devtools/locale",
"devtools/shared/locales": "chrome://devtools-shared/locale",
Bug 1444926 - Move devtools/shim to devtools/startup;r=ochameau MozReview-Commit-ID: K9WuJuTdYHS --HG-- rename : devtools/shim/DevToolsShim.jsm => devtools/startup/DevToolsShim.jsm rename : devtools/shim/aboutdebugging-registration.js => devtools/startup/aboutdebugging-registration.js rename : devtools/shim/aboutdebugging.manifest => devtools/startup/aboutdebugging.manifest rename : devtools/shim/aboutdevtools/aboutdevtools-registration.js => devtools/startup/aboutdevtools/aboutdevtools-registration.js rename : devtools/shim/aboutdevtools/aboutdevtools.css => devtools/startup/aboutdevtools/aboutdevtools.css rename : devtools/shim/aboutdevtools/aboutdevtools.js => devtools/startup/aboutdevtools/aboutdevtools.js rename : devtools/shim/aboutdevtools/aboutdevtools.manifest => devtools/startup/aboutdevtools/aboutdevtools.manifest rename : devtools/shim/aboutdevtools/aboutdevtools.xhtml => devtools/startup/aboutdevtools/aboutdevtools.xhtml rename : devtools/shim/aboutdevtools/images/dev-edition-logo.svg => devtools/startup/aboutdevtools/images/dev-edition-logo.svg rename : devtools/shim/aboutdevtools/images/external-link.svg => devtools/startup/aboutdevtools/images/external-link.svg rename : devtools/shim/aboutdevtools/images/feature-console.svg => devtools/startup/aboutdevtools/images/feature-console.svg rename : devtools/shim/aboutdevtools/images/feature-debugger.svg => devtools/startup/aboutdevtools/images/feature-debugger.svg rename : devtools/shim/aboutdevtools/images/feature-inspector.svg => devtools/startup/aboutdevtools/images/feature-inspector.svg rename : devtools/shim/aboutdevtools/images/feature-memory.svg => devtools/startup/aboutdevtools/images/feature-memory.svg rename : devtools/shim/aboutdevtools/images/feature-network.svg => devtools/startup/aboutdevtools/images/feature-network.svg rename : devtools/shim/aboutdevtools/images/feature-performance.svg => devtools/startup/aboutdevtools/images/feature-performance.svg rename : devtools/shim/aboutdevtools/images/feature-responsive.svg => devtools/startup/aboutdevtools/images/feature-responsive.svg rename : devtools/shim/aboutdevtools/images/feature-storage.svg => devtools/startup/aboutdevtools/images/feature-storage.svg rename : devtools/shim/aboutdevtools/images/feature-visualediting.svg => devtools/startup/aboutdevtools/images/feature-visualediting.svg rename : devtools/shim/aboutdevtools/images/otter.svg => devtools/startup/aboutdevtools/images/otter.svg rename : devtools/shim/aboutdevtools/moz.build => devtools/startup/aboutdevtools/moz.build rename : devtools/shim/aboutdevtools/subscribe.css => devtools/startup/aboutdevtools/subscribe.css rename : devtools/shim/aboutdevtools/subscribe.js => devtools/startup/aboutdevtools/subscribe.js rename : devtools/shim/aboutdevtools/test/.eslintrc.js => devtools/startup/aboutdevtools/test/.eslintrc.js rename : devtools/shim/aboutdevtools/test/browser.ini => devtools/startup/aboutdevtools/test/browser.ini rename : devtools/shim/aboutdevtools/test/browser_aboutdevtools_closes_page.js => devtools/startup/aboutdevtools/test/browser_aboutdevtools_closes_page.js rename : devtools/shim/aboutdevtools/test/browser_aboutdevtools_enables_devtools.js => devtools/startup/aboutdevtools/test/browser_aboutdevtools_enables_devtools.js rename : devtools/shim/aboutdevtools/test/browser_aboutdevtools_focus_owner_tab.js => devtools/startup/aboutdevtools/test/browser_aboutdevtools_focus_owner_tab.js rename : devtools/shim/aboutdevtools/test/browser_aboutdevtools_reuse_existing.js => devtools/startup/aboutdevtools/test/browser_aboutdevtools_reuse_existing.js rename : devtools/shim/aboutdevtools/test/head.js => devtools/startup/aboutdevtools/test/head.js rename : devtools/shim/aboutdevtoolstoolbox-registration.js => devtools/startup/aboutdevtoolstoolbox-registration.js rename : devtools/shim/aboutdevtoolstoolbox.manifest => devtools/startup/aboutdevtoolstoolbox.manifest rename : devtools/shim/devtools-startup-prefs.js => devtools/startup/devtools-startup-prefs.js rename : devtools/shim/devtools-startup.js => devtools/startup/devtools-startup.js rename : devtools/shim/devtools-startup.manifest => devtools/startup/devtools-startup.manifest rename : devtools/shim/jar.mn => devtools/startup/jar.mn rename : devtools/shim/locales/en-US/aboutdevtools.dtd => devtools/startup/locales/en-US/aboutdevtools.dtd rename : devtools/shim/locales/en-US/aboutdevtools.properties => devtools/startup/locales/en-US/aboutdevtools.properties rename : devtools/shim/locales/en-US/key-shortcuts.properties => devtools/startup/locales/en-US/key-shortcuts.properties rename : devtools/shim/locales/en-US/startup.properties => devtools/startup/locales/en-US/startup.properties rename : devtools/shim/locales/jar.mn => devtools/startup/locales/jar.mn rename : devtools/shim/locales/moz.build => devtools/startup/locales/moz.build rename : devtools/shim/moz.build => devtools/startup/moz.build rename : devtools/shim/tests/browser/.eslintrc.js => devtools/startup/tests/browser/.eslintrc.js rename : devtools/shim/tests/browser/browser.ini => devtools/startup/tests/browser/browser.ini rename : devtools/shim/tests/browser/browser_shim_disable_devtools.js => devtools/startup/tests/browser/browser_shim_disable_devtools.js rename : devtools/shim/tests/unit/.eslintrc.js => devtools/startup/tests/unit/.eslintrc.js rename : devtools/shim/tests/unit/test_devtools_shim.js => devtools/startup/tests/unit/test_devtools_shim.js rename : devtools/shim/tests/unit/xpcshell.ini => devtools/startup/tests/unit/xpcshell.ini extra : rebase_source : 7867a5b103d01dc936091a71deeaf526e7f0e47a
2018-03-12 13:41:48 +00:00
"devtools/startup/locales": "chrome://devtools-startup/locale",
"toolkit/locales": "chrome://global/locale",
};
// When creating a Loader invisible to the Debugger, we have to ensure
// using only modules and not depend on any JSM. As everything that is
// not loaded with Loader isn't going to respect `invisibleToDebugger`.
// But we have to keep using Promise.jsm for other loader to prevent
// breaking unhandled promise rejection in tests.
if (this.invisibleToDebugger) {
paths.promise = "resource://gre/modules/Promise-backend.js";
}
this.loader = new Loader({
paths,
invisibleToDebugger: this.invisibleToDebugger,
freshCompartment: this.freshCompartment,
sharedGlobal: true,
sandboxName: "DevTools (Module loader)",
requireHook: (id, require) => {
if (id.startsWith("raw!") || id.startsWith("theme-loader!")) {
return requireRawId(id, require);
}
return require(id);
},
});
},
unload: function(reason) {
unload(this.loader, reason);
delete this.loader;
},
};
var gNextLoaderID = 0;
/**
* The main devtools API. The standard instance of this loader is exported as
* |devtools| below, but if a fresh copy of the loader is needed, then a new
* one can also be created.
*/
this.DevToolsLoader = function DevToolsLoader() {
this.require = this.require.bind(this);
Services.obs.addObserver(this, "devtools-unload");
};
DevToolsLoader.prototype = {
destroy: function(reason = "shutdown") {
Services.obs.removeObserver(this, "devtools-unload");
if (this._provider) {
this._provider.unload(reason);
delete this._provider;
}
},
get provider() {
if (!this._provider) {
this._loadProvider();
}
return this._provider;
},
_provider: null,
get id() {
if (this._id) {
return this._id;
}
this._id = ++gNextLoaderID;
return this._id;
},
/**
* A dummy version of require, in case a provider hasn't been chosen yet when
* this is first called. This will then be replaced by the real version.
* @see setProvider
*/
require: function() {
if (!this._provider) {
this._loadProvider();
}
return this.require.apply(this, arguments);
},
/**
* Return true if |id| refers to something requiring help from a
* loader plugin.
*/
isLoaderPluginId: function(id) {
return id.startsWith("raw!");
},
/**
* Override the provider used to load the tools.
*/
setProvider: function(provider) {
if (provider === this._provider) {
return;
}
if (this._provider) {
delete this.require;
this._provider.unload("newprovider");
}
this._provider = provider;
// Pass through internal loader settings specific to this loader instance
this._provider.invisibleToDebugger = this.invisibleToDebugger;
this._provider.freshCompartment = this.freshCompartment;
this._provider.load();
this.require = Require(this._provider.loader, { id: "devtools" });
// Fetch custom pseudo modules and globals
const { modules, globals } = this.require("devtools/shared/builtin-modules");
// When creating a Loader for the browser toolbox, we have to use
// Promise-backend.js, as a Loader module. Instead of Promise.jsm which
// can't be flagged as invisible to debugger.
if (this.invisibleToDebugger) {
delete modules.promise;
}
// Register custom pseudo modules to the current loader instance
const loader = this._provider.loader;
for (const id in modules) {
const uri = resolveURI(id, loader.mapping);
loader.modules[uri] = {
get exports() {
return modules[id];
},
};
}
// Register custom globals to the current loader instance
globals.loader.id = this.id;
Object.defineProperties(loader.globals, Object.getOwnPropertyDescriptors(globals));
// Expose lazy helpers on loader
this.lazyGetter = globals.loader.lazyGetter;
this.lazyImporter = globals.loader.lazyImporter;
this.lazyServiceGetter = globals.loader.lazyServiceGetter;
this.lazyRequireGetter = globals.loader.lazyRequireGetter;
// When replaying, modify the require hook to allow the ReplayInspector to
// replace chrome interfaces with alternatives that understand the proxies
// created for objects in the recording/replaying process.
if (globals.isReplaying) {
const oldHook = this._provider.loader.requireHook;
const ReplayInspector = this.require("devtools/server/actors/replay/inspector");
this._provider.loader.requireHook = ReplayInspector.wrapRequireHook(oldHook);
}
},
/**
* Choose a default tools provider based on the preferences.
*/
_loadProvider: function() {
this.setProvider(new BuiltinProvider());
},
/**
* Handles "devtools-unload" event
*
* @param String data
* reason passed to modules when unloaded
*/
observe: function(subject, topic, data) {
if (topic != "devtools-unload") {
return;
}
this.destroy(data);
},
/**
* Sets whether the compartments loaded by this instance should be invisible
* to the debugger. Invisibility is needed for loaders that support debugging
* of chrome code. This is true of remote target environments, like Fennec or
* B2G. It is not the default case for desktop Firefox because we offer the
* Browser Toolbox for chrome debugging there, which uses its own, separate
* loader instance.
* @see devtools/client/framework/ToolboxProcess.jsm
*/
invisibleToDebugger: Services.appinfo.name !== "Firefox",
};
// Export the standard instance of DevToolsLoader used by the tools.
this.devtools = this.loader = new DevToolsLoader();
this.require = this.devtools.require.bind(this.devtools);
// For compatibility reasons, expose these symbols on "devtools":
Object.defineProperty(this.devtools, "Toolbox", {
get: () => this.require("devtools/client/framework/toolbox").Toolbox,
});
Object.defineProperty(this.devtools, "TargetFactory", {
get: () => this.require("devtools/client/framework/target").TargetFactory,
});