summaryrefslogtreecommitdiff
path: root/toolkit/devtools/projecteditor/lib/helpers/event.js
blob: 1c9a6576be878f4a210deaced51bbc98d38600f2 (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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* 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/. */

/**
 * This file wraps EventEmitter objects to provide functions to forget
 * all events bound on a certain object.
 */

const { Class } = require("sdk/core/heritage");

/**
 * The Scope object is used to keep track of listeners.
 * This object is not exported.
 */
var Scope = Class({
  on: function(target, event, handler) {
    this.listeners = this.listeners || [];
    this.listeners.push({
      target: target,
      event: event,
      handler: handler
    });
    target.on(event, handler);
  },

  off: function(t, e, h) {
    if (!this.listeners) return;
    this.listeners = this.listeners.filter(({ target, event, handler }) => {
      return !(target === t && event === e && handler === h);
    });
    target.off(event, handler);
  },

  clear: function(clearTarget) {
    if (!this.listeners) return;
    this.listeners = this.listeners.filter(({ target, event, handler }) => {
      if (target === clearTarget) {
        target.off(event, handler);
        return false;
      }
      return true;
    });
  },

  destroy: function() {
    if (!this.listeners) return;
    this.listeners.forEach(({ target, event, handler }) => {
      target.off(event, handler);
    });
    this.listeners = undefined;
  }
});

var scopes = new WeakMap();
function scope(owner) {
  if (!scopes.has(owner)) {
    let scope = new Scope(owner);
    scopes.set(owner, scope);
    return scope;
  }
  return scopes.get(owner);
}
exports.scope = scope;

exports.on = function on(owner, target, event, handler) {
  if (!target) return;
  scope(owner).on(target, event, handler);
}

exports.off = function off(owner, target, event, handler) {
  if (!target) return;
  scope(owner).off(target, event, handler);
}

exports.forget = function forget(owner, target) {
  scope(owner).clear(target);
}

exports.done = function done(owner) {
  scope(owner).destroy();
  scopes.delete(owner);
}