1318 |
alexandre_ |
1 |
/*
|
|
|
2 |
Copyright (c) 2004-2006, The Dojo Foundation
|
|
|
3 |
All Rights Reserved.
|
|
|
4 |
|
|
|
5 |
Licensed under the Academic Free License version 2.1 or above OR the
|
|
|
6 |
modified BSD license. For more information on Dojo licensing, see:
|
|
|
7 |
|
|
|
8 |
http://dojotoolkit.org/community/licensing.shtml
|
|
|
9 |
*/
|
|
|
10 |
|
|
|
11 |
|
|
|
12 |
|
|
|
13 |
dojo.require("dojo.event.*");
|
|
|
14 |
dojo.require("dojo.io.BrowserIO");
|
|
|
15 |
dojo.provide("dojo.io.RepubsubIO");
|
|
|
16 |
dojo.io.repubsubTranport = new function () {
|
|
|
17 |
var rps = dojo.io.repubsub;
|
|
|
18 |
this.canHandle = function (kwArgs) {
|
|
|
19 |
if ((kwArgs["mimetype"] == "text/javascript") && (kwArgs["method"] == "repubsub")) {
|
|
|
20 |
return true;
|
|
|
21 |
}
|
|
|
22 |
return false;
|
|
|
23 |
};
|
|
|
24 |
this.bind = function (kwArgs) {
|
|
|
25 |
if (!rps.isInitialized) {
|
|
|
26 |
rps.init();
|
|
|
27 |
}
|
|
|
28 |
if (!rps.topics[kwArgs.url]) {
|
|
|
29 |
kwArgs.rpsLoad = function (evt) {
|
|
|
30 |
kwArgs.load("load", evt);
|
|
|
31 |
};
|
|
|
32 |
rps.subscribe(kwArgs.url, kwArgs, "rpsLoad");
|
|
|
33 |
}
|
|
|
34 |
if (kwArgs["content"]) {
|
|
|
35 |
var cEvt = dojo.io.repubsubEvent.initFromProperties(kwArgs.content);
|
|
|
36 |
rps.publish(kwArgs.url, cEvt);
|
|
|
37 |
}
|
|
|
38 |
};
|
|
|
39 |
dojo.io.transports.addTransport("repubsubTranport");
|
|
|
40 |
};
|
|
|
41 |
dojo.io.repubsub = new function () {
|
|
|
42 |
this.initDoc = "init.html";
|
|
|
43 |
this.isInitialized = false;
|
|
|
44 |
this.subscriptionBacklog = [];
|
|
|
45 |
this.debug = true;
|
|
|
46 |
this.rcvNodeName = null;
|
|
|
47 |
this.sndNodeName = null;
|
|
|
48 |
this.rcvNode = null;
|
|
|
49 |
this.sndNode = null;
|
|
|
50 |
this.canRcv = false;
|
|
|
51 |
this.canSnd = false;
|
|
|
52 |
this.canLog = false;
|
|
|
53 |
this.sndTimer = null;
|
|
|
54 |
this.windowRef = window;
|
|
|
55 |
this.backlog = [];
|
|
|
56 |
this.tunnelInitCount = 0;
|
|
|
57 |
this.tunnelFrameKey = "tunnel_frame";
|
|
|
58 |
this.serverBaseURL = location.protocol + "//" + location.host + location.pathname;
|
|
|
59 |
this.logBacklog = [];
|
|
|
60 |
this.getRandStr = function () {
|
|
|
61 |
return Math.random().toString().substring(2, 10);
|
|
|
62 |
};
|
|
|
63 |
this.userid = "guest";
|
|
|
64 |
this.tunnelID = this.getRandStr();
|
|
|
65 |
this.attachPathList = [];
|
|
|
66 |
this.topics = [];
|
|
|
67 |
this.parseGetStr = function () {
|
|
|
68 |
var baseUrl = document.location.toString();
|
|
|
69 |
var params = baseUrl.split("?", 2);
|
|
|
70 |
if (params.length > 1) {
|
|
|
71 |
var paramStr = params[1];
|
|
|
72 |
var pairs = paramStr.split("&");
|
|
|
73 |
var opts = [];
|
|
|
74 |
for (var x in pairs) {
|
|
|
75 |
var sp = pairs[x].split("=");
|
|
|
76 |
try {
|
|
|
77 |
opts[sp[0]] = eval(sp[1]);
|
|
|
78 |
}
|
|
|
79 |
catch (e) {
|
|
|
80 |
opts[sp[0]] = sp[1];
|
|
|
81 |
}
|
|
|
82 |
}
|
|
|
83 |
return opts;
|
|
|
84 |
} else {
|
|
|
85 |
return [];
|
|
|
86 |
}
|
|
|
87 |
};
|
|
|
88 |
var getOpts = this.parseGetStr();
|
|
|
89 |
for (var x in getOpts) {
|
|
|
90 |
this[x] = getOpts[x];
|
|
|
91 |
}
|
|
|
92 |
if (!this["tunnelURI"]) {
|
|
|
93 |
this.tunnelURI = ["/who/", escape(this.userid), "/s/", this.getRandStr(), "/kn_journal"].join("");
|
|
|
94 |
}
|
|
|
95 |
if (window["repubsubOpts"] || window["rpsOpts"]) {
|
|
|
96 |
var optObj = window["repubsubOpts"] || window["rpsOpts"];
|
|
|
97 |
for (var x in optObj) {
|
|
|
98 |
this[x] = optObj[x];
|
|
|
99 |
}
|
|
|
100 |
}
|
|
|
101 |
this.tunnelCloseCallback = function () {
|
|
|
102 |
dojo.io.setIFrameSrc(this.rcvNode, this.initDoc + "?callback=repubsub.rcvNodeReady&domain=" + document.domain);
|
|
|
103 |
};
|
|
|
104 |
this.receiveEventFromTunnel = function (evt, srcWindow) {
|
|
|
105 |
if (!evt["elements"]) {
|
|
|
106 |
this.log("bailing! event received without elements!", "error");
|
|
|
107 |
return;
|
|
|
108 |
}
|
|
|
109 |
var e = {};
|
|
|
110 |
for (var i = 0; i < evt.elements.length; i++) {
|
|
|
111 |
var ee = evt.elements[i];
|
|
|
112 |
e[ee.name || ee.nameU] = (ee.value || ee.valueU);
|
|
|
113 |
this.log("[event]: " + (ee.name || ee.nameU) + ": " + e[ee.name || ee.nameU]);
|
|
|
114 |
}
|
|
|
115 |
this.dispatch(e);
|
|
|
116 |
};
|
|
|
117 |
this.widenDomain = function (domainStr) {
|
|
|
118 |
var cd = domainStr || document.domain;
|
|
|
119 |
if (cd.indexOf(".") == -1) {
|
|
|
120 |
return;
|
|
|
121 |
}
|
|
|
122 |
var dps = cd.split(".");
|
|
|
123 |
if (dps.length <= 2) {
|
|
|
124 |
return;
|
|
|
125 |
}
|
|
|
126 |
dps = dps.slice(dps.length - 2);
|
|
|
127 |
document.domain = dps.join(".");
|
|
|
128 |
};
|
|
|
129 |
this.parseCookie = function () {
|
|
|
130 |
var cs = document.cookie;
|
|
|
131 |
var keypairs = cs.split(";");
|
|
|
132 |
for (var x = 0; x < keypairs.length; x++) {
|
|
|
133 |
keypairs[x] = keypairs[x].split("=");
|
|
|
134 |
if (x != keypairs.length - 1) {
|
|
|
135 |
cs += ";";
|
|
|
136 |
}
|
|
|
137 |
}
|
|
|
138 |
return keypairs;
|
|
|
139 |
};
|
|
|
140 |
this.setCookie = function (keypairs, clobber) {
|
|
|
141 |
if ((clobber) && (clobber == true)) {
|
|
|
142 |
document.cookie = "";
|
|
|
143 |
}
|
|
|
144 |
var cs = "";
|
|
|
145 |
for (var x = 0; x < keypairs.length; x++) {
|
|
|
146 |
cs += keypairs[x][0] + "=" + keypairs[x][1];
|
|
|
147 |
if (x != keypairs.length - 1) {
|
|
|
148 |
cs += ";";
|
|
|
149 |
}
|
|
|
150 |
}
|
|
|
151 |
document.cookie = cs;
|
|
|
152 |
};
|
|
|
153 |
this.log = function (str, lvl) {
|
|
|
154 |
if (!this.debug) {
|
|
|
155 |
return;
|
|
|
156 |
}
|
|
|
157 |
while (this.logBacklog.length > 0) {
|
|
|
158 |
if (!this.canLog) {
|
|
|
159 |
break;
|
|
|
160 |
}
|
|
|
161 |
var blo = this.logBacklog.shift();
|
|
|
162 |
this.writeLog("[" + blo[0] + "]: " + blo[1], blo[2]);
|
|
|
163 |
}
|
|
|
164 |
this.writeLog(str, lvl);
|
|
|
165 |
};
|
|
|
166 |
this.writeLog = function (str, lvl) {
|
|
|
167 |
dojo.debug(((new Date()).toLocaleTimeString()) + ": " + str);
|
|
|
168 |
};
|
|
|
169 |
this.init = function () {
|
|
|
170 |
this.widenDomain();
|
|
|
171 |
this.openTunnel();
|
|
|
172 |
this.isInitialized = true;
|
|
|
173 |
while (this.subscriptionBacklog.length) {
|
|
|
174 |
this.subscribe.apply(this, this.subscriptionBacklog.shift());
|
|
|
175 |
}
|
|
|
176 |
};
|
|
|
177 |
this.clobber = function () {
|
|
|
178 |
if (this.rcvNode) {
|
|
|
179 |
this.setCookie([[this.tunnelFrameKey, "closed"], ["path", "/"]], false);
|
|
|
180 |
}
|
|
|
181 |
};
|
|
|
182 |
this.openTunnel = function () {
|
|
|
183 |
this.rcvNodeName = "rcvIFrame_" + this.getRandStr();
|
|
|
184 |
this.setCookie([[this.tunnelFrameKey, this.rcvNodeName], ["path", "/"]], false);
|
|
|
185 |
this.rcvNode = dojo.io.createIFrame(this.rcvNodeName);
|
|
|
186 |
dojo.io.setIFrameSrc(this.rcvNode, this.initDoc + "?callback=repubsub.rcvNodeReady&domain=" + document.domain);
|
|
|
187 |
this.sndNodeName = "sndIFrame_" + this.getRandStr();
|
|
|
188 |
this.sndNode = dojo.io.createIFrame(this.sndNodeName);
|
|
|
189 |
dojo.io.setIFrameSrc(this.sndNode, this.initDoc + "?callback=repubsub.sndNodeReady&domain=" + document.domain);
|
|
|
190 |
};
|
|
|
191 |
this.rcvNodeReady = function () {
|
|
|
192 |
var statusURI = [this.tunnelURI, "/kn_status/", this.getRandStr(), "_", String(this.tunnelInitCount++)].join("");
|
|
|
193 |
this.log("rcvNodeReady");
|
|
|
194 |
var initURIArr = [this.serverBaseURL, "/kn?kn_from=", escape(this.tunnelURI), "&kn_id=", escape(this.tunnelID), "&kn_status_from=", escape(statusURI)];
|
|
|
195 |
dojo.io.setIFrameSrc(this.rcvNode, initURIArr.join(""));
|
|
|
196 |
this.subscribe(statusURI, this, "statusListener", true);
|
|
|
197 |
this.log(initURIArr.join(""));
|
|
|
198 |
};
|
|
|
199 |
this.sndNodeReady = function () {
|
|
|
200 |
this.canSnd = true;
|
|
|
201 |
this.log("sndNodeReady");
|
|
|
202 |
this.log(this.backlog.length);
|
|
|
203 |
if (this.backlog.length > 0) {
|
|
|
204 |
this.dequeueEvent();
|
|
|
205 |
}
|
|
|
206 |
};
|
|
|
207 |
this.statusListener = function (evt) {
|
|
|
208 |
this.log("status listener called");
|
|
|
209 |
this.log(evt.status, "info");
|
|
|
210 |
};
|
|
|
211 |
this.dispatch = function (evt) {
|
|
|
212 |
if (evt["to"] || evt["kn_routed_from"]) {
|
|
|
213 |
var rf = evt["to"] || evt["kn_routed_from"];
|
|
|
214 |
var topic = rf.split(this.serverBaseURL, 2)[1];
|
|
|
215 |
if (!topic) {
|
|
|
216 |
topic = rf;
|
|
|
217 |
}
|
|
|
218 |
this.log("[topic] " + topic);
|
|
|
219 |
if (topic.length > 3) {
|
|
|
220 |
if (topic.slice(0, 3) == "/kn") {
|
|
|
221 |
topic = topic.slice(3);
|
|
|
222 |
}
|
|
|
223 |
}
|
|
|
224 |
if (this.attachPathList[topic]) {
|
|
|
225 |
this.attachPathList[topic](evt);
|
|
|
226 |
}
|
|
|
227 |
}
|
|
|
228 |
};
|
|
|
229 |
this.subscribe = function (topic, toObj, toFunc, dontTellServer) {
|
|
|
230 |
if (!this.isInitialized) {
|
|
|
231 |
this.subscriptionBacklog.push([topic, toObj, toFunc, dontTellServer]);
|
|
|
232 |
return;
|
|
|
233 |
}
|
|
|
234 |
if (!this.attachPathList[topic]) {
|
|
|
235 |
this.attachPathList[topic] = function () {
|
|
|
236 |
return true;
|
|
|
237 |
};
|
|
|
238 |
this.log("subscribing to: " + topic);
|
|
|
239 |
this.topics.push(topic);
|
|
|
240 |
}
|
|
|
241 |
var revt = new dojo.io.repubsubEvent(this.tunnelURI, topic, "route");
|
|
|
242 |
var rstr = [this.serverBaseURL + "/kn", revt.toGetString()].join("");
|
|
|
243 |
dojo.event.kwConnect({once:true, srcObj:this.attachPathList, srcFunc:topic, adviceObj:toObj, adviceFunc:toFunc});
|
|
|
244 |
if (!this.rcvNode) {
|
|
|
245 |
}
|
|
|
246 |
if (dontTellServer) {
|
|
|
247 |
return;
|
|
|
248 |
}
|
|
|
249 |
this.log("sending subscription to: " + topic);
|
|
|
250 |
this.sendTopicSubToServer(topic, rstr);
|
|
|
251 |
};
|
|
|
252 |
this.sendTopicSubToServer = function (topic, str) {
|
|
|
253 |
if (!this.attachPathList[topic]["subscriptions"]) {
|
|
|
254 |
this.enqueueEventStr(str);
|
|
|
255 |
this.attachPathList[topic].subscriptions = 0;
|
|
|
256 |
}
|
|
|
257 |
this.attachPathList[topic].subscriptions++;
|
|
|
258 |
};
|
|
|
259 |
this.unSubscribe = function (topic, toObj, toFunc) {
|
|
|
260 |
dojo.event.kwDisconnect({srcObj:this.attachPathList, srcFunc:topic, adviceObj:toObj, adviceFunc:toFunc});
|
|
|
261 |
};
|
|
|
262 |
this.publish = function (topic, event) {
|
|
|
263 |
var evt = dojo.io.repubsubEvent.initFromProperties(event);
|
|
|
264 |
evt.to = topic;
|
|
|
265 |
var evtURLParts = [];
|
|
|
266 |
evtURLParts.push(this.serverBaseURL + "/kn");
|
|
|
267 |
evtURLParts.push(evt.toGetString());
|
|
|
268 |
this.enqueueEventStr(evtURLParts.join(""));
|
|
|
269 |
};
|
|
|
270 |
this.enqueueEventStr = function (evtStr) {
|
|
|
271 |
this.log("enqueueEventStr");
|
|
|
272 |
this.backlog.push(evtStr);
|
|
|
273 |
this.dequeueEvent();
|
|
|
274 |
};
|
|
|
275 |
this.dequeueEvent = function (force) {
|
|
|
276 |
this.log("dequeueEvent");
|
|
|
277 |
if (this.backlog.length <= 0) {
|
|
|
278 |
return;
|
|
|
279 |
}
|
|
|
280 |
if ((this.canSnd) || (force)) {
|
|
|
281 |
dojo.io.setIFrameSrc(this.sndNode, this.backlog.shift() + "&callback=repubsub.sndNodeReady");
|
|
|
282 |
this.canSnd = false;
|
|
|
283 |
} else {
|
|
|
284 |
this.log("sndNode not available yet!", "debug");
|
|
|
285 |
}
|
|
|
286 |
};
|
|
|
287 |
};
|
|
|
288 |
dojo.io.repubsubEvent = function (to, from, method, id, routeURI, payload, dispname, uid) {
|
|
|
289 |
this.to = to;
|
|
|
290 |
this.from = from;
|
|
|
291 |
this.method = method || "route";
|
|
|
292 |
this.id = id || repubsub.getRandStr();
|
|
|
293 |
this.uri = routeURI;
|
|
|
294 |
this.displayname = dispname || repubsub.displayname;
|
|
|
295 |
this.userid = uid || repubsub.userid;
|
|
|
296 |
this.payload = payload || "";
|
|
|
297 |
this.flushChars = 4096;
|
|
|
298 |
this.initFromProperties = function (evt) {
|
|
|
299 |
if (evt.constructor = dojo.io.repubsubEvent) {
|
|
|
300 |
for (var x in evt) {
|
|
|
301 |
this[x] = evt[x];
|
|
|
302 |
}
|
|
|
303 |
} else {
|
|
|
304 |
for (var x in evt) {
|
|
|
305 |
if (typeof this.forwardPropertiesMap[x] == "string") {
|
|
|
306 |
this[this.forwardPropertiesMap[x]] = evt[x];
|
|
|
307 |
} else {
|
|
|
308 |
this[x] = evt[x];
|
|
|
309 |
}
|
|
|
310 |
}
|
|
|
311 |
}
|
|
|
312 |
};
|
|
|
313 |
this.toGetString = function (noQmark) {
|
|
|
314 |
var qs = [((noQmark) ? "" : "?")];
|
|
|
315 |
for (var x = 0; x < this.properties.length; x++) {
|
|
|
316 |
var tp = this.properties[x];
|
|
|
317 |
if (this[tp[0]]) {
|
|
|
318 |
qs.push(tp[1] + "=" + encodeURIComponent(String(this[tp[0]])));
|
|
|
319 |
}
|
|
|
320 |
}
|
|
|
321 |
return qs.join("&");
|
|
|
322 |
};
|
|
|
323 |
};
|
|
|
324 |
dojo.io.repubsubEvent.prototype.properties = [["from", "kn_from"], ["to", "kn_to"], ["method", "do_method"], ["id", "kn_id"], ["uri", "kn_uri"], ["displayname", "kn_displayname"], ["userid", "kn_userid"], ["payload", "kn_payload"], ["flushChars", "kn_response_flush"], ["responseFormat", "kn_response_format"]];
|
|
|
325 |
dojo.io.repubsubEvent.prototype.forwardPropertiesMap = {};
|
|
|
326 |
dojo.io.repubsubEvent.prototype.reversePropertiesMap = {};
|
|
|
327 |
for (var x = 0; x < dojo.io.repubsubEvent.prototype.properties.length; x++) {
|
|
|
328 |
var tp = dojo.io.repubsubEvent.prototype.properties[x];
|
|
|
329 |
dojo.io.repubsubEvent.prototype.reversePropertiesMap[tp[0]] = tp[1];
|
|
|
330 |
dojo.io.repubsubEvent.prototype.forwardPropertiesMap[tp[1]] = tp[0];
|
|
|
331 |
}
|
|
|
332 |
dojo.io.repubsubEvent.initFromProperties = function (evt) {
|
|
|
333 |
var eventObj = new dojo.io.repubsubEvent();
|
|
|
334 |
eventObj.initFromProperties(evt);
|
|
|
335 |
return eventObj;
|
|
|
336 |
};
|
|
|
337 |
|