Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge pull request #48 from sergeyksv/master

[lib] Making off and offAny correctly handle wildcard selectors
  • Loading branch information...
commit 285b810ec165b622d55d6ca1eaf54007bbed9fd2 2 parents 0322235 + 48b5456
Paolo Fragomeni authored
View
105 lib/eventemitter2.js
@@ -24,11 +24,16 @@
configure.call(this, conf);
}
+ //
+ // Attention, function return type now is array, always !
+ // It has zero elements if no any matches found and one or more
+ // elements (leafs) if there are matches
+ //
function searchListenerTree(handlers, type, tree, i) {
if (!tree) {
- return;
+ return [];
}
- var listeners, leaf, len, branch, xTree, xxTree, isolatedBranch, endReached,
+ var listeners=[], leaf, len, branch, xTree, xxTree, isolatedBranch, endReached,
typeLength = type.length, currentType = type[i], nextType = type[i+1];
if (i === typeLength && tree._listeners) {
//
@@ -37,12 +42,12 @@
//
if (typeof tree._listeners === 'function') {
handlers && handlers.push(tree._listeners);
- return tree;
+ return [tree];
} else {
for (leaf = 0, len = tree._listeners.length; leaf < len; leaf++) {
handlers && handlers.push(tree._listeners[leaf]);
}
- return tree;
+ return [tree];
}
}
@@ -54,7 +59,7 @@
if (currentType === '*') {
for (branch in tree) {
if (branch !== '_listeners' && tree.hasOwnProperty(branch)) {
- listeners = searchListenerTree(handlers, type, tree[branch], i+1);
+ listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], i+1));
}
}
return listeners;
@@ -62,28 +67,28 @@
endReached = (i+1 === typeLength || (i+2 === typeLength && nextType === '*'));
if(endReached && tree._listeners) {
// The next element has a _listeners, add it to the handlers.
- listeners = searchListenerTree(handlers, type, tree, typeLength);
+ listeners = listeners.concat(searchListenerTree(handlers, type, tree, typeLength));
}
for (branch in tree) {
if (branch !== '_listeners' && tree.hasOwnProperty(branch)) {
if(branch === '*' || branch === '**') {
if(tree[branch]._listeners && !endReached) {
- listeners = searchListenerTree(handlers, type, tree[branch], typeLength);
+ listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], typeLength));
}
- listeners = searchListenerTree(handlers, type, tree[branch], i);
+ listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], i));
} else if(branch === nextType) {
- listeners = searchListenerTree(handlers, type, tree[branch], i+2);
+ listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], i+2));
} else {
// No match on this one, shift into the tree but not in the type array.
- listeners = searchListenerTree(handlers, type, tree[branch], i);
+ listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], i));
}
}
}
return listeners;
}
- listeners = searchListenerTree(handlers, type, tree[currentType], i+1);
+ listeners = listeners.concat(searchListenerTree(handlers, type, tree[currentType], i+1));
}
xTree = tree['*'];
@@ -387,46 +392,58 @@
throw new Error('removeListener only takes instances of Function');
}
- var handlers;
+ var handlers,leafs=[];
if(this.wildcard) {
var ns = typeof type === 'string' ? type.split(this.delimiter) : type.slice();
- var leaf = searchListenerTree.call(this, null, ns, this.listenerTree, 0);
-
- if('undefined' === typeof leaf) { return this; }
- handlers = leaf._listeners;
+ leafs = searchListenerTree.call(this, null, ns, this.listenerTree, 0);
}
else {
// does not use listeners(), so no side effect of creating _events[type]
if (!this._events[type]) return this;
handlers = this._events[type];
+ leafs.push({_listeners:handlers});
}
- if (isArray(handlers)) {
+ for (var iLeaf=0; iLeaf<leafs.length; iLeaf++) {
+ var leaf = leafs[iLeaf];
+ handlers = leaf._listeners;
+ if (isArray(handlers)) {
- var position = -1;
+ var position = -1;
- for (var i = 0, length = handlers.length; i < length; i++) {
- if (handlers[i] === listener ||
- (handlers[i].listener && handlers[i].listener === listener) ||
- (handlers[i]._origin && handlers[i]._origin === listener)) {
- position = i;
- break;
+ for (var i = 0, length = handlers.length; i < length; i++) {
+ if (handlers[i] === listener ||
+ (handlers[i].listener && handlers[i].listener === listener) ||
+ (handlers[i]._origin && handlers[i]._origin === listener)) {
+ position = i;
+ break;
+ }
}
- }
- if (position < 0) {
- return this;
- }
+ if (position < 0) {
+ return this;
+ }
- if(this.wildcard) {
- leaf._listeners.splice(position, 1)
- }
- else {
- this._events[type].splice(position, 1);
- }
+ if(this.wildcard) {
+ leaf._listeners.splice(position, 1)
+ }
+ else {
+ this._events[type].splice(position, 1);
+ }
- if (handlers.length === 0) {
+ if (handlers.length === 0) {
+ if(this.wildcard) {
+ delete leaf._listeners;
+ }
+ else {
+ delete this._events[type];
+ }
+ }
+ }
+ else if (handlers === listener ||
+ (handlers.listener && handlers.listener === listener) ||
+ (handlers._origin && handlers._origin === listener)) {
if(this.wildcard) {
delete leaf._listeners;
}
@@ -435,16 +452,6 @@
}
}
}
- else if (handlers === listener ||
- (handlers.listener && handlers.listener === listener) ||
- (handlers._origin && handlers._origin === listener)) {
- if(this.wildcard) {
- delete leaf._listeners;
- }
- else {
- delete this._events[type];
- }
- }
return this;
};
@@ -475,10 +482,12 @@
if(this.wildcard) {
var ns = typeof type === 'string' ? type.split(this.delimiter) : type.slice();
- var leaf = searchListenerTree.call(this, null, ns, this.listenerTree, 0);
+ var leafs = searchListenerTree.call(this, null, ns, this.listenerTree, 0);
- if('undefined' === typeof leaf) { return this; }
- leaf._listeners = null;
+ for (var iLeaf=0; iLeaf<leafs.length; iLeaf++) {
+ var leaf = leafs[iLeaf];
+ leaf._listeners = null;
+ }
}
else {
if (!this._events[type]) return this;
View
24 test/common.js
@@ -64,18 +64,20 @@ process.on('exit', function() {
console,
Buffer,
process,
- ArrayBuffer,
- Int8Array,
- Uint8Array,
- Int16Array,
- Uint16Array,
- Int32Array,
- Uint32Array,
- Float32Array,
- Float64Array,
- DataView,
+ global.ArrayBuffer!==undefined?ArrayBuffer:null,
+ global.Int8Array!==undefined?Int8Array:null,
+ global.Uint8Array!==undefined?Uint8Array:null,
+ global.Int16Array!==undefined?Int16Array:null,
+ global.Uint16Array!==undefined?Uint16Array:null,
+ global.Int32Array!==undefined?Int32Array:null,
+ global.Uint32Array!==undefined?Uint32Array:null,
+ global.Float32Array!==undefined?Float32Array:null,
+ global.Float64Array!==undefined?Float64Array:null,
+ global.DataView!==undefined?DataView:null,
AssertionError,
- global];
+ global,
+ events
+ ];
if (global.errno) {
knownGlobals.push(errno);
View
71 test/wildcardEvents/removeListener.js
@@ -208,6 +208,77 @@ module.exports = simpleEvents({
test.expect(5);
test.done();
+ },
+
+ '8. Its ok to listen on wildcard, so it is ok to remove it.' : function (test) {
+ var emitter = this.emitter,
+ type1 = '*.wild.card',
+ type2 = 'just.another.event',
+ listeners;
+
+ var f = function () {
+ test.ok(true, 'event was raised');
+ };
+
+ emitter.on(type2, f);
+ emitter.on(type1, f);
+
+ //remove
+ emitter.removeListener(type1, f);
+ listeners = emitter.listeners(type1);
+ test.equal(listeners.length, 0, 'should be 0');
+
+ test.expect(1);
+ test.done();
+ },
+
+ '9. And (8) should not depend on order of listening.' : function (test) {
+ var emitter = this.emitter,
+ type1 = '*.wild.card',
+ type2 = 'just.another.event',
+ listeners;
+
+ var f = function () {
+ test.ok(true, 'event was raised');
+ };
+
+ emitter.on(type1, f);
+ emitter.on(type2, f);
+
+ //remove
+ emitter.removeListener(type1, f);
+ listeners = emitter.listeners(type1);
+ test.equal(listeners.length, 0, 'should be 0');
+
+ test.expect(1);
+ test.done();
+ },
+
+ '10. Reporting many listeners on wildcard all should removed.' : function (test) {
+ var emitter = this.emitter,
+ type1 = '*.wild.card',
+ type2 = 'exact.wild.card',
+ listeners;
+
+ var f = function () {
+ test.ok(true, 'event was raised');
+ };
+
+ emitter.on(type1, f);
+ emitter.on(type2, f);
+
+ // check number of listeners by wild card
+ listeners = emitter.listeners(type1);
+ test.equal(listeners.length, 2, 'should only have 2');
+
+ // remove by wild card should remove both
+ emitter.removeListener(type1, f);
+ listeners = emitter.listeners(type1);
+ test.equal(listeners.length, 0, 'should be 0');
+
+ test.expect(2);
+ test.done();
}
+
});
Please sign in to comment.
Something went wrong with that request. Please try again.