зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1497457 - Allow to remove one time listeners on event-source;r=ochameau
Differential Revision: https://phabricator.services.mozilla.com/D11992 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
93fd1e4504
Коммит
ff4d366afa
|
@ -27,8 +27,12 @@ function eventSource(proto) {
|
|||
* Called when the event is fired. If the same listener
|
||||
* is added more than once, it will be called once per
|
||||
* addListener call.
|
||||
* @param key function (optional)
|
||||
* Key to use for removeListener, defaults to the listener. Used by helper method
|
||||
* addOneTimeListener, which creates a custom listener. Use the original listener
|
||||
* as key to allow to remove oneTimeListeners.
|
||||
*/
|
||||
proto.addListener = function(name, listener) {
|
||||
proto.addListener = function(name, listener, key = listener) {
|
||||
if (typeof listener != "function") {
|
||||
throw TypeError("Listeners must be functions.");
|
||||
}
|
||||
|
@ -37,7 +41,7 @@ function eventSource(proto) {
|
|||
this._listeners = {};
|
||||
}
|
||||
|
||||
this._getListeners(name).push(listener);
|
||||
this._getListeners(name).push({ key, callback: listener });
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -53,14 +57,14 @@ function eventSource(proto) {
|
|||
*/
|
||||
proto.addOneTimeListener = function(name, listener) {
|
||||
return new Promise(resolve => {
|
||||
const l = (eventName, ...rest) => {
|
||||
this.removeListener(name, l);
|
||||
const oneTimeListener = (eventName, ...rest) => {
|
||||
this.removeListener(name, listener);
|
||||
if (listener) {
|
||||
listener(eventName, ...rest);
|
||||
}
|
||||
resolve(rest[0]);
|
||||
};
|
||||
this.addListener(name, l);
|
||||
this.addListener(name, oneTimeListener, listener);
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -83,7 +87,7 @@ function eventSource(proto) {
|
|||
this._listeners[name] = [];
|
||||
} else {
|
||||
this._listeners[name] =
|
||||
this._listeners[name].filter(l => l != listener);
|
||||
this._listeners[name].filter(l => l.key != listener);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -121,7 +125,7 @@ function eventSource(proto) {
|
|||
|
||||
for (const listener of listeners) {
|
||||
try {
|
||||
listener.apply(null, arguments);
|
||||
listener.callback.apply(null, arguments);
|
||||
} catch (e) {
|
||||
// Prevent a bad listener from interfering with the others.
|
||||
DevToolsUtils.reportException("notify event '" + name + "'", e);
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
/* -*- js-indent-level: 2; indent-tabs-mode: nil -*- */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const eventSource = require("devtools/shared/client/event-source");
|
||||
|
||||
// Test basic event-source APIs:
|
||||
// - addListener
|
||||
// - removeListener
|
||||
// - addOneTimeListener
|
||||
|
||||
add_task(function() {
|
||||
// Create a basic test object that can emit events using event-source.js
|
||||
class TestClass {}
|
||||
eventSource(TestClass.prototype);
|
||||
const testObject = new TestClass();
|
||||
|
||||
testBasicAddRemoveListener(testObject);
|
||||
|
||||
info("Check that one time listeners are only triggered once");
|
||||
testOneTimeListener(testObject);
|
||||
|
||||
info("Check that one time listeners can be removed");
|
||||
testRemoveOneTimeListener(testObject);
|
||||
});
|
||||
|
||||
function testBasicAddRemoveListener(testObject) {
|
||||
let eventsReceived = 0;
|
||||
const onTestEvent = () => eventsReceived++;
|
||||
|
||||
testObject.addListener("event-testBasicAddRemoveListener", onTestEvent);
|
||||
testObject.emit("event-testBasicAddRemoveListener");
|
||||
ok(eventsReceived === 1, "Event listener was triggered");
|
||||
|
||||
testObject.emit("event-testBasicAddRemoveListener");
|
||||
ok(eventsReceived === 2, "Event listener was triggered again");
|
||||
|
||||
testObject.removeListener("event-testBasicAddRemoveListener", onTestEvent);
|
||||
testObject.emit("event-testBasicAddRemoveListener");
|
||||
ok(eventsReceived === 2, "Event listener was not triggered anymore");
|
||||
}
|
||||
|
||||
function testOneTimeListener(testObject) {
|
||||
let eventsReceived = 0;
|
||||
const onTestEvent = () => eventsReceived++;
|
||||
|
||||
testObject.addOneTimeListener("event-testOneTimeListener", onTestEvent);
|
||||
testObject.emit("event-testOneTimeListener");
|
||||
ok(eventsReceived === 1, "Event listener was triggered");
|
||||
|
||||
testObject.emit("event-testOneTimeListener");
|
||||
ok(eventsReceived === 1, "Event listener was not triggered again");
|
||||
|
||||
testObject.removeListener("event-testOneTimeListener", onTestEvent);
|
||||
}
|
||||
|
||||
function testRemoveOneTimeListener(testObject) {
|
||||
let eventsReceived = 0;
|
||||
const onTestEvent = () => eventsReceived++;
|
||||
|
||||
testObject.addOneTimeListener("event-testRemoveOneTimeListener", onTestEvent);
|
||||
testObject.removeListener("event-testRemoveOneTimeListener", onTestEvent);
|
||||
testObject.emit("event-testRemoveOneTimeListener");
|
||||
ok(eventsReceived === 0, "Event listener was already removed");
|
||||
}
|
|
@ -16,6 +16,7 @@ support-files =
|
|||
run-if = nightly_build
|
||||
[test_eventemitter_basic.js]
|
||||
[test_eventemitter_static.js]
|
||||
[test_eventsource.js]
|
||||
[test_fetch-bom.js]
|
||||
[test_fetch-chrome.js]
|
||||
[test_fetch-file.js]
|
||||
|
|
Загрузка…
Ссылка в новой задаче