Subversion Repositories Applications.papyrus

Rev

Rev 1372 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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