Subversion Repositories Applications.papyrus

Rev

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

Rev Author Line No. Line
1318 alexandre_ 1
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
2
	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3
 
4
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
5
<head>
6
	<title></title>
7
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
1422 alexandre_ 8
	<!-- Security protection: uncomment the script tag to enable. -->
9
	<!-- script type="text/javascript" -->
1318 alexandre_ 10
	// <!--
11
	/*
12
	This file is really focused on just sending one message to the server, and
13
	receiving one response. The code does not expect to be re-used for multiple messages.
14
	This might be reworked later if performance indicates a need for it.
15
 
16
	xip fragment identifier/hash values have the form:
17
	#id:cmd:realEncodedMessage
18
 
19
	id: some ID that should be unique among messages. No inherent meaning,
20
	        just something to make sure the hash value is unique so the message
21
	        receiver knows a new message is available.
22
 
23
	cmd: command to the receiver. Valid values are:
24
	         - init: message used to init the frame. Sent as the first URL when loading
25
	                 the page. Contains some config parameters.
26
	         - loaded: the remote frame is loaded. Only sent from server to client.
27
	         - ok: the message that this page sent was received OK. The next message may
28
	               now be sent.
29
	         - start: the start message of a block of messages (a complete message may
30
	                  need to be segmented into many messages to get around the limitiations
31
	                  of the size of an URL that a browser accepts.
32
	         - part: indicates this is a part of a message.
33
	         - end: the end message of a block of messages. The message can now be acted upon.
34
	                If the message is small enough that it doesn't need to be segmented, then
35
	                just one hash value message can be sent with "end" as the command.
36
 
37
	To reassemble a segmented message, the realEncodedMessage parts just have to be concatenated
38
	together.
39
	*/
40
 
41
	//MSIE has the lowest limit for URLs with fragment identifiers,
42
	//at around 4K. Choosing a slightly smaller number for good measure.
43
	xipUrlLimit = 4000;
44
	xipIdCounter = 1;
45
 
46
	function xipInit(){
47
		xipStateId = "";
48
		xipIsSending = false;
49
		xipServerUrl = null;
50
		xipStateId = null;
51
		xipRequestData = null;
52
		xipCurrentHash = "";
53
		xipResponseMessage = "";
54
		xipRequestParts = [];
55
		xipPartIndex = 0;
56
		xipServerWindow = null;
57
		xipUseFrameRecursion = false;
58
	}
59
	xipInit();
60
 
61
	function send(encodedData){
62
		if(xipUseFrameRecursion == "true"){
63
			var clientEndPoint = window.open(xipStateId + "_clientEndPoint");
64
			clientEndPoint.send(encodedData);
65
		}else{
66
			if(!xipIsSending){
67
				xipIsSending = true;
68
 
69
				xipRequestData = encodedData || "";
70
 
71
				//Get a handle to the server iframe.
72
				xipServerWindow = frames[xipStateId + "_frame"];
73
				if (!xipServerWindow){
74
					xipServerWindow = document.getElementById(xipStateId + "_frame").contentWindow;
75
				}
76
 
77
				sendRequestStart();
78
			}
79
		}
80
	}
81
 
82
	//Modify the server URL if it is a local path and
83
	//This is done for local/same domain testing.
84
	function fixServerUrl(ifpServerUrl){
85
		if(ifpServerUrl.indexOf("..") == 0){
86
			var parts = ifpServerUrl.split("/");
87
			ifpServerUrl = parts[parts.length - 1];
88
		}
89
		return ifpServerUrl;
90
	}
91
 
92
 
93
	function pollHash(){
94
		//Can't use location.hash because at least Firefox does a decodeURIComponent on it.
95
		var urlParts = window.location.href.split("#");
96
		if(urlParts.length == 2){
97
			var newHash = urlParts[1];
98
			if(newHash != xipCurrentHash){
99
				try{
100
					messageReceived(newHash);
101
				}catch(e){
102
					//Make sure to not keep processing the error hash value.
103
					xipCurrentHash = newHash;
104
					throw e;
105
				}
106
				xipCurrentHash = newHash;
107
			}
108
		}
109
	}
110
 
111
	function messageReceived(encodedData){
112
		var msg = unpackMessage(encodedData);
113
 
114
		switch(msg.command){
115
			case "loaded":
116
				xipMasterFrame.dojo.io.XhrIframeProxy.clientFrameLoaded(xipStateId);
117
				break;
118
			case "ok":
119
				sendRequestPart();
120
				break;
121
			case "start":
122
				xipResponseMessage = "";
123
				xipResponseMessage += msg.message;
124
				setServerUrl("ok");
125
				break;
126
			case "part":
127
				xipResponseMessage += msg.message;
128
				setServerUrl("ok");
129
				break;
130
			case "end":
131
				setServerUrl("ok");
132
				xipResponseMessage += msg.message;
133
				xipMasterFrame.dojo.io.XhrIframeProxy.receive(xipStateId, xipResponseMessage);
134
				break;
135
		}
136
	}
137
 
138
	function sendRequestStart(){
139
		//Break the message into parts, if necessary.
140
		xipRequestParts = [];
141
		var reqData = xipRequestData;
142
		var urlLength = xipServerUrl.length;
143
		var partLength = xipUrlLimit - urlLength;
144
		var reqIndex = 0;
145
 
146
		while((reqData.length - reqIndex) + urlLength > xipUrlLimit){
147
			var part = reqData.substring(reqIndex, reqIndex + partLength);
148
			//Safari will do some extra hex escaping unless we keep the original hex
149
			//escaping complete.
150
			var percentIndex = part.lastIndexOf("%");
151
			if(percentIndex == part.length - 1 || percentIndex == part.length - 2){
152
				part = part.substring(0, percentIndex);
153
			}
154
			xipRequestParts.push(part);
155
			reqIndex += part.length;
156
		}
157
		xipRequestParts.push(reqData.substring(reqIndex, reqData.length));
158
 
159
		xipPartIndex = 0;
160
		sendRequestPart();
161
 
162
	}
163
 
164
	function sendRequestPart(){
165
		if(xipPartIndex < xipRequestParts.length){
166
			//Get the message part.
167
			var partData = xipRequestParts[xipPartIndex];
168
 
169
			//Get the command.
170
			var cmd = "part";
171
			if(xipPartIndex + 1 == xipRequestParts.length){
172
				cmd = "end";
173
			}else if (xipPartIndex == 0){
174
				cmd = "start";
175
			}
176
 
177
			setServerUrl(cmd, partData);
178
			xipPartIndex++;
179
		}
180
	}
181
 
182
	function setServerUrl(cmd, message){
183
		var serverUrl = makeServerUrl(cmd, message);
184
 
185
		//Safari won't let us replace across domains.
186
		if(navigator.userAgent.indexOf("Safari") == -1){
187
			xipServerWindow.location.replace(serverUrl);
188
		}else{
189
			xipServerWindow.location = serverUrl;
190
		}
191
	}
192
 
193
	function makeServerUrl(cmd, message){
194
		var serverUrl = xipServerUrl + "#" + (xipIdCounter++) + ":" + cmd;
195
		if(message){
196
			serverUrl += ":" + message;
197
		}
198
		return serverUrl;
199
	}
200
 
201
	function unpackMessage(encodedMessage){
202
		var parts = encodedMessage.split(":");
203
		var command = parts[1];
204
		encodedMessage = parts[2] || "";
205
 
206
		var config = null;
207
		if(command == "init"){
208
			var configParts = encodedMessage.split("&");
209
			config = {};
210
			for(var i = 0; i < configParts.length; i++){
211
				var nameValue = configParts[i].split("=");
212
				config[decodeURIComponent(nameValue[0])] = decodeURIComponent(nameValue[1]);
213
			}
214
		}
215
		return {command: command, message: encodedMessage, config: config};
216
	}
217
 
218
	function onClientLoad(){
219
		//Decode the init params
220
		var config = unpackMessage(window.location.href.split("#")[1]).config;
221
 
222
		xipStateId = config.id;
223
 
224
		//Remove the query param for the IE7 recursive case.
225
		xipServerUrl = fixServerUrl(config.server).replace(/(\?|\&)dojo\.fr\=1/, "");
1422 alexandre_ 226
 
227
		//Make sure we don't have a javascript: url, just for good measure.
228
		if(xipServerUrl.split(":")[0].match(/javascript/i)){
229
			throw "Invalid server URL";
230
		}
231
 
1318 alexandre_ 232
		xipUseFrameRecursion = config["fr"];
233
 
234
		if(xipUseFrameRecursion == "endpoint"){
235
			xipMasterFrame = parent.parent;
236
		}else{
237
			xipMasterFrame = parent;
238
		}
239
 
240
		//Start counter to inspect hash value.
241
		setInterval(pollHash, 10);
242
 
243
		var clientUrl = window.location.href.split("#")[0];
1422 alexandre_ 244
		var iframeNode = document.getElementsByTagName("iframe")[0];
245
		iframeNode.id = xipStateId + "_frame";
246
		iframeNode.src = makeServerUrl("init", 'id=' + xipStateId + '&client='
247
			+ encodeURIComponent(clientUrl) + '&fr=' + xipUseFrameRecursion);
1318 alexandre_ 248
	}
249
 
250
	if(typeof(window.addEventListener) == "undefined"){
251
		window.attachEvent("onload", onClientLoad);
252
	}else{
253
		window.addEventListener('load', onClientLoad, false);
254
	}
255
 
256
	// -->
257
	</script>
258
</head>
259
<body>
260
	<h4>The Dojo Toolkit -- xip_client.html</h4>
261
 
262
	<p>This file is used for Dojo's XMLHttpRequest Iframe Proxy. This is the "client" file used
263
	internally by dojo.io.XhrIframeProxy.</p>
264
 
1422 alexandre_ 265
	<iframe src="javascript:false"></iframe>
1318 alexandre_ 266
</body>
267
</html>