diff options
Diffstat (limited to 'tools/addon-sdk-1.7/packages/api-utils/lib/cuddlefish.js')
-rw-r--r-- | tools/addon-sdk-1.7/packages/api-utils/lib/cuddlefish.js | 302 |
1 files changed, 0 insertions, 302 deletions
diff --git a/tools/addon-sdk-1.7/packages/api-utils/lib/cuddlefish.js b/tools/addon-sdk-1.7/packages/api-utils/lib/cuddlefish.js deleted file mode 100644 index ac01aee..0000000 --- a/tools/addon-sdk-1.7/packages/api-utils/lib/cuddlefish.js +++ /dev/null @@ -1,302 +0,0 @@ -/* vim:set ts=2 sw=2 sts=2 expandtab */ -/* 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/. */ -var EXPORTED_SYMBOLS = [ 'Loader' ]; - -!function(exports) { - -"use strict"; - -const { classes: Cc, Constructor: CC, interfaces: Ci, utils: Cu, - results: Cr, manager: Cm } = Components; -const systemPrincipal = CC('@mozilla.org/systemprincipal;1', 'nsIPrincipal')(); -const scriptLoader = Cc['@mozilla.org/moz/jssubscript-loader;1']. - getService(Ci.mozIJSSubScriptLoader); - -const Sandbox = { - new: function ({ principal, prototype, name, existingSandbox }) { - let options = { sandboxPrototype: prototype || Sandbox.prototype, - wantXrays: Sandbox.wantXrays }; - if (name) - options.sandboxName = name; - if (existingSandbox) - options.sameGroupAs = existingSandbox.sandbox; - let sandbox = Object.create(Sandbox, { - sandbox: { value: Cu.Sandbox(principal || Sandbox.principal, options) } - }); - // There are few properties (dump, Iterator) that by default appear in - // sandboxes shadowing properties provided by a prototype. To workaround - // this we override all such properties by copying them directly to the - // sandbox. - Object.keys(prototype).forEach(function onEach(key) { - if (sandbox.sandbox[key] !== prototype[key]) - sandbox.sandbox[key] = prototype[key]; - }); - return sandbox; - }, - evaluate: function evaluate(source, uri, lineNumber) { - return Cu.evalInSandbox( - source, - this.sandbox, - this.version, - uri, - lineNumber || this.lineNumber - ); - }, - load: function load(uri) { - scriptLoader.loadSubScript(uri, this.sandbox, 'UTF-8'); - }, - merge: function merge(properties) { - Object.getOwnPropertyNames(properties).forEach(function(name) { - Object.defineProperty(this.sandbox, name, - Object.getOwnPropertyDescriptor(properties, name)); - }, this); - }, - principal: systemPrincipal, - version: '1.8', - lineNumber: 1, - wantXrays: false, - prototype: {} -}; - -// the Module object made available to CommonJS modules when they are -// evaluated, along with 'exports' and 'uri' -const Module = { - new: function(id, path, uri) { - let module = Object.create(this); - - module.id = id; - module.path = path; - module.uri = uri; - module.exports = {}; - - return module; - }, - // TODO: I'd like to remove this, it's not used adds complexity and does - // not has much adoption in commonjs either. - setExports: function setExports(exports) { - this.exports = exports; - } -}; - -const Loader = { - new: function (options) { - let loader = Object.create(Loader, { - // Manifest generated by a linker, containing map of module url's mapped - // to it's requirements, comes from harness-options.json - manifest: { value: options.manifest || {} }, - - // Following property may be passed in (usually for mocking purposes) in - // order to override default modules cache. - modules: { value: options.modules || Object.create(Loader.modules) }, - globals: { value: options.globals || {} }, - - uriPrefix: { value: options.uriPrefix }, - - sandboxes: { value: {} } - }); - loader.require = this.require.bind(loader, options.loader); - - // some 'magic' modules, that have no corresponding .js file - loader.modules['@packaging'] = Object.freeze({ - id: '@packaging', - exports: JSON.parse(JSON.stringify(options)) - }); - loader.modules['@loader'] = Object.freeze({ - exports: Object.freeze({ Loader: Loader }), - id: '@loader' - }); - - // This special module defines globals which will be added to every - // module this loader creates - let globals = loader.require('api-utils/globals!'); - Object.getOwnPropertyNames(globals).forEach(function(name) { - Object.defineProperty(loader.globals, name, - Object.getOwnPropertyDescriptor(globals, name)); - }); - // Freeze globals so that modules won't have a chance to mutate scope of - // other modules. - Object.freeze(globals); - - // Override global `dump` so that it behaves same as in any other module ( - // currently we override dump to write to a file instead of `stdout` so that - // python can read it on windows). - dump = globals.dump; - - return Object.freeze(loader); - }, - modules: { - 'chrome': Object.freeze({ - exports: Object.freeze({ - Cc: Cc, - CC: CC, - Ci: Ci, - Cu: Cu, - Cr: Cr, - Cm: Cm, - components: Components, - messageManager: 'addMessageListener' in exports ? exports : null - }), - id: 'chrome' - }), - 'self': function self(loader, requirer) { - return loader.require('api-utils/self!').create(requirer.path); - }, - }, - - // populate a Module by evaluating the CommonJS module code in the sandbox - load: function load(module) { - let require = Loader.require.bind(this, module.path); - require.main = this.main; - - // Get an existing module sandbox, if any, so we can reuse its compartment - // when creating the new one to reduce memory consumption. - let existingSandbox = [this.sandboxes[p] for (p in this.sandboxes)][0]; - - // XXX Always set "principal" to work around bug 705795, which generates - // 'reference to undefined property "principal"' warnings when the argument - // is deconstructed in the "new" function's parameter list. - // FIXME: stop setting "principal" once bug 705795 is fixed. - let sandbox = this.sandboxes[module.path] = - Sandbox.new({ principal: null, - prototype: this.globals, - name: module.uri, - existingSandbox: existingSandbox }); - sandbox.merge({ - require: require, - module: module, - exports: module.exports - }); - - sandbox.load(module.uri); - - // Workaround for bug 674195. Freezing objects from other sandboxes fail, - // so we create descendant and freeze it instead. - if (typeof(module.exports) === 'object') { - module.exports = Object.prototype.isPrototypeOf(module.exports) ? - Object.freeze(module.exports) : - Object.freeze(Object.create(module.exports)); - } - }, - - // this require() is the main entry point for regular CommonJS modules. The - // bind() in load (above) causes those modules to get a very restricted - // form of this require(): one which can only ever reference this one - // loader, and which always uses their URI as a "base" (so they're limited - // to their own manifest entries, and can't import anything off the - // manifest). - require: function require(base, id) { - let module, manifest = this.manifest[base], requirer = this.modules[base]; - - if (!id) - throw Error("you must provide a module name when calling require() from " - + (requirer && requirer.id), base, id); - - // If we have a manifest for requirer, then all it's requirements have been - // registered by linker and we should have a `path` to the required module. - // Even pseudo-modules like 'chrome', 'self', '@packaging', and '@loader' - // have pseudo-paths: exactly those same names. - // details see: Bug-697422. - let requirement = manifest && manifest.requirements[id]; - if (!requirement) - throw Error("Module: " + (requirer && requirer.id) + ' located at ' + - base + " has no authority to load: " + id); - let path = requirement.path; - - if (path in this.modules) { - module = this.modules[path]; - } - else { - let uri = this.uriPrefix + path; - module = this.modules[path] = Module.new(id, path, uri); - this.load(module); - Object.freeze(module); - } - - // "magic" modules which have contents that depend upon who imports them - // (like "self") are expressed in the Loader's pre-populated 'modules' - // table as callable functions, which are given the reference to this - // Loader and a copy of the importer's URI - // - // TODO: Find a better way to implement `self`. - // Maybe something like require('self!path/to/data') - if (typeof(module) === 'function') - module = module(this, requirer); - - return module.exports; - }, - - // process.process() will eventually cause a call to main() to be evaluated - // in the addon's context. This function loads and executes the addon's - // entry point module. - main: function main(id, path) { - try { - let uri = this.uriPrefix + path; - let module = this.modules[path] = Module.new(id, path, uri); - this.load(module); // this is where the addon's main.js finally runs - let program = Object.freeze(module).exports; - - if (typeof(program.onUnload) === 'function') - this.require('api-utils/unload').when(program.onUnload); - - if (program.main) { - let { exit, staticArgs } = this.require('api-utils/system'); - let { loadReason } = this.require('@packaging'); - program.main({ loadReason: loadReason, staticArgs: staticArgs }, - { print: function($) dump($ + '\n'), quit: exit }); - } - } catch (error) { - Cu.reportError(error); - if (this.globals.console) this.globals.console.exception(error); - throw error; - } - }, - - // This is the main entry-point: bootstrap.js calls this when the add-on is - // installed. The order of calls is a bit confusing, but here's what - // happens (in temporal order): - // * process.spawn creates a new XUL 'browser' element which will house the - // main addon code. When e10s is active, this uses a real separate OS - // process. When e10s is disabled, this element lives in the one original - // process. Either way, its API is the same. - // * Grab the channel named "require!" and attach a handler which will load - // modules (in the chrome process) when requested to by the addon - // process. This handler uses Loader.require to import the module, then - // calls the module's .initialize() function to connect a new channel. - // The remote caller winds up with a channel reference, which they can - // use to send messages to the newly loaded module. This is for e10s. - // * After the channel handler is attached, process.process() (invoked by - // process.spawn()) will use loadScript() to evaluate code in the - // 'browser' element (which is where the main addon code starts running), - // to do the following: - // * create a Loader, initialized with the same manifest and - // harness-options.json that we've got - // * invoke it's main() method, with the name and path of the addon's - // entry module (which comes from linker via harness-options.js, and is - // usually main.js). That executes main(), above. - // * main() loads the addon's main.js, which executes all top-level - // forms. If the module defines an "exports.main=" function, we invoke - // that too. This is where the addon finally gets to run. - spawn: function spawn(id, path) { - let loader = this; - let process = this.require('api-utils/process'); - process.spawn(id, path)(function(addon) { - // Listen to `require!` channel's input messages from the add-on process - // and load modules being required. - addon.channel('require!').input(function({ requirer: { path }, id }) { - try { - Loader.require.call(loader, path, id).initialize(addon.channel(id)); - } catch (error) { - this.globals.console.exception(error); - } - }); - }); - }, - unload: function unload(reason, callback) { - this.require('api-utils/unload').send(reason, callback); - } -}; -exports.Loader = Loader; - -}(this); |