Requests.js: handle errors, various other improvements
This commit is contained in:
parent
ec87a5c51c
commit
77adfbf7b8
1 changed files with 133 additions and 106 deletions
|
@ -2,93 +2,78 @@
|
|||
|
||||
/*@
|
||||
Ox.get <f> Get a remote file
|
||||
# fixme: remote? same-origin-policy? jsonp?
|
||||
(url, callback) -> <u> undefined
|
||||
url <s> Remote URL
|
||||
callback <f> Callback function
|
||||
data <s> The contents of the remote resource
|
||||
error <o|null> Error, or null
|
||||
code <n> Status code
|
||||
text <s> Status text
|
||||
@*/
|
||||
Ox.get = function(url, callback) {
|
||||
var req = new XMLHttpRequest();
|
||||
req.open('GET', url, true);
|
||||
req.onreadystatechange = function() {
|
||||
if (req.readyState == 4) {
|
||||
if (req.status == 200) {
|
||||
callback(req.responseText);
|
||||
var request = new XMLHttpRequest();
|
||||
request.open('GET', url, true);
|
||||
request.onreadystatechange = function() {
|
||||
if (request.readyState == 4) {
|
||||
if (request.status == 200) {
|
||||
callback(request.responseText, null);
|
||||
} else {
|
||||
throw new Error(
|
||||
'Cannot get URL "' + url + '" (Status: ' + req.status + ')'
|
||||
);
|
||||
callback(null, {
|
||||
code: request.status,
|
||||
text: request.statusText
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
req.send();
|
||||
request.send();
|
||||
};
|
||||
|
||||
/*@
|
||||
Ox.getJSON <f> Get and parse one or more remote JSON files
|
||||
# fixme: remote? same-origin-policy?
|
||||
(url, callback) -> <u> undefined
|
||||
url <s|[s]> One or more remote URLs
|
||||
Ox.getAsync <f> Runs an asynchonous loader for an array of URLs
|
||||
(urls, map, callback) -> <u> undefined
|
||||
urls <s|a> URL or array of either URLs or arrays of URLs
|
||||
Multiple URLs in the same array will be processed simultaneously, but
|
||||
multiple arrays of URLs will be processed in that order.
|
||||
callback <f> Callback function
|
||||
data <o> The parsed contents of the remote resource(s)
|
||||
For multiple URLs, keys are file names, values are contents
|
||||
results <o> Results
|
||||
Keys are file names, values are results
|
||||
errors <o|null> Errors, or null
|
||||
Keys are file names, values are error objects
|
||||
@*/
|
||||
Ox.getJSON = function(url, callback) {
|
||||
var urls = Ox.makeArray(url);
|
||||
Ox.loadAsync(urls, function(url, callback) {
|
||||
Ox.get(url, function(data) {
|
||||
var result = {};
|
||||
result[url] = JSON.parse(data);
|
||||
callback(result);
|
||||
});
|
||||
}, function(results) {
|
||||
callback(urls.length == 1 ? results[url] : results);
|
||||
});
|
||||
}
|
||||
|
||||
/*@
|
||||
Ox.getJSONP <f> Get and parse one or more remote JSONP files
|
||||
(url, callback) -> <u> undefined
|
||||
url <s|[s]> One or more remote URLs,
|
||||
{callback} gets replaced with jsonp callback function name
|
||||
callback <f> Callback function
|
||||
data <o> The parsed contents of the remote resource(s)
|
||||
For multiple URLs, keys are file names, values are contents
|
||||
@*/
|
||||
Ox.getJSONP = function(url, callback) {
|
||||
var urls = Ox.makeArray(url);
|
||||
Ox.loadAsync(urls, function(url, callback) {
|
||||
var id = 'callback' + Ox.uid();
|
||||
Ox.getJSONP[id] = function(data) {
|
||||
delete Ox.getJSONP[id];
|
||||
callback(data);
|
||||
Ox.getAsync = function(urls, map, callback) {
|
||||
urls = Ox.clone(Ox.makeArray(urls));
|
||||
var errors = {}, i = 0, n = urls.length, results = {};
|
||||
function done() {
|
||||
callback(
|
||||
n == 1 ? results[urls[0]] : results,
|
||||
n == 1 ? errors[urls[0]] : Ox.some(errors, function(error) {
|
||||
return error !== null;
|
||||
}) ? errors : null
|
||||
);
|
||||
}
|
||||
Ox.$('body').append(Ox.$('<script>').attr({
|
||||
'src': url.replace('{callback}', 'Ox.getJSONP.' + id),
|
||||
'type': 'text/javascript'
|
||||
}));
|
||||
}, function(results) {
|
||||
callback(urls.length == 1 ? results[url] : results);
|
||||
function iterate() {
|
||||
var url = urls.shift();
|
||||
Ox.getAsync(url, function(result, error) {
|
||||
Ox.extend(results, url, result);
|
||||
Ox.extend(errors, url, error);
|
||||
urls.length ? iterate() : done();
|
||||
});
|
||||
}
|
||||
|
||||
/*@
|
||||
Ox.getJSONC <f> Get and parse a remote JSONC file
|
||||
JSONC is JSON with JavaScript line or block comments
|
||||
(url, callback) -> <u> undefined
|
||||
url <s> Remote URL
|
||||
callback <f> Callback function
|
||||
data <s> The parsed contents of the remote resource
|
||||
@*/
|
||||
Ox.getJSONC = function(url, callback) {
|
||||
Ox.get(url, function(data) {
|
||||
callback(JSON.parse(Ox.minify(data)));
|
||||
}
|
||||
if (urls.some(Ox.isArray)) {
|
||||
iterate();
|
||||
} else {
|
||||
urls.forEach(function(url) {
|
||||
map(url, function(result, error) {
|
||||
Ox.extend(results, url, result);
|
||||
Ox.extend(errors, url, error);
|
||||
++i == n && done();
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/*@
|
||||
Ox.loadFile <f> Loads a file (image, script or stylesheet)
|
||||
Ox.getFile <f> Loads a file (image, script or stylesheet)
|
||||
(file="script.js", callback) -> <u> undefined
|
||||
(file="stylesheet.css", callback) -> <u> undefined
|
||||
(file="image.png", callback) -> <u> undefined
|
||||
|
@ -96,21 +81,16 @@ Ox.loadFile <f> Loads a file (image, script or stylesheet)
|
|||
callback <f> Callback function
|
||||
image <e> DOM element (if the file is an image)
|
||||
@*/
|
||||
Ox.loadFile = (function() {
|
||||
// fixme: this doesn't handle errors yet
|
||||
// fixme: rename to getFile?
|
||||
var cache = {};
|
||||
return function(files, callback) {
|
||||
Ox.loadAsync(files, function(file, callback) {
|
||||
loadFile(file, function(images) {
|
||||
callback(images ? {file: images} : {});
|
||||
});
|
||||
}, callback);
|
||||
}
|
||||
// FIXME: this doesn't handle errors yet
|
||||
Ox.getFile = (function() {
|
||||
|
||||
function loadFile(file, callback) {
|
||||
var cache = {};
|
||||
|
||||
function getFile(file, callback) {
|
||||
var element,
|
||||
head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement,
|
||||
head = document.head
|
||||
|| document.getElementsByTagName('head')[0]
|
||||
|| document.documentElement,
|
||||
request,
|
||||
type = file.split('.').pop(),
|
||||
isImage = type != 'css' && type != 'js';
|
||||
|
@ -124,13 +104,16 @@ Ox.loadFile = (function() {
|
|||
element = document.createElement(
|
||||
type == 'css' ? 'link' : 'script'
|
||||
);
|
||||
element[type == 'css' ? 'href' : 'src'] = file + '?' + Ox.random(1000000);
|
||||
element[
|
||||
type == 'css' ? 'href' : 'src'
|
||||
] = file + '?' + Ox.random(1000000);
|
||||
element.type = type == 'css' ? 'text/css' : 'text/javascript';
|
||||
if (type == 'css') {
|
||||
element.rel = 'stylesheet';
|
||||
}
|
||||
if (/MSIE/.test(navigator.userAgent)) {
|
||||
// fixme: find a way to check if css/js have loaded in msie
|
||||
// fixme: find a way to check
|
||||
// if css/js have loaded in msie
|
||||
setTimeout(addFileToCache, 2500);
|
||||
} else {
|
||||
if (type == 'css') {
|
||||
|
@ -180,34 +163,78 @@ Ox.loadFile = (function() {
|
|||
!error && addFileToCache();
|
||||
}
|
||||
};
|
||||
|
||||
return function(files, callback) {
|
||||
Ox.getAsync(files, function(file, callback) {
|
||||
getFile(file, function(images) {
|
||||
callback(images ? {file: images} : {});
|
||||
});
|
||||
}, callback);
|
||||
};
|
||||
|
||||
}());
|
||||
|
||||
/*@
|
||||
Ox.loadAsync <f> Runs an asynchonous function on array elements
|
||||
(arr, map, callback) -> <u> undefined
|
||||
arr <s|a> String or array of either strings or arrays of strings
|
||||
Multiple strings in the same array will be processed simultaneously, but
|
||||
multiple arrays of strings will be processed in that order.
|
||||
Ox.getJSON <f> Get and parse one or more remote JSON files
|
||||
(url, callback) -> <u> undefined
|
||||
url <s|a> One or more remote URLs
|
||||
callback <f> Callback function
|
||||
results <o> Results
|
||||
data <*|o> The parsed content of the remote resource(s)
|
||||
For multiple URLs, keys are file names, values are parsed contents
|
||||
error <o|null> Error(s)
|
||||
For multiple URLs, keys are file names, values are error objects
|
||||
@*/
|
||||
Ox.loadAsync = function(array, map, callback) {
|
||||
array = Ox.makeArray(array);
|
||||
var i = 0, n = array.length, results = {};
|
||||
if (array.some(Ox.isArray)) {
|
||||
iterate();
|
||||
} else {
|
||||
array.forEach(function(value) {
|
||||
map(value, function(result) {
|
||||
Ox.extend(results, result);
|
||||
++i == n && callback(results);
|
||||
Ox.getJSON = function(url, callback, isJSONC) {
|
||||
var urls = Ox.makeArray(url);
|
||||
Ox.getAsync(urls, function(url, callback) {
|
||||
Ox.get(url, function(data, error) {
|
||||
callback(JSON.parse(
|
||||
isJSONC ? Ox.minify(data || '') : data
|
||||
), error);
|
||||
});
|
||||
});
|
||||
}
|
||||
function iterate() {
|
||||
Ox.loadAsync(array.shift(), function(result) {
|
||||
Ox.extend(results, result);
|
||||
array.length ? iterate() : callback(results);
|
||||
});
|
||||
}
|
||||
}, callback);
|
||||
};
|
||||
|
||||
/*@
|
||||
Ox.getJSONC <f> Get and parse a remote JSONC file
|
||||
JSONC is JSON with JavaScript line or block comments
|
||||
(url, callback) -> <u> undefined
|
||||
url <s|a> One or more remote URLs
|
||||
callback <f> Callback function
|
||||
data <*|o> The parsed content of the remote resource(s)
|
||||
For multiple URLs, keys are file names, values are parsed contents
|
||||
error <o|null> Error(s)
|
||||
For multiple URLs, keys are file names, values are error objects
|
||||
@*/
|
||||
Ox.getJSONC = function(url, callback) {
|
||||
Ox.getJSON(url, function(results, errors) {
|
||||
callback(results, errors);
|
||||
}, true);
|
||||
};
|
||||
|
||||
/*@
|
||||
Ox.getJSONP <f> Get and parse one or more remote JSONP files
|
||||
(url, callback) -> <u> undefined
|
||||
url <s|a> One or more remote URLs
|
||||
{callback} gets replaced with jsonp callback function name
|
||||
callback <f> Callback function
|
||||
data <*|o> The parsed content of the remote resource(s)
|
||||
For multiple URLs, keys are file names, values are parsed contents
|
||||
error <o|null> Error(s)
|
||||
For multiple URLs, keys are file names, values are error objects
|
||||
@*/
|
||||
Ox.getJSONP = function(url, callback) {
|
||||
var urls = Ox.makeArray(url);
|
||||
Ox.getAsync(urls, function(url, callback) {
|
||||
var id = 'callback' + Ox.uid();
|
||||
Ox.getJSONP[id] = function(data) {
|
||||
Ox.print('DATA', data)
|
||||
delete Ox.getJSONP[id];
|
||||
callback(data, null);
|
||||
};
|
||||
Ox.$('body').append(Ox.$('<script>').attr({
|
||||
'src': url.replace('{callback}', 'Ox.getJSONP.' + id),
|
||||
'type': 'text/javascript'
|
||||
}));
|
||||
}, callback);
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue