-
Notifications
You must be signed in to change notification settings - Fork 99
/
miso.events.js
119 lines (102 loc) · 3.56 KB
/
miso.events.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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
(function(global, _) {
var Miso = global.Miso = (global.Miso || {});
/**
* Miso Events is a small set of methods that can be mixed into any object
* to make it evented. It allows one to then subscribe to specific object events,
* to publish events, unsubscribe and subscribeOnce.
*/
Miso.Events = {
/**
* Triggers a specific event and passes any additional arguments
* to the callbacks subscribed to that event.
* Params:
* name - the name of the event to trigger
* .* - any additional arguments to pass to callbacks.
*/
publish : function(name) {
var args = _.toArray(arguments);
args.shift();
if (this._events && this._events[name]) {
_.each(this._events[name], function(subscription) {
subscription.callback.apply(subscription.context || this, args);
}, this);
}
return this;
},
/**
* Allows subscribing on an evented object to a specific name.
* Provide a callback to trigger.
* Params:
* name - event to subscribe to
* callback - callback to trigger
* options - optional arguments
* priority - allows rearranging of existing callbacks based on priority
* context - allows attaching diff context to callback
* token - allows callback identification by token.
*/
subscribe : function(name, callback, options) {
options = options || {};
this._events = this._events || {};
this._events[name] = this._events[name] || [];
var subscription = {
callback : callback,
priority : options.priority || 0,
token : options.token || _.uniqueId('t'),
context : options.context || this
};
var position;
_.each(this._events[name], function(event, index) {
if (!_.isUndefined(position)) { return; }
if (event.priority <= subscription.priority) {
position = index;
}
});
this._events[name].splice(position, 0, subscription);
return subscription.token;
},
/**
* Allows subscribing to an event once. When the event is triggered
* this subscription will be removed.
* Params:
* name - name of event
* callback - The callback to trigger
* options - optional arguments
* priority - allows rearranging of existing callbacks based on priority
* context - allows attaching diff context to callback
* token - allows callback identification by token.
*/
subscribeOnce : function(name, callback, options) {
this._events = this._events || {};
options = options || {};
var self = this;
if (typeof options.token === "undefined") {
options.token = _.uniqueId('t');
}
return this.subscribe(name, function() {
self.unsubscribe(name, { token : options.token });
callback.apply(this, arguments);
}, options);
},
/**
* Allows unsubscribing from a specific event
* Params:
* name - event to unsubscribe from
* identifier - callback to remove OR token.
*/
unsubscribe : function(name, identifier) {
if (_.isUndefined(this._events[name])) { return this; }
if (_.isFunction(identifier)) {
this._events[name] = _.reject(this._events[name], function(b) {
return b.callback === identifier;
});
} else if ( _.isString(identifier)) {
this._events[name] = _.reject(this._events[name], function(b) {
return b.token === identifier;
});
} else {
this._events[name] = [];
}
return this;
}
};
}(this, _));