| /* |
| Copyright (c) 2004-2006, The Dojo Foundation |
| All Rights Reserved. |
| |
| Licensed under the Academic Free License version 2.1 or above OR the |
| modified BSD license. For more information on Dojo licensing, see: |
| |
| http://dojotoolkit.org/community/licensing.shtml |
| */ |
| |
| |
| |
| dojo.provide("dojo.io.ScriptSrcIO"); |
| dojo.require("dojo.io.BrowserIO"); |
| dojo.require("dojo.undo.browser"); |
| dojo.io.ScriptSrcTransport = new function () { |
| this.preventCache = false; |
| this.maxUrlLength = 1000; |
| this.inFlightTimer = null; |
| this.DsrStatusCodes = {Continue:100, Ok:200, Error:500}; |
| this.startWatchingInFlight = function () { |
| if (!this.inFlightTimer) { |
| this.inFlightTimer = setInterval("dojo.io.ScriptSrcTransport.watchInFlight();", 100); |
| } |
| }; |
| this.watchInFlight = function () { |
| var totalCount = 0; |
| var doneCount = 0; |
| for (var param in this._state) { |
| totalCount++; |
| var currentState = this._state[param]; |
| if (currentState.isDone) { |
| doneCount++; |
| delete this._state[param]; |
| } else { |
| if (!currentState.isFinishing) { |
| var listener = currentState.kwArgs; |
| try { |
| if (currentState.checkString && eval("typeof(" + currentState.checkString + ") != 'undefined'")) { |
| currentState.isFinishing = true; |
| this._finish(currentState, "load"); |
| doneCount++; |
| delete this._state[param]; |
| } else { |
| if (listener.timeoutSeconds && listener.timeout) { |
| if (currentState.startTime + (listener.timeoutSeconds * 1000) < (new Date()).getTime()) { |
| currentState.isFinishing = true; |
| this._finish(currentState, "timeout"); |
| doneCount++; |
| delete this._state[param]; |
| } |
| } else { |
| if (!listener.timeoutSeconds) { |
| doneCount++; |
| } |
| } |
| } |
| } |
| catch (e) { |
| currentState.isFinishing = true; |
| this._finish(currentState, "error", {status:this.DsrStatusCodes.Error, response:e}); |
| } |
| } |
| } |
| } |
| if (doneCount >= totalCount) { |
| clearInterval(this.inFlightTimer); |
| this.inFlightTimer = null; |
| } |
| }; |
| this.canHandle = function (kwArgs) { |
| 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"]; |
| }; |
| this.removeScripts = function () { |
| var scripts = document.getElementsByTagName("script"); |
| for (var i = 0; scripts && i < scripts.length; i++) { |
| var scriptTag = scripts[i]; |
| if (scriptTag.className == "ScriptSrcTransport") { |
| var parent = scriptTag.parentNode; |
| parent.removeChild(scriptTag); |
| i--; |
| } |
| } |
| }; |
| this.bind = function (kwArgs) { |
| var url = kwArgs.url; |
| var query = ""; |
| if (kwArgs["formNode"]) { |
| var ta = kwArgs.formNode.getAttribute("action"); |
| if ((ta) && (!kwArgs["url"])) { |
| url = ta; |
| } |
| var tp = kwArgs.formNode.getAttribute("method"); |
| if ((tp) && (!kwArgs["method"])) { |
| kwArgs.method = tp; |
| } |
| query += dojo.io.encodeForm(kwArgs.formNode, kwArgs.encoding, kwArgs["formFilter"]); |
| } |
| if (url.indexOf("#") > -1) { |
| dojo.debug("Warning: dojo.io.bind: stripping hash values from url:", url); |
| url = url.split("#")[0]; |
| } |
| var urlParts = url.split("?"); |
| if (urlParts && urlParts.length == 2) { |
| url = urlParts[0]; |
| query += (query ? "&" : "") + urlParts[1]; |
| } |
| if (kwArgs["backButton"] || kwArgs["back"] || kwArgs["changeUrl"]) { |
| dojo.undo.browser.addToHistory(kwArgs); |
| } |
| var id = kwArgs["apiId"] ? kwArgs["apiId"] : "id" + this._counter++; |
| var content = kwArgs["content"]; |
| var jsonpName = kwArgs.jsonParamName; |
| if (kwArgs.sendTransport || jsonpName) { |
| if (!content) { |
| content = {}; |
| } |
| if (kwArgs.sendTransport) { |
| content["dojo.transport"] = "scriptsrc"; |
| } |
| if (jsonpName) { |
| content[jsonpName] = "dojo.io.ScriptSrcTransport._state." + id + ".jsonpCall"; |
| } |
| } |
| if (kwArgs.postContent) { |
| query = kwArgs.postContent; |
| } else { |
| if (content) { |
| query += ((query) ? "&" : "") + dojo.io.argsFromMap(content, kwArgs.encoding, jsonpName); |
| } |
| } |
| if (kwArgs["apiId"]) { |
| kwArgs["useRequestId"] = true; |
| } |
| var state = {"id":id, "idParam":"_dsrid=" + id, "url":url, "query":query, "kwArgs":kwArgs, "startTime":(new Date()).getTime(), "isFinishing":false}; |
| if (!url) { |
| this._finish(state, "error", {status:this.DsrStatusCodes.Error, statusText:"url.none"}); |
| return; |
| } |
| if (content && content[jsonpName]) { |
| state.jsonp = content[jsonpName]; |
| state.jsonpCall = function (data) { |
| if (data["Error"] || data["error"]) { |
| if (dojo["json"] && dojo["json"]["serialize"]) { |
| dojo.debug(dojo.json.serialize(data)); |
| } |
| dojo.io.ScriptSrcTransport._finish(this, "error", data); |
| } else { |
| dojo.io.ScriptSrcTransport._finish(this, "load", data); |
| } |
| }; |
| } |
| if (kwArgs["useRequestId"] || kwArgs["checkString"] || state["jsonp"]) { |
| this._state[id] = state; |
| } |
| if (kwArgs["checkString"]) { |
| state.checkString = kwArgs["checkString"]; |
| } |
| state.constantParams = (kwArgs["constantParams"] == null ? "" : kwArgs["constantParams"]); |
| if (kwArgs["preventCache"] || (this.preventCache == true && kwArgs["preventCache"] != false)) { |
| state.nocacheParam = "dojo.preventCache=" + new Date().valueOf(); |
| } else { |
| state.nocacheParam = ""; |
| } |
| var urlLength = state.url.length + state.query.length + state.constantParams.length + state.nocacheParam.length + this._extraPaddingLength; |
| if (kwArgs["useRequestId"]) { |
| urlLength += state.idParam.length; |
| } |
| if (!kwArgs["checkString"] && kwArgs["useRequestId"] && !state["jsonp"] && !kwArgs["forceSingleRequest"] && urlLength > this.maxUrlLength) { |
| if (url > this.maxUrlLength) { |
| this._finish(state, "error", {status:this.DsrStatusCodes.Error, statusText:"url.tooBig"}); |
| return; |
| } else { |
| this._multiAttach(state, 1); |
| } |
| } else { |
| var queryParams = [state.constantParams, state.nocacheParam, state.query]; |
| if (kwArgs["useRequestId"] && !state["jsonp"]) { |
| queryParams.unshift(state.idParam); |
| } |
| var finalUrl = this._buildUrl(state.url, queryParams); |
| state.finalUrl = finalUrl; |
| this._attach(state.id, finalUrl); |
| } |
| this.startWatchingInFlight(); |
| }; |
| this._counter = 1; |
| this._state = {}; |
| this._extraPaddingLength = 16; |
| this._buildUrl = function (url, nameValueArray) { |
| var finalUrl = url; |
| var joiner = "?"; |
| for (var i = 0; i < nameValueArray.length; i++) { |
| if (nameValueArray[i]) { |
| finalUrl += joiner + nameValueArray[i]; |
| joiner = "&"; |
| } |
| } |
| return finalUrl; |
| }; |
| this._attach = function (id, url) { |
| var element = document.createElement("script"); |
| element.type = "text/javascript"; |
| element.src = url; |
| element.id = id; |
| element.className = "ScriptSrcTransport"; |
| document.getElementsByTagName("head")[0].appendChild(element); |
| }; |
| this._multiAttach = function (state, part) { |
| if (state.query == null) { |
| this._finish(state, "error", {status:this.DsrStatusCodes.Error, statusText:"query.null"}); |
| return; |
| } |
| if (!state.constantParams) { |
| state.constantParams = ""; |
| } |
| var queryMax = this.maxUrlLength - state.idParam.length - state.constantParams.length - state.url.length - state.nocacheParam.length - this._extraPaddingLength; |
| var isDone = state.query.length < queryMax; |
| var currentQuery; |
| if (isDone) { |
| currentQuery = state.query; |
| state.query = null; |
| } else { |
| var ampEnd = state.query.lastIndexOf("&", queryMax - 1); |
| var eqEnd = state.query.lastIndexOf("=", queryMax - 1); |
| if (ampEnd > eqEnd || eqEnd == queryMax - 1) { |
| currentQuery = state.query.substring(0, ampEnd); |
| state.query = state.query.substring(ampEnd + 1, state.query.length); |
| } else { |
| currentQuery = state.query.substring(0, queryMax); |
| var queryName = currentQuery.substring((ampEnd == -1 ? 0 : ampEnd + 1), eqEnd); |
| state.query = queryName + "=" + state.query.substring(queryMax, state.query.length); |
| } |
| } |
| var queryParams = [currentQuery, state.idParam, state.constantParams, state.nocacheParam]; |
| if (!isDone) { |
| queryParams.push("_part=" + part); |
| } |
| var url = this._buildUrl(state.url, queryParams); |
| this._attach(state.id + "_" + part, url); |
| }; |
| this._finish = function (state, callback, event) { |
| if (callback != "partOk" && !state.kwArgs[callback] && !state.kwArgs["handle"]) { |
| if (callback == "error") { |
| state.isDone = true; |
| throw event; |
| } |
| } else { |
| switch (callback) { |
| case "load": |
| var response = event ? event.response : null; |
| if (!response) { |
| response = event; |
| } |
| state.kwArgs[(typeof state.kwArgs.load == "function") ? "load" : "handle"]("load", response, event, state.kwArgs); |
| state.isDone = true; |
| break; |
| case "partOk": |
| var part = parseInt(event.response.part, 10) + 1; |
| if (event.response.constantParams) { |
| state.constantParams = event.response.constantParams; |
| } |
| this._multiAttach(state, part); |
| state.isDone = false; |
| break; |
| case "error": |
| state.kwArgs[(typeof state.kwArgs.error == "function") ? "error" : "handle"]("error", event.response, event, state.kwArgs); |
| state.isDone = true; |
| break; |
| default: |
| state.kwArgs[(typeof state.kwArgs[callback] == "function") ? callback : "handle"](callback, event, event, state.kwArgs); |
| state.isDone = true; |
| } |
| } |
| }; |
| dojo.io.transports.addTransport("ScriptSrcTransport"); |
| }; |
| window.onscriptload = function (event) { |
| var state = null; |
| var transport = dojo.io.ScriptSrcTransport; |
| if (transport._state[event.id]) { |
| state = transport._state[event.id]; |
| } else { |
| var tempState; |
| for (var param in transport._state) { |
| tempState = transport._state[param]; |
| if (tempState.finalUrl && tempState.finalUrl == event.id) { |
| state = tempState; |
| break; |
| } |
| } |
| if (state == null) { |
| var scripts = document.getElementsByTagName("script"); |
| for (var i = 0; scripts && i < scripts.length; i++) { |
| var scriptTag = scripts[i]; |
| if (scriptTag.getAttribute("class") == "ScriptSrcTransport" && scriptTag.src == event.id) { |
| state = transport._state[scriptTag.id]; |
| break; |
| } |
| } |
| } |
| if (state == null) { |
| throw "No matching state for onscriptload event.id: " + event.id; |
| } |
| } |
| var callbackName = "error"; |
| switch (event.status) { |
| case dojo.io.ScriptSrcTransport.DsrStatusCodes.Continue: |
| callbackName = "partOk"; |
| break; |
| case dojo.io.ScriptSrcTransport.DsrStatusCodes.Ok: |
| callbackName = "load"; |
| break; |
| } |
| transport._finish(state, callbackName, event); |
| }; |
| |