186 lines
6.3 KiB
JavaScript
186 lines
6.3 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 one or more remote JSON files
|
|
# fixme: remote? same-origin-policy? jsonp?
|
|
(url, callback) -> <u> undefined
|
|
url <s|[s]> One or more remote URLs
|
|
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.getJSON = (function() {
|
|
function getJSON(url, callback) {
|
|
Ox.get(url, function(data) {
|
|
callback(JSON.parse(data));
|
|
});
|
|
}
|
|
return function(url, callback) {
|
|
var urls = Ox.toArray(url), data = {}, i = 0, n = urls.length;
|
|
urls.forEach(function(url) {
|
|
getJSON(url, function(data_) {
|
|
data[url] = data_;
|
|
++i == n && callback(n == 1 ? data[url] : 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) -> <u> undefined
|
|
file <s> Local path or remote URL
|
|
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?
|
|
// 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();
|
|
}
|
|
};
|
|
}());
|
|
|
|
/*@
|
|
Ox.loadFiles <f> Loads multiple files (images, scripts or stylesheets)
|
|
(files, callback) -> <u> undefined
|
|
files <[s]|[[s]]> Array of files, or array of arrays of files
|
|
Multiple files in the same array will be loaded simultaneously, but
|
|
multiple arrays of files will be loaded in that order.
|
|
callback <f> Callback function
|
|
images <o> DOM elements (if any file was an image)
|
|
Keys are the file names, values are the DOM elements
|
|
@*/
|
|
Ox.loadFiles = (function() {
|
|
function loadFiles(files, callback) {
|
|
files = Ox.toArray(files);
|
|
var i = 0, n = files.length, images = {};
|
|
Ox.toArray(files).forEach(function(file) {
|
|
Ox.loadFile(file, function(image) {
|
|
if (image) {
|
|
images[file] = image;
|
|
}
|
|
++i == n && callback(images);
|
|
});
|
|
});
|
|
}
|
|
return function(files, callback) {
|
|
var i = 0, n = files.length, images = {};
|
|
files.forEach(function(file) {
|
|
loadFiles(file, function(images_) {
|
|
Ox.extend(images, images_)
|
|
++i == n && callback(Ox.len(images) ? images : void 0);
|
|
});
|
|
});
|
|
};
|
|
}());
|