addon-sdk/source/lib/sdk/core/disposable.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.

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 "use strict";
     7 module.metadata = {
     8   "stability": "experimental"
     9 };
    12 const { Class } = require("./heritage");
    13 const { Observer, subscribe, unsubscribe, observe } = require("./observer");
    14 const { isWeak, WeakReference } = require("./reference");
    15 const method = require("../../method/core");
    17 const unloadSubject = require('@loader/unload');
    18 const addonUnloadTopic = "sdk:loader:destroy";
    22 const uninstall = method("disposable/uninstall");
    23 exports.uninstall = uninstall;
    26 const shutdown = method("disposable/shutdown");
    27 exports.shutdown = shutdown;
    29 const disable = method("disposable/disable");
    30 exports.disable = disable;
    32 const upgrade = method("disposable/upgrade");
    33 exports.upgrade = upgrade;
    35 const downgrade = method("disposable/downgrade");
    36 exports.downgrade = downgrade;
    38 const unload = method("disposable/unload");
    39 exports.unload = unload;
    41 const dispose = method("disposable/dispose");
    42 exports.dispose = dispose;
    43 dispose.define(Object, object => object.dispose());
    46 const setup = method("disposable/setup");
    47 exports.setup = setup;
    48 setup.define(Object, (object, ...args) => object.setup(...args));
    51 // Set's up disposable instance.
    52 const setupDisposable = disposable => {
    53   subscribe(disposable, addonUnloadTopic, isWeak(disposable));
    54 };
    56 // Tears down disposable instance.
    57 const disposeDisposable = disposable => {
    58   unsubscribe(disposable, addonUnloadTopic);
    59 };
    61 // Base type that takes care of disposing it's instances on add-on unload.
    62 // Also makes sure to remove unload listener if it's already being disposed.
    63 const Disposable = Class({
    64   implements: [Observer],
    65   initialize: function(...args) {
    66     // First setup instance before initializing it's disposal. If instance
    67     // fails to initialize then there is no instance to be disposed at the
    68     // unload.
    69     setup(this, ...args);
    70     setupDisposable(this);
    71   },
    72   destroy: function(reason) {
    73     // Destroying disposable removes unload handler so that attempt to dispose
    74     // won't be made at unload & delegates to dispose.
    75     disposeDisposable(this);
    76     unload(this, reason);
    77   },
    78   setup: function() {
    79     // Implement your initialize logic here.
    80   },
    81   dispose: function() {
    82     // Implement your cleanup logic here.
    83   }
    84 });
    85 exports.Disposable = Disposable;
    87 // Disposable instances observe add-on unload notifications in
    88 // order to trigger `unload` on them.
    89 observe.define(Disposable, (disposable, subject, topic, data) => {
    90   const isUnloadTopic = topic === addonUnloadTopic;
    91   const isUnloadSubject = subject.wrappedJSObject === unloadSubject;
    92   if (isUnloadTopic && isUnloadSubject) {
    93     unsubscribe(disposable, topic);
    94     unload(disposable);
    95   }
    96 });
    98 const unloaders = {
    99   destroy: dispose,
   100   uninstall: uninstall,
   101   shutdown: shutdown,
   102   disable: disable,
   103   upgrade: upgrade,
   104   downgrade: downgrade
   105 }
   106 const unloaded = new WeakMap();
   107 unload.define(Disposable, (disposable, reason) => {
   108   if (!unloaded.get(disposable)) {
   109     unloaded.set(disposable, true);
   110     // Pick an unload handler associated with an unload
   111     // reason (falling back to destroy if not found) and
   112     // delegate unloading to it.
   113     const unload = unloaders[reason] || unloaders.destroy;
   114     unload(disposable);
   115   }
   116 });
   119 // If add-on is disabled munally, it's being upgraded, downgraded
   120 // or uniststalled `dispose` is invoked to undo any changes that
   121 // has being done by it in this session.
   122 disable.define(Disposable, dispose);
   123 downgrade.define(Disposable, dispose);
   124 upgrade.define(Disposable, dispose);
   125 uninstall.define(Disposable, dispose);
   127 // If application is shut down no dispose is invoked as undo-ing
   128 // changes made by instance is likely to just waste of resources &
   129 // increase shutdown time. Although specefic components may choose
   130 // to implement shutdown handler that does something better.
   131 shutdown.define(Disposable, disposable => {});

mercurial