-
Notifications
You must be signed in to change notification settings - Fork 1
/
topic.js
133 lines (116 loc) · 3 KB
/
topic.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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
define([
'dojo/topic',
'./lang',
'./groups'
], function(dojoTopic, lang, groups){
// summary:
// A multi-featured version of dojo/topic, which allows for a context
// (this) to be passed and a stringified method. Also provides a way of
// subscribing to multiple topics. The handle is pauseable and resumable.
// note:
// dojo.topics are attached to this, so you can use this module and not
// miss any topics called from the traditional dojo/topic.publish
//
var topics = {};
// TODO:
// Wire up groups
//
var topic = {
sub: function(/*String*/channel, /*Object|Function*/ctx, /*String|Function*/method, /*String?*/group){
// summary:
// subscribe to a topic.
// returns:Object
// handle includes:
// remove
// pause
// resume
//
var gid, fn, cb;
if(!!group){
gid = group;
cb = lang.bind(ctx, method);
}else if(typeof ctx == 'function' && !!method){
gid = method;
cb = ctx;
}else{
cb = lang.bind(ctx, method);
}
if(!topics[channel]){
topics[channel] = {};
}
var uid = lang.uid("sub");
topics[channel][uid] = cb;
var handle = {
remove: function(){
delete topics[channel][uid];
},
pause: function(){
this.cb = topics[channel][uid];
topics[channel][uid] = function(){};
},
resume: function(){
if(!this.cb) return;
topics[channel][uid] = this.cb;
}
};
if(gid) groups.add(gid, handle);
return handle;
},
pub: function(/*String*/channel /*arguments*/){
// summary:
// Publish a topic. All arguments are passed. No arrays
// necessary.
//
if(!topics[channel]) return;
var args = Array.prototype.slice.call(arguments);
args.shift();
for(var nm in topics[channel]){
topics[channel][nm].apply(null, args);
}
}
};
topic.sub.multi = function(/*Object*/obj, /*Object?*/context, /*String?*/group){
// summary:
// Subscribe to multiple topics. The key-values in the object
// should match to the topic-method.
// note:
// If context is used, all methods should resolve to that one
// context.
// returns: Object
// Handle.
var subs = [], ctx, gid;
if(typeof ctx == 'string'){
gid = context;
}else if(typeof context == 'object'){
ctx = context;
}
if(typeof group == 'string'){
gid = group;
}
if(ctx){
for(var nm in obj){
subs.push(topic.sub(nm, ctx, obj[nm], group));
}
}else{
for(var nm in obj){
subs.push(topic.sub(nm, obj[nm], group));
}
}
return {
remove: function(){
subs.forEach(function(s){ s.remove(); });
},
pause: function(){
subs.forEach(function(s){ s.pause(); });
},
resume: function(){
subs.forEach(function(s){ s.resume(); });
}
}
}
topic.group = groups;
// Make Dojo Topics work with util pub/sub
dojoTopic.publish = lang.bind(topic, "pub");
dojoTopic.subscribe = lang.bind(topic, "sub");
return topic;
});