oxjs/source/Ox/js/Request.js

139 lines
4.5 KiB
JavaScript

'use strict';
/*@
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
@*/
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);
} else {
throw new Error(
'Cannot get URL "' + url + '" (Status: ' + req.status + ')'
);
}
}
};
req.send();
};
/*@
Ox.getJSON <f> Get and parse a remote JSON file
# fixme: remote? same-origin-policy? jsonp?
(url, callback) -> <u> undefined
url <s> Remote URL
callback <f> Callback function
data <s> The parsed contents of the remote resource
@*/
Ox.getJSON = function(url, callback) {
Ox.get(url, function(data) {
callback(JSON.parse(data));
});
};
/*@
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)));
});
};
/*@
Ox.loadFile <f> Loads a file (image, script or stylesheet)
(file="script.js", callback) -> <u> undefined
(file="stylesheet.css", callback) -> <u> undefined
(file="image.png", callback) -> <e> DOM element
file <s> Local path or remote URL
callback <f> Callback function
@*/
Ox.loadFile = (function() {
// fixme: this doesn't handle errors yet
// fixme: rename to getFile?
// fixme: what about array of files?
var cache = {};
return function (file, callback) {
var element,
head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement,
request,
type = file.split('.').pop(),
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'
);
element[type == 'css' ? 'href' : 'src'] = file + '?' + Ox.random(1000000);
element.type = type == 'css' ? 'text/css' : 'text/javascript';
if (/MSIE/.test(navigator.userAgent)) {
// fixme: find a way to check if css/js have loaded in msie
setTimeout(addFileToCache, 2500);
} else {
if (type == 'css') {
element.rel = 'stylesheet';
waitForCSS();
} else {
element.onload = addFileToCache;
}
}
head.appendChild(element);
} else {
addFileToCache();
}
}
} else {
callback();
}
function addFileToCache() {
if (isImage) {
// for an image, save the element itself,
// so that it remains in the browser cache
cache[file] = element;
callback(element);
} else {
cache[file] = true;
callback();
}
}
function findFileInHead() {
return Ox.makeArray(
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;
} catch(e) {
error = true;
setTimeout(function() {
waitForCSS();
}, 25);
}
!error && addFileToCache();
}
};
}());