bug 1523104: remote: use toolkit's event emitter; r=ato
authorAlexandre Poirot <poirot.alex@gmail.com>
Tue, 05 Mar 2019 12:39:55 -0800
changeset 521121 45eecaf3a611fd15617ed9f694b02facee912ea8
parent 521120 7ab41ce7425a4402cfffb3cdd17241081972e295
child 521122 f9eb88415e06e11f3bf58ead711168f633111283
push id10862
push userffxbld-merge
push dateMon, 11 Mar 2019 13:01:11 +0000
treeherdermozilla-beta@a2e7f5c935da [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersato
bugs1523104
milestone67.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
bug 1523104: remote: use toolkit's event emitter; r=ato
remote/EventEmitter.jsm
remote/RemoteAgent.js
remote/TargetListener.jsm
remote/WindowManager.jsm
remote/jar.mn
remote/server/Socket.jsm
remote/server/WebSocketTransport.jsm
deleted file mode 100644
--- a/remote/EventEmitter.jsm
+++ /dev/null
@@ -1,159 +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";
-
-var EXPORTED_SYMBOLS = ["EventEmitter"];
-
-const LISTENERS = Symbol("EventEmitter/listeners");
-const ONCE_ORIGINAL_LISTENER = Symbol("EventEmitter/once-original-listener");
-
-const BAD_LISTENER = "Listener must be a function " +
-    "or an object that has an onevent function";
-
-class EventEmitter {
-  constructor() {
-    this.listeners = new Map();
-  }
-
-  static on(target, type, listener) {
-    if (typeof listener != "function" && !isEventHandler(listener)) {
-      throw new TypeError(BAD_LISTENER);
-    }
-
-    if (!(LISTENERS in target)) {
-      target[LISTENERS] = new Map();
-    }
-
-    const events = target[LISTENERS];
-    if (events.has(type)) {
-      events.get(type).add(listener);
-    } else {
-      events.set(type, new Set([listener]));
-    }
-  }
-
-  static off(target, type = undefined, listener = undefined) {
-    if (!target[LISTENERS]) {
-      return;
-    }
-
-    if (listener) {
-      EventEmitter._removeListener(target, type, listener);
-    } else if (type) {
-      EventEmitter._removeTypedListeners(target, type);
-    } else {
-      EventEmitter._removeAllListeners(target);
-    }
-  }
-
-  static _removeListener(target, type, listener) {
-    const events = target[LISTENERS];
-
-    const listenersForType = events.get(type);
-    if (!listenersForType) {
-      return;
-    }
-
-    if (listenersForType.has(listener)) {
-      listenersForType.delete(listener);
-    } else {
-      for (const value of listenersForType.values()) {
-        if (ONCE_ORIGINAL_LISTENER in value &&
-            value[ONCE_ORIGINAL_LISTENER] === listener) {
-          listenersForType.delete(value);
-          break;
-        }
-      }
-    }
-  }
-
-  static _removeTypedListeners(target, type) {
-    const events = target[LISTENERS];
-    if (events.has(type)) {
-      events.delete(type);
-    }
-  }
-
-  static _removeAllListeners(target) {
-    const events = target[LISTENERS];
-    events.clear();
-  }
-
-  static once(target, type, listener) {
-    return new Promise(resolve => {
-      const newListener = (first, ...rest) => {
-        EventEmitter.off(target, type, listener);
-        invoke(listener, target, type, first, ...rest);
-        resolve(first);
-      };
-
-      newListener[ONCE_ORIGINAL_LISTENER] = listener;
-      EventEmitter.on(target, type, newListener);
-    });
-  }
-
-  static emit(target, type, ...rest) {
-    if (!(LISTENERS in target)) {
-      return;
-    }
-
-    for (const [candidate, listeners] of target[LISTENERS]) {
-      if (!type.match(expr(candidate))) {
-        continue;
-      }
-
-      for (const listener of listeners) {
-        invoke(listener, target, type, ...rest);
-      }
-    }
-  }
-
-  static decorate(target) {
-    const descriptors = Object.getOwnPropertyDescriptors(this.prototype);
-    delete descriptors.constructor;
-    return Object.defineProperties(target, descriptors);
-  }
-
-  on(...args) {
-    EventEmitter.on(this, ...args);
-  }
-
-  off(...args) {
-    EventEmitter.off(this, ...args);
-  }
-
-  once(...args) {
-    EventEmitter.once(this, ...args);
-  }
-
-  emit(...args) {
-    EventEmitter.emit(this, ...args);
-  }
-}
-
-function invoke(listener, target, type, ...args) {
-  if (!listener) {
-    return;
-  }
-
-  try {
-    if (isEventHandler(listener)) {
-      listener.onevent(type, ...args);
-    } else {
-      listener.call(target, ...args);
-    }
-  } catch (e) {
-    Cu.reportError(e);
-  }
-}
-
-function isEventHandler(listener) {
-  return listener && "onevent" in listener &&
-      typeof listener.onevent == "function";
-}
-
-function expr(type) {
-  return new RegExp(type.replace("*", "([a-zA-Z.:-]+)"));
-}
--- a/remote/RemoteAgent.js
+++ b/remote/RemoteAgent.js
@@ -31,18 +31,22 @@ const DEFAULT_PORT = 9222;
 const LOOPBACKS = ["localhost", "127.0.0.1", "[::1]"];
 
 class ParentRemoteAgent {
   constructor() {
     this.server = null;
     this.targets = new Targets();
 
     this.tabs = new TabObserver({registerExisting: true});
-    this.tabs.on("open", tab => this.targets.connect(tab.linkedBrowser));
-    this.tabs.on("close", tab => this.targets.disconnect(tab.linkedBrowser));
+    this.tabs.on("open", (eventName, tab) => {
+      this.targets.connect(tab.linkedBrowser);
+    });
+    this.tabs.on("close", (eventName, tab) => {
+      this.targets.disconnect(tab.linkedBrowser);
+    });
 
     // This allows getting access to the underlying JS object
     // of the '@mozilla.org/remote/agent' XPCOM components.
     this.wrappedJSObject = this;
   }
 
   get listening() {
     return !!this.server && !this.server._socketClosed;
--- a/remote/TargetListener.jsm
+++ b/remote/TargetListener.jsm
@@ -52,20 +52,21 @@ class TargetListener {
     this.listener = null;
     this.sessions.clear();
   }
 
   /**
    * SocketListener's `accepted` listener. Called whenever a new WebSocket connection is
    * established.
    *
+   * @param String eventName
    * @param WebSocketDebuggerTransport transport
    * @param SocketListener listener
    */
-  onConnectionAccepted(transport, listener) {
+  onConnectionAccepted(eventName, transport, listener) {
     const conn = new Connection(this.nextConnID++, transport);
     transport.ready();
     this.sessions.set(conn, new Session(conn, this.target));
   }
 
   get url() {
     if (this.listening) {
       const {network, host, port} = this.listener;
--- a/remote/WindowManager.jsm
+++ b/remote/WindowManager.jsm
@@ -7,17 +7,17 @@
 var EXPORTED_SYMBOLS = [
   "BrowserObserver",
   "TabObserver",
   "WindowObserver",
   "WindowManager",
 ];
 
 const {DOMContentLoadedPromise} = ChromeUtils.import("chrome://remote/content/Sync.jsm");
-const {EventEmitter} = ChromeUtils.import("chrome://remote/content/EventEmitter.jsm");
+const {EventEmitter} = ChromeUtils.import("resource://gre/modules/EventEmitter.jsm");
 const {Log} = ChromeUtils.import("chrome://remote/content/Log.jsm");
 const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
 const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 
 XPCOMUtils.defineLazyGetter(this, "log", Log.get);
 
 /**
  * The WindowManager provides tooling for application-agnostic observation
@@ -124,17 +124,17 @@ class TabObserver {
   }
 
   onTabClose(tab) {
     this.emit("close", tab);
   }
 
   // WindowObserver
 
-  async onWindowOpen(window) {
+  async onWindowOpen(eventName, window) {
     if (!window.gBrowser) {
       return;
     }
 
     for (const tab of window.gBrowser.tabs) {
       // If `linkedBrowser` isn't set, it means that the tab is still initializing
       // and a `TabOpen` event will be fired once it is all set.
       if (!tab.linkedBrowser) {
--- a/remote/jar.mn
+++ b/remote/jar.mn
@@ -2,17 +2,16 @@
 # 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/.
 
 remote.jar:
 % content remote %content/
   content/Connection.jsm (Connection.jsm)
   content/ContentProcessSession.jsm (ContentProcessSession.jsm)
   content/Error.jsm (Error.jsm)
-  content/EventEmitter.jsm (EventEmitter.jsm)
   content/Handler.jsm (Handler.jsm)
   content/Log.jsm (Log.jsm)
   content/Observer.jsm (Observer.jsm)
   content/RecommendedPreferences.jsm (RecommendedPreferences.jsm)
   content/Protocol.jsm (Protocol.jsm)
   content/Session.jsm (Session.jsm)
   content/Sync.jsm (Sync.jsm)
   content/Target.jsm (Target.jsm)
--- a/remote/server/Socket.jsm
+++ b/remote/server/Socket.jsm
@@ -6,17 +6,17 @@
 
 var EXPORTED_SYMBOLS = [
   "ConnectionHandshake",
   "SocketListener",
 ];
 
 // This is an XPCOM-service-ified copy of ../devtools/shared/security/socket.js.
 
-const {EventEmitter} = ChromeUtils.import("chrome://remote/content/EventEmitter.jsm");
+const {EventEmitter} = ChromeUtils.import("resource://gre/modules/EventEmitter.jsm");
 const {Log} = ChromeUtils.import("chrome://remote/content/Log.jsm");
 const {Preferences} = ChromeUtils.import("resource://gre/modules/Preferences.jsm");
 const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 
 XPCOMUtils.defineLazyModuleGetters(this, {
   DebuggerTransport: "chrome://remote/content/server/Transport.jsm",
   WebSocketDebuggerTransport: "chrome://remote/content/server/WebSocketTransport.jsm",
   WebSocketServer: "chrome://remote/content/server/WebSocket.jsm",
@@ -130,17 +130,17 @@ this.SocketListener = class SocketListen
 
   get port() {
     if (this.socket) {
       return this.socket.port;
     }
     return null;
   }
 
-  onAllowedConnection(transport) {
+  onAllowedConnection(eventName, transport) {
     this.emit("accepted", transport, this);
   }
 
   // nsIServerSocketListener implementation
 
   onSocketAccepted(socket, socketTransport) {
     const conn = new ConnectionHandshake(this, socketTransport);
     conn.once("allowed", this.onAllowedConnection.bind(this));
--- a/remote/server/WebSocketTransport.jsm
+++ b/remote/server/WebSocketTransport.jsm
@@ -3,17 +3,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 // This is an XPCOM service-ified copy of ../devtools/shared/transport/websocket-transport.js.
 
 "use strict";
 
 var EXPORTED_SYMBOLS = ["WebSocketDebuggerTransport"];
 
-const {EventEmitter} = ChromeUtils.import("chrome://remote/content/EventEmitter.jsm");
+const {EventEmitter} = ChromeUtils.import("resource://gre/modules/EventEmitter.jsm");
 
 function WebSocketDebuggerTransport(socket) {
   EventEmitter.decorate(this);
 
   this.active = false;
   this.hooks = null;
   this.socket = socket;
 }