forked from DimitarChristoff/primish
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathemitter.js
105 lines (89 loc) · 2.48 KB
/
emitter.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/**
* @module primish/emitter
* @description emitter for primish, standalone mediator or mixin
**/
;(function(factory){
// UMD wrap
if (typeof define === 'function' && define.amd){
define('primish/emitter', ['./primish'], factory);
} else if (typeof module !== 'undefined' && module.exports){
module.exports = factory(require('./primish'));
} else {
this.emitter = factory(this.primish);
}
}).call(this, function(primish){
var slice = Array.prototype.slice;
var EID = 0;
var pseudoEvents = {
once: function(eventName, fn){
var self = this,
wrapped = function(){
fn.apply(this, arguments);
self.off(eventName, wrapped);
};
return wrapped;
}
};
var emitter = primish({
on: function(event, fn){
// supports multiple events split by white space
event = event.split(/\s+/);
var i = 0,
len = event.length,
listeners = this._listeners || primish.hide(this, '_listeners'),
events,
k,
pseudos,
eventName,
knownPseudo;
loopEvents:
for (; i < len; ++i){
pseudos = event[i].split(':');
eventName = pseudos.shift();
knownPseudo = pseudos.length && pseudos[0] in pseudoEvents;
knownPseudo || (eventName = event[i]);
events = listeners[eventName] || (listeners[eventName] = {});
for (k in events) if (events[k] === fn) continue loopEvents;
events[(EID++).toString(36)] = knownPseudo ? pseudoEvents[pseudos[0]].call(this, eventName, fn) : fn;
}
return this;
},
off: function(event, fn){
var listeners = this._listeners, events, key, length = 0, l, k;
if (listeners && (events = listeners[event])){
for (k in events){
length++;
/* don't touch this, === breaks tests due to undefined after delete */
if (key == null && events[k] === fn) key = k;
if (key && length > 1) break;
}
if (key){
delete events[key];
if (length === 1){
// delete so that the order of the array remains unaffected, making it sparse
delete listeners[event];
for (l in listeners) return this;
delete this._listeners;
}
}
}
return this;
},
trigger: function(event){
var listeners = this._listeners,
events,
k,
args = slice.call(arguments, 1),
copy = {};
if (listeners && (events = listeners[event])){
for (k in events) copy[k] = events[k];
for (k in copy) copy[k].apply(this, args);
}
return this;
}
});
emitter.definePseudo = function(pseudo, fn){
pseudoEvents[pseudo] = fn;
};
return emitter;
});