//-------------------------------------------------------------- // Copyright (C) 2006 Michael Schwarz (http://www.ajaxpro.info). // All rights reserved. //-------------------------------------------------------------- // core.js Object.extend(Function.prototype, { getArguments: function() { var args = []; for (var i = 0; i < this.arguments.length; i++) { args.push(this.arguments[i]); } return args; } }, false); var MS = { "Browser": {} }; Object.extend(MS.Browser, { isIE: navigator.userAgent.indexOf('MSIE') != -1, isFirefox: navigator.userAgent.indexOf('Firefox') != -1, isOpera: window.opera != null }, false); var AjaxPro = {}; AjaxPro.IFrameXmlHttp = function() { }; AjaxPro.IFrameXmlHttp.prototype = { onreadystatechange: null, headers: [], method: "POST", url: null, async: true, iframe: null, status: 0, readyState: 0, responseText: null, abort: function() { }, readystatechanged: function() { var doc = this.iframe.contentDocument || this.iframe.document; if (doc != null && doc.readyState == "complete" && doc.body != null && doc.body.res != null) { this.status = 200; this.statusText = "OK"; this.readyState = 4; this.responseText = doc.body.res; this.onreadystatechange(); return; } setTimeout(this.readystatechanged.bind(this), 10); }, open: function(method, url, async) { if (async == false) { alert("Synchronous call using IFrameXMLHttp is not supported."); return; } if (this.iframe == null) { var iframeID = "hans"; if (document.createElement && document.documentElement && (window.opera || navigator.userAgent.indexOf('MSIE 5.0') == -1)) { var ifr = document.createElement('iframe'); ifr.setAttribute('id', iframeID); ifr.style.visibility = 'hidden'; ifr.style.position = 'absolute'; ifr.style.width = ifr.style.height = ifr.borderWidth = '0px'; this.iframe = document.getElementsByTagName('body')[0].appendChild(ifr); } else if (document.body && document.body.insertAdjacentHTML) { document.body.insertAdjacentHTML('beforeEnd', ''); } if (window.frames && window.frames[iframeID]) { this.iframe = window.frames[iframeID]; } this.iframe.name = iframeID; this.iframe.document.open(); this.iframe.document.write("<" + "html><" + "body>"); this.iframe.document.close(); } this.method = method; this.url = url; this.async = async; }, setRequestHeader: function(name, value) { for (var i = 0; i < this.headers.length; i++) { if (this.headers[i].name == name) { this.headers[i].value = value; return; } } this.headers.push({ "name": name, "value": value }); }, getResponseHeader: function(name, value) { return null; }, addInput: function(doc, form, name, value) { var ele; var tag = "input"; if (value.indexOf("\n") >= 0) { tag = "textarea"; } if (doc.all) { ele = doc.createElement("<" + tag + " name=\"" + name + "\" />"); } else { ele = doc.createElement(tag); ele.setAttribute("name", name); } ele.setAttribute("value", value); form.appendChild(ele); ele = null; }, send: function(data) { if (this.iframe == null) { return; } var doc = this.iframe.contentDocument || this.iframe.document; var form = doc.createElement("form"); doc.body.appendChild(form); form.setAttribute("action", this.url); form.setAttribute("method", this.method); form.setAttribute("enctype", "application/x-www-form-urlencoded"); for (var i = 0; i < this.headers.length; i++) { switch (this.headers[i].name.toLowerCase()) { case "content-length": case "accept-encoding": case "content-type": break; default: this.addInput(doc, form, this.headers[i].name, this.headers[i].value); } } this.addInput(doc, form, "data", data); form.submit(); setTimeout(this.readystatechanged.bind(this), 0); } }; var progids = ["Msxml2.XMLHTTP.6.0", "Msxml2.XMLHTTP.3.0", "MSXML2.XMLHTTP", "Microsoft.XMLHTTP"]; var progid = null; if (typeof ActiveXObject != "undefined") { var ie7xmlhttp = false; if (typeof XMLHttpRequest == "object") { try { var o = new XMLHttpRequest(); ie7xmlhttp = true; } catch (e) { } } if (typeof XMLHttpRequest == "undefined" || !ie7xmlhttp) { XMLHttpRequest = function() { var xmlHttp = null; if (!AjaxPro.noActiveX) { if (progid != null) { return new ActiveXObject(progid); } for (var i = 0; i < progids.length && xmlHttp == null; i++) { try { xmlHttp = new ActiveXObject(progids[i]); progid = progids[i]; } catch (e) { } } } if (xmlHttp == null && MS.Browser.isIE) { return new AjaxPro.IFrameXmlHttp(); } return xmlHttp; }; } } Object.extend(AjaxPro, { noOperation: function() { }, onLoading: function() { }, onError: function() { }, onTimeout: function() { return true; }, onStateChanged: function() { }, cryptProvider: null, queue: null, token: "", version: "9.2.17.1", ID: "AjaxPro", noActiveX: false, timeoutPeriod: 15 * 1000, queue: null, noUtcTime: false, regExDate: function(str, p1, p2, offset, s) { str = str.substring(1).replace('"', ''); var date = str; if (str.substring(0, 7) == "\\\/Date(") { str = str.match(/Date\((.*?)\)/)[1]; date = "new Date(" + parseInt(str) + ")"; } else { // ISO Date 2007-12-31T23:59:59Z var matches = str.split(/[-,:,T,Z]/); matches[1] = (parseInt(matches[1], 0) - 1).toString(); date = "new Date(Date.UTC(" + matches.join(",") + "))"; } return date; }, parse: function(text) { // not yet possible as we still return new type() JSON // if (!(!(/[^,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]/.test( // text.replace(/"(\\.|[^"\\])*"/g, ''))) )) // throw new Error("Invalid characters in JSON parse string."); var regEx = /(\"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}.*?\")|(\"\\\/Date\(.*?\)\\\/")/g; text = text.replace(regEx, this.regExDate); return eval('(' + text + ')'); }, m: { '\b': '\\b', '\t': '\\t', '\n': '\\n', '\f': '\\f', '\r': '\\r', '"': '\\"', '\\': '\\\\' }, toJSON: function(o) { if (o == null) { return "null"; } var v = []; var i; var c = o.constructor; if (c == Number) { return isFinite(o) ? o.toString() : AjaxPro.toJSON(null); } else if (c == Boolean) { return o.toString(); } else if (c == String) { if (/["\\\x00-\x1f]/.test(o)) { o = o.replace(/([\x00-\x1f\\"])/g, function(a, b) { var c = AjaxPro.m[b]; if (c) { return c; } c = b.charCodeAt(); return '\\u00' + Math.floor(c / 16).toString(16) + (c % 16).toString(16); }); } return '"' + o + '"'; } else if (c == Array) { for (i = 0; i < o.length; i++) { v.push(AjaxPro.toJSON(o[i])); } return "[" + v.join(",") + "]"; } else if (c == Date) { // var d = {}; // d.__type = "System.DateTime"; // if(AjaxPro.noUtcTime == true) { // d.Year = o.getFullYear(); // d.Month = o.getMonth() +1; // d.Day = o.getDate(); // d.Hour = o.getHours(); // d.Minute = o.getMinutes(); // d.Second = o.getSeconds(); // d.Millisecond = o.getMilliseconds(); // } else { // d.Year = o.getUTCFullYear(); // d.Month = o.getUTCMonth() +1; // d.Day = o.getUTCDate(); // d.Hour = o.getUTCHours(); // d.Minute = o.getUTCMinutes(); // d.Second = o.getUTCSeconds(); // d.Millisecond = o.getUTCMilliseconds(); // } return AjaxPro.toJSON("/Date(" + new Date(Date.UTC(o.getUTCFullYear(), o.getUTCMonth(), o.getUTCDate(), o.getUTCHours(), o.getUTCMinutes(), o.getUTCSeconds(), o.getUTCMilliseconds())).getTime() + ")/"); } if (typeof o.toJSON == "function") { return o.toJSON(); } if (typeof o == "object") { for (var attr in o) { if (typeof o[attr] != "function") { v.push('"' + attr + '":' + AjaxPro.toJSON(o[attr])); } } if (v.length > 0) { return "{" + v.join(",") + "}"; } return "{}"; } return o.toString(); }, dispose: function() { if (AjaxPro.queue != null) { AjaxPro.queue.dispose(); } } }, false); addEvent(window, "unload", AjaxPro.dispose); AjaxPro.Request = function(url) { this.url = url; this.xmlHttp = null; }; AjaxPro.Request.prototype = { url: null, callback: null, onLoading: null, onError: null, onTimeout: null, onStateChanged: null, args: null, context: null, isRunning: false, abort: function() { if (this.timeoutTimer != null) { clearTimeout(this.timeoutTimer); } if (this.xmlHttp) { this.xmlHttp.onreadystatechange = AjaxPro.noOperation; this.xmlHttp.abort(); } if (this.isRunning) { this.isRunning = false; this.onLoading(false); } }, dispose: function() { this.abort(); }, getEmptyRes: function() { return { error: null, value: null, request: { method: this.method, args: this.args }, context: this.context, duration: this.duration }; }, endRequest: function(res) { this.abort(); if (res.error != null) { this.onError(res.error, this); } if (typeof this.callback == "function") { this.callback(res, this); } }, mozerror: function() { if (this.timeoutTimer != null) { clearTimeout(this.timeoutTimer); } var res = this.getEmptyRes(); res.error = { Message: "Unknown", Type: "ConnectFailure", Status: 0 }; this.endRequest(res); }, doStateChange: function() { this.onStateChanged(this.xmlHttp.readyState, this); if (this.xmlHttp.readyState != 4 || !this.isRunning) { return; } this.duration = new Date().getTime() - this.__start; if (this.timeoutTimer != null) { clearTimeout(this.timeoutTimer); } var res = this.getEmptyRes(); if (this.xmlHttp.status == 200 && this.xmlHttp.statusText == "OK") { res = this.createResponse(res); } else { res = this.createResponse(res, true); res.error = { Message: this.xmlHttp.statusText, Type: "ConnectFailure", Status: this.xmlHttp.status }; } this.endRequest(res); }, createResponse: function(r, noContent) { if (!noContent) { if (typeof (this.xmlHttp.responseText) == "unknown") { r.error = { Message: "XmlHttpRequest error reading property responseText.", Type: "XmlHttpRequestException" }; return r; } var responseText = "" + this.xmlHttp.responseText; if (AjaxPro.cryptProvider != null && typeof AjaxPro.cryptProvider.decrypt == "function") { responseText = AjaxPro.cryptProvider.decrypt(responseText); } if (this.xmlHttp.getResponseHeader("Content-Type") == "text/xml") { r.value = this.xmlHttp.responseXML; } else { if (responseText != null && responseText.trim().length > 0) { r.json = responseText; var v = null; v = AjaxPro.parse(responseText); if (v != null) { if (typeof v.value != "undefined") r.value = v.value; else if (typeof v.error != "undefined") r.error = v.error; } } } } /* if(this.xmlHttp.getResponseHeader("X-" + AjaxPro.ID + "-Cache") == "server") { r.isCached = true; } */ return r; }, timeout: function() { this.duration = new Date().getTime() - this.__start; try { ////Shove ��ԭ�������� try var r = this.onTimeout(this.duration, this); if (typeof r == "undefined" || r != false) { this.abort(); } else { this.timeoutTimer = setTimeout(this.timeout.bind(this), AjaxPro.timeoutPeriod); } } catch (e) { } }, invoke: function(method, args, callback, context) { this.__start = new Date().getTime(); // if(this.xmlHttp == null) { this.xmlHttp = new XMLHttpRequest(); // } this.isRunning = true; this.method = method; this.args = args; this.callback = callback; this.context = context; var async = typeof (callback) == "function" && callback != AjaxPro.noOperation; if (async) { if (MS.Browser.isIE) { this.xmlHttp.onreadystatechange = this.doStateChange.bind(this); } else { this.xmlHttp.onload = this.doStateChange.bind(this); this.xmlHttp.onerror = this.mozerror.bind(this); } this.onLoading(true); } var json = AjaxPro.toJSON(args) + ""; if (AjaxPro.cryptProvider != null && typeof AjaxPro.cryptProvider.encrypt == "function") { json = AjaxPro.cryptProvider.encrypt(json); } this.xmlHttp.open("POST", this.url, async); this.xmlHttp.setRequestHeader("Content-Type", "text/plain; charset=utf-8"); this.xmlHttp.setRequestHeader("X-" + AjaxPro.ID + "-Method", method); if (AjaxPro.token != null && AjaxPro.token.length > 0) { this.xmlHttp.setRequestHeader("X-" + AjaxPro.ID + "-Token", AjaxPro.token); } /* if(!MS.Browser.isIE) { this.xmlHttp.setRequestHeader("Connection", "close"); } */ this.timeoutTimer = setTimeout(this.timeout.bind(this), AjaxPro.timeoutPeriod); try { this.xmlHttp.send(json); } catch (e) { } // IE offline exception if (!async) { return this.createResponse({ error: null, value: null }); } return true; } }; AjaxPro.RequestQueue = function(conc) { this.queue = []; this.requests = []; this.timer = null; if (isNaN(conc)) { conc = 2; } for (var i = 0; i < conc; i++) { // max 2 http connections this.requests[i] = new AjaxPro.Request(); this.requests[i].callback = function(res) { var r = res.context; res.context = r[3][1]; r[3][0](res, this); }; this.requests[i].callbackHandle = this.requests[i].callback.bind(this.requests[i]); } this.processHandle = this.process.bind(this); }; AjaxPro.RequestQueue.prototype = { process: function() { this.timer = null; if (this.queue.length == 0) { return; } for (var i = 0; i < this.requests.length && this.queue.length > 0; i++) { if (this.requests[i].isRunning == false) { var r = this.queue.shift(); this.requests[i].url = r[0]; this.requests[i].onLoading = r[3].length > 2 && r[3][2] != null && typeof r[3][2] == "function" ? r[3][2] : AjaxPro.onLoading; this.requests[i].onError = r[3].length > 3 && r[3][3] != null && typeof r[3][3] == "function" ? r[3][3] : AjaxPro.onError; this.requests[i].onTimeout = r[3].length > 4 && r[3][4] != null && typeof r[3][4] == "function" ? r[3][4] : AjaxPro.onTimeout; this.requests[i].onStateChanged = r[3].length > 5 && r[3][5] != null && typeof r[3][5] == "function" ? r[3][5] : AjaxPro.onStateChanged; this.requests[i].invoke(r[1], r[2], this.requests[i].callbackHandle, r); r = null; } } if (this.queue.length > 0 && this.timer == null) { this.timer = setTimeout(this.processHandle, 0); } }, add: function(url, method, args, e) { this.queue.push([url, method, args, e]); if (this.timer == null) { this.timer = setTimeout(this.processHandle, 0); } // this.process(); }, abort: function() { this.queue.length = 0; if (this.timer != null) { clearTimeout(this.timer); } this.timer = null; for (var i = 0; i < this.requests.length; i++) { if (this.requests[i].isRunning == true) { this.requests[i].abort(); } } }, dispose: function() { for (var i = 0; i < this.requests.length; i++) { var r = this.requests[i]; r.dispose(); } this.requests.clear(); } }; AjaxPro.queue = new AjaxPro.RequestQueue(2); // 2 http connections AjaxPro.AjaxClass = function(url) { this.url = url; }; AjaxPro.AjaxClass.prototype = { invoke: function(method, args, e) { if (e != null) { if (e.length != 6) { for (; e.length < 6; ) { e.push(null); } } if (e[0] != null && typeof (e[0]) == "function") { return AjaxPro.queue.add(this.url, method, args, e); } } var r = new AjaxPro.Request(); r.url = this.url; return r.invoke(method, args); } };