oxjs/source/UI/js/Core/Request.js

236 lines
7.2 KiB
JavaScript
Raw Permalink Normal View History

2011-11-05 16:46:53 +00:00
'use strict';
2012-05-21 10:38:18 +00:00
2011-05-16 08:24:46 +00:00
/*@
Ox.Request <o> Basic request controller
# FIXME: options is not a property, just documenting defaults
# options <o> Options object
# timeout <n|60000> request timeout
# type <s|"POST"> request type, possible values POST, GET, PUT, DELETE
# url <s> request url
2011-05-16 08:24:46 +00:00
@*/
2011-04-22 22:03:10 +00:00
2011-11-30 14:49:11 +00:00
Ox.Request = (function() {
2011-04-22 22:03:10 +00:00
var cache = {},
pending = {},
requests = {},
self = {
2011-11-30 14:49:11 +00:00
options: {
2013-08-27 14:26:52 +00:00
cache: true,
2011-04-22 22:03:10 +00:00
timeout: 60000,
type: 'POST',
url: '/api/'
2011-11-30 14:49:11 +00:00
}
},
$element;
2011-04-22 22:03:10 +00:00
return {
2013-08-27 14:26:52 +00:00
/*@
bindEvent <f> Bind event
@*/
bindEvent: function() {
if (!$element) {
$element = Ox.Element();
}
2014-09-20 10:29:27 +00:00
$element.bindEvent.apply($element, arguments);
2013-08-27 14:26:52 +00:00
},
2011-05-16 08:24:46 +00:00
/*@
cancel <f> cancel pending requests
() -> <u> cancel all requests
(fn) -> <u> cancel all requests where function returns true
(id) -> <u> cancel request by id
2011-05-16 08:24:46 +00:00
@*/
2011-04-22 22:03:10 +00:00
cancel: function() {
if (arguments.length == 0) {
// cancel all requests
requests = {};
} else if (Ox.isFunction(arguments[0])) {
// cancel with function
var fn = arguments[0];
2011-04-22 22:03:10 +00:00
Ox.forEach(requests, function(req, id) {
if (fn(req)) {
2011-04-22 22:03:10 +00:00
delete requests[id];
}
});
} else {
// cancel by id
delete requests[arguments[0]];
}
2012-01-27 14:29:11 +00:00
$element && $element.triggerEvent('request', {
requests: Ox.len(requests)
});
2011-04-22 22:03:10 +00:00
},
2013-08-27 14:26:52 +00:00
2011-05-16 08:24:46 +00:00
/*@
clearCache <f> clear cached results
() -> <u> ...
2011-05-16 08:24:46 +00:00
@*/
clearCache: function(query) {
if (!query) {
cache = {};
} else {
cache = Ox.filter(cache, function(val, key) {
return key.indexOf(query) == -1;
});
}
2011-04-22 22:03:10 +00:00
},
2012-01-27 14:29:11 +00:00
2011-05-16 08:24:46 +00:00
/*@
options <f> get/set options
() -> <o> get options
(options) -> <o> set options
options <o> Options Object
@*/
2011-11-30 14:49:11 +00:00
options: function() {
return Ox.getset(self.options, arguments, function() {}, this);
2011-04-22 22:03:10 +00:00
},
2011-05-16 08:24:46 +00:00
/*@
requests <f> pending requests
() -> <n> returns number of requests
@*/
2011-04-22 22:03:10 +00:00
requests: function() {
return Ox.len(requests);
},
2011-05-16 08:24:46 +00:00
/*@
send <f> send request
(options) -> <n> returns request id
options <o> Options Object
age <n|-1> cache age
id <n|Ox.uid()> request id
timeout <n|self.options.timeout> overwrite default timeout
type <n|self.options.timeout> overwrite default type
url <n|self.options.timeout> overwrite default url
@*/
2011-04-22 22:03:10 +00:00
send: function(options) {
var data,
options = Ox.extend({
2011-04-22 22:03:10 +00:00
age: -1,
callback: null,
id: Ox.uid(),
timeout: self.options.timeout,
type: self.options.type,
url: self.options.url
}, options),
req = JSON.stringify({
url: options.url,
data: options.data
});
if (pending[req]) {
wait();
2011-04-22 22:03:10 +00:00
} else {
requests[options.id] = {
url: options.url,
data: options.data
};
if (cache[req] && (
options.age == -1
|| options.age > +new Date() - cache[req].time
)) {
data = cache[req].data;
2011-04-22 22:03:10 +00:00
setTimeout(function() {
callback(data, true);
2013-08-27 14:26:52 +00:00
});
2011-04-22 22:03:10 +00:00
} else {
pending[req] = true;
2011-04-22 22:03:10 +00:00
$.ajax({
2013-07-27 23:07:42 +00:00
beforeSend: function(request) {
var csrftoken = Ox.Cookies('csrftoken');
if (csrftoken) {
2013-07-27 23:07:42 +00:00
request.setRequestHeader('X-CSRFToken', csrftoken);
}
},
complete: complete,
2011-04-22 22:03:10 +00:00
data: options.data,
2013-07-27 23:07:42 +00:00
// dataType: 'json',
2011-04-22 22:03:10 +00:00
timeout: options.timeout,
type: options.type,
url: options.url
});
}
2012-01-27 14:29:11 +00:00
$element && $element.triggerEvent('request', {
requests: Ox.len(requests)
});
2011-04-22 22:03:10 +00:00
}
2013-07-27 23:07:42 +00:00
function callback(data, success) {
if (requests[options.id]) {
delete requests[options.id];
2012-01-27 14:29:11 +00:00
$element && $element.triggerEvent('request', {
requests: Ox.len(requests)
});
if (success) {
options.callback && options.callback(data);
} else {
$element && $element.triggerEvent('error', data);
}
2013-07-27 23:07:42 +00:00
}
2011-04-22 22:03:10 +00:00
}
function complete(request) {
2012-01-14 10:48:26 +00:00
var $dialog, data;
try {
data = JSON.parse(request.responseText);
2012-05-25 09:44:43 +00:00
} catch (error) {
2011-04-22 22:03:10 +00:00
try {
data = {
status: {
code: request.status,
text: request.statusText
}
};
2012-05-25 09:44:43 +00:00
} catch (error) {
data = {
status: {
code: '500',
text: 'Unknown Error'
}
};
2011-04-22 22:03:10 +00:00
}
}
2012-11-04 11:05:25 +00:00
if (Ox.contains([200, 404, 409], data.status.code)) {
2011-10-31 16:02:00 +00:00
// we have to include not found and conflict
// so that handlers can handle these cases
2013-08-27 14:26:52 +00:00
if (self.options.cache) {
cache[req] = {
data: data,
time: Ox.getTime()
};
}
2013-07-27 23:07:42 +00:00
callback(data, true);
2011-04-22 22:03:10 +00:00
} else {
2013-07-27 23:07:42 +00:00
callback(data, false);
2011-04-22 22:03:10 +00:00
}
delete pending[req];
}
function wait() {
setTimeout(function() {
if (pending[req]) {
wait();
} else {
Ox.Request.send(options);
}
});
2011-04-22 22:03:10 +00:00
}
return options.id;
},
/*@
2012-01-27 14:29:11 +00:00
unbindEvent <f> Unbind event
@*/
unbindEvent: function() {
2014-09-20 10:29:27 +00:00
$element && $element.unbindEvent.apply($element, arguments);
2011-04-22 22:03:10 +00:00
}
};
2011-11-30 14:49:11 +00:00
}());