Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

add global listener support

  • Loading branch information...
commit f71bbee92b80a2334552e5e60b0cb4a41e4fc830 1 parent 24a1f6e
@polotek authored
View
78 lib/events.js
@@ -36,9 +36,14 @@ EventEmitter.prototype.setMaxListeners = function(n) {
this._events.maxListeners = n;
};
-
EventEmitter.prototype.emit = function() {
var type = arguments[0];
+
+ // execute global listeners first
+ if (this._globalListeners) {
+ this.emitGlobal.apply(this, arguments);
+ }
+
// If there is no 'error' event listener then throw.
if (type === 'error') {
if (!this._events || !this._events.error ||
@@ -94,6 +99,26 @@ EventEmitter.prototype.emit = function() {
}
};
+EventEmitter.prototype.emitGlobal = function() {
+ var handler = this._globalListeners;
+ if (!this._globalListeners) return false;
+
+ if (typeof handler == 'function') {
+ handler.apply(this, arguments);
+ return true;
+
+ } else if (isArray(handler)) {
+ var listeners = handler.slice();
+ for (var i = 0, l = listeners.length; i < l; i++) {
+ listeners[i].apply(this, arguments);
+ }
+ return true;
+
+ } else {
+ return false;
+ }
+};
+
// EventEmitter is defined in src/node_events.cc
// EventEmitter.prototype.emit() is also defined there.
EventEmitter.prototype.addListener = function(type, listener) {
@@ -103,7 +128,7 @@ EventEmitter.prototype.addListener = function(type, listener) {
if (!this._events) this._events = {};
- // To avoid recursion in the case that type == "newListeners"! Before
+ // To avoid recursion in the case that type == "newListener"! Before
// adding it to the listeners, first emit "newListeners".
this.emit('newListener', type, listener);
@@ -160,6 +185,19 @@ EventEmitter.prototype.once = function(type, listener) {
return this;
};
+EventEmitter.prototype.addGlobalListener = function(listener) {
+ if (!this._globalListeners) {
+ // Optimize the case of one listener. Don't need the extra array object.
+ this._globalListeners = listener;
+ } else if (isArray(this._globalListeners)) {
+ this._globalListeners.push(listener);
+ } else {
+ this._globalListeners = [this._globalListeners, listener];
+ }
+
+ return this;
+};
+
EventEmitter.prototype.removeListener = function(type, listener) {
if ('function' !== typeof listener) {
throw new Error('removeListener only takes instances of Function');
@@ -194,6 +232,33 @@ EventEmitter.prototype.removeListener = function(type, listener) {
return this;
};
+EventEmitter.prototype.removeGlobalListener = function(listener) {
+ if(!this._globalListeners) return this;
+
+ if(isArray(this._globalListeners)) {
+ var position = -1;
+ for (var i = 0, length = this._globalListeners.length; i < length; i++) {
+ if (this._globalListeners[i] === listener ||
+ this._globalListeners[i].listener === listener)
+ {
+ position = i;
+ break;
+ }
+ }
+
+ if(position > -1) {
+ this._globalListeners.splice(position, 1);
+ if (!this._globalListeners.length) {
+ this._globalListeners = null;
+ }
+ }
+ } else {
+ this._globalListeners = null;
+ }
+
+ return this;
+};
+
EventEmitter.prototype.removeAllListeners = function(type) {
if (arguments.length === 0) {
this._events = {};
@@ -205,6 +270,10 @@ EventEmitter.prototype.removeAllListeners = function(type) {
return this;
};
+EventEmitter.prototype.removeAllGlobalListeners = function() {
+ this._globalListeners = null;
+};
+
EventEmitter.prototype.listeners = function(type) {
if (!this._events) this._events = {};
if (!this._events[type]) this._events[type] = [];
@@ -213,3 +282,8 @@ EventEmitter.prototype.listeners = function(type) {
}
return this._events[type];
};
+
+EventEmitter.prototype.globalListeners = function() {
+ if (!this._globalListeners) this._globalListeners = [];
+ return this._globalListeners;
+};
View
15 test/simple/test-event-emitter-add-listeners.js
@@ -25,12 +25,13 @@ var events = require('events');
var e = new events.EventEmitter();
-var events_new_listener_emited = [];
+var events_new_listener_emitted = [];
+var events_global_listener_emitted = [];
var times_hello_emited = 0;
e.addListener('newListener', function(event, listener) {
console.log('newListener: ' + event);
- events_new_listener_emited.push(event);
+ events_new_listener_emitted.push(event);
});
e.on('hello', function(a, b) {
@@ -40,6 +41,13 @@ e.on('hello', function(a, b) {
assert.equal('b', b);
});
+e.addGlobalListener(function(event) {
+ console.log('global');
+ events_global_listener_emitted.push(event);
+ assert.equal('a', arguments[1]);
+ assert.equal('b', arguments[2]);
+});
+
console.log('start');
e.emit('hello', 'a', 'b');
@@ -51,7 +59,8 @@ f.setMaxListeners(0);
process.addListener('exit', function() {
- assert.deepEqual(['hello'], events_new_listener_emited);
+ assert.deepEqual(['hello'], events_new_listener_emitted);
+ assert.deepEqual(['hello'], events_global_listener_emitted);
assert.equal(1, times_hello_emited);
});
View
16 test/simple/test-event-emitter-num-args.js
@@ -24,12 +24,19 @@ var assert = require('assert');
var events = require('events');
var e = new events.EventEmitter(),
- num_args_emited = [];
+ num_args_emitted = [],
+ num_global_args_emitted = [];
e.on('numArgs', function() {
var numArgs = arguments.length;
console.log('numArgs: ' + numArgs);
- num_args_emited.push(numArgs);
+ num_args_emitted.push(numArgs);
+});
+
+e.addGlobalListener(function() {
+ var numArgs = arguments.length;
+ console.log('numGlobalArgs: ' + numArgs);
+ num_global_args_emitted.push(numArgs);
});
console.log('start');
@@ -42,7 +49,6 @@ e.emit('numArgs', null, null, null, null);
e.emit('numArgs', null, null, null, null, null);
process.addListener('exit', function() {
- assert.deepEqual([0, 1, 2, 3, 4, 5], num_args_emited);
+ assert.deepEqual([0, 1, 2, 3, 4, 5], num_args_emitted);
+ assert.deepEqual([1, 2, 3, 4, 5, 6], num_global_args_emitted);
});
-
-
View
9 test/simple/test-event-emitter-remove-all-listeners.js
@@ -25,6 +25,8 @@ var events = require('events');
function listener() {}
+function gListener1() {}
+function gListener2() {}
var e1 = new events.EventEmitter();
e1.addListener('foo', listener);
@@ -38,6 +40,11 @@ var e2 = new events.EventEmitter();
e2.addListener('foo', listener);
e2.addListener('bar', listener);
e2.removeAllListeners();
-console.error(e2);
assert.deepEqual([], e2.listeners('foo'));
assert.deepEqual([], e2.listeners('bar'));
+
+var e3 = new events.EventEmitter();
+e3.addGlobalListener(gListener1);
+e3.addGlobalListener(gListener2);
+e3.removeAllGlobalListeners();
+assert.deepEqual([], e2.globalListeners());
View
21 test/simple/test-event-emitter-remove-listeners.js
@@ -25,6 +25,7 @@ var events = require('events');
var count = 0;
+var gcount = 0;
function listener1() {
console.log('listener1');
@@ -41,6 +42,16 @@ function listener3() {
count++;
}
+function globalListener1() {
+ console.log('globalListener1');
+ gcount++;
+}
+
+function globalListener2() {
+ console.log('globalListener2');
+ gcount++;
+}
+
var e1 = new events.EventEmitter();
e1.addListener('hello', listener1);
e1.removeListener('hello', listener1);
@@ -57,5 +68,13 @@ e3.addListener('hello', listener2);
e3.removeListener('hello', listener1);
assert.deepEqual([listener2], e3.listeners('hello'));
+var e4 = new events.EventEmitter();
+e4.addGlobalListener(globalListener1);
+e4.removeGlobalListener(globalListener1);
+assert.deepEqual([], e4.globalListeners());
-
+var e5 = new events.EventEmitter();
+e5.addGlobalListener(globalListener1);
+e5.addGlobalListener(globalListener2);
+e5.removeGlobalListener(globalListener1);
+assert.deepEqual([globalListener2], e5.globalListeners());
Please sign in to comment.
Something went wrong with that request. Please try again.