Bug 1382580 - Delete old event emitter; r=nchevobbe
MozReview-Commit-ID: 1g3ax7KP2vf
--- a/devtools/shared/moz.build
+++ b/devtools/shared/moz.build
@@ -59,17 +59,16 @@ DevToolsModules(
'extend.js',
'flags.js',
'generate-uuid.js',
'indentation.js',
'indexed-db.js',
'l10n.js',
'loader-plugin-raw.jsm',
'Loader.jsm',
- 'old-event-emitter.js',
'Parser.jsm',
'path.js',
'plural-form.js',
'protocol.js',
'system.js',
'task.js',
'ThreadSafeDevToolsUtils.js',
'throttle.js',
deleted file mode 100644
--- a/devtools/shared/old-event-emitter.js
+++ /dev/null
@@ -1,195 +0,0 @@
-/* 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/. */
-
-"use strict";
-
-const Services = require("Services");
-const defer = require("devtools/shared/defer");
-const { getNthPathExcluding } = require("devtools/shared/platform/stack");
-let loggingEnabled = false;
-
-if (!isWorker) {
- loggingEnabled = Services.prefs.getBoolPref("devtools.dump.emit");
- Services.prefs.addObserver("devtools.dump.emit", {
- observe: () => {
- loggingEnabled = Services.prefs.getBoolPref("devtools.dump.emit");
- }
- });
-}
-
-let EventEmitter = this.EventEmitter = function() {};
-module.exports = EventEmitter;
-
-/**
- * Decorate an object with event emitter functionality.
- *
- * @param Object objectToDecorate
- * Bind all public methods of EventEmitter to
- * the objectToDecorate object.
- * @return Object the object given.
- */
-EventEmitter.decorate = function(objectToDecorate) {
- let emitter = new EventEmitter();
- objectToDecorate.on = emitter.on.bind(emitter);
- objectToDecorate.off = emitter.off.bind(emitter);
- objectToDecorate.once = emitter.once.bind(emitter);
- objectToDecorate.emit = emitter.emit.bind(emitter);
-
- return objectToDecorate;
-};
-
-EventEmitter.prototype = {
- /**
- * Connect a listener.
- *
- * @param string event
- * The event name to which we're connecting.
- * @param function listener
- * Called when the event is fired.
- */
- on(event, listener) {
- if (!this._eventEmitterListeners) {
- this._eventEmitterListeners = new Map();
- }
- if (!this._eventEmitterListeners.has(event)) {
- this._eventEmitterListeners.set(event, []);
- }
- this._eventEmitterListeners.get(event).push(listener);
- },
-
- /**
- * Listen for the next time an event is fired.
- *
- * @param string event
- * The event name to which we're connecting.
- * @param function listener
- * (Optional) Called when the event is fired. Will be called at most
- * one time.
- * @return promise
- * A promise which is resolved when the event next happens. The
- * resolution value of the promise is the first event argument. If
- * you need access to second or subsequent event arguments (it's rare
- * that this is needed) then use listener
- */
- once(event, listener) {
- let deferred = defer();
-
- let handler = (_, first, ...rest) => {
- this.off(event, handler);
- if (listener) {
- listener(event, first, ...rest);
- }
- deferred.resolve(first);
- };
-
- handler._originalListener = listener;
- this.on(event, handler);
-
- return deferred.promise;
- },
-
- /**
- * Remove a previously-registered event listener. Works for events
- * registered with either on or once.
- *
- * @param string event
- * The event name whose listener we're disconnecting.
- * @param function listener
- * The listener to remove.
- */
- off(event, listener) {
- if (!this._eventEmitterListeners) {
- return;
- }
- let listeners = this._eventEmitterListeners.get(event);
- if (listeners) {
- this._eventEmitterListeners.set(event, listeners.filter(l => {
- return l !== listener && l._originalListener !== listener;
- }));
- }
- },
-
- /**
- * Emit an event. All arguments to this method will
- * be sent to listener functions.
- */
- emit(event) {
- this.logEvent(event, arguments);
-
- if (!this._eventEmitterListeners || !this._eventEmitterListeners.has(event)) {
- return;
- }
-
- let originalListeners = this._eventEmitterListeners.get(event);
- for (let listener of this._eventEmitterListeners.get(event)) {
- // If the object was destroyed during event emission, stop
- // emitting.
- if (!this._eventEmitterListeners) {
- break;
- }
-
- // If listeners were removed during emission, make sure the
- // event handler we're going to fire wasn't removed.
- if (originalListeners === this._eventEmitterListeners.get(event) ||
- this._eventEmitterListeners.get(event).some(l => l === listener)) {
- try {
- listener.apply(null, arguments);
- } catch (ex) {
- // Prevent a bad listener from interfering with the others.
- let msg = ex + ": " + ex.stack;
- console.error(msg);
- dump(msg + "\n");
- }
- }
- }
- },
-
- logEvent(event, args) {
- if (!loggingEnabled) {
- return;
- }
-
- let description = getNthPathExcluding(0, "devtools/shared/old-event-emitter.js");
-
- let argOut = "(";
- if (args.length === 1) {
- argOut += event;
- }
-
- let out = "EMITTING: ";
-
- // We need this try / catch to prevent any dead object errors.
- try {
- for (let i = 1; i < args.length; i++) {
- if (i === 1) {
- argOut = "(" + event + ", ";
- } else {
- argOut += ", ";
- }
-
- let arg = args[i];
- argOut += arg;
-
- if (arg && arg.nodeName) {
- argOut += " (" + arg.nodeName;
- if (arg.id) {
- argOut += "#" + arg.id;
- }
- if (arg.className) {
- argOut += "." + arg.className;
- }
- argOut += ")";
- }
- }
- } catch (e) {
- // Object is dead so the toolbox is most likely shutting down,
- // do nothing.
- }
-
- argOut += ")";
- out += "emit" + argOut + " from " + description + "\n";
-
- dump(out);
- },
-};
deleted file mode 100644
--- a/devtools/shared/tests/mochitest/test_eventemitter_basic.html
+++ /dev/null
@@ -1,192 +0,0 @@
-<!DOCTYPE html>
-<!--
- Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/
--->
-
-<html>
-
- <head>
- <meta charset="utf8">
- <title></title>
-
- <script type="application/javascript"
- src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
- <link rel="stylesheet" type="text/css"
- href="chrome://mochikit/content/tests/SimpleTest/test.css">
- </head>
-
- <body>
-
- <script type="application/javascript">
- "use strict";
-
- const { require } = ChromeUtils.import("resource://devtools/shared/Loader.jsm", {});
- const promise = require("promise");
- const EventEmitter = require("devtools/shared/old-event-emitter");
-
- SimpleTest.waitForExplicitFinish();
-
- testEmitter();
- testEmitter({});
-
- testPromise()
- .catch(ok.bind(null, false))
- .then(SimpleTest.finish);
-
- function testEmitter(aObject) {
- let emitter;
-
- if (aObject) {
- emitter = aObject;
- EventEmitter.decorate(emitter);
- } else {
- emitter = new EventEmitter();
- }
-
- ok(emitter, "We have an event emitter");
-
- let beenHere1 = false;
- let beenHere2 = false;
-
- emitter.on("next", next);
- emitter.emit("next", "abc", "def");
-
- function next(eventName, str1, str2) {
- is(eventName, "next", "Got event");
- is(str1, "abc", "Argument 1 is correct");
- is(str2, "def", "Argument 2 is correct");
-
- ok(!beenHere1, "first time in next callback");
- beenHere1 = true;
-
- emitter.off("next", next);
-
- emitter.emit("next");
-
- emitter.once("onlyonce", onlyOnce);
-
- emitter.emit("onlyonce");
- emitter.emit("onlyonce");
- }
-
- function onlyOnce() {
- ok(!beenHere2, "\"once\" listener has been called once");
- beenHere2 = true;
- emitter.emit("onlyonce");
-
- testThrowingExceptionInListener();
- }
-
- function testThrowingExceptionInListener() {
- function throwListener() {
- emitter.off("throw-exception");
- throw {
- toString: () => "foo",
- stack: "bar",
- };
- }
-
- emitter.on("throw-exception", throwListener);
- emitter.emit("throw-exception");
-
- killItWhileEmitting();
- }
-
- function killItWhileEmitting() {
- function c1() {
- ok(true, "c1 called");
- }
- function c2() {
- ok(true, "c2 called");
- emitter.off("tick", c3);
- }
- function c3() {
- ok(false, "c3 should not be called");
- }
- function c4() {
- ok(true, "c4 called");
- }
-
- emitter.on("tick", c1);
- emitter.on("tick", c2);
- emitter.on("tick", c3);
- emitter.on("tick", c4);
-
- emitter.emit("tick");
-
- offAfterOnce();
- }
-
- function offAfterOnce() {
- let enteredC1 = false;
-
- function c1() {
- enteredC1 = true;
- }
-
- emitter.once("oao", c1);
- emitter.off("oao", c1);
-
- emitter.emit("oao");
-
- ok(!enteredC1, "c1 should not be called");
- }
- }
-
- function testPromise() {
- let emitter = new EventEmitter();
- let p = emitter.once("thing");
-
- // Check that the promise is only resolved once event though we
- // emit("thing") more than once
- let firstCallbackCalled = false;
- let check1 = p.then(arg => {
- is(firstCallbackCalled, false, "first callback called only once");
- firstCallbackCalled = true;
- is(arg, "happened", "correct arg in promise");
- return "rval from c1";
- });
-
- emitter.emit("thing", "happened", "ignored");
-
- // Check that the promise is resolved asynchronously
- let secondCallbackCalled = false;
- let check2 = p.then(arg => {
- ok(true, "second callback called");
- is(arg, "happened", "correct arg in promise");
- secondCallbackCalled = true;
- is(arg, "happened", "correct arg in promise (a second time)");
- return "rval from c2";
- });
-
- // Shouldn't call any of the above listeners
- emitter.emit("thing", "trashinate");
-
- // Check that we can still separate events with different names
- // and that it works with no parameters
- let pfoo = emitter.once("foo");
- let pbar = emitter.once("bar");
-
- let check3 = pfoo.then(arg => {
- ok(arg === undefined, "no arg for foo event");
- return "rval from c3";
- });
-
- pbar.then(() => {
- ok(false, "pbar should not be called");
- });
-
- emitter.emit("foo");
-
- is(secondCallbackCalled, false, "second callback not called yet");
-
- return promise.all([ check1, check2, check3 ]).then(args => {
- is(args[0], "rval from c1", "callback 1 done good");
- is(args[1], "rval from c2", "callback 2 done good");
- is(args[2], "rval from c3", "callback 3 done good");
- });
- }
- </script>
- </body>
-</html>
deleted file mode 100644
--- a/devtools/shared/tests/unit/test_old_eventemitter_basic.js
+++ /dev/null
@@ -1,208 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-const {
- ConsoleAPIListener
-} = require("devtools/server/actors/webconsole/listeners");
-const EventEmitter = require("devtools/shared/old-event-emitter");
-
-/**
- * Each method of this object is a test; tests can be synchronous or asynchronous:
- *
- * 1. Plain functions are synchronous tests.
- * 2. methods with `async` keyword are asynchronous tests.
- * 3. methods with `done` as argument are asynchronous tests (`done` needs to be called to
- * finish the test).
- */
-const TESTS = {
- testEventEmitterCreation() {
- let emitter = getEventEmitter();
-
- ok(emitter, "We have an event emitter");
- },
-
- testEmittingEvents(done) {
- let emitter = getEventEmitter();
-
- let beenHere1 = false;
- let beenHere2 = false;
-
- function next(eventName, str1, str2) {
- equal(eventName, "next", "Got event");
- equal(str1, "abc", "Argument 1 is correct");
- equal(str2, "def", "Argument 2 is correct");
-
- ok(!beenHere1, "first time in next callback");
- beenHere1 = true;
-
- emitter.off("next", next);
-
- emitter.emit("next");
-
- emitter.once("onlyonce", onlyOnce);
-
- emitter.emit("onlyonce");
- emitter.emit("onlyonce");
- }
-
- function onlyOnce() {
- ok(!beenHere2, "\"once\" listener has been called once");
- beenHere2 = true;
- emitter.emit("onlyonce");
-
- done();
- }
-
- emitter.on("next", next);
- emitter.emit("next", "abc", "def");
- },
-
- testThrowingExceptionInListener(done) {
- let emitter = getEventEmitter();
- let listener = new ConsoleAPIListener(null, {
- onConsoleAPICall(message) {
- equal(message.level, "error");
- equal(message.arguments[0], "foo: bar");
- listener.destroy();
- done();
- }
- });
-
- listener.init();
-
- function throwListener() {
- emitter.off("throw-exception");
- throw Object.create({
- toString: () => "foo",
- stack: "bar",
- });
- }
-
- emitter.on("throw-exception", throwListener);
- emitter.emit("throw-exception");
- },
-
- testKillItWhileEmitting(done) {
- let emitter = getEventEmitter();
-
- const c1 = () => ok(true, "c1 called");
- const c2 = () => {
- ok(true, "c2 called");
- emitter.off("tick", c3);
- };
- const c3 = () => ok(false, "c3 should not be called");
- const c4 = () => {
- ok(true, "c4 called");
- done();
- };
-
- emitter.on("tick", c1);
- emitter.on("tick", c2);
- emitter.on("tick", c3);
- emitter.on("tick", c4);
-
- emitter.emit("tick");
- },
-
- testOffAfterOnce() {
- let emitter = getEventEmitter();
-
- let enteredC1 = false;
- let c1 = () => (enteredC1 = true);
-
- emitter.once("oao", c1);
- emitter.off("oao", c1);
-
- emitter.emit("oao");
-
- ok(!enteredC1, "c1 should not be called");
- },
-
- testPromise() {
- let emitter = getEventEmitter();
- let p = emitter.once("thing");
-
- // Check that the promise is only resolved once event though we
- // emit("thing") more than once
- let firstCallbackCalled = false;
- let check1 = p.then(arg => {
- equal(firstCallbackCalled, false, "first callback called only once");
- firstCallbackCalled = true;
- equal(arg, "happened", "correct arg in promise");
- return "rval from c1";
- });
-
- emitter.emit("thing", "happened", "ignored");
-
- // Check that the promise is resolved asynchronously
- let secondCallbackCalled = false;
- let check2 = p.then(arg => {
- ok(true, "second callback called");
- equal(arg, "happened", "correct arg in promise");
- secondCallbackCalled = true;
- equal(arg, "happened", "correct arg in promise (a second time)");
- return "rval from c2";
- });
-
- // Shouldn't call any of the above listeners
- emitter.emit("thing", "trashinate");
-
- // Check that we can still separate events with different names
- // and that it works with no parameters
- let pfoo = emitter.once("foo");
- let pbar = emitter.once("bar");
-
- let check3 = pfoo.then(arg => {
- ok(arg === undefined, "no arg for foo event");
- return "rval from c3";
- });
-
- pbar.then(() => {
- ok(false, "pbar should not be called");
- });
-
- emitter.emit("foo");
-
- equal(secondCallbackCalled, false, "second callback not called yet");
-
- return Promise.all([ check1, check2, check3 ]).then(args => {
- equal(args[0], "rval from c1", "callback 1 done good");
- equal(args[1], "rval from c2", "callback 2 done good");
- equal(args[2], "rval from c3", "callback 3 done good");
- });
- }
-};
-
-/**
- * Create a runnable tests based on the tests descriptor given.
- *
- * @param {Object} tests
- * The tests descriptor object, contains the tests to run.
- */
-const runnable = (tests) => (async function() {
- for (let name of Object.keys(tests)) {
- info(name);
- if (tests[name].length === 1) {
- await (new Promise(resolve => tests[name](resolve)));
- } else {
- await tests[name]();
- }
- }
-});
-
-// We want to run the same tests for both an instance of `EventEmitter` and an object
-// decorate with EventEmitter; therefore we create two strategies (`createNewEmitter` and
-// `decorateObject`) and a factory (`getEventEmitter`), where the factory is the actual
-// function used in the tests.
-
-const createNewEmitter = () => new EventEmitter();
-const decorateObject = () => EventEmitter.decorate({});
-
-// First iteration of the tests with a new instance of `EventEmitter`.
-let getEventEmitter = createNewEmitter;
-add_task(runnable(TESTS));
-// Second iteration of the tests with an object decorate using `EventEmitter`
-add_task(() => (getEventEmitter = decorateObject));
-add_task(runnable(TESTS));
--- a/devtools/shared/tests/unit/xpcshell.ini
+++ b/devtools/shared/tests/unit/xpcshell.ini
@@ -21,17 +21,16 @@ run-if = nightly_build
[test_fetch-file.js]
[test_fetch-http.js]
[test_fetch-resource.js]
[test_flatten.js]
[test_indentation.js]
[test_independent_loaders.js]
[test_invisible_loader.js]
[test_isSet.js]
-[test_old_eventemitter_basic.js]
[test_safeErrorString.js]
[test_defineLazyPrototypeGetter.js]
[test_console_filtering.js]
[test_pluralForm-english.js]
[test_pluralForm-makeGetter.js]
[test_prettifyCSS.js]
[test_require_lazy.js]
[test_require_raw.js]