1/** 2 * JsHttpRequest: JavaScript "AJAX" data loader (form support only!) 3 * Minimized version: see debug directory for the complete one. 4 * 5 * @license LGPL 6 * @author Dmitry Koterov, http://en.dklab.ru/lib/JsHttpRequest/ 7 * @version 5.x $Id$ 8 */ 9function JsHttpRequest(){ 10var t=this; 11t.onreadystatechange=null; 12t.readyState=0; 13t.responseText=null; 14t.responseXML=null; 15t.status=200; 16t.statusText="OK"; 17t.responseJS=null; 18t.caching=false; 19t.loader=null; 20t.session_name="PHPSESSID"; 21t._ldObj=null; 22t._reqHeaders=[]; 23t._openArgs=null; 24t._errors={inv_form_el:"Invalid FORM element detected: name=%, tag=%",must_be_single_el:"If used, <form> must be a single HTML element in the list.",js_invalid:"JavaScript code generated by backend is invalid!\n%",url_too_long:"Cannot use so long query with GET request (URL is larger than % bytes)",unk_loader:"Unknown loader: %",no_loaders:"No loaders registered at all, please check JsHttpRequest.LOADERS array",no_loader_matched:"Cannot find a loader which may process the request. Notices are:\n%",no_headers:"Method setRequestHeader() cannot work together with the % loader."}; 25t.abort=function(){ 26with(this){ 27if(_ldObj&&_ldObj.abort){ 28_ldObj.abort(); 29} 30_cleanup(); 31if(readyState==0){ 32return; 33} 34if(readyState==1&&!_ldObj){ 35readyState=0; 36return; 37} 38_changeReadyState(4,true); 39} 40}; 41t.open=function(_2,_3,_4,_5,_6){ 42with(this){ 43try{ 44if(document.location.search.match(new RegExp("[&?]"+session_name+"=([^&?]*)"))||document.cookie.match(new RegExp("(?:;|^)\\s*"+session_name+"=([^;]*)"))){ 45_3+=(_3.indexOf("?")>=0?"&":"?")+session_name+"="+this.escape(RegExp.$1); 46} 47} 48catch(e){ 49} 50_openArgs={method:(_2||"").toUpperCase(),url:_3,asyncFlag:_4,username:_5!=null?_5:"",password:_6!=null?_6:""}; 51_ldObj=null; 52_changeReadyState(1,true); 53return true; 54} 55}; 56t.send=function(_7){ 57if(!this.readyState){ 58return; 59} 60this._changeReadyState(1,true); 61this._ldObj=null; 62var _8=[]; 63var _9=[]; 64if(!this._hash2query(_7,null,_8,_9)){ 65return; 66} 67var _a=null; 68if(this.caching&&!_9.length){ 69_a=this._openArgs.username+":"+this._openArgs.password+"@"+this._openArgs.url+"|"+_8+"#"+this._openArgs.method; 70var _b=JsHttpRequest.CACHE[_a]; 71if(_b){ 72this._dataReady(_b[0],_b[1]); 73return false; 74} 75} 76var _c=(this.loader||"").toLowerCase(); 77if(_c&&!JsHttpRequest.LOADERS[_c]){ 78return this._error("unk_loader",_c); 79} 80var _d=[]; 81var _e=JsHttpRequest.LOADERS; 82for(var _f in _e){ 83var ldr=_e[_f].loader; 84if(!ldr){ 85continue; 86} 87if(_c&&_f!=_c){ 88continue; 89} 90var _11=new ldr(this); 91JsHttpRequest.extend(_11,this._openArgs); 92JsHttpRequest.extend(_11,{queryText:_8.join("&"),queryElem:_9,id:(new Date().getTime())+""+JsHttpRequest.COUNT++,hash:_a,span:null}); 93var _12=_11.load(); 94if(!_12){ 95this._ldObj=_11; 96JsHttpRequest.PENDING[_11.id]=this; 97return true; 98} 99if(!_c){ 100_d[_d.length]="- "+_f.toUpperCase()+": "+this._l(_12); 101}else{ 102return this._error(_12); 103} 104} 105return _f?this._error("no_loader_matched",_d.join("\n")):this._error("no_loaders"); 106}; 107t.getAllResponseHeaders=function(){ 108with(this){ 109return _ldObj&&_ldObj.getAllResponseHeaders?_ldObj.getAllResponseHeaders():[]; 110} 111}; 112t.getResponseHeader=function(_13){ 113with(this){ 114return _ldObj&&_ldObj.getResponseHeader?_ldObj.getResponseHeader():[]; 115} 116}; 117t.setRequestHeader=function(_14,_15){ 118with(this){ 119_reqHeaders[_reqHeaders.length]=[_14,_15]; 120} 121}; 122t._dataReady=function(_16,js){ 123with(this){ 124if(caching&&_ldObj){ 125JsHttpRequest.CACHE[_ldObj.hash]=[_16,js]; 126} 127if(_16!==null||js!==null){ 128status=4; 129responseText=responseXML=_16; 130responseJS=js; 131}else{ 132status=500; 133responseText=responseXML=responseJS=null; 134} 135_changeReadyState(2); 136_changeReadyState(3); 137_changeReadyState(4); 138_cleanup(); 139} 140}; 141t._l=function(_18){ 142var i=0,p=0,msg=this._errors[_18[0]]; 143while((p=msg.indexOf("%",p))>=0){ 144var a=_18[++i]+""; 145msg=msg.substring(0,p)+a+msg.substring(p+1,msg.length); 146p+=1+a.length; 147} 148return msg; 149}; 150t._error=function(msg){ 151msg=this._l(typeof (msg)=="string"?arguments:msg); 152msg="JsHttpRequest: "+msg; 153if(!window.Error){ 154throw msg; 155}else{ 156if((new Error(1,"test")).description=="test"){ 157throw new Error(1,msg); 158}else{ 159throw new Error(msg); 160} 161} 162}; 163t._hash2query=function(_1e,_1f,_20,_21){ 164if(_1f==null){ 165_1f=""; 166} 167if((""+typeof (_1e)).toLowerCase()=="object"){ 168var _22=false; 169if(_1e&&_1e.parentNode&&_1e.parentNode.appendChild&&_1e.tagName&&_1e.tagName.toUpperCase()=="FORM"){ 170_1e={form:_1e}; 171} 172for(var k in _1e){ 173var v=_1e[k]; 174if(v instanceof Function){ 175continue; 176} 177var _25=_1f?_1f+"["+this.escape(k)+"]":this.escape(k); 178var _26=v&&v.parentNode&&v.parentNode.appendChild&&v.tagName; 179if(_26){ 180var tn=v.tagName.toUpperCase(); 181if(tn=="FORM"){ 182_22=true; 183}else{ 184if(tn=="INPUT"||tn=="TEXTAREA"||tn=="SELECT"){ 185}else{ 186return this._error("inv_form_el",(v.name||""),v.tagName); 187} 188} 189_21[_21.length]={name:_25,e:v}; 190}else{ 191if(v instanceof Object){ 192this._hash2query(v,_25,_20,_21); 193}else{ 194if(v===null){ 195continue; 196} 197_20[_20.length]=_25+"="+this.escape(""+v); 198} 199} 200if(_22&&_21.length>1){ 201return this._error("must_be_single_el"); 202} 203} 204}else{ 205_20[_20.length]=_1e; 206} 207return true; 208}; 209t._cleanup=function(){ 210var _28=this._ldObj; 211if(!_28){ 212return; 213} 214JsHttpRequest.PENDING[_28.id]=false; 215var _29=_28.span; 216if(!_29){ 217return; 218} 219_28.span=null; 220var _2a=function(){ 221_29.parentNode.removeChild(_29); 222}; 223JsHttpRequest.setTimeout(_2a,50); 224}; 225t._changeReadyState=function(s,_2c){ 226with(this){ 227if(_2c){ 228status=statusText=responseJS=null; 229responseText=""; 230} 231readyState=s; 232if(onreadystatechange){ 233onreadystatechange(); 234} 235} 236}; 237t.escape=function(s){ 238return escape(s).replace(new RegExp("\\+","g"),"%2B"); 239}; 240} 241JsHttpRequest.COUNT=0; 242JsHttpRequest.MAX_URL_LEN=2000; 243JsHttpRequest.CACHE={}; 244JsHttpRequest.PENDING={}; 245JsHttpRequest.LOADERS={}; 246JsHttpRequest._dummy=function(){ 247}; 248JsHttpRequest.TIMEOUTS={s:window.setTimeout,c:window.clearTimeout}; 249JsHttpRequest.setTimeout=function(_2e,dt){ 250window.JsHttpRequest_tmp=JsHttpRequest.TIMEOUTS.s; 251if(typeof (_2e)=="string"){ 252id=window.JsHttpRequest_tmp(_2e,dt); 253}else{ 254var id=null; 255var _31=function(){ 256_2e(); 257delete JsHttpRequest.TIMEOUTS[id]; 258}; 259id=window.JsHttpRequest_tmp(_31,dt); 260JsHttpRequest.TIMEOUTS[id]=_31; 261} 262window.JsHttpRequest_tmp=null; 263return id; 264}; 265JsHttpRequest.clearTimeout=function(id){ 266window.JsHttpRequest_tmp=JsHttpRequest.TIMEOUTS.c; 267delete JsHttpRequest.TIMEOUTS[id]; 268var r=window.JsHttpRequest_tmp(id); 269window.JsHttpRequest_tmp=null; 270return r; 271}; 272JsHttpRequest.query=function(url,_35,_36,_37){ 273var req=new this(); 274req.caching=!_37; 275req.onreadystatechange=function(){ 276if(req.readyState==4){ 277_36(req.responseJS,req.responseText); 278} 279}; 280var _39=null; 281if(url.match(/^((\w+)\.)?(GET|POST)\s+(.*)/i)){ 282req.loader=RegExp.$2?RegExp.$2:null; 283_39=RegExp.$3; 284url=RegExp.$4; 285} 286req.open(_39,url,true); 287req.send(_35); 288}; 289JsHttpRequest.dataReady=function(d){ 290var th=this.PENDING[d.id]; 291delete this.PENDING[d.id]; 292if(th){ 293th._dataReady(d.text,d.js); 294}else{ 295if(th!==false){ 296throw "dataReady(): unknown pending id: "+d.id; 297} 298} 299}; 300JsHttpRequest.extend=function(_3c,src){ 301for(var k in src){ 302_3c[k]=src[k]; 303} 304}; 305JsHttpRequest.LOADERS.form={loader:function(req){ 306JsHttpRequest.extend(req._errors,{form_el_not_belong:"Element \"%\" does not belong to any form!",form_el_belong_diff:"Element \"%\" belongs to a different form. All elements must belong to the same form!",form_el_inv_enctype:"Attribute \"enctype\" of the form must be \"%\" (for IE), \"%\" given."}); 307this.load=function(){ 308var th=this; 309if(!th.method){ 310th.method="POST"; 311} 312th.url+=(th.url.indexOf("?")>=0?"&":"?")+"JsHttpRequest="+th.id+"-"+"form"; 313if(req._reqHeaders.length){ 314return ["no_headers","FORM"]; 315} 316if(th.method=="GET"){ 317if(th.queryText){ 318th.url+=(th.url.indexOf("?")>=0?"&":"?")+th.queryText; 319} 320if(th.url.length>JsHttpRequest.MAX_URL_LEN){ 321return ["url_too_long",JsHttpRequest.MAX_URL_LEN]; 322} 323var p=th.url.split("?",2); 324th.url=p[0]; 325th.queryText=p[1]||""; 326} 327var _42=null; 328var _43=false; 329if(th.queryElem.length){ 330if(th.queryElem[0].e.tagName.toUpperCase()=="FORM"){ 331_42=th.queryElem[0].e; 332_43=true; 333th.queryElem=[]; 334}else{ 335_42=th.queryElem[0].e.form; 336for(var i=0;i<th.queryElem.length;i++){ 337var e=th.queryElem[i].e; 338if(!e.form){ 339return ["form_el_not_belong",e.name]; 340} 341if(e.form!=_42){ 342return ["form_el_belong_diff",e.name]; 343} 344} 345} 346if(th.method=="POST"){ 347var _46="multipart/form-data"; 348var _47=(_42.attributes.encType&&_42.attributes.encType.nodeValue)||(_42.attributes.enctype&&_42.attributes.enctype.value)||_42.enctype; 349if(_47!=_46){ 350return ["form_el_inv_enctype",_46,_47]; 351} 352} 353} 354var d=_42&&(_42.ownerDocument||_42.document)||document; 355var _49="jshr_i_"+th.id; 356var s=th.span=d.createElement("DIV"); 357s.style.position="absolute"; 358s.style.display="none"; 359s.style.visibility="hidden"; 360s.innerHTML=(_42?"":"<form"+(th.method=="POST"?" enctype=\"multipart/form-data\" method=\"post\"":"")+"></form>")+"<iframe name=\""+_49+"\" id=\""+_49+"\" style=\"width:0px; height:0px; overflow:hidden; border:none\"></iframe>"; 361if(!_42){ 362_42=th.span.firstChild; 363} 364d.body.insertBefore(s,d.body.lastChild); 365var _4b=function(e,_4d){ 366var sv=[]; 367var _4f=e; 368if(e.mergeAttributes){ 369var _4f=d.createElement("form"); 370_4f.mergeAttributes(e,false); 371} 372for(var i=0;i<_4d.length;i++){ 373var k=_4d[i][0],v=_4d[i][1]; 374sv[sv.length]=[k,_4f.getAttribute(k)]; 375_4f.setAttribute(k,v); 376} 377if(e.mergeAttributes){ 378e.mergeAttributes(_4f,false); 379} 380return sv; 381}; 382var _53=function(){ 383top.JsHttpRequestGlobal=JsHttpRequest; 384var _54=[]; 385if(!_43){ 386for(var i=0,n=_42.elements.length;i<n;i++){ 387_54[i]=_42.elements[i].name; 388_42.elements[i].name=""; 389} 390} 391var qt=th.queryText.split("&"); 392for(var i=qt.length-1;i>=0;i--){ 393var _58=qt[i].split("=",2); 394var e=d.createElement("INPUT"); 395e.type="hidden"; 396e.name=unescape(_58[0]); 397e.value=_58[1]!=null?unescape(_58[1]):""; 398_42.appendChild(e); 399} 400for(var i=0;i<th.queryElem.length;i++){ 401th.queryElem[i].e.name=th.queryElem[i].name; 402} 403var sv=_4b(_42,[["action",th.url],["method",th.method],["onsubmit",null],["target",_49]]); 404_42.submit(); 405_4b(_42,sv); 406for(var i=0;i<qt.length;i++){ 407_42.lastChild.parentNode.removeChild(_42.lastChild); 408} 409if(!_43){ 410for(var i=0,n=_42.elements.length;i<n;i++){ 411_42.elements[i].name=_54[i]; 412} 413} 414}; 415JsHttpRequest.setTimeout(_53,100); 416return null; 417}; 418}}; 419 420