/* DynAPI Distribution IOElement Class The DynAPI Distribution is distributed under the terms of the GNU LGPL license. requires: dynapi.api.DynLayer // pages loaded must include this code: */ function IOElement(hiddenThreads,useXFrames) { this.DynLayer = DynLayer; this.DynLayer(); this._elmID = this.id+'elm'; this._requests = {}; // [url,data,fn,method,elmThread,timer,cargo] this._cargoID=''; this._requestList = []; this._requestIndex = -1; this._retryID=null; this._transactions = {}; this._singleThread=false; this._elmBusy=[]; this._elmThread=null; this._maxThreads=(hiddenThreads>=1 && hiddenThreads<=8)? hiddenThreads : 1; this._hidden = (hiddenThreads)? true : false; this.isSync=false; this.failTime = 50000; // create XFrame window if(useXFrames && dynapi.ua.ns4) { this._winXFrames=window.open("about:blank",null,'left=3000,top=3000,width=100,height=100,scrollbars=no,status=no,toolbar=no'); this._winXFrames.blur(); // hide the new window var wxf=this._winXFrames; dynapi.onUnload(function() { // tidy up if(wxf.open && !wxf.closed) wxf.close(); }); } if (this._hidden) { var o = this; o.setLocation(1,1);// Strange! ns4 requires that the x,y be set in order to load the java applet inside the layer o.setVisible(false); dynapi.document.addChild(o); } this.onPreCreate(IOElement.fnPrecreate); this.onCreate(IOElement.fnCreate); }; IOElement.fnPrecreate = function() { var t,r=['*'],html=[]; if (this._hidden) { if (this._winXFrames) html = ['']; else if (dynapi.ua.ns4) html = ['']; else { // Opera v7.11 requires an IFrame's src to be set before it's accessible - pixel.gif is a 1x1 transparent gif html = ['']; } t=html.join(''); this._elmThread=this._elmID; this._elmBusy[this._elmID]=false; for(var i=1;i'; else if (dynapi.ua.ns4) t = ''; else t = ''; this._elmThread=this._elmID; this._elmBusy[this._elmID]=false; } if (!this._winXFrames) this.html=t; else{ var src='DynAPI XFrame\n' +'\n'+t +'\n' this._winXFrames.document.open(); this._winXFrames.document.write(src); this._winXFrames.document.close(); this._winXFrames.top.dynapi=dynapi; this._winXFrames.top.IOElement=IOElement; } }; IOElement.fnCreate = function() { if (this._SyncFn) window.setTimeout(this+'._initSync()',100); if (this.getScope()) { if (this._requestList.length>0) { this._setRequestTimeout(100); } } }; var p = dynapi.setPrototype('IOElement','DynLayer'); p.execInParent = function(fn){ // Executes javascript codes within the parent element if(typeof(fn)=='function') eval('fn='+fn); else eval('fn=function(){'+fn+'}'); fn(); }; p.getVariable = function(name) { var v=this.getScope()[name]; if (IOElement.SODA) v=IOElement.ws_SODA2Var(v); return v; }; p.getScope = function(thread) { var scope; if (!thread) thread=this._elmThread; if (this._winXFrames && this._winXFrames.top) scope = this._winXFrames.top.frames[thread]; else if (dynapi.ua.ns4) scope = this.doc.layers[thread]; else scope = window.frames[thread]; if (!scope) return alert('IOElement Error: no load element'); else return scope; }; p.getCargoID=function(){return this._cargoID} p.getCargo=function(dontRemove){ if(!this._cargoID) return null; var c=this._requests[this._cargoID][6]; if(!dontRemove) { // normal cargo are removed from storage this._requests[this._cargoID][6]=null; } return c; }; p.isBusy = function(){ for (var i in this._elmBusy){ if (this._elmBusy[i]==false) return false; };return true; }; p.cancel= function(id){ id=(id)? id:this._retryID; var req=this._requests[id]; if(req){ this._elmBusy[req[4]]=false; delete this._requests[id]; this._clearScope(); return true; } }; p.cancelAll=function(){ this._requests={}; for (var i in this._elmBusy){ this.elmThread=i; this._clearScope(); } }; p.retry=function(id){ id=this._retryID=((id)? id:this._retryID); var req=this._requests[id]; if(req) { this._setRequestTimeout(50,id); return true; } }; p.setTimeout = function(ms){ if(!isNaN(ms))this.failTime=ms; } p.useSingleThread = function(b){ this._singleThread=b; }; p.get = function(url,data,fn,cargo) { if(fn==false && this.isSync) return this._syncRequest(url,data,'get'); else return this._asyncRequest(url,data,fn,'get',cargo); }; p.post = function(url,data,fn,cargo) { if(fn==false && this.isSync) return this._syncRequest(url,data,'post'); return this._asyncRequest(url,data,fn,'post',cargo); }; p.upload=function(url,form,fn,cargo){ // file upload return this._asyncRequest(url,form,fn,'upload',cargo); }; p._asyncRequest = function(url,data,fn,method,cargo) { var i,l,src; var id = this._getRandomID(); // create random load ID to ensure no caching dynapi.debug.print("IOElement "+method+" request"); if (typeof(url)=="string") this._requests[id] = [url,data,fn,method,null,null,cargo]; else if (method=="get") { for (i=0;i'; if (data) { for (i in data) { if(i) str += ''; } } str += ''; elm.document.open(); elm.document.write(str); elm.document.close(); var f = elm.document.forms['ioDataForm']; if (!f) return alert("IOElement Error: no form element found"); if (f && data) { for (i in data) { if(i) f[i].value = data[i]; } } f.submit(); } // begin transaction - data sent but awaiting reply // to-do work on a way to detech if caller is in the same domain as if(!dynapi.ua.ns4) { elm.document._tranState="begin"; this._monitorTransactions(); } this.invokeEvent("request"); } } }; p._clearScope=function(){ var doc=this.getScope().document; if(doc){doc.open();doc.write('');doc.close()} }; p._getFreeElm= function(){ for (var i in this._elmBusy){ if (this._elmBusy[i]==false){ this._elmThread=i;this._elmBusy[i]=true; return this.getScope(); }else if(this._singleThread) break; } }; p._getRandomID = function(){ var id = Math.random()+''; return 'io'+id.substring(2); }; p._monitorTransactions = function(){ var c,r,tr,id,elm; for (id in this._transactions){ r=this._requests[id]; tr=this._transactions[id]; if(r && this._elmBusy[r[4]]) { elm=this.getScope(r[4]); if(elm && elm.document && !elm.document._tranState){ // document completed without proper response from server tr[0]+=1; // counter. if(tr[0]>=3){ //three strikes and you're out! eval(tr[1]); } } } } if(id) window.setTimeout(this+'._monitorTransactions()',1000); }; p._notify = function(id, url, success) { var fn,req=this._requests[id]; if(!req)return; var s = (success!=null)? success : true; // delete transaction record delete this._transactions[id]; if (!this._elmBusy[req[4]] && success) { dynapi.debug.print('IOElement Error: '+id+' '+this._elmID+' '+url); return; } clearTimeout(req[5]); this._elmThread=req[4]; fn = req[2]; // callback function if(!s) this._retryID=id; else this._retryID=''; this._cargoID=id; if (fn) { var r,e = new DynEvent("load",this); if(typeof(fn)=='function') r=fn(e, s); else r=eval(fn); // cancels server response and preserve request object if(r==false) { s=false; this._retryID=id; } }else{ this.invokeEvent("response",null,s); } this._cargoID=''; if(s && id!=this._retryID) delete this._requests[id]; else if(this._hidden) this._clearScope(); this._elmBusy[req[4]] = false; // release document - prevent incomplete progressbar in ie if(dynapi.ua.ie) location.href = "javascript:void (document.close())"; this._doRequest(); }; p._setRequestTimeout=function(interval,id){ var evl=this+'._doRequest('+((id)? "'"+id+"'":'')+')'; return window.setTimeout(evl,interval); }; // Helper Methods ------------------------- IOElement.getSharedIO=function(useXFrames){ // Returns a Shared instance of the IOElement object if(!IOElement.ShareIO) IOElement.ShareIO=new IOElement(1,useXFrames); return IOElement.ShareIO; }; IOElement.notify = function(elm, fn, success) { // ds: added success parameter to nicely relay server generated error messages if (elm) { var url, id; if (dynapi.ua.ns4 && elm.src) url = elm.src; else if (dynapi.ua.ns4 && elm.location) url = elm.location.href; else url = elm.document.location.href; if (url) { elm.args = dynapi.functions.getURLArguments(url); var id = elm.args["IORequestID"]; var obj = DynObject.all[elm.args["IOElementID"]]; if (obj!=null && id!=null) { // transaction completed - server has respond sucessfully elm.document._tranState="complete"; elm.onload = function() { if (fn) fn(obj); // send obj fn - rmo obj._notify(id,url, success); // ds: success }; return obj; } else { return false; } } } return null; }; IOElement.URLEncode = function (d){ d=d.replace(/\s/g,'+').replace(/\%/g,'%25').replace(/\=/g,'%3D'); d=d.replace(/\&/g,'%26').replace(/\n/g,'%0A').replace(/\r/g,'%0D'); d=d.replace(/\#/g,'%23').replace(/\\/g,'%5C'); return d; };