diff options
Diffstat (limited to 'addon-sdk/source/lib/sdk/core')
-rw-r--r-- | addon-sdk/source/lib/sdk/core/disposable.js | 186 | ||||
-rw-r--r-- | addon-sdk/source/lib/sdk/core/heritage.js | 184 | ||||
-rw-r--r-- | addon-sdk/source/lib/sdk/core/namespace.js | 43 | ||||
-rw-r--r-- | addon-sdk/source/lib/sdk/core/observer.js | 89 | ||||
-rw-r--r-- | addon-sdk/source/lib/sdk/core/promise.js | 118 | ||||
-rw-r--r-- | addon-sdk/source/lib/sdk/core/reference.js | 29 |
6 files changed, 0 insertions, 649 deletions
diff --git a/addon-sdk/source/lib/sdk/core/disposable.js b/addon-sdk/source/lib/sdk/core/disposable.js deleted file mode 100644 index 19f7eaa9f..000000000 --- a/addon-sdk/source/lib/sdk/core/disposable.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"; - -module.metadata = { - "stability": "experimental" -}; - -const { Class } = require("./heritage"); -const { Observer, subscribe, unsubscribe, observe } = require("./observer"); -const { isWeak } = require("./reference"); -const SDKWeakSet = require("../lang/weak-set"); - -const method = require("../../method/core"); - -const unloadSubject = require('@loader/unload'); -const addonUnloadTopic = "sdk:loader:destroy"; - -const uninstall = method("disposable/uninstall"); -exports.uninstall = uninstall; - -const shutdown = method("disposable/shutdown"); -exports.shutdown = shutdown; - -const disable = method("disposable/disable"); -exports.disable = disable; - -const upgrade = method("disposable/upgrade"); -exports.upgrade = upgrade; - -const downgrade = method("disposable/downgrade"); -exports.downgrade = downgrade; - -const unload = method("disposable/unload"); -exports.unload = unload; - -const dispose = method("disposable/dispose"); -exports.dispose = dispose; -dispose.define(Object, object => object.dispose()); - -const setup = method("disposable/setup"); -exports.setup = setup; -setup.define(Object, (object, ...args) => object.setup(...args)); - -// DisposablesUnloadObserver is the class which subscribe the -// Observer Service to be notified when the add-on loader is -// unloading to be able to dispose all the existent disposables. -const DisposablesUnloadObserver = Class({ - implements: [Observer], - initialize: function(...args) { - // Set of the non-weak disposables registered to be disposed. - this.disposables = new Set(); - // Target of the weak disposables registered to be disposed - // (and tracked on this target using the SDK weak-set module). - this.weakDisposables = {}; - }, - subscribe(disposable) { - if (isWeak(disposable)) { - SDKWeakSet.add(this.weakDisposables, disposable); - } else { - this.disposables.add(disposable); - } - }, - unsubscribe(disposable) { - if (isWeak(disposable)) { - SDKWeakSet.remove(this.weakDisposables, disposable); - } else { - this.disposables.delete(disposable); - } - }, - tryUnloadDisposable(disposable) { - try { - if (disposable) { - unload(disposable); - } - } catch(e) { - console.error("Error unloading a", - isWeak(disposable) ? "weak disposable" : "disposable", - disposable, e); - } - }, - unloadAll() { - // Remove all the subscribed disposables. - for (let disposable of this.disposables) { - this.tryUnloadDisposable(disposable); - } - - this.disposables.clear(); - - // Remove all the subscribed weak disposables. - for (let disposable of SDKWeakSet.iterator(this.weakDisposables)) { - this.tryUnloadDisposable(disposable); - } - - SDKWeakSet.clear(this.weakDisposables); - } -}); -const disposablesUnloadObserver = new DisposablesUnloadObserver(); - -// The DisposablesUnloadObserver instance is the only object which subscribes -// the Observer Service directly, it observes add-on unload notifications in -// order to trigger `unload` on all its subscribed disposables. -observe.define(DisposablesUnloadObserver, (obj, subject, topic, data) => { - const isUnloadTopic = topic === addonUnloadTopic; - const isUnloadSubject = subject.wrappedJSObject === unloadSubject; - if (isUnloadTopic && isUnloadSubject) { - unsubscribe(disposablesUnloadObserver, addonUnloadTopic); - disposablesUnloadObserver.unloadAll(); - } -}); - -subscribe(disposablesUnloadObserver, addonUnloadTopic, false); - -// Set's up disposable instance. -const setupDisposable = disposable => { - disposablesUnloadObserver.subscribe(disposable); -}; -exports.setupDisposable = setupDisposable; - -// Tears down disposable instance. -const disposeDisposable = disposable => { - disposablesUnloadObserver.unsubscribe(disposable); -}; -exports.disposeDisposable = disposeDisposable; - -// Base type that takes care of disposing it's instances on add-on unload. -// Also makes sure to remove unload listener if it's already being disposed. -const Disposable = Class({ - initialize: function(...args) { - // First setup instance before initializing it's disposal. If instance - // fails to initialize then there is no instance to be disposed at the - // unload. - setup(this, ...args); - setupDisposable(this); - }, - destroy: function(reason) { - // Destroying disposable removes unload handler so that attempt to dispose - // won't be made at unload & delegates to dispose. - disposeDisposable(this); - unload(this, reason); - }, - setup: function() { - // Implement your initialize logic here. - }, - dispose: function() { - // Implement your cleanup logic here. - } -}); -exports.Disposable = Disposable; - -const unloaders = { - destroy: dispose, - uninstall: uninstall, - shutdown: shutdown, - disable: disable, - upgrade: upgrade, - downgrade: downgrade -}; - -const unloaded = new WeakMap(); -unload.define(Disposable, (disposable, reason) => { - if (!unloaded.get(disposable)) { - unloaded.set(disposable, true); - // Pick an unload handler associated with an unload - // reason (falling back to destroy if not found) and - // delegate unloading to it. - const unload = unloaders[reason] || unloaders.destroy; - unload(disposable); - } -}); - -// If add-on is disabled manually, it's being upgraded, downgraded -// or uninstalled `dispose` is invoked to undo any changes that -// has being done by it in this session. -disable.define(Disposable, dispose); -downgrade.define(Disposable, dispose); -upgrade.define(Disposable, dispose); -uninstall.define(Disposable, dispose); - -// If application is shut down no dispose is invoked as undo-ing -// changes made by instance is likely to just waste of resources & -// increase shutdown time. Although specefic components may choose -// to implement shutdown handler that does something better. -shutdown.define(Disposable, disposable => {}); diff --git a/addon-sdk/source/lib/sdk/core/heritage.js b/addon-sdk/source/lib/sdk/core/heritage.js deleted file mode 100644 index fc87ba1f5..000000000 --- a/addon-sdk/source/lib/sdk/core/heritage.js +++ /dev/null @@ -1,184 +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 getPrototypeOf = Object.getPrototypeOf; -var getNames = x => [...Object.getOwnPropertyNames(x), - ...Object.getOwnPropertySymbols(x)]; -var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; -var create = Object.create; -var freeze = Object.freeze; -var unbind = Function.call.bind(Function.bind, Function.call); - -// This shortcut makes sure that we do perform desired operations, even if -// associated methods have being overridden on the used object. -var owns = unbind(Object.prototype.hasOwnProperty); -var apply = unbind(Function.prototype.apply); -var slice = Array.slice || unbind(Array.prototype.slice); -var reduce = Array.reduce || unbind(Array.prototype.reduce); -var map = Array.map || unbind(Array.prototype.map); -var concat = Array.concat || unbind(Array.prototype.concat); - -// Utility function to get own properties descriptor map. -function getOwnPropertyDescriptors(object) { - return reduce(getNames(object), function(descriptor, name) { - descriptor[name] = getOwnPropertyDescriptor(object, name); - return descriptor; - }, {}); -} - -function isDataProperty(property) { - var value = property.value; - var type = typeof(property.value); - return "value" in property && - (type !== "object" || value === null) && - type !== "function"; -} - -function getDataProperties(object) { - var properties = getOwnPropertyDescriptors(object); - return getNames(properties).reduce(function(result, name) { - var property = properties[name]; - if (isDataProperty(property)) { - result[name] = { - value: property.value, - writable: true, - configurable: true, - enumerable: false - }; - } - return result; - }, {}) -} - -/** - * Takes `source` object as an argument and returns identical object - * with the difference that all own properties will be non-enumerable - */ -function obscure(source) { - var descriptor = reduce(getNames(source), function(descriptor, name) { - var property = getOwnPropertyDescriptor(source, name); - property.enumerable = false; - descriptor[name] = property; - return descriptor; - }, {}); - return create(getPrototypeOf(source), descriptor); -} -exports.obscure = obscure; - -/** - * Takes arbitrary number of source objects and returns fresh one, that - * inherits from the same prototype as a first argument and implements all - * own properties of all argument objects. If two or more argument objects - * have own properties with the same name, the property is overridden, with - * precedence from right to left, implying, that properties of the object on - * the left are overridden by a same named property of the object on the right. - */ -var mix = function(source) { - var descriptor = reduce(slice(arguments), function(descriptor, source) { - return reduce(getNames(source), function(descriptor, name) { - descriptor[name] = getOwnPropertyDescriptor(source, name); - return descriptor; - }, descriptor); - }, {}); - - return create(getPrototypeOf(source), descriptor); -}; -exports.mix = mix; - -/** - * Returns a frozen object with that inherits from the given `prototype` and - * implements all own properties of the given `properties` object. - */ -function extend(prototype, properties) { - return create(prototype, getOwnPropertyDescriptors(properties)); -} -exports.extend = extend; - -/** - * Returns a constructor function with a proper `prototype` setup. Returned - * constructor's `prototype` inherits from a given `options.extends` or - * `Class.prototype` if omitted and implements all the properties of the - * given `option`. If `options.implemens` array is passed, it's elements - * will be mixed into prototype as well. Also, `options.extends` can be - * a function or a prototype. If function than it's prototype is used as - * an ancestor of the prototype, if it's an object that it's used directly. - * Also `options.implements` may contain functions or objects, in case of - * functions their prototypes are used for mixing. - */ -var Class = new function() { - function prototypeOf(input) { - return typeof(input) === 'function' ? input.prototype : input; - } - var none = freeze([]); - - return function Class(options) { - // Create descriptor with normalized `options.extends` and - // `options.implements`. - var descriptor = { - // Normalize extends property of `options.extends` to a prototype object - // in case it's constructor. If property is missing that fallback to - // `Type.prototype`. - extends: owns(options, 'extends') ? - prototypeOf(options.extends) : Class.prototype, - // Normalize `options.implements` to make sure that it's array of - // prototype objects instead of constructor functions. - implements: owns(options, 'implements') ? - freeze(map(options.implements, prototypeOf)) : none - }; - - // Create array of property descriptors who's properties will be defined - // on the resulting prototype. Note: Using reflection `concat` instead of - // method as it may be overridden. - var descriptors = concat(descriptor.implements, options, descriptor, { - constructor: constructor - }); - - // Note: we use reflection `apply` in the constructor instead of method - // call since later may be overridden. - function constructor() { - var instance = create(prototype, attributes); - if (initialize) apply(initialize, instance, arguments); - return instance; - } - // Create `prototype` that inherits from given ancestor passed as - // `options.extends`, falling back to `Type.prototype`, implementing all - // properties of given `options.implements` and `options` itself. - var prototype = extend(descriptor.extends, mix.apply(mix, descriptors)); - var initialize = prototype.initialize; - - // Combine ancestor attributes with prototype's attributes so that - // ancestors attributes also become initializeable. - var attributes = mix(descriptor.extends.constructor.attributes || {}, - getDataProperties(prototype)); - - constructor.attributes = attributes; - Object.defineProperty(constructor, 'prototype', { - configurable: false, - writable: false, - value: prototype - }); - return constructor; - }; -} -Class.prototype = extend(null, obscure({ - constructor: function constructor() { - this.initialize.apply(this, arguments); - return this; - }, - initialize: function initialize() { - // Do your initialization logic here - }, - // Copy useful properties from `Object.prototype`. - toString: Object.prototype.toString, - toLocaleString: Object.prototype.toLocaleString, - toSource: Object.prototype.toSource, - valueOf: Object.prototype.valueOf, - isPrototypeOf: Object.prototype.isPrototypeOf -})); -exports.Class = freeze(Class); diff --git a/addon-sdk/source/lib/sdk/core/namespace.js b/addon-sdk/source/lib/sdk/core/namespace.js deleted file mode 100644 index 3ceb73b72..000000000 --- a/addon-sdk/source/lib/sdk/core/namespace.js +++ /dev/null @@ -1,43 +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 create = Object.create; -const prototypeOf = Object.getPrototypeOf; - -/** - * Returns a new namespace, function that may can be used to access an - * namespaced object of the argument argument. Namespaced object are associated - * with owner objects via weak references. Namespaced objects inherit from the - * owners ancestor namespaced object. If owner's ancestor is `null` then - * namespaced object inherits from given `prototype`. Namespaces can be used - * to define internal APIs that can be shared via enclosing `namespace` - * function. - * @examples - * const internals = ns(); - * internals(object).secret = secret; - */ -function ns() { - const map = new WeakMap(); - return function namespace(target) { - if (!target) // If `target` is not an object return `target` itself. - return target; - // If target has no namespaced object yet, create one that inherits from - // the target prototype's namespaced object. - if (!map.has(target)) - map.set(target, create(namespace(prototypeOf(target) || null))); - - return map.get(target); - }; -}; - -// `Namespace` is a e4x function in the scope, so we export the function also as -// `ns` as alias to avoid clashing. -exports.ns = ns; -exports.Namespace = ns; diff --git a/addon-sdk/source/lib/sdk/core/observer.js b/addon-sdk/source/lib/sdk/core/observer.js deleted file mode 100644 index 7e11bf8f9..000000000 --- a/addon-sdk/source/lib/sdk/core/observer.js +++ /dev/null @@ -1,89 +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 { Cc, Ci, Cr, Cu } = require("chrome"); -const { Class } = require("./heritage"); -const { isWeak } = require("./reference"); -const method = require("../../method/core"); - -const observerService = Cc['@mozilla.org/observer-service;1']. - getService(Ci.nsIObserverService); - -const { ShimWaiver } = Cu.import("resource://gre/modules/ShimWaiver.jsm"); -const addObserver = ShimWaiver.getProperty(observerService, "addObserver"); -const removeObserver = ShimWaiver.getProperty(observerService, "removeObserver"); - -// This is a method that will be invoked when notification observer -// subscribed to occurs. -const observe = method("observer/observe"); -exports.observe = observe; - -// Method to subscribe to the observer notification. -const subscribe = method("observe/subscribe"); -exports.subscribe = subscribe; - - -// Method to unsubscribe from the observer notifications. -const unsubscribe = method("observer/unsubscribe"); -exports.unsubscribe = unsubscribe; - - -// This is wrapper class that takes a `delegate` and produces -// instance of `nsIObserver` which will delegate to a given -// object when observer notification occurs. -const ObserverDelegee = Class({ - initialize: function(delegate) { - this.delegate = delegate; - }, - QueryInterface: function(iid) { - if (!iid.equals(Ci.nsIObserver) && - !iid.equals(Ci.nsISupportsWeakReference) && - !iid.equals(Ci.nsISupports)) - throw Cr.NS_ERROR_NO_INTERFACE; - - return this; - }, - observe: function(subject, topic, data) { - observe(this.delegate, subject, topic, data); - } -}); - - -// Class that can be either mixed in or inherited from in -// order to subscribe / unsubscribe for observer notifications. -const Observer = Class({}); -exports.Observer = Observer; - -// Weak maps that associates instance of `ObserverDelegee` with -// an actual observer. It ensures that `ObserverDelegee` instance -// won't be GC-ed until given `observer` is. -const subscribers = new WeakMap(); - -// Implementation of `subscribe` for `Observer` type just registers -// observer for an observer service. If `isWeak(observer)` is `true` -// observer service won't hold strong reference to a given `observer`. -subscribe.define(Observer, (observer, topic) => { - if (!subscribers.has(observer)) { - const delegee = new ObserverDelegee(observer); - subscribers.set(observer, delegee); - addObserver(delegee, topic, isWeak(observer)); - } -}); - -// Unsubscribes `observer` from observer notifications for the -// given `topic`. -unsubscribe.define(Observer, (observer, topic) => { - const delegee = subscribers.get(observer); - if (delegee) { - subscribers.delete(observer); - removeObserver(delegee, topic); - } -}); diff --git a/addon-sdk/source/lib/sdk/core/promise.js b/addon-sdk/source/lib/sdk/core/promise.js deleted file mode 100644 index f4bd7b0f5..000000000 --- a/addon-sdk/source/lib/sdk/core/promise.js +++ /dev/null @@ -1,118 +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'; - -/* - * Uses `Promise.jsm` as a core implementation, with additional sugar - * from previous implementation, with inspiration from `Q` and `when` - * - * https://developer.mozilla.org/en-US/docs/Mozilla/JavaScript_code_modules/Promise.jsm - * https://github.com/cujojs/when - * https://github.com/kriskowal/q - */ -const PROMISE_URI = 'resource://gre/modules/Promise.jsm'; - -getEnvironment.call(this, function ({ require, exports, module, Cu }) { - -const Promise = Cu.import(PROMISE_URI, {}).Promise; -const { Debugging, defer, resolve, all, reject, race } = Promise; - -module.metadata = { - 'stability': 'unstable' -}; - -var promised = (function() { - // Note: Define shortcuts and utility functions here in order to avoid - // slower property accesses and unnecessary closure creations on each - // call of this popular function. - - var call = Function.call; - var concat = Array.prototype.concat; - - // Utility function that does following: - // execute([ f, self, args...]) => f.apply(self, args) - function execute (args) { - return call.apply(call, args); - } - - // Utility function that takes promise of `a` array and maybe promise `b` - // as arguments and returns promise for `a.concat(b)`. - function promisedConcat(promises, unknown) { - return promises.then(function (values) { - return resolve(unknown) - .then(value => values.concat([value])); - }); - } - - return function promised(f, prototype) { - /** - Returns a wrapped `f`, which when called returns a promise that resolves to - `f(...)` passing all the given arguments to it, which by the way may be - promises. Optionally second `prototype` argument may be provided to be used - a prototype for a returned promise. - - ## Example - - var promise = promised(Array)(1, promise(2), promise(3)) - promise.then(console.log) // => [ 1, 2, 3 ] - **/ - - return function promised(...args) { - // create array of [ f, this, args... ] - return [f, this, ...args]. - // reduce it via `promisedConcat` to get promised array of fulfillments - reduce(promisedConcat, resolve([], prototype)). - // finally map that to promise of `f.apply(this, args...)` - then(execute); - }; - }; -})(); - -exports.promised = promised; -exports.all = all; -exports.defer = defer; -exports.resolve = resolve; -exports.reject = reject; -exports.race = race; -exports.Promise = Promise; -exports.Debugging = Debugging; -}); - -function getEnvironment (callback) { - let Cu, _exports, _module, _require; - - // CommonJS / SDK - if (typeof(require) === 'function') { - Cu = require('chrome').Cu; - _exports = exports; - _module = module; - _require = require; - } - // JSM - else if (String(this).indexOf('BackstagePass') >= 0) { - Cu = this['Components'].utils; - _exports = this.Promise = {}; - _module = { uri: __URI__, id: 'promise/core' }; - _require = uri => { - let imports = {}; - Cu.import(uri, imports); - return imports; - }; - this.EXPORTED_SYMBOLS = ['Promise']; - // mozIJSSubScriptLoader.loadSubscript - } else if (~String(this).indexOf('Sandbox')) { - Cu = this['Components'].utils; - _exports = this; - _module = { id: 'promise/core' }; - _require = uri => {}; - } - - callback({ - Cu: Cu, - exports: _exports, - module: _module, - require: _require - }); -} - diff --git a/addon-sdk/source/lib/sdk/core/reference.js b/addon-sdk/source/lib/sdk/core/reference.js deleted file mode 100644 index 04549cd0f..000000000 --- a/addon-sdk/source/lib/sdk/core/reference.js +++ /dev/null @@ -1,29 +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 method = require("../../method/core"); -const { Class } = require("./heritage"); - -// Object that inherit or mix WeakRefence inn will register -// weak observes for system notifications. -const WeakReference = Class({}); -exports.WeakReference = WeakReference; - - -// If `isWeak(object)` is `true` observer installed -// for such `object` will be weak, meaning that it will -// be GC-ed if nothing else but observer is observing it. -// By default everything except `WeakReference` will return -// `false`. -const isWeak = method("reference/weak?"); -exports.isWeak = isWeak; - -isWeak.define(Object, _ => false); -isWeak.define(WeakReference, _ => true); |