-
Notifications
You must be signed in to change notification settings - Fork 0
/
event-router.js
108 lines (93 loc) · 3.21 KB
/
event-router.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
(function (undefined) {
// Regexp that parses [eventEmitterName]eventName strings.
var RE = /\[(.+)\](.+)/;
function EventRouter() {
this._emitter = {};
}
/**
* Registers a handler. Event emitter is chosen using event description string, e.g.:
* .on("[testEmitter]testEvent", handler) will register handler using 'testEmitter' as the event
* emitter. To connect name with real object, use .setEmitter() function.
* @param {string} eventDesc
* @param {function} handler
*/
EventRouter.prototype.on = function(eventDesc, handler) {
var parsedDesc = RE.exec(eventDesc);
if (parsedDesc.length !== 3) {
throw new Error("Incorrect event description " + eventDesc);
}
var emitterName = parsedDesc[1];
var eventName = parsedDesc[2];
this._registerEmitter(emitterName);
this._setHandler(emitterName, eventName, handler);
this._emitter[emitterName].handlers.push({
eventName: eventName,
handler: handler
});
};
/**
* Sets or updates event emitter bound to a given name, e.g.:
* .set('testEmitter', emitter)
* When you set a new object connected with a given name, all handlers attached to events
* and emitter with this name will be registered again on the new object.
* Configuration object can be used to translated incompatible API, e.g. to support emitter
* that provides .addObserver method:
* {
* on: function(emitter, eventDesc, handler) {
* emitter.addObserver(eventDesc, handler);
* }
* }
*
* @param {string} name
* @param {object} emitter
* @param {object} config
*/
EventRouter.prototype.setEmitter = function(name, emitter, config) {
this._registerEmitter(name);
this._emitter[name].emitter = emitter;
if (config) {
this._emitter[name].config = config;
}
this._setAllHandlers(name);
};
// Private methods:
EventRouter.prototype._registerEmitter = function(emitterName) {
if (this._emitter[emitterName] === undefined) {
this._emitter[emitterName] = {
emitter: null,
config: null,
handlers: []
};
}
};
EventRouter.prototype._setAllHandlers = function(emitterName) {
var self = this;
this._emitter[emitterName].handlers.forEach(function (obj) {
self._setHandler(emitterName, obj.eventName, obj.handler);
});
};
EventRouter.prototype._setHandler = function(emitterName, eventName, handler) {
var emitter = this._emitter[emitterName].emitter;
var config = this._emitter[emitterName].config;
if (!emitter) {
// Emitter object isn't available yet.
return;
}
if (config) {
config.on(emitter, eventName, handler);
} else {
emitter.on(eventName, handler);
}
};
// Support node-style modules and AMD.
if (typeof module === "object" && module && typeof module.exports === "object") {
module.exports = EventRouter;
} else if (typeof define === "function" && define.amd) {
define(function () { return EventRouter; });
}
// If there is a window object, that at least has a document property,
// define Lab.EventRouter.
if (typeof window === "object" && typeof window.document === "object") {
window.EventRouter = EventRouter;
}
}());