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 |
|
1422 |
alexandre_ |
11 |
|
|
|
12 |
|
1318 |
alexandre_ |
13 |
dojo.provide("dojo.io.ScriptSrcIO");
|
|
|
14 |
dojo.require("dojo.io.BrowserIO");
|
|
|
15 |
dojo.require("dojo.undo.browser");
|
|
|
16 |
dojo.io.ScriptSrcTransport = new function () {
|
|
|
17 |
this.preventCache = false;
|
|
|
18 |
this.maxUrlLength = 1000;
|
|
|
19 |
this.inFlightTimer = null;
|
|
|
20 |
this.DsrStatusCodes = {Continue:100, Ok:200, Error:500};
|
|
|
21 |
this.startWatchingInFlight = function () {
|
|
|
22 |
if (!this.inFlightTimer) {
|
|
|
23 |
this.inFlightTimer = setInterval("dojo.io.ScriptSrcTransport.watchInFlight();", 100);
|
|
|
24 |
}
|
|
|
25 |
};
|
|
|
26 |
this.watchInFlight = function () {
|
|
|
27 |
var totalCount = 0;
|
|
|
28 |
var doneCount = 0;
|
|
|
29 |
for (var param in this._state) {
|
|
|
30 |
totalCount++;
|
|
|
31 |
var currentState = this._state[param];
|
|
|
32 |
if (currentState.isDone) {
|
|
|
33 |
doneCount++;
|
|
|
34 |
delete this._state[param];
|
|
|
35 |
} else {
|
|
|
36 |
if (!currentState.isFinishing) {
|
|
|
37 |
var listener = currentState.kwArgs;
|
|
|
38 |
try {
|
|
|
39 |
if (currentState.checkString && eval("typeof(" + currentState.checkString + ") != 'undefined'")) {
|
|
|
40 |
currentState.isFinishing = true;
|
|
|
41 |
this._finish(currentState, "load");
|
|
|
42 |
doneCount++;
|
|
|
43 |
delete this._state[param];
|
|
|
44 |
} else {
|
|
|
45 |
if (listener.timeoutSeconds && listener.timeout) {
|
|
|
46 |
if (currentState.startTime + (listener.timeoutSeconds * 1000) < (new Date()).getTime()) {
|
|
|
47 |
currentState.isFinishing = true;
|
|
|
48 |
this._finish(currentState, "timeout");
|
|
|
49 |
doneCount++;
|
|
|
50 |
delete this._state[param];
|
|
|
51 |
}
|
|
|
52 |
} else {
|
|
|
53 |
if (!listener.timeoutSeconds) {
|
|
|
54 |
doneCount++;
|
|
|
55 |
}
|
|
|
56 |
}
|
|
|
57 |
}
|
|
|
58 |
}
|
|
|
59 |
catch (e) {
|
|
|
60 |
currentState.isFinishing = true;
|
|
|
61 |
this._finish(currentState, "error", {status:this.DsrStatusCodes.Error, response:e});
|
|
|
62 |
}
|
|
|
63 |
}
|
|
|
64 |
}
|
|
|
65 |
}
|
|
|
66 |
if (doneCount >= totalCount) {
|
|
|
67 |
clearInterval(this.inFlightTimer);
|
|
|
68 |
this.inFlightTimer = null;
|
|
|
69 |
}
|
|
|
70 |
};
|
|
|
71 |
this.canHandle = function (kwArgs) {
|
|
|
72 |
return dojo.lang.inArray(["text/javascript", "text/json", "application/json"], (kwArgs["mimetype"].toLowerCase())) && (kwArgs["method"].toLowerCase() == "get") && !(kwArgs["formNode"] && dojo.io.formHasFile(kwArgs["formNode"])) && (!kwArgs["sync"] || kwArgs["sync"] == false) && !kwArgs["file"] && !kwArgs["multipart"];
|
|
|
73 |
};
|
|
|
74 |
this.removeScripts = function () {
|
|
|
75 |
var scripts = document.getElementsByTagName("script");
|
|
|
76 |
for (var i = 0; scripts && i < scripts.length; i++) {
|
|
|
77 |
var scriptTag = scripts[i];
|
|
|
78 |
if (scriptTag.className == "ScriptSrcTransport") {
|
|
|
79 |
var parent = scriptTag.parentNode;
|
|
|
80 |
parent.removeChild(scriptTag);
|
|
|
81 |
i--;
|
|
|
82 |
}
|
|
|
83 |
}
|
|
|
84 |
};
|
|
|
85 |
this.bind = function (kwArgs) {
|
|
|
86 |
var url = kwArgs.url;
|
|
|
87 |
var query = "";
|
|
|
88 |
if (kwArgs["formNode"]) {
|
|
|
89 |
var ta = kwArgs.formNode.getAttribute("action");
|
|
|
90 |
if ((ta) && (!kwArgs["url"])) {
|
|
|
91 |
url = ta;
|
|
|
92 |
}
|
|
|
93 |
var tp = kwArgs.formNode.getAttribute("method");
|
|
|
94 |
if ((tp) && (!kwArgs["method"])) {
|
|
|
95 |
kwArgs.method = tp;
|
|
|
96 |
}
|
|
|
97 |
query += dojo.io.encodeForm(kwArgs.formNode, kwArgs.encoding, kwArgs["formFilter"]);
|
|
|
98 |
}
|
|
|
99 |
if (url.indexOf("#") > -1) {
|
|
|
100 |
dojo.debug("Warning: dojo.io.bind: stripping hash values from url:", url);
|
|
|
101 |
url = url.split("#")[0];
|
|
|
102 |
}
|
|
|
103 |
var urlParts = url.split("?");
|
|
|
104 |
if (urlParts && urlParts.length == 2) {
|
|
|
105 |
url = urlParts[0];
|
|
|
106 |
query += (query ? "&" : "") + urlParts[1];
|
|
|
107 |
}
|
|
|
108 |
if (kwArgs["backButton"] || kwArgs["back"] || kwArgs["changeUrl"]) {
|
|
|
109 |
dojo.undo.browser.addToHistory(kwArgs);
|
|
|
110 |
}
|
|
|
111 |
var id = kwArgs["apiId"] ? kwArgs["apiId"] : "id" + this._counter++;
|
|
|
112 |
var content = kwArgs["content"];
|
|
|
113 |
var jsonpName = kwArgs.jsonParamName;
|
|
|
114 |
if (kwArgs.sendTransport || jsonpName) {
|
|
|
115 |
if (!content) {
|
|
|
116 |
content = {};
|
|
|
117 |
}
|
|
|
118 |
if (kwArgs.sendTransport) {
|
|
|
119 |
content["dojo.transport"] = "scriptsrc";
|
|
|
120 |
}
|
|
|
121 |
if (jsonpName) {
|
|
|
122 |
content[jsonpName] = "dojo.io.ScriptSrcTransport._state." + id + ".jsonpCall";
|
|
|
123 |
}
|
|
|
124 |
}
|
|
|
125 |
if (kwArgs.postContent) {
|
|
|
126 |
query = kwArgs.postContent;
|
|
|
127 |
} else {
|
|
|
128 |
if (content) {
|
|
|
129 |
query += ((query) ? "&" : "") + dojo.io.argsFromMap(content, kwArgs.encoding, jsonpName);
|
|
|
130 |
}
|
|
|
131 |
}
|
|
|
132 |
if (kwArgs["apiId"]) {
|
|
|
133 |
kwArgs["useRequestId"] = true;
|
|
|
134 |
}
|
|
|
135 |
var state = {"id":id, "idParam":"_dsrid=" + id, "url":url, "query":query, "kwArgs":kwArgs, "startTime":(new Date()).getTime(), "isFinishing":false};
|
|
|
136 |
if (!url) {
|
|
|
137 |
this._finish(state, "error", {status:this.DsrStatusCodes.Error, statusText:"url.none"});
|
|
|
138 |
return;
|
|
|
139 |
}
|
|
|
140 |
if (content && content[jsonpName]) {
|
|
|
141 |
state.jsonp = content[jsonpName];
|
|
|
142 |
state.jsonpCall = function (data) {
|
|
|
143 |
if (data["Error"] || data["error"]) {
|
|
|
144 |
if (dojo["json"] && dojo["json"]["serialize"]) {
|
|
|
145 |
dojo.debug(dojo.json.serialize(data));
|
|
|
146 |
}
|
|
|
147 |
dojo.io.ScriptSrcTransport._finish(this, "error", data);
|
|
|
148 |
} else {
|
|
|
149 |
dojo.io.ScriptSrcTransport._finish(this, "load", data);
|
|
|
150 |
}
|
|
|
151 |
};
|
|
|
152 |
}
|
|
|
153 |
if (kwArgs["useRequestId"] || kwArgs["checkString"] || state["jsonp"]) {
|
|
|
154 |
this._state[id] = state;
|
|
|
155 |
}
|
|
|
156 |
if (kwArgs["checkString"]) {
|
|
|
157 |
state.checkString = kwArgs["checkString"];
|
|
|
158 |
}
|
|
|
159 |
state.constantParams = (kwArgs["constantParams"] == null ? "" : kwArgs["constantParams"]);
|
|
|
160 |
if (kwArgs["preventCache"] || (this.preventCache == true && kwArgs["preventCache"] != false)) {
|
|
|
161 |
state.nocacheParam = "dojo.preventCache=" + new Date().valueOf();
|
|
|
162 |
} else {
|
|
|
163 |
state.nocacheParam = "";
|
|
|
164 |
}
|
|
|
165 |
var urlLength = state.url.length + state.query.length + state.constantParams.length + state.nocacheParam.length + this._extraPaddingLength;
|
|
|
166 |
if (kwArgs["useRequestId"]) {
|
|
|
167 |
urlLength += state.idParam.length;
|
|
|
168 |
}
|
|
|
169 |
if (!kwArgs["checkString"] && kwArgs["useRequestId"] && !state["jsonp"] && !kwArgs["forceSingleRequest"] && urlLength > this.maxUrlLength) {
|
|
|
170 |
if (url > this.maxUrlLength) {
|
|
|
171 |
this._finish(state, "error", {status:this.DsrStatusCodes.Error, statusText:"url.tooBig"});
|
|
|
172 |
return;
|
|
|
173 |
} else {
|
|
|
174 |
this._multiAttach(state, 1);
|
|
|
175 |
}
|
|
|
176 |
} else {
|
|
|
177 |
var queryParams = [state.constantParams, state.nocacheParam, state.query];
|
|
|
178 |
if (kwArgs["useRequestId"] && !state["jsonp"]) {
|
|
|
179 |
queryParams.unshift(state.idParam);
|
|
|
180 |
}
|
|
|
181 |
var finalUrl = this._buildUrl(state.url, queryParams);
|
|
|
182 |
state.finalUrl = finalUrl;
|
|
|
183 |
this._attach(state.id, finalUrl);
|
|
|
184 |
}
|
|
|
185 |
this.startWatchingInFlight();
|
|
|
186 |
};
|
|
|
187 |
this._counter = 1;
|
|
|
188 |
this._state = {};
|
|
|
189 |
this._extraPaddingLength = 16;
|
|
|
190 |
this._buildUrl = function (url, nameValueArray) {
|
|
|
191 |
var finalUrl = url;
|
|
|
192 |
var joiner = "?";
|
|
|
193 |
for (var i = 0; i < nameValueArray.length; i++) {
|
|
|
194 |
if (nameValueArray[i]) {
|
|
|
195 |
finalUrl += joiner + nameValueArray[i];
|
|
|
196 |
joiner = "&";
|
|
|
197 |
}
|
|
|
198 |
}
|
|
|
199 |
return finalUrl;
|
|
|
200 |
};
|
|
|
201 |
this._attach = function (id, url) {
|
|
|
202 |
var element = document.createElement("script");
|
|
|
203 |
element.type = "text/javascript";
|
|
|
204 |
element.src = url;
|
|
|
205 |
element.id = id;
|
|
|
206 |
element.className = "ScriptSrcTransport";
|
|
|
207 |
document.getElementsByTagName("head")[0].appendChild(element);
|
|
|
208 |
};
|
|
|
209 |
this._multiAttach = function (state, part) {
|
|
|
210 |
if (state.query == null) {
|
|
|
211 |
this._finish(state, "error", {status:this.DsrStatusCodes.Error, statusText:"query.null"});
|
|
|
212 |
return;
|
|
|
213 |
}
|
|
|
214 |
if (!state.constantParams) {
|
|
|
215 |
state.constantParams = "";
|
|
|
216 |
}
|
|
|
217 |
var queryMax = this.maxUrlLength - state.idParam.length - state.constantParams.length - state.url.length - state.nocacheParam.length - this._extraPaddingLength;
|
|
|
218 |
var isDone = state.query.length < queryMax;
|
|
|
219 |
var currentQuery;
|
|
|
220 |
if (isDone) {
|
|
|
221 |
currentQuery = state.query;
|
|
|
222 |
state.query = null;
|
|
|
223 |
} else {
|
|
|
224 |
var ampEnd = state.query.lastIndexOf("&", queryMax - 1);
|
|
|
225 |
var eqEnd = state.query.lastIndexOf("=", queryMax - 1);
|
|
|
226 |
if (ampEnd > eqEnd || eqEnd == queryMax - 1) {
|
|
|
227 |
currentQuery = state.query.substring(0, ampEnd);
|
|
|
228 |
state.query = state.query.substring(ampEnd + 1, state.query.length);
|
|
|
229 |
} else {
|
|
|
230 |
currentQuery = state.query.substring(0, queryMax);
|
|
|
231 |
var queryName = currentQuery.substring((ampEnd == -1 ? 0 : ampEnd + 1), eqEnd);
|
|
|
232 |
state.query = queryName + "=" + state.query.substring(queryMax, state.query.length);
|
|
|
233 |
}
|
|
|
234 |
}
|
|
|
235 |
var queryParams = [currentQuery, state.idParam, state.constantParams, state.nocacheParam];
|
|
|
236 |
if (!isDone) {
|
|
|
237 |
queryParams.push("_part=" + part);
|
|
|
238 |
}
|
|
|
239 |
var url = this._buildUrl(state.url, queryParams);
|
|
|
240 |
this._attach(state.id + "_" + part, url);
|
|
|
241 |
};
|
|
|
242 |
this._finish = function (state, callback, event) {
|
|
|
243 |
if (callback != "partOk" && !state.kwArgs[callback] && !state.kwArgs["handle"]) {
|
|
|
244 |
if (callback == "error") {
|
|
|
245 |
state.isDone = true;
|
|
|
246 |
throw event;
|
|
|
247 |
}
|
|
|
248 |
} else {
|
|
|
249 |
switch (callback) {
|
|
|
250 |
case "load":
|
|
|
251 |
var response = event ? event.response : null;
|
|
|
252 |
if (!response) {
|
|
|
253 |
response = event;
|
|
|
254 |
}
|
|
|
255 |
state.kwArgs[(typeof state.kwArgs.load == "function") ? "load" : "handle"]("load", response, event, state.kwArgs);
|
|
|
256 |
state.isDone = true;
|
|
|
257 |
break;
|
|
|
258 |
case "partOk":
|
|
|
259 |
var part = parseInt(event.response.part, 10) + 1;
|
|
|
260 |
if (event.response.constantParams) {
|
|
|
261 |
state.constantParams = event.response.constantParams;
|
|
|
262 |
}
|
|
|
263 |
this._multiAttach(state, part);
|
|
|
264 |
state.isDone = false;
|
|
|
265 |
break;
|
|
|
266 |
case "error":
|
|
|
267 |
state.kwArgs[(typeof state.kwArgs.error == "function") ? "error" : "handle"]("error", event.response, event, state.kwArgs);
|
|
|
268 |
state.isDone = true;
|
|
|
269 |
break;
|
|
|
270 |
default:
|
|
|
271 |
state.kwArgs[(typeof state.kwArgs[callback] == "function") ? callback : "handle"](callback, event, event, state.kwArgs);
|
|
|
272 |
state.isDone = true;
|
|
|
273 |
}
|
|
|
274 |
}
|
|
|
275 |
};
|
|
|
276 |
dojo.io.transports.addTransport("ScriptSrcTransport");
|
|
|
277 |
};
|
|
|
278 |
window.onscriptload = function (event) {
|
|
|
279 |
var state = null;
|
|
|
280 |
var transport = dojo.io.ScriptSrcTransport;
|
|
|
281 |
if (transport._state[event.id]) {
|
|
|
282 |
state = transport._state[event.id];
|
|
|
283 |
} else {
|
|
|
284 |
var tempState;
|
|
|
285 |
for (var param in transport._state) {
|
|
|
286 |
tempState = transport._state[param];
|
|
|
287 |
if (tempState.finalUrl && tempState.finalUrl == event.id) {
|
|
|
288 |
state = tempState;
|
|
|
289 |
break;
|
|
|
290 |
}
|
|
|
291 |
}
|
|
|
292 |
if (state == null) {
|
|
|
293 |
var scripts = document.getElementsByTagName("script");
|
|
|
294 |
for (var i = 0; scripts && i < scripts.length; i++) {
|
|
|
295 |
var scriptTag = scripts[i];
|
|
|
296 |
if (scriptTag.getAttribute("class") == "ScriptSrcTransport" && scriptTag.src == event.id) {
|
|
|
297 |
state = transport._state[scriptTag.id];
|
|
|
298 |
break;
|
|
|
299 |
}
|
|
|
300 |
}
|
|
|
301 |
}
|
|
|
302 |
if (state == null) {
|
|
|
303 |
throw "No matching state for onscriptload event.id: " + event.id;
|
|
|
304 |
}
|
|
|
305 |
}
|
|
|
306 |
var callbackName = "error";
|
|
|
307 |
switch (event.status) {
|
|
|
308 |
case dojo.io.ScriptSrcTransport.DsrStatusCodes.Continue:
|
|
|
309 |
callbackName = "partOk";
|
|
|
310 |
break;
|
|
|
311 |
case dojo.io.ScriptSrcTransport.DsrStatusCodes.Ok:
|
|
|
312 |
callbackName = "load";
|
|
|
313 |
break;
|
|
|
314 |
}
|
|
|
315 |
transport._finish(state, callbackName, event);
|
|
|
316 |
};
|
|
|
317 |
|