﻿var XHR=new Class({options:{method:'post',async:true,onRequest:Class.empty,onSuccess:Class.empty,onFailure:Class.empty,urlEncoded:true,encoding:'utf-8',autoCancel:false,headers:{}},setTransport:function(){this.transport=(window.XMLHttpRequest)?new XMLHttpRequest():(window.ie?new ActiveXObject('Microsoft.XMLHTTP'):false);return this},initialize:function(options){this.setTransport().setOptions(options);this.options.isSuccess=this.options.isSuccess||this.isSuccess;this.headers={};if(this.options.urlEncoded&&this.options.method=='post'){var encoding=(this.options.encoding)?'; charset='+this.options.encoding:'';this.setHeader('Content-type','application/x-www-form-urlencoded'+encoding)}if(this.options.initialize)this.options.initialize.call(this)},onStateChange:function(){if(this.transport.readyState!=4||!this.running)return;this.running=false;var status=0;try{status=this.transport.status}catch(e){};if(this.options.isSuccess.call(this,status))this.onSuccess();else this.onFailure();this.transport.onreadystatechange=Class.empty},isSuccess:function(status){return((status>=200)&&(status<300))},onSuccess:function(){this.response={'text':this.transport.responseText,'xml':this.transport.responseXML};this.fireEvent('onSuccess',[this.response.text,this.response.xml]);this.callChain()},onFailure:function(){this.fireEvent('onFailure',this.transport)},setHeader:function(name,value){this.headers[name]=value;return this},send:function(url,data){if(this.options.autoCancel)this.cancel();else if(this.running)return this;this.running=true;if(data&&this.options.method=='get'){url=url+(url.contains('?')?'&':'?')+data;data=null}this.transport.open(this.options.method.toUpperCase(),url,this.options.async);this.transport.onreadystatechange=this.onStateChange.bind(this);if((this.options.method=='post')&&this.transport.overrideMimeType)this.setHeader('Connection','close');$extend(this.headers,this.options.headers);for(var type in this.headers)try{this.transport.setRequestHeader(type,this.headers[type])}catch(e){};this.fireEvent('onRequest');this.transport.send($pick(data,null));return this},cancel:function(){if(!this.running)return this;this.running=false;this.transport.abort();this.transport.onreadystatechange=Class.empty;this.setTransport();this.fireEvent('onCancel');return this}});XHR.implement(new Chain,new Events,new Options);var Ajax=XHR.extend({options:{data:null,update:null,onComplete:Class.empty,evalScripts:false,evalResponse:false},initialize:function(url,options){this.addEvent('onSuccess',this.onComplete);this.setOptions(options);this.options.data=this.options.data||this.options.postBody;if(!['post','get'].contains(this.options.method)){this._method='_method='+this.options.method;this.options.method='post'}this.parent();this.setHeader('X-Requested-With','XMLHttpRequest');this.setHeader('Accept','text/javascript, text/html, application/xml, text/xml, */*');this.url=url},onComplete:function(){if(this.options.update)$(this.options.update).empty().setHTML(this.response.text);if(this.options.evalScripts||this.options.evalResponse)this.evalScripts();this.fireEvent('onComplete',[this.response.text,this.response.xml],20)},request:function(data){data=data||this.options.data;switch($type(data)){case'element':data=$(data).toQueryString();break;case'object':data=Object.toQueryString(data)}if(this._method)data=(data)?[this._method,data].join('&'):this._method;return this.send(this.url,data)},evalScripts:function(){var script,scripts;if(this.options.evalResponse||(/(ecma|java)script/).test(this.getHeader('Content-type')))scripts=this.response.text;else{scripts=[];var regexp=/<script[^>]*>([\s\S]*?)<\/script>/gi;while((script=regexp.exec(this.response.text)))scripts.push(script[1]);scripts=scripts.join('\n')}if(scripts)(window.execScript)?window.execScript(scripts):window.setTimeout(scripts,0)},getHeader:function(name){try{return this.transport.getResponseHeader(name)}catch(e){};return null}});Object.toQueryString=function(source){var queryString=[];for(var property in source)queryString.push(encodeURIComponent(property)+'='+encodeURIComponent(source[property]));return queryString.join('&')};Element.extend({send:function(options){return new Ajax(this.getProperty('action'),$merge({data:this.toQueryString()},options,{method:'post'})).request()}});var Cookie=new Abstract({options:{domain:false,path:false,duration:false,secure:false},set:function(key,value,options){options=$merge(this.options,options);value=encodeURIComponent(value);if(options.domain)value+='; domain='+options.domain;if(options.path)value+='; path='+options.path;if(options.duration){var date=new Date();date.setTime(date.getTime()+options.duration*24*60*60*1000);value+='; expires='+date.toGMTString()}if(options.secure)value+='; secure';document.cookie=key+'='+value;return $extend(options,{'key':key,'value':value})},get:function(key){var value=document.cookie.match('(?:^|;)\\s*'+key.escapeRegExp()+'=([^;]*)');return value?decodeURIComponent(value[1]):false},remove:function(cookie,options){if($type(cookie)=='object')this.set(cookie.key,'',$merge(cookie,{duration:-1}));else this.set(cookie,'',$merge(options,{duration:-1}))}});var Json={toString:function(obj){switch($type(obj)){case'string':return'"'+obj.replace(/(["\\])/g,'\\$1')+'"';case'array':return'['+obj.map(Json.toString).join(',')+']';case'object':var string=[];for(var property in obj)string.push(Json.toString(property)+':'+Json.toString(obj[property]));return'{'+string.join(',')+'}';case'number':if(isFinite(obj))break;case false:return'null'}return String(obj)},evaluate:function(str,secure){return(($type(str)!='string')||(secure&&!str.test(/^("(\\.|[^"\\\n\r])*?"|[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t])+?$/)))?null:eval('('+str+')')}};Json.Remote=XHR.extend({initialize:function(url,options){this.url=url;this.addEvent('onSuccess',this.onComplete);this.parent(options);this.setHeader('X-Request','JSON')},send:function(obj){return this.parent(this.url,'json='+Json.toString(obj))},onComplete:function(){this.fireEvent('onComplete',[Json.evaluate(this.response.text,this.options.secure)])}});var Asset=new Abstract({javascript:function(source,properties){properties=$merge({'onload':Class.empty},properties);var script=new Element('script',{'src':source}).addEvents({'load':properties.onload,'readystatechange':function(){if(this.readyState=='complete')this.fireEvent('load')}});delete properties.onload;return script.setProperties(properties).inject(document.head)},css:function(source,properties){return new Element('link',$merge({'rel':'stylesheet','media':'screen','type':'text/css','href':source},properties)).inject(document.head)},image:function(source,properties){properties=$merge({'onload':Class.empty,'onabort':Class.empty,'onerror':Class.empty},properties);var image=new Image();image.src=source;var element=new Element('img',{'src':source});['load','abort','error'].each(function(type){var event=properties['on'+type];delete properties['on'+type];element.addEvent(type,function(){this.removeEvent(type,arguments.callee);event.call(this)})});if(image.width&&image.height)element.fireEvent('load',element,1);return element.setProperties(properties)},images:function(sources,options){options=$merge({onComplete:Class.empty,onProgress:Class.empty},options);if(!sources.push)sources=[sources];var images=[];var counter=0;sources.each(function(source){var img=new Asset.image(source,{'onload':function(){options.onProgress.call(this,counter);counter++;if(counter==sources.length)options.onComplete()}});images.push(img)});return new Elements(images)}});
