New file |
0,0 → 1,261 |
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" |
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> |
|
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> |
<head> |
<title></title> |
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta> |
<script type="text/javascript"> |
// <!-- |
/* |
This file is really focused on just sending one message to the server, and |
receiving one response. The code does not expect to be re-used for multiple messages. |
This might be reworked later if performance indicates a need for it. |
|
xip fragment identifier/hash values have the form: |
#id:cmd:realEncodedMessage |
|
id: some ID that should be unique among messages. No inherent meaning, |
just something to make sure the hash value is unique so the message |
receiver knows a new message is available. |
|
cmd: command to the receiver. Valid values are: |
- init: message used to init the frame. Sent as the first URL when loading |
the page. Contains some config parameters. |
- loaded: the remote frame is loaded. Only sent from server to client. |
- ok: the message that this page sent was received OK. The next message may |
now be sent. |
- start: the start message of a block of messages (a complete message may |
need to be segmented into many messages to get around the limitiations |
of the size of an URL that a browser accepts. |
- part: indicates this is a part of a message. |
- end: the end message of a block of messages. The message can now be acted upon. |
If the message is small enough that it doesn't need to be segmented, then |
just one hash value message can be sent with "end" as the command. |
|
To reassemble a segmented message, the realEncodedMessage parts just have to be concatenated |
together. |
*/ |
|
//MSIE has the lowest limit for URLs with fragment identifiers, |
//at around 4K. Choosing a slightly smaller number for good measure. |
xipUrlLimit = 4000; |
xipIdCounter = 1; |
|
function xipInit(){ |
xipStateId = ""; |
xipIsSending = false; |
xipServerUrl = null; |
xipStateId = null; |
xipRequestData = null; |
xipCurrentHash = ""; |
xipResponseMessage = ""; |
xipRequestParts = []; |
xipPartIndex = 0; |
xipServerWindow = null; |
xipUseFrameRecursion = false; |
} |
xipInit(); |
|
function send(encodedData){ |
if(xipUseFrameRecursion == "true"){ |
var clientEndPoint = window.open(xipStateId + "_clientEndPoint"); |
clientEndPoint.send(encodedData); |
}else{ |
if(!xipIsSending){ |
xipIsSending = true; |
|
xipRequestData = encodedData || ""; |
|
//Get a handle to the server iframe. |
xipServerWindow = frames[xipStateId + "_frame"]; |
if (!xipServerWindow){ |
xipServerWindow = document.getElementById(xipStateId + "_frame").contentWindow; |
} |
|
sendRequestStart(); |
} |
} |
} |
|
//Modify the server URL if it is a local path and |
//This is done for local/same domain testing. |
function fixServerUrl(ifpServerUrl){ |
if(ifpServerUrl.indexOf("..") == 0){ |
var parts = ifpServerUrl.split("/"); |
ifpServerUrl = parts[parts.length - 1]; |
} |
return ifpServerUrl; |
} |
|
|
function pollHash(){ |
//Can't use location.hash because at least Firefox does a decodeURIComponent on it. |
var urlParts = window.location.href.split("#"); |
if(urlParts.length == 2){ |
var newHash = urlParts[1]; |
if(newHash != xipCurrentHash){ |
try{ |
messageReceived(newHash); |
}catch(e){ |
//Make sure to not keep processing the error hash value. |
xipCurrentHash = newHash; |
throw e; |
} |
xipCurrentHash = newHash; |
} |
} |
} |
|
function messageReceived(encodedData){ |
var msg = unpackMessage(encodedData); |
|
switch(msg.command){ |
case "loaded": |
xipMasterFrame.dojo.io.XhrIframeProxy.clientFrameLoaded(xipStateId); |
break; |
case "ok": |
sendRequestPart(); |
break; |
case "start": |
xipResponseMessage = ""; |
xipResponseMessage += msg.message; |
setServerUrl("ok"); |
break; |
case "part": |
xipResponseMessage += msg.message; |
setServerUrl("ok"); |
break; |
case "end": |
setServerUrl("ok"); |
xipResponseMessage += msg.message; |
xipMasterFrame.dojo.io.XhrIframeProxy.receive(xipStateId, xipResponseMessage); |
break; |
} |
} |
|
function sendRequestStart(){ |
//Break the message into parts, if necessary. |
xipRequestParts = []; |
var reqData = xipRequestData; |
var urlLength = xipServerUrl.length; |
var partLength = xipUrlLimit - urlLength; |
var reqIndex = 0; |
|
while((reqData.length - reqIndex) + urlLength > xipUrlLimit){ |
var part = reqData.substring(reqIndex, reqIndex + partLength); |
//Safari will do some extra hex escaping unless we keep the original hex |
//escaping complete. |
var percentIndex = part.lastIndexOf("%"); |
if(percentIndex == part.length - 1 || percentIndex == part.length - 2){ |
part = part.substring(0, percentIndex); |
} |
xipRequestParts.push(part); |
reqIndex += part.length; |
} |
xipRequestParts.push(reqData.substring(reqIndex, reqData.length)); |
|
xipPartIndex = 0; |
sendRequestPart(); |
|
} |
|
function sendRequestPart(){ |
if(xipPartIndex < xipRequestParts.length){ |
//Get the message part. |
var partData = xipRequestParts[xipPartIndex]; |
|
//Get the command. |
var cmd = "part"; |
if(xipPartIndex + 1 == xipRequestParts.length){ |
cmd = "end"; |
}else if (xipPartIndex == 0){ |
cmd = "start"; |
} |
|
setServerUrl(cmd, partData); |
xipPartIndex++; |
} |
} |
|
function setServerUrl(cmd, message){ |
var serverUrl = makeServerUrl(cmd, message); |
|
//Safari won't let us replace across domains. |
if(navigator.userAgent.indexOf("Safari") == -1){ |
xipServerWindow.location.replace(serverUrl); |
}else{ |
xipServerWindow.location = serverUrl; |
} |
} |
|
function makeServerUrl(cmd, message){ |
var serverUrl = xipServerUrl + "#" + (xipIdCounter++) + ":" + cmd; |
if(message){ |
serverUrl += ":" + message; |
} |
return serverUrl; |
} |
|
function unpackMessage(encodedMessage){ |
var parts = encodedMessage.split(":"); |
var command = parts[1]; |
encodedMessage = parts[2] || ""; |
|
var config = null; |
if(command == "init"){ |
var configParts = encodedMessage.split("&"); |
config = {}; |
for(var i = 0; i < configParts.length; i++){ |
var nameValue = configParts[i].split("="); |
config[decodeURIComponent(nameValue[0])] = decodeURIComponent(nameValue[1]); |
} |
} |
return {command: command, message: encodedMessage, config: config}; |
} |
|
function onClientLoad(){ |
//Decode the init params |
var config = unpackMessage(window.location.href.split("#")[1]).config; |
|
xipStateId = config.id; |
|
//Remove the query param for the IE7 recursive case. |
xipServerUrl = fixServerUrl(config.server).replace(/(\?|\&)dojo\.fr\=1/, ""); |
xipUseFrameRecursion = config["fr"]; |
|
if(xipUseFrameRecursion == "endpoint"){ |
xipMasterFrame = parent.parent; |
}else{ |
xipMasterFrame = parent; |
} |
|
//Start counter to inspect hash value. |
setInterval(pollHash, 10); |
|
var clientUrl = window.location.href.split("#")[0]; |
document.getElementById("iframeHolder").innerHTML = '<iframe src="' |
+ makeServerUrl("init", 'id=' + xipStateId + '&client=' + encodeURIComponent(clientUrl) |
+ '&fr=' + xipUseFrameRecursion) + '" id="' + xipStateId + '_frame"></iframe>'; |
|
|
} |
|
if(typeof(window.addEventListener) == "undefined"){ |
window.attachEvent("onload", onClientLoad); |
}else{ |
window.addEventListener('load', onClientLoad, false); |
} |
|
// --> |
</script> |
</head> |
<body> |
<h4>The Dojo Toolkit -- xip_client.html</h4> |
|
<p>This file is used for Dojo's XMLHttpRequest Iframe Proxy. This is the "client" file used |
internally by dojo.io.XhrIframeProxy.</p> |
|
<span id="iframeHolder"></span> |
</body> |
</html> |