blob: 6506e32e01a00e44d4a698b5f831204d1560f48d (
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
|
/**
* Wrapper around listeners on various WebExtensions
* APIs (e.g. webRequest.on*), as a best effort to
* let them run last by removing and re-adding them
* on each call (swapping 2 copies because
* addListener() calls are asynchronous).
* Note: we rely on implementation details Like
* listeners being called in addition order; also,
* clients should ensure they're not called twice for
* the same event, if that's important.
}
*/
class LastListener {
constructor(observed, listener, ...extras) {
this.observed = observed;
this.listener = listener;
this.extras = extras;
let ww = this._wrapped = [listener, listener].map(l => {
let w = (...args) => {
if (this.observed.hasListener(w._other)) {
this.observed.removeListener(w);
if (this.last !== w) return this.defaultResult;
} else if (this.installed) {
this.observed.addListener(w._other, ...this.extras);
this.last = w._other;
}
debug("Running listener", w === ww[0] ? 0 : 1, ...args);
return this.installed ? this.listener(...args)
: this.defaultResult;
}
return w;
});
ww[0]._other = ww[1];
ww[1]._other = ww[0];
this.installed = false;
this.defaultResult = null;
}
install() {
if (this.installed) return;
this.observed.addListener(this._wrapped[0], ...this.extras);
this.installed = true;
}
uninstall() {
this.installed = false;
for (let l of this._wrapped) this.observed.removeListener(l);
}
}
|