Subversion Repositories Applications.papyrus

Rev

Rev 1371 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
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