Bug 918588 - Properly support off after once with EventEmitter. r=mratcliffe
authorJ. Ryan Stinnett <jryans@gmail.com>
Thu, 19 Sep 2013 19:36:13 -0500
changeset 148074 42d54d6f6d1c109287dec399733ea75be6ecb858
parent 148073 59d5404eadf50aedd55b81df28643390445780c4
child 148075 c36f479a97554f80f147deb77a8e93e18acd70a9
push id2762
push userryanvm@gmail.com
push dateFri, 20 Sep 2013 14:21:59 +0000
treeherderfx-team@42d54d6f6d1c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmratcliffe
bugs918588
milestone27.0a1
Bug 918588 - Properly support off after once with EventEmitter. r=mratcliffe
browser/devtools/shared/event-emitter.js
browser/devtools/shared/test/browser_eventemitter_basic.js
--- a/browser/devtools/shared/event-emitter.js
+++ b/browser/devtools/shared/event-emitter.js
@@ -57,16 +57,17 @@ EventEmitter.prototype = {
    * @param function aListener
    *        Called when the event is fired.  Will be called at most one time.
    */
   once: function EventEmitter_once(aEvent, aListener) {
     let handler = function() {
       this.off(aEvent, handler);
       aListener.apply(null, arguments);
     }.bind(this);
+    handler._originalListener = aListener;
     this.on(aEvent, handler);
   },
 
   /**
    * Remove a previously-registered event listener.  Works for events
    * registered with either on or once.
    *
    * @param string aEvent
@@ -74,17 +75,19 @@ EventEmitter.prototype = {
    * @param function aListener
    *        The listener to remove.
    */
   off: function EventEmitter_off(aEvent, aListener) {
     if (!this._eventEmitterListeners)
       return;
     let listeners = this._eventEmitterListeners.get(aEvent);
     if (listeners) {
-      this._eventEmitterListeners.set(aEvent, listeners.filter(function(l) aListener != l));
+      this._eventEmitterListeners.set(aEvent, listeners.filter(l => {
+        return l !== aListener && l._originalListener !== aListener;
+      }));
     }
   },
 
   /**
    * Emit an event.  All arguments to this method will
    * be sent to listner functions.
    */
   emit: function EventEmitter_emit(aEvent) {
--- a/browser/devtools/shared/test/browser_eventemitter_basic.js
+++ b/browser/devtools/shared/test/browser_eventemitter_basic.js
@@ -69,12 +69,29 @@ function testEmitter(aObject) {
 
     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");
+
     delete emitter;
     finish();
   }
 }