2 var Emitter
, Mixin
, Signal
, Subscription
, removeFromArray
, subscriptionRemovedPattern
, _ref
,
3 __hasProp
= {}.hasOwnProperty
,
4 __extends = function(child
, parent
) { for (var key
in parent
) { if (__hasProp
.call(parent
, key
)) child
[key
] = parent
[key
]; } function ctor() { this.constructor = child
; } ctor
.prototype = parent
.prototype; child
.prototype = new ctor(); child
.__super__
= parent
.prototype; return child
; },
7 Mixin
= require('mixto');
13 subscriptionRemovedPattern
= /^(last-)?.+-subscription-removed$/;
15 module
.exports
= Emitter
= (function(_super
) {
16 __extends(Emitter
, _super
);
19 _ref
= Emitter
.__super__
.constructor.apply(this, arguments
);
23 Emitter
.prototype.eventHandlersByEventName
= null;
25 Emitter
.prototype.eventHandlersByNamespace
= null;
27 Emitter
.prototype.subscriptionCounts
= null;
29 Emitter
.prototype.pauseCountsByEventName
= null;
31 Emitter
.prototype.queuedEventsByEventName
= null;
33 Emitter
.prototype.globalPauseCount
= null;
35 Emitter
.prototype.globalQueuedEvents
= null;
37 Emitter
.prototype.signalsByEventName
= null;
39 Emitter
.prototype.on = function(eventNames
, handler
) {
40 var eventName
, namespace, _base
, _base1
, _base2
, _i
, _len
, _ref1
, _ref2
;
41 _ref1
= eventNames
.split(/\s+/);
42 for (_i
= 0, _len
= _ref1
.length
; _i
< _len
; _i
++) {
43 eventName
= _ref1
[_i
];
44 if (!(eventName
!== '')) {
47 _ref2
= eventName
.split('.'), eventName
= _ref2
[0], namespace = _ref2
[1];
48 this.emit("" + eventName
+ "-subscription-will-be-added", handler
);
49 if (this.incrementSubscriptionCount(eventName
) === 1) {
50 this.emit("first-" + eventName
+ "-subscription-will-be-added", handler
);
52 if (this.eventHandlersByEventName
== null) {
53 this.eventHandlersByEventName
= {};
55 if ((_base
= this.eventHandlersByEventName
)[eventName
] == null) {
56 _base
[eventName
] = [];
58 this.eventHandlersByEventName
[eventName
].push(handler
);
60 if (this.eventHandlersByNamespace
== null) {
61 this.eventHandlersByNamespace
= {};
63 if ((_base1
= this.eventHandlersByNamespace
)[namespace] == null) {
64 _base1
[namespace] = {};
66 if ((_base2
= this.eventHandlersByNamespace
[namespace])[eventName
] == null) {
67 _base2
[eventName
] = [];
69 this.eventHandlersByNamespace
[namespace][eventName
].push(handler
);
71 this.emit("" + eventName
+ "-subscription-added", handler
);
73 if (Subscription
== null) {
74 Subscription
= require('./subscription');
76 return new Subscription(this, eventNames
, handler
);
79 Emitter
.prototype.once = function(eventName
, handler
) {
81 return subscription
= this.on(eventName
, function() {
83 args
= 1 <= arguments
.length
? __slice
.call(arguments
, 0) : [];
85 return handler
.apply(null, args
);
89 Emitter
.prototype.signal = function(eventName
) {
92 Signal
= require('./signal');
94 if (this.signalsByEventName
== null) {
95 this.signalsByEventName
= {};
97 return (_base
= this.signalsByEventName
)[eventName
] != null ? (_base
= this.signalsByEventName
)[eventName
] : _base
[eventName
] = Signal
.fromEmitter(this, eventName
);
100 Emitter
.prototype.behavior = function(eventName
, initialValue
) {
101 return this.signal(eventName
).toBehavior(initialValue
);
104 Emitter
.prototype.emit = function(eventName
, payload
) {
105 var handler
, handlers
, queuedEvents
, _i
, _len
, _ref1
, _ref2
, _ref3
;
106 if (arguments
.length
> 2 || /\s|\./.test(eventName
)) {
107 return this.emitSlow
.apply(this, arguments
);
109 if (this.globalQueuedEvents
!= null) {
110 return this.globalQueuedEvents
.push([eventName
, payload
]);
112 if (queuedEvents
= (_ref1
= this.queuedEventsByEventName
) != null ? _ref1
[eventName
] : void 0) {
113 return queuedEvents
.push([eventName
, payload
]);
114 } else if (handlers
= (_ref2
= this.eventHandlersByEventName
) != null ? _ref2
[eventName
] : void 0) {
115 _ref3
= handlers
.slice();
116 for (_i
= 0, _len
= _ref3
.length
; _i
< _len
; _i
++) {
120 return this.emit("after-" + eventName
, payload
);
126 Emitter
.prototype.emitSlow = function() {
127 var args
, eventName
, handlers
, namespace, queuedEvents
, _ref1
, _ref2
, _ref3
, _ref4
, _ref5
, _ref6
;
128 eventName
= arguments
[0], args
= 2 <= arguments
.length
? __slice
.call(arguments
, 1) : [];
129 if (this.globalQueuedEvents
) {
130 return this.globalQueuedEvents
.push([eventName
].concat(__slice
.call(args
)));
132 _ref1
= eventName
.split('.'), eventName
= _ref1
[0], namespace = _ref1
[1];
134 if (queuedEvents
= (_ref2
= this.queuedEventsByEventName
) != null ? _ref2
[eventName
] : void 0) {
135 return queuedEvents
.push(["" + eventName
+ "." + namespace].concat(__slice
.call(args
)));
136 } else if (handlers
= (_ref3
= this.eventHandlersByNamespace
) != null ? (_ref4
= _ref3
[namespace]) != null ? _ref4
[eventName
] : void 0 : void 0) {
137 (function(func
, args
, ctor
) {
138 ctor
.prototype = func
.prototype;
139 var child
= new ctor
, result
= func
.apply(child
, args
);
140 return Object(result
) === result
? result : child
;
141 })(Array
, handlers
, function(){}).forEach(function(handler
) {
142 return handler
.apply(null, args
);
144 return this.emit
.apply(this, ["after-" + eventName
].concat(__slice
.call(args
)));
147 if (queuedEvents
= (_ref5
= this.queuedEventsByEventName
) != null ? _ref5
[eventName
] : void 0) {
148 return queuedEvents
.push([eventName
].concat(__slice
.call(args
)));
149 } else if (handlers
= (_ref6
= this.eventHandlersByEventName
) != null ? _ref6
[eventName
] : void 0) {
150 (function(func
, args
, ctor
) {
151 ctor
.prototype = func
.prototype;
152 var child
= new ctor
, result
= func
.apply(child
, args
);
153 return Object(result
) === result
? result : child
;
154 })(Array
, handlers
, function(){}).forEach(function(handler
) {
155 return handler
.apply(null, args
);
157 return this.emit
.apply(this, ["after-" + eventName
].concat(__slice
.call(args
)));
163 Emitter
.prototype.off = function(eventNames
, handler
) {
164 var eventHandlers
, eventName
, handlers
, namespace, namespaceHandlers
, _i
, _j
, _k
, _l
, _len
, _len1
, _len2
, _len3
, _ref1
, _ref10
, _ref2
, _ref3
, _ref4
, _ref5
, _ref6
, _ref7
, _ref8
, _ref9
;
166 _ref1
= eventNames
.split(/\s+/);
167 for (_i
= 0, _len
= _ref1
.length
; _i
< _len
; _i
++) {
168 eventName
= _ref1
[_i
];
169 if (!(eventName
!== '')) {
172 _ref2
= eventName
.split('.'), eventName
= _ref2
[0], namespace = _ref2
[1];
173 if (eventName
=== '') {
178 handlers
= (_ref3
= (_ref4
= this.eventHandlersByNamespace
) != null ? (_ref5
= _ref4
[namespace]) != null ? _ref5
[eventName
] : void 0 : void 0) != null ? _ref3 : [];
179 if (handler
!= null) {
180 removeFromArray(handlers
, handler
);
181 this.off(eventName
, handler
);
183 _ref6
= (function(func
, args
, ctor
) {
184 ctor
.prototype = func
.prototype;
185 var child
= new ctor
, result
= func
.apply(child
, args
);
186 return Object(result
) === result
? result : child
;
187 })(Array
, handlers
, function(){});
188 for (_j
= 0, _len1
= _ref6
.length
; _j
< _len1
; _j
++) {
190 removeFromArray(handlers
, handler
);
191 this.off(eventName
, handler
);
195 namespaceHandlers
= (_ref7
= (_ref8
= this.eventHandlersByNamespace
) != null ? _ref8
[namespace] : void 0) != null ? _ref7 : {};
196 if (handler
!= null) {
197 for (eventName
in namespaceHandlers
) {
198 handlers
= namespaceHandlers
[eventName
];
199 removeFromArray(handlers
, handler
);
200 this.off(eventName
, handler
);
203 for (eventName
in namespaceHandlers
) {
204 handlers
= namespaceHandlers
[eventName
];
205 _ref9
= (function(func
, args
, ctor
) {
206 ctor
.prototype = func
.prototype;
207 var child
= new ctor
, result
= func
.apply(child
, args
);
208 return Object(result
) === result
? result : child
;
209 })(Array
, handlers
, function(){});
210 for (_k
= 0, _len2
= _ref9
.length
; _k
< _len2
; _k
++) {
212 removeFromArray(handlers
, handler
);
213 this.off(eventName
, handler
);
219 eventHandlers
= (_ref10
= this.eventHandlersByEventName
) != null ? _ref10
[eventName
] : void 0;
220 if (eventHandlers
== null) {
223 if (handler
== null) {
224 for (_l
= 0, _len3
= eventHandlers
.length
; _l
< _len3
; _l
++) {
225 handler
= eventHandlers
[_l
];
226 this.off(eventName
, handler
);
230 if (removeFromArray(eventHandlers
, handler
)) {
231 this.decrementSubscriptionCount(eventName
);
232 this.emit("" + eventName
+ "-subscription-removed", handler
);
233 if (this.getSubscriptionCount(eventName
) === 0) {
234 this.emit("last-" + eventName
+ "-subscription-removed", handler
);
235 delete this.eventHandlersByEventName
[eventName
];
241 for (eventName
in this.eventHandlersByEventName
) {
242 if (!subscriptionRemovedPattern
.test(eventName
)) {
246 for (eventName
in this.eventHandlersByEventName
) {
249 return this.eventHandlersByNamespace
= {};
253 Emitter
.prototype.pauseEvents = function(eventNames
) {
254 var eventName
, _base
, _base1
, _i
, _len
, _ref1
, _results
;
256 _ref1
= eventNames
.split(/\s+/);
258 for (_i
= 0, _len
= _ref1
.length
; _i
< _len
; _i
++) {
259 eventName
= _ref1
[_i
];
260 if (!(eventName
!== '')) {
263 if (this.pauseCountsByEventName
== null) {
264 this.pauseCountsByEventName
= {};
266 if (this.queuedEventsByEventName
== null) {
267 this.queuedEventsByEventName
= {};
269 if ((_base
= this.pauseCountsByEventName
)[eventName
] == null) {
270 _base
[eventName
] = 0;
272 this.pauseCountsByEventName
[eventName
]++;
273 _results
.push((_base1
= this.queuedEventsByEventName
)[eventName
] != null ? (_base1
= this.queuedEventsByEventName
)[eventName
] : _base1
[eventName
] = []);
277 if (this.globalPauseCount
== null) {
278 this.globalPauseCount
= 0;
280 if (this.globalQueuedEvents
== null) {
281 this.globalQueuedEvents
= [];
283 return this.globalPauseCount
++;
287 Emitter
.prototype.resumeEvents = function(eventNames
) {
288 var event
, eventName
, queuedEvents
, _i
, _j
, _len
, _len1
, _ref1
, _ref2
, _results
, _results1
;
290 _ref1
= eventNames
.split(/\s+/);
292 for (_i
= 0, _len
= _ref1
.length
; _i
< _len
; _i
++) {
293 eventName
= _ref1
[_i
];
294 if (eventName
!== '') {
295 if (((_ref2
= this.pauseCountsByEventName
) != null ? _ref2
[eventName
] : void 0) > 0 && --this.pauseCountsByEventName
[eventName
] === 0) {
296 queuedEvents
= this.queuedEventsByEventName
[eventName
];
297 this.queuedEventsByEventName
[eventName
] = null;
298 _results
.push((function() {
299 var _j
, _len1
, _results1
;
301 for (_j
= 0, _len1
= queuedEvents
.length
; _j
< _len1
; _j
++) {
302 event
= queuedEvents
[_j
];
303 _results1
.push(this.emit
.apply(this, event
));
308 _results
.push(void 0);
314 for (eventName
in this.pauseCountsByEventName
) {
315 this.resumeEvents(eventName
);
317 if (this.globalPauseCount
> 0 && --this.globalPauseCount
=== 0) {
318 queuedEvents
= this.globalQueuedEvents
;
319 this.globalQueuedEvents
= null;
321 for (_j
= 0, _len1
= queuedEvents
.length
; _j
< _len1
; _j
++) {
322 event
= queuedEvents
[_j
];
323 _results1
.push(this.emit
.apply(this, event
));
330 Emitter
.prototype.incrementSubscriptionCount = function(eventName
) {
332 if (this.subscriptionCounts
== null) {
333 this.subscriptionCounts
= {};
335 if ((_base
= this.subscriptionCounts
)[eventName
] == null) {
336 _base
[eventName
] = 0;
338 return ++this.subscriptionCounts
[eventName
];
341 Emitter
.prototype.decrementSubscriptionCount = function(eventName
) {
343 count
= --this.subscriptionCounts
[eventName
];
345 delete this.subscriptionCounts
[eventName
];
350 Emitter
.prototype.getSubscriptionCount = function(eventName
) {
351 var count
, name
, total
, _ref1
, _ref2
, _ref3
;
352 if (eventName
!= null) {
353 return (_ref1
= (_ref2
= this.subscriptionCounts
) != null ? _ref2
[eventName
] : void 0) != null ? _ref1 : 0;
356 _ref3
= this.subscriptionCounts
;
357 for (name
in _ref3
) {
365 Emitter
.prototype.hasSubscriptions = function(eventName
) {
366 return this.getSubscriptionCount(eventName
) > 0;
373 removeFromArray = function(array
, element
) {
375 index
= array
.indexOf(element
);
377 array
.splice(index
, 1);