+
+/*
+********************************************************************************
+** AJAX HELPER CLASS ***********************************************************
+********************************************************************************
+*/
+var pzHttpRequest = function (url, errorHandler, cookieDomain) {
+ this.maxUrlLength = 2048;
+ this.request = null;
+ this.url = url;
+ this.errorHandler = errorHandler || null;
+ this.async = true;
+ this.requestHeaders = {};
+ this.isXDR = false;
+ this.domainRegex = /https?:\/\/([^:/]+).*/;
+ this.cookieDomain = cookieDomain || null;
+
+ var xhr = new XMLHttpRequest();
+ var domain = this._getDomainFromUrl(url);
+ if ("withCredentials" in xhr) {
+ // XHR for Chrome/Firefox/Opera/Safari.
+ } else if (domain && this._isCrossDomain(domain) &&
+ typeof XDomainRequest != "undefined") {
+ // use XDR (IE7/8) when no other way
+ xhr = new XDomainRequest();
+ this.isXDR = true;
+ } else {
+ // CORS not supported.
+ }
+ this.request = xhr;
+};
+
+
+pzHttpRequest.prototype =
+{
+ safeGet: function ( params, callback )
+ {
+ var encodedParams = this.encodeParams(params);
+ var url = this._urlAppendParams(encodedParams);
+ if (url.length >= this.maxUrlLength) {
+ this.requestHeaders["Content-Type"]
+ = "application/x-www-form-urlencoded";
+ this._send( 'POST', this.url, encodedParams, callback );
+ } else {
+ this._send( 'GET', url, '', callback );
+ }
+ },
+
+ get: function ( params, callback )
+ {
+ this._send( 'GET', this._urlAppendParams(this.encodeParams(params)),
+ '', callback );
+ },
+
+ post: function ( params, data, callback )
+ {
+ this._send( 'POST', this._urlAppendParams(this.encodeParams(params)),
+ data, callback );
+ },
+
+ load: function ()
+ {
+ this.async = false;
+ this.request.open( 'GET', this.url, this.async );
+ this.request.send('');
+ if ( this.request.status == 200 )
+ return this.request.responseXML;
+ },
+
+ encodeParams: function (params)
+ {
+ var sep = "";
+ var encoded = "";
+ for (var key in params) {
+ if (params[key] != null) {
+ encoded += sep + key + '=' + encodeURIComponent(params[key]);
+ sep = '&';
+ }
+ }
+ return encoded;
+ },
+
+ _getDomainFromUrl: function (url)
+ {
+ if (this.cookieDomain) return this.cookieDomain; //explicit cookie domain
+ var m = this.domainRegex.exec(url);
+ return (m && m.length > 1) ? m[1] : null;
+ },
+
+ _strEndsWith: function (str, suffix)
+ {
+ return str.indexOf(suffix, str.length - suffix.length) !== -1;
+ },
+
+ _isCrossDomain: function (domain)
+ {
+ if (this.cookieDomain) return true; //assume xdomain is cookie domain set
+ return !this._strEndsWith(domain, document.domain);
+ },
+
+ getCookie: function (sKey) {
+ return decodeURI(document.cookie.replace(new RegExp("(?:(?:^|.*;)\\s*"
+ + encodeURI(sKey).replace(/[\-\.\+\*]/g, "\\$&")
+ + "\\s*\\=\\s*([^;]*).*$)|^.*$"), "$1")) || null;
+ },
+
+ setCookie: function (sKey, sValue, vEnd, sPath, sDomain, bSecure) {
+ if (!sKey || /^(?:expires|max\-age|path|domain|secure)$/i.test(sKey)) {
+ return false;
+ }
+ var sExpires = "";
+ if (vEnd) {
+ switch (vEnd.constructor) {
+ case Number:
+ sExpires = vEnd === Infinity
+ ? "; expires=Fri, 31 Dec 9999 23:59:59 GMT"
+ : "; max-age=" + vEnd;
+ break;
+ case String:
+ sExpires = "; expires=" + vEnd;
+ break;
+ case Date:
+ sExpires = "; expires=" + vEnd.toGMTString();
+ break;
+ }
+ }
+ document.cookie = encodeURI(sKey) + "=" + encodeURI(sValue)
+ + sExpires
+ + (sDomain ? "; domain=" + sDomain : "")
+ + (sPath ? "; path=" + sPath : "")
+ + (bSecure ? "; secure" : "");
+ return true;
+ },
+
+ _send: function ( type, url, data, callback)
+ {
+ var context = this;
+ this.callback = callback;
+ this.async = true;
+ //we never do withCredentials, so if it's CORS and we have
+ //session cookie, resend it
+ var domain = this._getDomainFromUrl(url);
+ if (domain && this._isCrossDomain(domain) &&
+ this.getCookie(domain+":SESSID")) {
+ //rewrite the URL
+ var sessparam = ';jsessionid=' + this.getCookie(domain+":SESSID");
+ var q = url.indexOf('?');
+ if (q == -1) {
+ url += sessparam;
+ } else {
+ url = url.substring(0, q) + sessparam + url.substring(q);
+ }
+ }
+ this.request.open( type, url, this.async );
+ if (!this.isXDR) {
+ //setting headers is only allowed with XHR
+ for (var key in this.requestHeaders)
+ this.request.setRequestHeader(key, this.requestHeaders[key]);
+ }
+ if (this.isXDR) {
+ this.request.onload = function () {
+ //fake XHR props
+ context.request.status = 200;
+ context.request.readyState = 4;
+ //handle
+ context._handleResponse(url);
+ }
+ this.request.onerror = function () {
+ //fake XHR props
+ context.request.status = 417; //not really, but what can we do
+ context.request.readyState = 4;
+ //handle
+ context._handleResponse(url);
+ }
+ } else {
+ this.request.onreadystatechange = function () {
+ context._handleResponse(url); /// url used ONLY for error reporting
+ }
+ }
+ this.request.send(data);
+ },
+
+ _urlAppendParams: function (encodedParams)
+ {
+ if (encodedParams)
+ return this.url + "?" + encodedParams;
+ else
+ return this.url;
+ },
+
+ _handleResponse: function (requestUrl)
+ {
+ if ( this.request.readyState == 4 ) {
+ // pick up appplication errors first
+ var errNode = null;
+ // xdomainreq does not have responseXML
+ if (this.isXDR) {
+ if (this.request.contentType.match(/\/xml/)){
+ var dom = new ActiveXObject('Microsoft.XMLDOM');
+ dom.async = false;
+ dom.loadXML(this.request.responseText);
+ this.request.responseXML = dom;
+ } else {
+ this.request.responseXML = null;
+ }
+ }
+ if (this.request.responseXML &&
+ (errNode = this.request.responseXML.documentElement)
+ && errNode.nodeName == 'error') {
+ var errMsg = errNode.getAttribute("msg");
+ var errCode = errNode.getAttribute("code");
+ var errAddInfo = '';
+ if (errNode.childNodes.length)
+ errAddInfo = ': ' + errNode.childNodes[0].nodeValue;
+
+ var err = new Error(errMsg + errAddInfo);
+ err.code = errCode;
+
+ if (this.errorHandler) {
+ this.errorHandler(err);
+ }
+ else {
+ throw err;
+ }
+ }
+ else if (this.request.status == 200 &&
+ this.request.responseXML === null) {
+ if (this.request.responseText !== null) {
+ //assume JSON
+ var json = null;
+ var text = this.request.responseText;
+ if (typeof window.JSON == "undefined") {
+ json = eval("(" + text + ")");
+ } else {
+ try {
+ json = JSON.parse(text);
+ } catch (e) {
+ }
+ }
+ this.callback(json, "json");
+ } else {
+ var err = new Error("XML/Text response is empty but no error " +
+ "for " + requestUrl);
+ err.code = -1;
+ if (this.errorHandler) {
+ this.errorHandler(err);
+ } else {
+ throw err;
+ }
+ }
+ } else if (this.request.status == 200) {
+ //set cookie manually only if cross-domain
+ var domain = this._getDomainFromUrl(requestUrl);
+ if (domain && this._isCrossDomain(domain)) {
+ var jsessionId = this.request.responseXML
+ .documentElement.getAttribute('jsessionId');
+ if (jsessionId)
+ this.setCookie(domain+":SESSID", jsessionId);
+ }
+ this.callback(this.request.responseXML);
+ } else {
+ var err = new Error("HTTP response not OK: "
+ + this.request.status + " - "
+ + this.request.statusText );
+ err.code = '00' + this.request.status;
+ if (this.errorHandler) {
+ this.errorHandler(err);
+ }
+ else {
+ throw err;
+ }
+ }
+ }
+ }
+};
+
+/*
+********************************************************************************
+** XML HELPER FUNCTIONS ********************************************************
+********************************************************************************
+*/
+
+// DOMDocument
+
+if ( window.ActiveXObject) {
+ var DOMDoc = document;
+} else {
+ var DOMDoc = Document.prototype;
+}
+
+DOMDoc.newXmlDoc = function ( root )
+{
+ var doc;
+
+ if (document.implementation && document.implementation.createDocument) {
+ doc = document.implementation.createDocument('', root, null);
+ } else if ( window.ActiveXObject ) {
+ doc = new ActiveXObject("MSXML2.DOMDocument");
+ doc.loadXML('<' + root + '/>');
+ } else {
+ throw new Error ('No XML support in this browser');
+ }
+
+ return doc;
+}
+
+
+DOMDoc.parseXmlFromString = function ( xmlString )
+{
+ var doc;
+
+ if ( window.DOMParser ) {
+ var parser = new DOMParser();
+ doc = parser.parseFromString( xmlString, "text/xml");
+ } else if ( window.ActiveXObject ) {
+ doc = new ActiveXObject("MSXML2.DOMDocument");
+ doc.loadXML( xmlString );
+ } else {
+ throw new Error ("No XML parsing support in this browser.");
+ }
+
+ return doc;
+}
+
+DOMDoc.transformToDoc = function (xmlDoc, xslDoc)
+{
+ if ( window.XSLTProcessor ) {
+ var proc = new XSLTProcessor();
+ proc.importStylesheet( xslDoc );
+ return proc.transformToDocument(xmlDoc);
+ } else if ( window.ActiveXObject ) {
+ return document.parseXmlFromString(xmlDoc.transformNode(xslDoc));
+ } else {
+ alert( 'Unable to perform XSLT transformation in this browser' );
+ }
+}
+
+// DOMElement
+
+Element_removeFromDoc = function (DOM_Element)
+{
+ DOM_Element.parentNode.removeChild(DOM_Element);
+}
+
+Element_emptyChildren = function (DOM_Element)
+{
+ while( DOM_Element.firstChild ) {
+ DOM_Element.removeChild( DOM_Element.firstChild )
+ }
+}
+
+Element_appendTransformResult = function ( DOM_Element, xmlDoc, xslDoc )
+{
+ if ( window.XSLTProcessor ) {
+ var proc = new XSLTProcessor();
+ proc.importStylesheet( xslDoc );
+ var docFrag = false;
+ docFrag = proc.transformToFragment( xmlDoc, DOM_Element.ownerDocument );
+ DOM_Element.appendChild(docFrag);
+ } else if ( window.ActiveXObject ) {
+ DOM_Element.innerHTML = xmlDoc.transformNode( xslDoc );
+ } else {
+ alert( 'Unable to perform XSLT transformation in this browser' );
+ }
+}
+
+Element_appendTextNode = function (DOM_Element, tagName, textContent )
+{
+ var node = DOM_Element.ownerDocument.createElement(tagName);
+ var text = DOM_Element.ownerDocument.createTextNode(textContent);
+
+ DOM_Element.appendChild(node);
+ node.appendChild(text);
+
+ return node;
+}
+
+Element_setTextContent = function ( DOM_Element, textContent )
+{
+ if (typeof DOM_Element.textContent !== "undefined") {
+ DOM_Element.textContent = textContent;
+ } else if (typeof DOM_Element.innerText !== "undefined" ) {
+ DOM_Element.innerText = textContent;
+ } else {
+ throw new Error("Cannot set text content of the node, no such method.");
+ }
+}
+
+Element_getTextContent = function (DOM_Element)
+{
+ if ( typeof DOM_Element.textContent != 'undefined' ) {
+ return DOM_Element.textContent;
+ } else if (typeof DOM_Element.text != 'undefined') {
+ return DOM_Element.text;
+ } else {
+ throw new Error("Cannot get text content of the node, no such method.");
+ }
+}
+
+Element_parseChildNodes = function (node)
+{
+ var parsed = {};
+ var hasChildElems = false;
+ var textContent = '';
+
+ if (node.hasChildNodes()) {
+ var children = node.childNodes;
+ for (var i = 0; i < children.length; i++) {
+ var child = children[i];
+ switch (child.nodeType) {
+ case Node.ELEMENT_NODE:
+ hasChildElems = true;
+ var nodeName = child.nodeName;
+ if (!(nodeName in parsed))
+ parsed[nodeName] = [];
+ parsed[nodeName].push(Element_parseChildNodes(child));
+ break;
+ case Node.TEXT_NODE:
+ textContent += child.nodeValue;
+ break;
+ case Node.CDATA_SECTION_NODE:
+ textContent += child.nodeValue;
+ break;
+ }
+ }
+ }
+
+ var attrs = node.attributes;
+ for (var i = 0; i < attrs.length; i++) {
+ hasChildElems = true;
+ var attrName = '@' + attrs[i].nodeName;
+ var attrValue = attrs[i].nodeValue;
+ parsed[attrName] = attrValue;
+ }
+
+ // if no nested elements/attrs set value to text
+ if (hasChildElems)
+ parsed['#text'] = textContent;
+ else
+ parsed = textContent;
+
+ return parsed;
+}
+
+/* do not remove trailing bracket */