123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- /* 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';
- module.metadata = {
- "stability": "unstable"
- };
- // This module is manually loaded by bootstrap.js in a sandbox and immediatly
- // put in module cache so that it is never loaded in any other way.
- /* Workarounds to include dependencies in the manifest
- require('chrome') // Otherwise CFX will complain about Components
- require('toolkit/loader') // Otherwise CFX will stip out loader.js
- require('sdk/addon/runner') // Otherwise CFX will stip out addon/runner.js
- require('sdk/system/xul-app') // Otherwise CFX will stip out sdk/system/xul-app
- */
- const { classes: Cc, Constructor: CC, interfaces: Ci, utils: Cu } = Components;
- // `loadSandbox` is exposed by bootstrap.js
- const loaderURI = module.uri.replace("sdk/loader/cuddlefish.js",
- "toolkit/loader.js");
- const xulappURI = module.uri.replace("loader/cuddlefish.js",
- "system/xul-app.js");
- // We need to keep a reference to the sandbox in order to unload it in
- // bootstrap.js
- const loaderSandbox = loadSandbox(loaderURI);
- const loaderModule = loaderSandbox.exports;
- const xulappSandbox = loadSandbox(xulappURI);
- const xulappModule = xulappSandbox.exports;
- const { override, load } = loaderModule;
- /**
- * Ensure the current application satisfied the requirements specified in the
- * module given. If not, an exception related to the incompatibility is
- * returned; `null` otherwise.
- *
- * @param {Object} module
- * The module to check
- * @returns {Error}
- */
- function incompatibility(module) {
- let { metadata, id } = module;
- // if metadata or engines are not specified we assume compatibility is not
- // an issue.
- if (!metadata || !("engines" in metadata))
- return null;
- let { engines } = metadata;
- if (engines === null || typeof(engines) !== "object")
- return new Error("Malformed engines' property in metadata");
- let applications = Object.keys(engines);
- let versionRange;
- applications.forEach(function(name) {
- if (xulappModule.is(name)) {
- versionRange = engines[name];
- // Continue iteration. We want to ensure the module doesn't
- // contain a typo in the applications' name or some unknown
- // application - `is` function throws an exception in that case.
- }
- });
- if (typeof(versionRange) === "string") {
- if (xulappModule.satisfiesVersion(versionRange))
- return null;
- return new Error("Unsupported Application version: The module " + id +
- " currently supports only version " + versionRange + " of " +
- xulappModule.name + ".");
- }
- return new Error("Unsupported Application: The module " + id +
- " currently supports only " + applications.join(", ") + ".")
- }
- function CuddlefishLoader(options) {
- let { manifest } = options;
- options = override(options, {
- // Put `api-utils/loader` and `api-utils/cuddlefish` loaded as JSM to module
- // cache to avoid subsequent loads via `require`.
- modules: override({
- 'toolkit/loader': loaderModule,
- 'sdk/loader/cuddlefish': exports,
- 'sdk/system/xul-app': xulappModule
- }, options.modules),
- resolve: function resolve(id, requirer) {
- let entry = requirer && requirer in manifest && manifest[requirer];
- let uri = null;
- // If manifest entry for this requirement is present we follow manifest.
- // Note: Standard library modules like 'panel' will be present in
- // manifest unless they were moved to platform.
- if (entry) {
- let requirement = entry.requirements[id];
- // If requirer entry is in manifest and it's requirement is not, than
- // it has no authority to load since linker was not able to find it.
- if (!requirement)
- throw Error('Module: ' + requirer + ' has no authority to load: '
- + id, requirer);
- uri = requirement;
- } else {
- // If requirer is off manifest than it's a system module and we allow it
- // to go off manifest by resolving a relative path.
- uri = loaderModule.resolve(id, requirer);
- }
- return uri;
- },
- load: function(loader, module) {
- let result;
- let error;
- // In order to get the module's metadata, we need to load the module.
- // if an exception is raised here, it could be that is due to application
- // incompatibility. Therefore the exception is stored, and thrown again
- // only if the module seems be compatible with the application currently
- // running. Otherwise the incompatibility message takes the precedence.
- try {
- result = load(loader, module);
- }
- catch (e) {
- error = e;
- }
- error = incompatibility(module) || error;
- if (error)
- throw error;
- return result;
- }
- });
- let loader = loaderModule.Loader(options);
- // Hack to allow loading from `toolkit/loader`.
- loader.modules[loaderURI] = loaderSandbox;
- return loader;
- }
- exports = override(loaderModule, {
- Loader: CuddlefishLoader
- });
|