addon-sdk/source/lib/sdk/loader/cuddlefish.js

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4 'use strict';
michael@0 5
michael@0 6 module.metadata = {
michael@0 7 "stability": "unstable"
michael@0 8 };
michael@0 9
michael@0 10 // This module is manually loaded by bootstrap.js in a sandbox and immediatly
michael@0 11 // put in module cache so that it is never loaded in any other way.
michael@0 12
michael@0 13 /* Workarounds to include dependencies in the manifest
michael@0 14 require('chrome') // Otherwise CFX will complain about Components
michael@0 15 require('toolkit/loader') // Otherwise CFX will stip out loader.js
michael@0 16 require('sdk/addon/runner') // Otherwise CFX will stip out addon/runner.js
michael@0 17 require('sdk/system/xul-app') // Otherwise CFX will stip out sdk/system/xul-app
michael@0 18 */
michael@0 19
michael@0 20 const { classes: Cc, Constructor: CC, interfaces: Ci, utils: Cu } = Components;
michael@0 21
michael@0 22 // `loadSandbox` is exposed by bootstrap.js
michael@0 23 const loaderURI = module.uri.replace("sdk/loader/cuddlefish.js",
michael@0 24 "toolkit/loader.js");
michael@0 25 const xulappURI = module.uri.replace("loader/cuddlefish.js",
michael@0 26 "system/xul-app.js");
michael@0 27 // We need to keep a reference to the sandbox in order to unload it in
michael@0 28 // bootstrap.js
michael@0 29
michael@0 30 const loaderSandbox = loadSandbox(loaderURI);
michael@0 31 const loaderModule = loaderSandbox.exports;
michael@0 32
michael@0 33 const xulappSandbox = loadSandbox(xulappURI);
michael@0 34 const xulappModule = xulappSandbox.exports;
michael@0 35
michael@0 36 const { override, load } = loaderModule;
michael@0 37
michael@0 38 /**
michael@0 39 * Ensure the current application satisfied the requirements specified in the
michael@0 40 * module given. If not, an exception related to the incompatibility is
michael@0 41 * returned; `null` otherwise.
michael@0 42 *
michael@0 43 * @param {Object} module
michael@0 44 * The module to check
michael@0 45 * @returns {Error}
michael@0 46 */
michael@0 47 function incompatibility(module) {
michael@0 48 let { metadata, id } = module;
michael@0 49
michael@0 50 // if metadata or engines are not specified we assume compatibility is not
michael@0 51 // an issue.
michael@0 52 if (!metadata || !("engines" in metadata))
michael@0 53 return null;
michael@0 54
michael@0 55 let { engines } = metadata;
michael@0 56
michael@0 57 if (engines === null || typeof(engines) !== "object")
michael@0 58 return new Error("Malformed engines' property in metadata");
michael@0 59
michael@0 60 let applications = Object.keys(engines);
michael@0 61
michael@0 62 let versionRange;
michael@0 63 applications.forEach(function(name) {
michael@0 64 if (xulappModule.is(name)) {
michael@0 65 versionRange = engines[name];
michael@0 66 // Continue iteration. We want to ensure the module doesn't
michael@0 67 // contain a typo in the applications' name or some unknown
michael@0 68 // application - `is` function throws an exception in that case.
michael@0 69 }
michael@0 70 });
michael@0 71
michael@0 72 if (typeof(versionRange) === "string") {
michael@0 73 if (xulappModule.satisfiesVersion(versionRange))
michael@0 74 return null;
michael@0 75
michael@0 76 return new Error("Unsupported Application version: The module " + id +
michael@0 77 " currently supports only version " + versionRange + " of " +
michael@0 78 xulappModule.name + ".");
michael@0 79 }
michael@0 80
michael@0 81 return new Error("Unsupported Application: The module " + id +
michael@0 82 " currently supports only " + applications.join(", ") + ".")
michael@0 83 }
michael@0 84
michael@0 85 function CuddlefishLoader(options) {
michael@0 86 let { manifest } = options;
michael@0 87
michael@0 88 options = override(options, {
michael@0 89 // Put `api-utils/loader` and `api-utils/cuddlefish` loaded as JSM to module
michael@0 90 // cache to avoid subsequent loads via `require`.
michael@0 91 modules: override({
michael@0 92 'toolkit/loader': loaderModule,
michael@0 93 'sdk/loader/cuddlefish': exports,
michael@0 94 'sdk/system/xul-app': xulappModule
michael@0 95 }, options.modules),
michael@0 96 resolve: function resolve(id, requirer) {
michael@0 97 let entry = requirer && requirer in manifest && manifest[requirer];
michael@0 98 let uri = null;
michael@0 99
michael@0 100 // If manifest entry for this requirement is present we follow manifest.
michael@0 101 // Note: Standard library modules like 'panel' will be present in
michael@0 102 // manifest unless they were moved to platform.
michael@0 103 if (entry) {
michael@0 104 let requirement = entry.requirements[id];
michael@0 105 // If requirer entry is in manifest and it's requirement is not, than
michael@0 106 // it has no authority to load since linker was not able to find it.
michael@0 107 if (!requirement)
michael@0 108 throw Error('Module: ' + requirer + ' has no authority to load: '
michael@0 109 + id, requirer);
michael@0 110
michael@0 111 uri = requirement;
michael@0 112 } else {
michael@0 113 // If requirer is off manifest than it's a system module and we allow it
michael@0 114 // to go off manifest by resolving a relative path.
michael@0 115 uri = loaderModule.resolve(id, requirer);
michael@0 116 }
michael@0 117 return uri;
michael@0 118 },
michael@0 119 load: function(loader, module) {
michael@0 120 let result;
michael@0 121 let error;
michael@0 122
michael@0 123 // In order to get the module's metadata, we need to load the module.
michael@0 124 // if an exception is raised here, it could be that is due to application
michael@0 125 // incompatibility. Therefore the exception is stored, and thrown again
michael@0 126 // only if the module seems be compatible with the application currently
michael@0 127 // running. Otherwise the incompatibility message takes the precedence.
michael@0 128 try {
michael@0 129 result = load(loader, module);
michael@0 130 }
michael@0 131 catch (e) {
michael@0 132 error = e;
michael@0 133 }
michael@0 134
michael@0 135 error = incompatibility(module) || error;
michael@0 136
michael@0 137 if (error)
michael@0 138 throw error;
michael@0 139
michael@0 140 return result;
michael@0 141 }
michael@0 142 });
michael@0 143
michael@0 144 let loader = loaderModule.Loader(options);
michael@0 145 // Hack to allow loading from `toolkit/loader`.
michael@0 146 loader.modules[loaderURI] = loaderSandbox;
michael@0 147 return loader;
michael@0 148 }
michael@0 149
michael@0 150 exports = override(loaderModule, {
michael@0 151 Loader: CuddlefishLoader
michael@0 152 });

mercurial