aboutsummaryrefslogtreecommitdiff
path: root/tools/addon-sdk-1.3/packages/api-utils/lib/unload.js
blob: 3bbeb389b617b8f52f068b55eede694fe095ec92 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
// Parts of this module were taken from narwhal:
//
// http://narwhaljs.org

var observers = [];
var unloaders = [];

var when = exports.when = function when(observer) {
  if (observers.indexOf(observer) != -1)
    return;
  observers.unshift(observer);
};

var send = exports.send = function send(reason, onError) {
  onError = onError || console.exception;
  observers.forEach(function (observer) {
    try {
      observer(reason);
    } catch (e) {
      onError(e);
    }
  });
};

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;
    }
  };

  unloaders.push(unloadWrapper);

  obj[destructorName] = unloadWrapper;
};

when(
  function(reason) {
    unloaders.slice().forEach(
      function(unloadWrapper) {
        unloadWrapper(reason);
      });
  });