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