Subversion Repositories Applications.papyrus

Rev

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