diff options
author | Matt A. Tobin <email@mattatobin.com> | 2018-02-09 06:46:43 -0500 |
---|---|---|
committer | Matt A. Tobin <email@mattatobin.com> | 2018-02-09 06:46:43 -0500 |
commit | ac46df8daea09899ce30dc8fd70986e258c746bf (patch) | |
tree | 2750d3125fc253fd5b0671e4bd268eff1fd97296 /addon-sdk/source/lib/sdk/system | |
parent | 8cecf8d5208f3945b35f879bba3015bb1a11bec6 (diff) | |
download | UXP-ac46df8daea09899ce30dc8fd70986e258c746bf.tar UXP-ac46df8daea09899ce30dc8fd70986e258c746bf.tar.gz UXP-ac46df8daea09899ce30dc8fd70986e258c746bf.tar.lz UXP-ac46df8daea09899ce30dc8fd70986e258c746bf.tar.xz UXP-ac46df8daea09899ce30dc8fd70986e258c746bf.zip |
Move Add-on SDK source to toolkit/jetpack
Diffstat (limited to 'addon-sdk/source/lib/sdk/system')
-rw-r--r-- | addon-sdk/source/lib/sdk/system/child_process.js | 332 | ||||
-rw-r--r-- | addon-sdk/source/lib/sdk/system/child_process/subprocess.js | 186 | ||||
-rw-r--r-- | addon-sdk/source/lib/sdk/system/environment.js | 33 | ||||
-rw-r--r-- | addon-sdk/source/lib/sdk/system/events-shimmed.js | 16 | ||||
-rw-r--r-- | addon-sdk/source/lib/sdk/system/events.js | 181 | ||||
-rw-r--r-- | addon-sdk/source/lib/sdk/system/globals.js | 46 | ||||
-rw-r--r-- | addon-sdk/source/lib/sdk/system/process.js | 62 | ||||
-rw-r--r-- | addon-sdk/source/lib/sdk/system/runtime.js | 28 | ||||
-rw-r--r-- | addon-sdk/source/lib/sdk/system/unload.js | 104 | ||||
-rw-r--r-- | addon-sdk/source/lib/sdk/system/xul-app.js | 12 | ||||
-rw-r--r-- | addon-sdk/source/lib/sdk/system/xul-app.jsm | 242 |
11 files changed, 0 insertions, 1242 deletions
diff --git a/addon-sdk/source/lib/sdk/system/child_process.js b/addon-sdk/source/lib/sdk/system/child_process.js deleted file mode 100644 index 8ea1f4f80..000000000 --- a/addon-sdk/source/lib/sdk/system/child_process.js +++ /dev/null @@ -1,332 +0,0 @@ -/* 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': 'experimental' -}; - -var { Ci } = require('chrome'); -var subprocess = require('./child_process/subprocess'); -var { EventTarget } = require('../event/target'); -var { Stream } = require('../io/stream'); -var { on, emit, off } = require('../event/core'); -var { Class } = require('../core/heritage'); -var { platform } = require('../system'); -var { isFunction, isArray } = require('../lang/type'); -var { delay } = require('../lang/functional'); -var { merge } = require('../util/object'); -var { setTimeout, clearTimeout } = require('../timers'); -var isWindows = platform.indexOf('win') === 0; - -var processes = new WeakMap(); - - -/** - * The `Child` class wraps a subprocess command, exposes - * the stdio streams, and methods to manipulate the subprocess - */ -var Child = Class({ - implements: [EventTarget], - initialize: function initialize (options) { - let child = this; - let proc; - - this.killed = false; - this.exitCode = undefined; - this.signalCode = undefined; - - this.stdin = Stream(); - this.stdout = Stream(); - this.stderr = Stream(); - - try { - proc = subprocess.call({ - command: options.file, - arguments: options.cmdArgs, - environment: serializeEnv(options.env), - workdir: options.cwd, - charset: options.encoding, - stdout: data => emit(child.stdout, 'data', data), - stderr: data => emit(child.stderr, 'data', data), - stdin: stream => { - child.stdin.on('data', pumpStdin); - child.stdin.on('end', function closeStdin () { - child.stdin.off('data', pumpStdin); - child.stdin.off('end', closeStdin); - stream.close(); - }); - function pumpStdin (data) { - stream.write(data); - } - }, - done: function (result, error) { - if (error) - return handleError(error); - - // Only emit if child is not killed; otherwise, - // the `kill` method will handle this - if (!child.killed) { - child.exitCode = result.exitCode; - child.signalCode = null; - - // If process exits with < 0, there was an error - if (child.exitCode < 0) { - handleError(new Error('Process exited with exit code ' + child.exitCode)); - } - else { - // Also do 'exit' event as there's not much of - // a difference in our implementation as we're not using - // node streams - emit(child, 'exit', child.exitCode, child.signalCode); - } - - // Emit 'close' event with exit code and signal, - // which is `null`, as it was not a killed process - emit(child, 'close', child.exitCode, child.signalCode); - } - } - }); - processes.set(child, proc); - } catch (e) { - // Delay the error handling so an error handler can be set - // during the same tick that the Child was created - delay(() => handleError(e)); - } - - // `handleError` is called when process could not even - // be spawned - function handleError (e) { - // If error is an nsIObject, make a fresh error object - // so we're not exposing nsIObjects, and we can modify it - // with additional process information, like node - let error = e; - if (e instanceof Ci.nsISupports) { - error = new Error(e.message, e.filename, e.lineNumber); - } - emit(child, 'error', error); - child.exitCode = -1; - child.signalCode = null; - emit(child, 'close', child.exitCode, child.signalCode); - } - }, - kill: function kill (signal) { - let proc = processes.get(this); - proc.kill(signal); - this.killed = true; - this.exitCode = null; - this.signalCode = signal; - emit(this, 'exit', this.exitCode, this.signalCode); - emit(this, 'close', this.exitCode, this.signalCode); - }, - get pid() { return processes.get(this, {}).pid || -1; } -}); - -function spawn (file, ...args) { - let cmdArgs = []; - // Default options - let options = { - cwd: null, - env: null, - encoding: 'UTF-8' - }; - - if (args[1]) { - merge(options, args[1]); - cmdArgs = args[0]; - } - else { - if (isArray(args[0])) - cmdArgs = args[0]; - else - merge(options, args[0]); - } - - if ('gid' in options) - console.warn('`gid` option is not yet supported for `child_process`'); - if ('uid' in options) - console.warn('`uid` option is not yet supported for `child_process`'); - if ('detached' in options) - console.warn('`detached` option is not yet supported for `child_process`'); - - options.file = file; - options.cmdArgs = cmdArgs; - - return Child(options); -} - -exports.spawn = spawn; - -/** - * exec(command, options, callback) - */ -function exec (cmd, ...args) { - let file, cmdArgs, callback, options = {}; - - if (isFunction(args[0])) - callback = args[0]; - else { - merge(options, args[0]); - callback = args[1]; - } - - if (isWindows) { - file = 'C:\\Windows\\System32\\cmd.exe'; - cmdArgs = ['/S/C', cmd || '']; - } - else { - file = '/bin/sh'; - cmdArgs = ['-c', cmd]; - } - - // Undocumented option from node being able to specify shell - if (options && options.shell) - file = options.shell; - - return execFile(file, cmdArgs, options, callback); -} -exports.exec = exec; -/** - * execFile (file, args, options, callback) - */ -function execFile (file, ...args) { - let cmdArgs = [], callback; - // Default options - let options = { - cwd: null, - env: null, - encoding: 'utf8', - timeout: 0, - maxBuffer: 204800, //200 KB (200*1024 bytes) - killSignal: 'SIGTERM' - }; - - if (isFunction(args[args.length - 1])) - callback = args[args.length - 1]; - - if (isArray(args[0])) { - cmdArgs = args[0]; - merge(options, args[1]); - } else if (!isFunction(args[0])) - merge(options, args[0]); - - let child = spawn(file, cmdArgs, options); - let exited = false; - let stdout = ''; - let stderr = ''; - let error = null; - let timeoutId = null; - - child.stdout.setEncoding(options.encoding); - child.stderr.setEncoding(options.encoding); - - on(child.stdout, 'data', pumpStdout); - on(child.stderr, 'data', pumpStderr); - on(child, 'close', exitHandler); - on(child, 'error', errorHandler); - - if (options.timeout > 0) { - setTimeout(() => { - kill(); - timeoutId = null; - }, options.timeout); - } - - function exitHandler (code, signal) { - - // Return if exitHandler called previously, occurs - // when multiple maxBuffer errors thrown and attempt to kill multiple - // times - if (exited) return; - exited = true; - - if (!isFunction(callback)) return; - - if (timeoutId) { - clearTimeout(timeoutId); - timeoutId = null; - } - - if (!error && (code !== 0 || signal !== null)) - error = createProcessError(new Error('Command failed: ' + stderr), { - code: code, - signal: signal, - killed: !!child.killed - }); - - callback(error, stdout, stderr); - - off(child.stdout, 'data', pumpStdout); - off(child.stderr, 'data', pumpStderr); - off(child, 'close', exitHandler); - off(child, 'error', errorHandler); - } - - function errorHandler (e) { - error = e; - exitHandler(); - } - - function kill () { - try { - child.kill(options.killSignal); - } catch (e) { - // In the scenario where the kill signal happens when - // the process is already closing, just abort the kill fail - if (/library is not open/.test(e)) - return; - error = e; - exitHandler(-1, options.killSignal); - } - } - - function pumpStdout (data) { - stdout += data; - if (stdout.length > options.maxBuffer) { - error = new Error('stdout maxBuffer exceeded'); - kill(); - } - } - - function pumpStderr (data) { - stderr += data; - if (stderr.length > options.maxBuffer) { - error = new Error('stderr maxBuffer exceeded'); - kill(); - } - } - - return child; -} -exports.execFile = execFile; - -exports.fork = function fork () { - throw new Error("child_process#fork is not currently supported"); -}; - -function serializeEnv (obj) { - return Object.keys(obj || {}).map(prop => prop + '=' + obj[prop]); -} - -function createProcessError (err, options = {}) { - // If code and signal look OK, this was probably a failure - // attempting to spawn the process (like ENOENT in node) -- use - // the code from the error message - if (!options.code && !options.signal) { - let match = err.message.match(/(NS_ERROR_\w*)/); - if (match && match.length > 1) - err.code = match[1]; - else { - // If no good error message found, use the passed in exit code; - // this occurs when killing a process that's already closing, - // where we want both a valid exit code (0) and the error - err.code = options.code != null ? options.code : null; - } - } - else - err.code = options.code != null ? options.code : null; - err.signal = options.signal || null; - err.killed = options.killed || false; - return err; -} diff --git a/addon-sdk/source/lib/sdk/system/child_process/subprocess.js b/addon-sdk/source/lib/sdk/system/child_process/subprocess.js deleted file mode 100644 index e3454e95b..000000000 --- a/addon-sdk/source/lib/sdk/system/child_process/subprocess.js +++ /dev/null @@ -1,186 +0,0 @@ -/* 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'; - -const { Ci, Cu } = require("chrome"); - -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/Subprocess.jsm"); -Cu.import("resource://gre/modules/Task.jsm"); - -const Runtime = require("sdk/system/runtime"); -const Environment = require("sdk/system/environment").env; -const DEFAULT_ENVIRONMENT = []; -if (Runtime.OS == "Linux" && "DISPLAY" in Environment) { - DEFAULT_ENVIRONMENT.push("DISPLAY=" + Environment.DISPLAY); -} - -function awaitPromise(promise) { - let value; - let resolved = null; - promise.then(val => { - resolved = true; - value = val; - }, val => { - resolved = false; - value = val; - }); - - while (resolved === null) - Services.tm.mainThread.processNextEvent(true); - - if (resolved === true) - return value; - throw value; -} - -let readAllData = Task.async(function* (pipe, read, callback) { - let string; - while (string = yield read(pipe)) - callback(string); -}); - -let write = (pipe, data) => { - let buffer = new Uint8Array(Array.from(data, c => c.charCodeAt(0))); - return pipe.write(data); -}; - -var subprocess = { - call: function(options) { - var result; - - let procPromise = Task.spawn(function*() { - let opts = {}; - - if (options.mergeStderr) { - opts.stderr = "stdout" - } else if (options.stderr) { - opts.stderr = "pipe"; - } - - if (options.command instanceof Ci.nsIFile) { - opts.command = options.command.path; - } else { - opts.command = yield Subprocess.pathSearch(options.command); - } - - if (options.workdir) { - opts.workdir = options.workdir; - } - - opts.arguments = options.arguments || []; - - - // Set up environment - - let envVars = options.environment || DEFAULT_ENVIRONMENT; - if (envVars.length) { - let environment = {}; - for (let val of envVars) { - let idx = val.indexOf("="); - if (idx >= 0) - environment[val.slice(0, idx)] = val.slice(idx + 1); - } - - opts.environment = environment; - } - - - let proc = yield Subprocess.call(opts); - - Object.defineProperty(result, "pid", { - value: proc.pid, - enumerable: true, - configurable: true, - }); - - - let promises = []; - - // Set up IO handlers. - - let read = pipe => pipe.readString(); - if (options.charset === null) { - read = pipe => { - return pipe.read().then(buffer => { - return String.fromCharCode(...buffer); - }); - }; - } - - if (options.stdout) - promises.push(readAllData(proc.stdout, read, options.stdout)); - - if (options.stderr && proc.stderr) - promises.push(readAllData(proc.stderr, read, options.stderr)); - - // Process stdin - - if (typeof options.stdin === "string") { - write(proc.stdin, options.stdin); - proc.stdin.close(); - } - - - // Handle process completion - - if (options.done) - Promise.all(promises) - .then(() => proc.wait()) - .then(options.done); - - return proc; - }); - - procPromise.catch(e => { - if (options.done) - options.done({exitCode: -1}, e); - else - Cu.reportError(e instanceof Error ? e : e.message || e); - }); - - if (typeof options.stdin === "function") { - // Unfortunately, some callers (child_process.js) depend on this - // being called synchronously. - options.stdin({ - write(val) { - procPromise.then(proc => { - write(proc.stdin, val); - }); - }, - - close() { - procPromise.then(proc => { - proc.stdin.close(); - }); - }, - }); - } - - result = { - get pid() { - return awaitPromise(procPromise.then(proc => { - return proc.pid; - })); - }, - - wait() { - return awaitPromise(procPromise.then(proc => { - return proc.wait().then(({exitCode}) => exitCode); - })); - }, - - kill(hard = false) { - procPromise.then(proc => { - proc.kill(hard ? 0 : undefined); - }); - }, - }; - - return result; - }, -}; - -module.exports = subprocess; diff --git a/addon-sdk/source/lib/sdk/system/environment.js b/addon-sdk/source/lib/sdk/system/environment.js deleted file mode 100644 index 13621a696..000000000 --- a/addon-sdk/source/lib/sdk/system/environment.js +++ /dev/null @@ -1,33 +0,0 @@ -/* 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": "stable" -}; - -const { Cc, Ci } = require('chrome'); -const { get, set, exists } = Cc['@mozilla.org/process/environment;1']. - getService(Ci.nsIEnvironment); - -exports.env = new Proxy({}, { - deleteProperty(target, property) { - set(property, null); - return true; - }, - - get(target, property, receiver) { - return get(property) || undefined; - }, - - has(target, property) { - return exists(property); - }, - - set(target, property, value, receiver) { - set(property, value); - return true; - } -}); diff --git a/addon-sdk/source/lib/sdk/system/events-shimmed.js b/addon-sdk/source/lib/sdk/system/events-shimmed.js deleted file mode 100644 index 14496f1f0..000000000 --- a/addon-sdk/source/lib/sdk/system/events-shimmed.js +++ /dev/null @@ -1,16 +0,0 @@ -/* 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' -}; - -const events = require('./events.js'); - -exports.emit = (type, event) => events.emit(type, event, true); -exports.on = (type, listener, strong) => events.on(type, listener, strong, true); -exports.once = (type, listener) => events.once(type, listener, true); -exports.off = (type, listener) => events.off(type, listener, true); diff --git a/addon-sdk/source/lib/sdk/system/events.js b/addon-sdk/source/lib/sdk/system/events.js deleted file mode 100644 index 0cf525aa1..000000000 --- a/addon-sdk/source/lib/sdk/system/events.js +++ /dev/null @@ -1,181 +0,0 @@ -/* 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' -}; - -const { Cc, Ci, Cu } = require('chrome'); -const { Unknown } = require('../platform/xpcom'); -const { Class } = require('../core/heritage'); -const { ns } = require('../core/namespace'); -const observerService = - Cc['@mozilla.org/observer-service;1'].getService(Ci.nsIObserverService); -const { addObserver, removeObserver, notifyObservers } = observerService; -const { ShimWaiver } = Cu.import("resource://gre/modules/ShimWaiver.jsm"); -const addObserverNoShim = ShimWaiver.getProperty(observerService, "addObserver"); -const removeObserverNoShim = ShimWaiver.getProperty(observerService, "removeObserver"); -const notifyObserversNoShim = ShimWaiver.getProperty(observerService, "notifyObservers"); -const unloadSubject = require('@loader/unload'); - -const Subject = Class({ - extends: Unknown, - initialize: function initialize(object) { - // Double-wrap the object and set a property identifying the - // wrappedJSObject as one of our wrappers to distinguish between - // subjects that are one of our wrappers (which we should unwrap - // when notifying our observers) and those that are real JS XPCOM - // components (which we should pass through unaltered). - this.wrappedJSObject = { - observersModuleSubjectWrapper: true, - object: object - }; - }, - getScriptableHelper: function() {}, - getInterfaces: function() {} -}); - -function emit(type, event, shimmed = false) { - // From bug 910599 - // We must test to see if 'subject' or 'data' is a defined property - // of the event object, but also allow primitives to be passed in, - // which the `in` operator breaks, yet `null` is an object, hence - // the long conditional - let subject = event && typeof event === 'object' && 'subject' in event ? - Subject(event.subject) : - null; - let data = event && typeof event === 'object' ? - // An object either returns its `data` property or null - ('data' in event ? event.data : null) : - // All other types return themselves (and cast to strings/null - // via observer service) - event; - if (shimmed) { - notifyObservers(subject, type, data); - } else { - notifyObserversNoShim(subject, type, data); - } -} -exports.emit = emit; - -const Observer = Class({ - extends: Unknown, - initialize: function initialize(listener) { - this.listener = listener; - }, - interfaces: [ 'nsIObserver', 'nsISupportsWeakReference' ], - observe: function(subject, topic, data) { - // Extract the wrapped object for subjects that are one of our - // wrappers around a JS object. This way we support both wrapped - // subjects created using this module and those that are real - // XPCOM components. - if (subject && typeof(subject) == 'object' && - ('wrappedJSObject' in subject) && - ('observersModuleSubjectWrapper' in subject.wrappedJSObject)) - subject = subject.wrappedJSObject.object; - - try { - this.listener({ - type: topic, - subject: subject, - data: data - }); - } - catch (error) { - console.exception(error); - } - } -}); - -const subscribers = ns(); - -function on(type, listener, strong, shimmed = false) { - // Unless last optional argument is `true` we use a weak reference to a - // listener. - let weak = !strong; - // Take list of observers associated with given `listener` function. - let observers = subscribers(listener); - // If `observer` for the given `type` is not registered yet, then - // associate an `observer` and register it. - if (!(type in observers)) { - let observer = Observer(listener); - observers[type] = observer; - if (shimmed) { - addObserver(observer, type, weak); - } else { - addObserverNoShim(observer, type, weak); - } - // WeakRef gymnastics to remove all alive observers on unload - let ref = Cu.getWeakReference(observer); - weakRefs.set(observer, ref); - stillAlive.set(ref, type); - wasShimmed.set(ref, shimmed); - } -} -exports.on = on; - -function once(type, listener, shimmed = false) { - // Note: this code assumes order in which listeners are called, which is fine - // as long as dispatch happens in same order as listener registration which - // is the case now. That being said we should be aware that this may break - // in a future if order will change. - on(type, listener, shimmed); - on(type, function cleanup() { - off(type, listener, shimmed); - off(type, cleanup, shimmed); - }, true, shimmed); -} -exports.once = once; - -function off(type, listener, shimmed = false) { - // Take list of observers as with the given `listener`. - let observers = subscribers(listener); - // If `observer` for the given `type` is registered, then - // remove it & unregister. - if (type in observers) { - let observer = observers[type]; - delete observers[type]; - if (shimmed) { - removeObserver(observer, type); - } else { - removeObserverNoShim(observer, type); - } - stillAlive.delete(weakRefs.get(observer)); - wasShimmed.delete(weakRefs.get(observer)); - } -} -exports.off = off; - -// must use WeakMap to keep reference to all the WeakRefs (!), see bug 986115 -var weakRefs = new WeakMap(); - -// and we're out of beta, we're releasing on time! -var stillAlive = new Map(); - -var wasShimmed = new Map(); - -on('sdk:loader:destroy', function onunload({ subject, data: reason }) { - // using logic from ./unload, to avoid a circular module reference - if (subject.wrappedJSObject === unloadSubject) { - off('sdk:loader:destroy', onunload, false); - - // don't bother - if (reason === 'shutdown') - return; - - stillAlive.forEach( (type, ref) => { - let observer = ref.get(); - if (observer) { - if (wasShimmed.get(ref)) { - removeObserver(observer, type); - } else { - removeObserverNoShim(observer, type); - } - } - }) - } - // a strong reference -}, true, false); diff --git a/addon-sdk/source/lib/sdk/system/globals.js b/addon-sdk/source/lib/sdk/system/globals.js deleted file mode 100644 index a1a6cf9a2..000000000 --- a/addon-sdk/source/lib/sdk/system/globals.js +++ /dev/null @@ -1,46 +0,0 @@ -/* 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" -}; - -var { Cc, Ci, CC } = require('chrome'); -var { PlainTextConsole } = require('../console/plain-text'); -var { stdout } = require('../system'); -var ScriptError = CC('@mozilla.org/scripterror;1', 'nsIScriptError'); -var consoleService = Cc['@mozilla.org/consoleservice;1'].getService(Ci.nsIConsoleService); - -// On windows dump does not writes into stdout so cfx can't read thous dumps. -// To workaround this issue we write to a special file from which cfx will -// read and print to the console. -// For more details see: bug-673383 -exports.dump = stdout.write; - -exports.console = new PlainTextConsole(); - -// Provide CommonJS `define` to allow authoring modules in a format that can be -// loaded both into jetpack and into browser via AMD loaders. -Object.defineProperty(exports, 'define', { - // `define` is provided as a lazy getter that binds below defined `define` - // function to the module scope, so that require, exports and module - // variables remain accessible. - configurable: true, - get: function() { - let sandbox = this; - return function define(factory) { - factory = Array.slice(arguments).pop(); - factory.call(sandbox, sandbox.require, sandbox.exports, sandbox.module); - } - }, - set: function(value) { - Object.defineProperty(this, 'define', { - configurable: true, - enumerable: true, - value, - }); - }, -}); diff --git a/addon-sdk/source/lib/sdk/system/process.js b/addon-sdk/source/lib/sdk/system/process.js deleted file mode 100644 index f44a36658..000000000 --- a/addon-sdk/source/lib/sdk/system/process.js +++ /dev/null @@ -1,62 +0,0 @@ -/* 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" -}; - -const { - exit, version, stdout, stderr, platform, architecture -} = require("../system"); - -/** - * Supported - */ - -exports.stdout = stdout; -exports.stderr = stderr; -exports.version = version; -exports.versions = {}; -exports.config = {}; -exports.arch = architecture; -exports.platform = platform; -exports.exit = exit; - -/** - * Partial support - */ - -// An alias to `setTimeout(fn, 0)`, which isn't the same as node's `nextTick`, -// but atleast ensures it'll occur asynchronously -exports.nextTick = (callback) => setTimeout(callback, 0); - -/** - * Unsupported - */ - -exports.maxTickDepth = 1000; -exports.pid = 0; -exports.title = ""; -exports.stdin = {}; -exports.argv = []; -exports.execPath = ""; -exports.execArgv = []; -exports.abort = function () {}; -exports.chdir = function () {}; -exports.cwd = function () {}; -exports.env = {}; -exports.getgid = function () {}; -exports.setgid = function () {}; -exports.getuid = function () {}; -exports.setuid = function () {}; -exports.getgroups = function () {}; -exports.setgroups = function () {}; -exports.initgroups = function () {}; -exports.kill = function () {}; -exports.memoryUsage = function () {}; -exports.umask = function () {}; -exports.uptime = function () {}; -exports.hrtime = function () {}; diff --git a/addon-sdk/source/lib/sdk/system/runtime.js b/addon-sdk/source/lib/sdk/system/runtime.js deleted file mode 100644 index 9a70f142d..000000000 --- a/addon-sdk/source/lib/sdk/system/runtime.js +++ /dev/null @@ -1,28 +0,0 @@ -/* 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" -}; - -const { Cc, Ci } = require("chrome"); -const runtime = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime); - -exports.inSafeMode = runtime.inSafeMode; -exports.OS = runtime.OS; -exports.processType = runtime.processType; -exports.widgetToolkit = runtime.widgetToolkit; -exports.processID = runtime.processID; - -// Attempt to access `XPCOMABI` may throw exception, in which case exported -// `XPCOMABI` will be set to `null`. -// https://mxr.mozilla.org/mozilla-central/source/toolkit/xre/nsAppRunner.cpp#732 -try { - exports.XPCOMABI = runtime.XPCOMABI; -} -catch (error) { - exports.XPCOMABI = null; -} diff --git a/addon-sdk/source/lib/sdk/system/unload.js b/addon-sdk/source/lib/sdk/system/unload.js deleted file mode 100644 index 98ab5f8f3..000000000 --- a/addon-sdk/source/lib/sdk/system/unload.js +++ /dev/null @@ -1,104 +0,0 @@ -/* 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/. */ - -// Parts of this module were taken from narwhal: -// -// http://narwhaljs.org - -module.metadata = { - "stability": "experimental" -}; - -const { Cu } = require('chrome'); -const { on, off } = require('./events'); -const unloadSubject = require('@loader/unload'); - -const observers = []; -const unloaders = []; - -function WeakObserver(inner) { - this._inner = Cu.getWeakReference(inner); -} - -Object.defineProperty(WeakObserver.prototype, 'value', { - get: function() { this._inner.get() } -}); - -var when = exports.when = function when(observer, opts) { - opts = opts || {}; - for (var i = 0; i < observers.length; ++i) { - if (observers[i] === observer || observers[i].value === observer) { - return; - } - } - if (opts.weak) { - observers.unshift(new WeakObserver(observer)); - } else { - observers.unshift(observer); - } -}; - -var ensure = exports.ensure = function ensure(obj, destructorName) { - if (!destructorName) - destructorName = "unload"; - if (!(destructorName in obj)) - throw new Error("object has no '" + destructorName + "' property"); - - let called = false; - let originalDestructor = obj[destructorName]; - - function unloadWrapper(reason) { - if (!called) { - called = true; - let index = unloaders.indexOf(unloadWrapper); - if (index == -1) - throw new Error("internal error: unloader not found"); - unloaders.splice(index, 1); - originalDestructor.call(obj, reason); - originalDestructor = null; - destructorName = null; - obj = null; - } - }; - - // TODO: Find out why the order is inverted here. It seems that - // it may be causing issues! - unloaders.push(unloadWrapper); - - obj[destructorName] = unloadWrapper; -}; - -function unload(reason) { - observers.forEach(function(observer) { - try { - if (observer instanceof WeakObserver) { - observer = observer.value; - } - if (typeof observer === 'function') { - observer(reason); - } - } - catch (error) { - console.exception(error); - } - }); -} - -when(function(reason) { - unloaders.slice().forEach(function(unloadWrapper) { - unloadWrapper(reason); - }); -}); - -on('sdk:loader:destroy', function onunload({ subject, data: reason }) { - // If this loader is unload then `subject.wrappedJSObject` will be - // `destructor`. - if (subject.wrappedJSObject === unloadSubject) { - off('sdk:loader:destroy', onunload); - unload(reason); - } -// Note that we use strong reference to listener here to make sure it's not -// GC-ed, which may happen otherwise since nothing keeps reference to `onunolad` -// function. -}, true); diff --git a/addon-sdk/source/lib/sdk/system/xul-app.js b/addon-sdk/source/lib/sdk/system/xul-app.js deleted file mode 100644 index 612386f77..000000000 --- a/addon-sdk/source/lib/sdk/system/xul-app.js +++ /dev/null @@ -1,12 +0,0 @@ -/* 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": "experimental" -}; - -const { XulApp } = require("./xul-app.jsm"); - -Object.keys(XulApp).forEach(k => exports[k] = XulApp[k]); diff --git a/addon-sdk/source/lib/sdk/system/xul-app.jsm b/addon-sdk/source/lib/sdk/system/xul-app.jsm deleted file mode 100644 index 90681bb1b..000000000 --- a/addon-sdk/source/lib/sdk/system/xul-app.jsm +++ /dev/null @@ -1,242 +0,0 @@ -/* 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"; - -this.EXPORTED_SYMBOLS = [ "XulApp" ]; - -var { classes: Cc, interfaces: Ci } = Components; - -var exports = {}; -this.XulApp = exports; - -var appInfo; - -// NOTE: below is required to avoid failing xpcshell tests, -// which do not implement nsIXULAppInfo -// See Bug 1114752 https://bugzilla.mozilla.org/show_bug.cgi?id=1114752 -try { - appInfo = Cc["@mozilla.org/xre/app-info;1"] - .getService(Ci.nsIXULAppInfo); -} -catch (e) { - // xpcshell test case - appInfo = {}; -} -var vc = Cc["@mozilla.org/xpcom/version-comparator;1"] - .getService(Ci.nsIVersionComparator); - -var ID = exports.ID = appInfo.ID; -var name = exports.name = appInfo.name; -var version = exports.version = appInfo.version; -var platformVersion = exports.platformVersion = appInfo.platformVersion; - -// The following mapping of application names to GUIDs was taken from: -// -// https://addons.mozilla.org/en-US/firefox/pages/appversions -// -// Using the GUID instead of the app's name is preferable because sometimes -// re-branded versions of a product have different names: for instance, -// Firefox, Minefield, Iceweasel, and Shiretoko all have the same -// GUID. - -var ids = exports.ids = { - Firefox: "{ec8030f7-c20a-464f-9b0e-13a3a9e97384}", - Mozilla: "{86c18b42-e466-45a9-ae7a-9b95ba6f5640}", - SeaMonkey: "{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}", - Fennec: "{aa3c5121-dab2-40e2-81ca-7ea25febc110}", - Thunderbird: "{3550f703-e582-4d05-9a08-453d09bdfdc6}", - Instantbird: "{33cb9019-c295-46dd-be21-8c4936574bee}" -}; - -function is(name) { - if (!(name in ids)) - throw new Error("Unkown Mozilla Application: " + name); - return ID == ids[name]; -}; -exports.is = is; - -function isOneOf(names) { - for (var i = 0; i < names.length; i++) - if (is(names[i])) - return true; - return false; -}; -exports.isOneOf = isOneOf; - -/** - * Use this to check whether the given version (e.g. xulApp.platformVersion) - * is in the given range. Versions must be in version comparator-compatible - * format. See MDC for details: - * https://developer.mozilla.org/en/XPCOM_Interface_Reference/nsIVersionComparator - */ -var versionInRange = exports.versionInRange = -function versionInRange(version, lowInclusive, highExclusive) { - return (vc.compare(version, lowInclusive) >= 0) && - (vc.compare(version, highExclusive) < 0); -} - -const reVersionRange = /^((?:<|>)?=?)?\s*((?:\d+[\S]*)|\*)(?:\s+((?:<|>)=?)?(\d+[\S]+))?$/; -const reOnlyInifinity = /^[<>]?=?\s*[*x]$/; -const reSubInfinity = /\.[*x]/g; -const reHyphenRange = /^(\d+.*?)\s*-\s*(\d+.*?)$/; -const reRangeSeparator = /\s*\|\|\s*/; - -const compares = { - "=": function (c) { return c === 0 }, - ">=": function (c) { return c >= 0 }, - "<=": function (c) { return c <= 0}, - "<": function (c) { return c < 0 }, - ">": function (c) { return c > 0 } -} - -function normalizeRange(range) { - return range - .replace(reOnlyInifinity, "") - .replace(reSubInfinity, ".*") - .replace(reHyphenRange, ">=$1 <=$2") -} - -/** - * Compare the versions given, using the comparison operator provided. - * Internal use only. - * - * @example - * compareVersion("1.2", "<=", "1.*") // true - * - * @param {String} version - * A version to compare - * - * @param {String} comparison - * The comparison operator - * - * @param {String} compareVersion - * A version to compare - */ -function compareVersion(version, comparison, compareVersion) { - let hasWildcard = compareVersion.indexOf("*") !== -1; - - comparison = comparison || "="; - - if (hasWildcard) { - switch (comparison) { - case "=": - let zeroVersion = compareVersion.replace(reSubInfinity, ".0"); - return versionInRange(version, zeroVersion, compareVersion); - case ">=": - compareVersion = compareVersion.replace(reSubInfinity, ".0"); - break; - } - } - - let compare = compares[comparison]; - - return typeof compare === "function" && compare(vc.compare(version, compareVersion)); -} - -/** - * Returns `true` if `version` satisfies the `versionRange` given. - * If only an argument is passed, is used as `versionRange` and compared against - * `xulApp.platformVersion`. - * - * `versionRange` is either a string which has one or more space-separated - * descriptors, or a range like "fromVersion - toVersion". - * Version range descriptors may be any of the following styles: - * - * - "version" Must match `version` exactly - * - "=version" Same as just `version` - * - ">version" Must be greater than `version` - * - ">=version" Must be greater or equal than `version` - * - "<version" Must be less than `version` - * - "<=version" Must be less or equal than `version` - * - "1.2.x" or "1.2.*" See 'X version ranges' below - * - "*" or "" (just an empty string) Matches any version - * - "version1 - version2" Same as ">=version1 <=version2" - * - "range1 || range2" Passes if either `range1` or `range2` are satisfied - * - * For example, these are all valid: - * - "1.0.0 - 2.9999.9999" - * - ">=1.0.2 <2.1.2" - * - ">1.0.2 <=2.3.4" - * - "2.0.1" - * - "<1.0.0 || >=2.3.1 <2.4.5 || >=2.5.2 <3.0.0" - * - "2.x" (equivalent to "2.*") - * - "1.2.x" (equivalent to "1.2.*" and ">=1.2.0 <1.3.0") - */ -function satisfiesVersion(version, versionRange) { - if (arguments.length === 1) { - versionRange = version; - version = appInfo.version; - } - - let ranges = versionRange.trim().split(reRangeSeparator); - - return ranges.some(function(range) { - range = normalizeRange(range); - - // No versions' range specified means that any version satisfies the - // requirements. - if (range === "") - return true; - - let matches = range.match(reVersionRange); - - if (!matches) - return false; - - let [, lowMod, lowVer, highMod, highVer] = matches; - - return compareVersion(version, lowMod, lowVer) && (highVer !== undefined - ? compareVersion(version, highMod, highVer) - : true); - }); -} -exports.satisfiesVersion = satisfiesVersion; - -/** - * 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 (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 (satisfiesVersion(versionRange)) - return null; - - return new Error("Unsupported Application version: The module " + id + - " currently supports only version " + versionRange + " of " + - name + "."); - } - - return new Error("Unsupported Application: The module " + id + - " currently supports only " + applications.join(", ") + ".") -} -exports.incompatibility = incompatibility; |