2011-11-05 16:46:53 +00:00
|
|
|
'use strict';
|
|
|
|
|
2011-10-07 01:04:47 +00:00
|
|
|
/*@
|
|
|
|
Ox.get <f> Get a remote file
|
|
|
|
(url, callback) -> <u> undefined
|
|
|
|
url <s> Remote URL
|
|
|
|
callback <f> Callback function
|
|
|
|
data <s> The contents of the remote resource
|
2012-06-17 13:36:55 +00:00
|
|
|
error <o|null> Error, or null
|
|
|
|
code <n> Status code
|
|
|
|
text <s> Status text
|
2011-10-07 01:04:47 +00:00
|
|
|
@*/
|
|
|
|
Ox.get = function(url, callback) {
|
2012-06-17 13:36:55 +00:00
|
|
|
var request = new XMLHttpRequest();
|
|
|
|
request.open('GET', url, true);
|
|
|
|
request.onreadystatechange = function() {
|
|
|
|
if (request.readyState == 4) {
|
|
|
|
if (request.status == 200) {
|
|
|
|
callback(request.responseText, null);
|
2011-10-07 01:04:47 +00:00
|
|
|
} else {
|
2012-06-17 13:36:55 +00:00
|
|
|
callback(null, {
|
|
|
|
code: request.status,
|
|
|
|
text: request.statusText
|
|
|
|
});
|
2011-10-07 01:04:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
2012-06-17 13:36:55 +00:00
|
|
|
request.send();
|
2011-10-07 01:04:47 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/*@
|
2012-06-17 13:36:55 +00:00
|
|
|
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.
|
2011-10-07 01:04:47 +00:00
|
|
|
callback <f> Callback function
|
2012-06-17 13:36:55 +00:00
|
|
|
results <o> Results
|
|
|
|
Keys are file names, values are results
|
|
|
|
errors <o|null> Errors, or null
|
|
|
|
Keys are file names, values are error objects
|
2011-10-07 01:04:47 +00:00
|
|
|
@*/
|
2012-06-17 13:36:55 +00:00
|
|
|
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
|
|
|
|
);
|
|
|
|
}
|
|
|
|
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();
|
2012-04-19 11:23:24 +00:00
|
|
|
});
|
2012-06-17 13:36:55 +00:00
|
|
|
}
|
|
|
|
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();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
2011-11-23 14:53:17 +00:00
|
|
|
};
|
2011-10-07 01:04:47 +00:00
|
|
|
|
|
|
|
/*@
|
2012-06-17 13:36:55 +00:00
|
|
|
Ox.getFile <f> Loads a file (image, script or stylesheet)
|
2011-10-07 01:04:47 +00:00
|
|
|
(file="script.js", callback) -> <u> undefined
|
|
|
|
(file="stylesheet.css", callback) -> <u> undefined
|
2012-04-19 11:13:43 +00:00
|
|
|
(file="image.png", callback) -> <u> undefined
|
2011-10-07 01:04:47 +00:00
|
|
|
file <s> Local path or remote URL
|
|
|
|
callback <f> Callback function
|
2012-04-19 11:13:43 +00:00
|
|
|
image <e> DOM element (if the file is an image)
|
2011-10-07 01:04:47 +00:00
|
|
|
@*/
|
2012-06-17 13:36:55 +00:00
|
|
|
// FIXME: this doesn't handle errors yet
|
|
|
|
Ox.getFile = (function() {
|
|
|
|
|
2011-10-07 01:04:47 +00:00
|
|
|
var cache = {};
|
2012-05-22 23:17:17 +00:00
|
|
|
|
2012-06-17 13:36:55 +00:00
|
|
|
function getFile(file, callback) {
|
2011-10-07 01:04:47 +00:00
|
|
|
var element,
|
2012-06-17 13:36:55 +00:00
|
|
|
head = document.head
|
|
|
|
|| document.getElementsByTagName('head')[0]
|
|
|
|
|| document.documentElement,
|
2011-10-07 01:04:47 +00:00
|
|
|
request,
|
2011-11-05 16:46:53 +00:00
|
|
|
type = file.split('.').pop(),
|
2011-10-07 01:04:47 +00:00
|
|
|
isImage = type != 'css' && type != 'js';
|
|
|
|
if (!cache[file]) {
|
|
|
|
if (isImage) {
|
|
|
|
element = new Image();
|
|
|
|
element.onload = addFileToCache;
|
|
|
|
element.src = file;
|
|
|
|
} else {
|
|
|
|
if (!findFileInHead()) {
|
|
|
|
element = document.createElement(
|
|
|
|
type == 'css' ? 'link' : 'script'
|
|
|
|
);
|
2012-06-17 13:36:55 +00:00
|
|
|
element[
|
|
|
|
type == 'css' ? 'href' : 'src'
|
|
|
|
] = file + '?' + Ox.random(1000000);
|
2011-10-07 01:04:47 +00:00
|
|
|
element.type = type == 'css' ? 'text/css' : 'text/javascript';
|
2012-05-25 16:28:05 +00:00
|
|
|
if (type == 'css') {
|
|
|
|
element.rel = 'stylesheet';
|
|
|
|
}
|
2011-10-07 01:04:47 +00:00
|
|
|
if (/MSIE/.test(navigator.userAgent)) {
|
2012-06-17 13:36:55 +00:00
|
|
|
// fixme: find a way to check
|
|
|
|
// if css/js have loaded in msie
|
2011-10-07 01:04:47 +00:00
|
|
|
setTimeout(addFileToCache, 2500);
|
|
|
|
} else {
|
|
|
|
if (type == 'css') {
|
|
|
|
waitForCSS();
|
|
|
|
} else {
|
|
|
|
element.onload = addFileToCache;
|
|
|
|
}
|
|
|
|
}
|
2012-02-17 10:24:42 +00:00
|
|
|
head.appendChild(element);
|
2011-10-07 01:04:47 +00:00
|
|
|
} else {
|
|
|
|
addFileToCache();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
callback();
|
|
|
|
}
|
|
|
|
function addFileToCache() {
|
|
|
|
if (isImage) {
|
|
|
|
// for an image, save the element itself,
|
|
|
|
// so that it remains in the browser cache
|
2011-10-23 16:00:59 +00:00
|
|
|
cache[file] = element;
|
2011-10-07 01:04:47 +00:00
|
|
|
callback(element);
|
|
|
|
} else {
|
2011-10-23 16:00:59 +00:00
|
|
|
cache[file] = true;
|
2011-10-07 01:04:47 +00:00
|
|
|
callback();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function findFileInHead() {
|
2012-05-19 08:40:59 +00:00
|
|
|
return Ox.toArray(
|
2011-10-07 01:04:47 +00:00
|
|
|
document.getElementsByTagName(type == 'css' ? 'link' : 'script')
|
|
|
|
).map(function(element) {
|
|
|
|
return element[type == 'css' ? 'href' : 'src'] == file;
|
|
|
|
}).reduce(function(prev, curr) {
|
|
|
|
return prev || curr;
|
|
|
|
}, false);
|
|
|
|
}
|
|
|
|
function waitForCSS() {
|
|
|
|
var error = false;
|
|
|
|
try {
|
|
|
|
element.sheet.cssRule;
|
2012-05-25 09:41:51 +00:00
|
|
|
} catch (e) {
|
2011-10-07 01:04:47 +00:00
|
|
|
error = true;
|
|
|
|
setTimeout(function() {
|
|
|
|
waitForCSS();
|
|
|
|
}, 25);
|
|
|
|
}
|
|
|
|
!error && addFileToCache();
|
|
|
|
}
|
|
|
|
};
|
2012-06-17 13:36:55 +00:00
|
|
|
|
|
|
|
return function(files, callback) {
|
|
|
|
Ox.getAsync(files, function(file, callback) {
|
|
|
|
getFile(file, function(images) {
|
|
|
|
callback(images ? {file: images} : {});
|
|
|
|
});
|
|
|
|
}, callback);
|
|
|
|
};
|
|
|
|
|
2012-02-17 10:24:42 +00:00
|
|
|
}());
|
2012-04-19 11:13:43 +00:00
|
|
|
|
|
|
|
/*@
|
2012-06-17 13:36:55 +00:00
|
|
|
Ox.getJSON <f> Get and parse one or more remote JSON files
|
|
|
|
(url, callback) -> <u> undefined
|
|
|
|
url <s|a> One or more remote URLs
|
2012-04-19 11:13:43 +00:00
|
|
|
callback <f> Callback function
|
2012-06-17 13:36:55 +00:00
|
|
|
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
|
2012-04-19 11:13:43 +00:00
|
|
|
@*/
|
2012-06-17 13:36:55 +00:00
|
|
|
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);
|
2012-04-19 11:13:43 +00:00
|
|
|
});
|
2012-06-17 13:36:55 +00:00
|
|
|
}, 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) {
|
|
|
|
delete Ox.getJSONP[id];
|
|
|
|
callback(data, null);
|
|
|
|
};
|
|
|
|
Ox.$('body').append(Ox.$('<script>').attr({
|
|
|
|
'src': url.replace('{callback}', 'Ox.getJSONP.' + id),
|
|
|
|
'type': 'text/javascript'
|
|
|
|
}));
|
|
|
|
}, callback);
|
2012-05-22 23:17:17 +00:00
|
|
|
};
|