addon-sdk/source/lib/sdk/system/unload.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 // Parts of this module were taken from narwhal:
     6 //
     7 // http://narwhaljs.org
     9 module.metadata = {
    10   "stability": "experimental"
    11 };
    13 const { on, off } = require('./events');
    14 const unloadSubject = require('@loader/unload');
    16 const observers = [];
    17 const unloaders = [];
    19 var when = exports.when = function when(observer) {
    20   if (observers.indexOf(observer) != -1)
    21     return;
    22   observers.unshift(observer);
    23 };
    25 var ensure = exports.ensure = function ensure(obj, destructorName) {
    26   if (!destructorName)
    27     destructorName = "unload";
    28   if (!(destructorName in obj))
    29     throw new Error("object has no '" + destructorName + "' property");
    31   let called = false;
    32   let originalDestructor = obj[destructorName];
    34   function unloadWrapper(reason) {
    35     if (!called) {
    36       called = true;
    37       let index = unloaders.indexOf(unloadWrapper);
    38       if (index == -1)
    39         throw new Error("internal error: unloader not found");
    40       unloaders.splice(index, 1);
    41       originalDestructor.call(obj, reason);
    42       originalDestructor = null;
    43       destructorName = null;
    44       obj = null;
    45     }
    46   };
    48   // TODO: Find out why the order is inverted here. It seems that
    49   // it may be causing issues!
    50   unloaders.push(unloadWrapper);
    52   obj[destructorName] = unloadWrapper;
    53 };
    55 function unload(reason) {
    56   observers.forEach(function(observer) {
    57     try {
    58       observer(reason);
    59     }
    60     catch (error) {
    61       console.exception(error);
    62     }
    63   });
    64 }
    66 when(function(reason) {
    67   unloaders.slice().forEach(function(unloadWrapper) {
    68     unloadWrapper(reason);
    69   });
    70 });
    72 on('sdk:loader:destroy', function onunload({ subject, data: reason }) {
    73   // If this loader is unload then `subject.wrappedJSObject` will be
    74   // `destructor`.
    75   if (subject.wrappedJSObject === unloadSubject) {
    76     off('sdk:loader:destroy', onunload);
    77     unload(reason);
    78   }
    79 // Note that we use strong reference to listener here to make sure it's not
    80 // GC-ed, which may happen otherwise since nothing keeps reference to `onunolad`
    81 // function.
    82 }, true);

mercurial