Skip to content

Commit

Permalink
Import Request
Browse files Browse the repository at this point in the history
  • Loading branch information
Arian committed Sep 11, 2011
0 parents commit c66c88a
Show file tree
Hide file tree
Showing 2 changed files with 265 additions and 0 deletions.
Empty file added README.md
Empty file.
265 changes: 265 additions & 0 deletions Source/Request.js
@@ -0,0 +1,265 @@

define([
'Base/Core/Class',
'Base/Class/Options',
'Base/Class/Events',
'Base/Class/Chain'
], function(Class, Options, Events, Chain){

var XMLHTTP = function(){
return new XMLHttpRequest();
};

var MSXML2 = function(){
return new ActiveXObject('MSXML2.XMLHTTP');
};

var MSXML = function(){
return new ActiveXObject('Microsoft.XMLHTTP');
};

var XHR;
try {
XMLHTTP();
XHR = XMLHTTP;
} catch (e){}

if (!XHR) try {
MSXML2();
XHR = MSXML2;
} catch (e){}

if (!XHR) try {
MSXML();
XHR = MSXML;
} catch (e){}

var empty = function(){},
progressSupport = ('onprogress' in new XHR);

var Request = new Class({

Implements: [Chain, Events, Options],

options: {/*
onRequest: function(){},
onLoadstart: function(event, xhr){},
onProgress: function(event, xhr){},
onComplete: function(){},
onCancel: function(){},
onSuccess: function(responseText, responseXML){},
onFailure: function(xhr){},
onException: function(headerName, value){},
onTimeout: function(){},
user: '',
password: '',*/
url: '',
data: '',
headers: {
'X-Requested-With': 'XMLHttpRequest',
'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
},
async: true,
format: false,
method: 'post',
link: 'ignore',
isSuccess: null,
emulation: true,
urlEncoded: true,
encoding: 'utf-8',
evalScripts: false,
evalResponse: false,
timeout: 0,
noCache: false
},

initialize: function(options){
this.xhr = new Browser.Request();
this.setOptions(options);
this.headers = this.options.headers;
},

onStateChange: function(){
var xhr = this.xhr;
if (xhr.readyState != 4 || !this.running) return;
this.running = false;
this.status = 0;
Function.attempt(function(){
var status = xhr.status;
this.status = (status == 1223) ? 204 : status;
}.bind(this));
xhr.onreadystatechange = empty;
if (progressSupport) xhr.onprogress = xhr.onloadstart = empty;
clearTimeout(this.timer);

this.response = {text: this.xhr.responseText || '', xml: this.xhr.responseXML};
if (this.options.isSuccess.call(this, this.status))
this.success(this.response.text, this.response.xml);
else
this.failure();
},

isSuccess: function(){
var status = this.status;
return (status >= 200 && status < 300);
},

isRunning: function(){
return !!this.running;
},

processScripts: function(text){
if (this.options.evalResponse || (/(ecma|java)script/).test(this.getHeader('Content-type'))) return Browser.exec(text);
return text.stripScripts(this.options.evalScripts);
},

success: function(text, xml){
this.onSuccess(this.processScripts(text), xml);
},

onSuccess: function(){
this.fireEvent('complete', arguments).fireEvent('success', arguments).callChain();
},

failure: function(){
this.onFailure();
},

onFailure: function(){
this.fireEvent('complete').fireEvent('failure', this.xhr);
},

loadstart: function(event){
this.fireEvent('loadstart', [event, this.xhr]);
},

progress: function(event){
this.fireEvent('progress', [event, this.xhr]);
},

timeout: function(){
this.fireEvent('timeout', this.xhr);
},

setHeader: function(name, value){
this.headers[name] = value;
return this;
},

getHeader: function(name){
return Function.attempt(function(){
return this.xhr.getResponseHeader(name);
}.bind(this));
},

check: function(){
if (!this.running) return true;
switch (this.options.link){
case 'cancel': this.cancel(); return true;
case 'chain': this.chain(this.caller.pass(arguments, this)); return false;
}
return false;
},

send: function(options){
if (!this.check(options)) return this;

this.options.isSuccess = this.options.isSuccess || this.isSuccess;
this.running = true;

var type = typeOf(options);
if (type == 'string' || type == 'element') options = {data: options};

var old = this.options;
options = Object.append({data: old.data, url: old.url, method: old.method}, options);
var data = options.data, url = String(options.url), method = options.method.toLowerCase();

switch (typeOf(data)){
case 'element': data = document.id(data).toQueryString(); break;
case 'object': case 'hash': data = Object.toQueryString(data);
}

if (this.options.format){
var format = 'format=' + this.options.format;
data = (data) ? format + '&' + data : format;
}

if (this.options.emulation && !['get', 'post'].contains(method)){
var _method = '_method=' + method;
data = (data) ? _method + '&' + data : _method;
method = 'post';
}

if (this.options.urlEncoded && ['post', 'put'].contains(method)){
var encoding = (this.options.encoding) ? '; charset=' + this.options.encoding : '';
this.headers['Content-type'] = 'application/x-www-form-urlencoded' + encoding;
}

if (!url) url = document.location.pathname;

var trimPosition = url.lastIndexOf('/');
if (trimPosition > -1 && (trimPosition = url.indexOf('#')) > -1) url = url.substr(0, trimPosition);

if (this.options.noCache)
url += (url.contains('?') ? '&' : '?') + String.uniqueID();

if (data && method == 'get'){
url += (url.contains('?') ? '&' : '?') + data;
data = null;
}

var xhr = this.xhr;
if (progressSupport){
xhr.onloadstart = this.loadstart.bind(this);
xhr.onprogress = this.progress.bind(this);
}

xhr.open(method.toUpperCase(), url, this.options.async, this.options.user, this.options.password);
if (this.options.user && 'withCredentials' in xhr) xhr.withCredentials = true;

xhr.onreadystatechange = this.onStateChange.bind(this);

Object.each(this.headers, function(value, key){
try {
xhr.setRequestHeader(key, value);
} catch (e){
this.fireEvent('exception', [key, value]);
}
}, this);

this.fireEvent('request');
xhr.send(data);
if (!this.options.async) this.onStateChange();
if (this.options.timeout) this.timer = this.timeout.delay(this.options.timeout, this);
return this;
},

cancel: function(){
if (!this.running) return this;
this.running = false;
var xhr = this.xhr;
xhr.abort();
clearTimeout(this.timer);
xhr.onreadystatechange = empty;
if (progressSupport) xhr.onprogress = xhr.onloadstart = empty;
this.xhr = new Browser.Request();
this.fireEvent('cancel');
return this;
}

});

var methods = {};
['get', 'post', 'put', 'delete', 'GET', 'POST', 'PUT', 'DELETE'].each(function(method){
methods[method] = function(data){
var object = {
method: method
};
if (data != null) object.data = data;
return this.send(object);
};
});

Request.implement(methods);

});

0 comments on commit c66c88a

Please sign in to comment.