/* The XMLHTTPRequest object needs to be encapsulated inside a class (object) in order to avoid conflicting problems in FireFox */ var oAJAXHandler = null; var oAJAXHandlerNewMail = null; var oAJAXHandlerFreeBusy = null; var oAJAXHandlerCheckFreeBusy = null; var oAJAXHandlerReminders = null; var oAJAXHandlerReportSpam = null; var oAJAXHandlerMarkRead = null; var oAJAXHandlerGetMessage = null; var oAJAXHandlerGetUsage = null; var oAJAXHandlerListFolders = null; var oAJAXHandlerListPublicFolders = null; var oAJAXHandlerListFilesFolders = null; var oAJAXHandlerListMessages = null; var oAJAXHandlerSearch = null; var oAJAXHandlerCalcQuota = null; var MAX_URL_LENGTH = 2083; function readCookie(name) { var nameEQ = name + "="; var ca = document.cookie.split(';'); for (var i = 0; i < ca.length; i++) { var c = ca[i]; while (c.charAt(0) == ' ') c = c.substring(1, c.length); if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length); } return null; } /* Constructor */ function AJAXHandler() { // get a new XMLHTTPRequest and store it in an instance var. this._request = this._getXMLHTTPRequest(); this._browserType = this._getBrowserType(); this._busy = false; this._requestpage = ''; return true; } // to hold an instance of the XMLHTTPRequest object AJAXHandler.prototype._request = null; AJAXHandler.prototype._getXMLHTTPRequest = function() { if (typeof XMLHttpRequest != 'undefined') return new XMLHttpRequest(); if (window.ActiveXObject) { var Xs = ['Msxml2.XMLHTTP.6.0', 'Msxml2.XMLHTTP.3.0', 'Microsoft.XMLHTTP']; for (var i = 0; i < Xs.length; i++) { try { return new ActiveXObject(Xs[i]); } catch (e) { } } } return; }; AJAXHandler.prototype._onData = function(url, callback, sFrameName) { var bResult = true; if (this._request.readyState == 4) // AJAX request completed { if (this._request.status == 200) // server page processed successfully { bResult = this._ValidateResponse(url, callback, sFrameName); } else if (this._request.status == 404) // server page not found (File Not Found) { alert(t_("[ME_TXT-ServerNotReachable]")); this._request.abort(); bResult = false; } else // some other error { if (gBrowserType != BROWSER_TYPE_FF && (this.FailSilently == undefined || !this.FailSilently)) { // firefox is erroneously producing an extra call to this function on a POST request // immediately after the request, before the response is ready, resulting in // this alert at the user (the request is still actually made to the server, // processed, and the response later received and processed correctly, so this // alert is the only incorrect behaviour). Working around the bug by not alerting in FF. alert(t_("[ME_TXT-HTTPresponsestatusnotOK]")); } this._request.abort(); bResult = false; } this._busy = false; } else // AJAX request not completed for some reason { bResult = false; } return bResult; }; AJAXHandler.prototype._getRootURL = function () { var rootURL = window.location; // make sure it is a string........... rootURL += 'stringitup'; // N.B. The '*?' in the regular expression below // is there to provide a lazy star match; so that // it will stop after the first instance of "/Mondo", // which is all we want (in case the location string // also has other "/Mondo" instances trailing. // http://www.regular-expressions.info/reference.html // http://www.regular-expressions.info/refflavors.html rootURL = rootURL.match(/^.*?\/Mondo/i); return rootURL; }; AJAXHandler.prototype._getBrowserType = function () { return GetBrowserType(); }; function getHandlerFromMethod(sCommand, sData) { if (oAJAXHandler == null) { oAJAXHandler = new AJAXHandler(); } if (oAJAXHandlerNewMail == null) {oAJAXHandlerNewMail = new AJAXHandler();oAJAXHandlerNewMail.FailSilently = true;} if (oAJAXHandlerFreeBusy == null) {oAJAXHandlerFreeBusy = new AJAXHandler();} if (oAJAXHandlerCheckFreeBusy == null) {oAJAXHandlerCheckFreeBusy = new AJAXHandler();} if (oAJAXHandlerReminders == null) {oAJAXHandlerReminders = new AJAXHandler();} if (oAJAXHandlerReportSpam == null) {oAJAXHandlerReportSpam = new AJAXHandler();} if (oAJAXHandlerMarkRead == null) {oAJAXHandlerMarkRead = new AJAXHandler();} if (oAJAXHandlerGetMessage == null) {oAJAXHandlerGetMessage = new AJAXHandler();} if (oAJAXHandlerGetUsage == null) { oAJAXHandlerGetUsage = new AJAXHandler(); } if (oAJAXHandlerListFolders == null) { oAJAXHandlerListFolders = new AJAXHandler(); } if (oAJAXHandlerListPublicFolders == null) { oAJAXHandlerListPublicFolders = new AJAXHandler(); } if (oAJAXHandlerListFilesFolders == null) { oAJAXHandlerListFilesFolders = new AJAXHandler(); } if (oAJAXHandlerListMessages == null) { oAJAXHandlerListMessages = new AJAXHandler(); } if (oAJAXHandlerSearch == null) { oAJAXHandlerSearch = new AJAXHandler(); } if (oAJAXHandlerCalcQuota == null) { oAJAXHandlerCalcQuota = new AJAXHandler(); } var bAsyncServerPage = false; var handler = null; if (sData && (sData.indexOf('RID=') !== -1)) { handler = new AJAXHandler(); bAsyncServerPage = true; } else { switch (sCommand) { case 'CHECK-NEW-MAIL': handler = oAJAXHandlerNewMail; break; case 'GET-FREEBUSY': handler = oAJAXHandlerFreeBusy; break; case 'CHECK-FREEBUSY': handler = oAJAXHandlerCheckFreeBusy; break; case 'CHECK-APPOINTMENT-REMINDER': handler = oAJAXHandlerReminders; bAsyncServerPage = true; break; case 'REPORT-SPAM': handler = oAJAXHandlerReportSpam; break; case 'CALCULATE-QUOTA': handler = oAJAXHandlerCalcQuota; bAsyncServerPage = true; break; case 'GET-MAILBOX-USAGE': handler = oAJAXHandlerGetUsage; bAsyncServerPage = true; break; case 'LIST-MESSAGES': handler = oAJAXHandlerListMessages; bAsyncServerPage = true; break; case 'LIST-FILES-FOLDERS': handler = oAJAXHandlerListFilesFolders; bAsyncServerPage = true; break; case 'LIST-FOLDERS': if (sData.match(/\\public/i)) { handler = oAJAXHandlerListPublicFolders; } else { handler = oAJAXHandlerListFolders; } bAsyncServerPage = true; break; case 'SET-PROPERTY': if (sData.match('READ')) { handler = oAJAXHandlerMarkRead; } else { handler = oAJAXHandler; } break; case 'GET-MESSAGE': handler = oAJAXHandlerGetMessage; break; case 'SEARCH-MESSAGES': handler = oAJAXHandlerSearch; break; default: handler = oAJAXHandler; break; } } if (bAsyncServerPage) { handler._requestpage = "async"; } else { //console.log('Performance: Synchronous Call (' + sCommand + ')'); } return handler; } function LIBAjax_ServerRequest(sCommand, sData, bUseCallback, sFrameName) { var Handler = getHandlerFromMethod(sCommand, sData); //if (Handler._requestpage == 'async') bUseCallback = true; return Handler._AJAXRequest(sCommand, sData, bUseCallback, sFrameName); } function LIBAjax_ServerPost(sCommand, sData, bUseCallback, sFrameName) { var Handler = getHandlerFromMethod(sCommand, sData); //if it has a callback, it has to be async and vice versa if (Handler._requestpage == 'async') bUseCallback = true; return Handler._AJAXPost(sCommand, sData, bUseCallback, sFrameName); } function LIBAjax_InlineRequest(sCommand, sData, oResult) { //issues an inline request so we can get the actual XML result where we need it without horrible callback stuff //oResult contains the actual result values from the ajax request var bResult = false; var Handler = getHandlerFromMethod(sCommand, sData); //define callback to get the result and insert it into the object var callback = function (_responseXML, _sFrameName) { oResult.responseXML = _responseXML; } //bUseCallBack is poorly named - because it actually means whether to do synchronous ajax or not bResult = Handler._AJAXRequest(sCommand, sData, false, '', callback); return bResult; } AJAXHandler.prototype.abort = function() { if (this._busy) { // http://www.quirksmode.org/blog/archives/2005/09/xmlhttp_notes_a_1.html this._request.onreadystatechange = function() { } this._request.abort(); this._request = this._getXMLHTTPRequest(); } } // Issues the AJAX GET call AJAXHandler.prototype._AJAXRequest = function (sCommand, sData, bUseCallback, sFrameName, callback) { // set the var so we can scope the callback var _this = this; this.abort(); this._busy = true; if (!callback) { callback = function (_responseXML, _sFrameName) { var bResult = true; try { bResult = ProcessXMLResult(_responseXML, _sFrameName); } catch (ex) { //console.log("_AJAXRequest error: " + ex.message); bResult = false; }; return bResult; }; } // callback will be an anonymous function that calls back into our class // this allows the call back in which we handle the response (_onData()) // to have the correct scope. var url = this._getRootURL(); url += '/Servlet/' + this._requestpage + 'request.aspx?Cmd=' + sCommand; url += '&Browser=' + this._browserType; url += '&' + sData; url += '&DT=' + (new Date()).getTime(); if (url.toLowerCase().indexOf("&me_validationtoken") === -1) { if (getTopAppWindow().g_opt['ME_VALIDATIONTOKEN']) url += '&ME_VALIDATIONTOKEN=' + getTopAppWindow().g_opt['ME_VALIDATIONTOKEN']; } var bResult = true; //this._request.open("GET", url, bUseCallback); if (url.length <= MAX_URL_LENGTH) { this._request.open("GET", url, bUseCallback); //set cookie to prevent XSS with ajax this._request.setRequestHeader('MailEnable-SessionId', readCookie('MailEnable-SessionId')); if (bUseCallback) { // Asynchronous request this._request.onreadystatechange = function () { _this._onData(url, callback, sFrameName); }; this._request.send(null); } else { // Synchronous request //this._request.onreadystatechange = null; this._request.onreadystatechange = function () { }; // N.B. We have to do this otherwise callback will get called twice! // i.e. on 'onreadystatechange' and '_ValidateResponse', try { this._request.send(null); this._busy = false; bResult = this._ValidateResponse(url, callback, sFrameName); } catch (ex) { //alert("_AJAXRequest error: " + ex.message); bResult = false; }; } return bResult; } else { return this._AJAXPost(sCommand, sData, bUseCallback, sFrameName, callback); } }; AJAXHandler.prototype._ValidateResponse = function(url, callback, sFrameName) { var ValidResponse = true; try { // we want to make sure we have a formatted response from the server // we did not deliberately make it this ugly - we needed to do so for cross browser var x = this._request.responseXML.getElementsByTagName('BASEELEMENT')[0]; ValidResponse = (x != null); } catch (ex) { ValidResponse = false; } if (ValidResponse) { return callback(this._request.responseXML, sFrameName); } else { window.open(url); } return ValidResponse; } // Issues the AJAX POST call AJAXHandler.prototype._AJAXPost = function (sCommand, sData, bUseCallback, sFrameName, callback) { var contentType = "application/x-www-form-urlencoded; charset=UTF-8"; sData = "Cmd=" + sCommand + "&" + sData; if (sData.toLowerCase().indexOf("&me_validationtoken") === -1) { if (getTopAppWindow().g_opt['ME_VALIDATIONTOKEN']) sData += '&ME_VALIDATIONTOKEN=' + getTopAppWindow().g_opt['ME_VALIDATIONTOKEN']; } this.abort(); if (!callback) { callback = function (_responseXML, _sFrameName) { var bResult = true; try { bResult = ProcessXMLResult(_responseXML, _sFrameName); } catch (ex) { //alert("_AJAXPost error: " + ex.message); bResult = false; }; return bResult; }; } this._busy = true; var bResult = true; if (this._request) { // set the var so we can scope the callback var _this = this; var url = this._getRootURL() + '/Servlet/request.aspx'; this._request.open("POST", url, bUseCallback); this._request.setRequestHeader("Content-Type", contentType); //set cookie to prevent XSS with ajax this._request.setRequestHeader('MailEnable-SessionId', readCookie('MailEnable-SessionId')); if (bUseCallback) { this._request.onreadystatechange = function () { _this._onData(url, callback, sFrameName); }; this._request.send(sData); } else { this._request.send(sData); this._busy = false; bResult = this._ValidateResponse(url, callback, sFrameName); } } else { bResult = false; } return bResult; } function Ajax_LoadPage(oTarget, sURL) { var req = null; oTarget.innerHTML = "Started..."; if (window.XMLHttpRequest) { req = new XMLHttpRequest(); if (req.overrideMimeType) { req.overrideMimeType('text/xml'); } } else if (window.ActiveXObject) { try { req = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { try { req = new ActiveXObject("Microsoft.XMLHTTP"); } catch (e) { } } } req.onreadystatechange = function() { oTarget.innerHTML = "Please wait..."; if (req.readyState == 4) { if (req.status == 200) { oTarget.innerHTML = req.responseText; } else { oTarget.innerHTML = "Error: returned status code " + req.status + " " + req.statusText; } } }; req.open("GET", sURL, true); req.send(null); }