Skip to content

Instantly share code, notes, and snippets.

@tsing
Created February 10, 2010 02:07
Show Gist options
  • Save tsing/299936 to your computer and use it in GitHub Desktop.
Save tsing/299936 to your computer and use it in GitHub Desktop.
ensure.js, inspired by ensure.js on codeplex.com
var ensure = (function() {
var loader = function() {};
loader.prototype = {
queues: { js: {}, css: {} },
load: function(data, callback, context) {
if (! data.css) data.css = [];
if (! data.js) data.js = [];
this.queueCSS(data.css, this.bind(function() {
this.queueJS(data.js, this.bind(callback, context));
}));
},
bind: function(func, context) {
context = context || this;
return function() { func.apply(context, arguments); }
},
tagExists: function(type, src) {
var tagName = "script";
var attName = "src";
if (type == "css") {
var tagName = "link";
var attName = "href";
}
var tag = document.createElement(tagName);
tag[attName] = src;
var tags = document.getElementsByTagName(tagName);
for (var i=0; i<tags.length; i++) {
if (tag[attName] === tags[i][attName]) {
return true;
}
}
return false;
},
process: function(type, src) {
if (this.queues[type][src]["status"] == "init") {
this.queues[type][src]["status"] = "loading";
this["get"+type.toUpperCase()].call(this, src);
}
else if (this.queues[type][src]["status"] == "loaded")
{
this.finish(type, src);
}
},
finish: function(type, src) {
this.queues[type][src]["status"] = "loaded";
while(this.queues[type][src]["callbacks"].length > 0) {
(this.queues[type][src]["callbacks"].shift())();
}
},
queue: function(type, src, callback) {
if (! this.queues[type][src]) {
this.queues[type][src] = {};
this.queues[type][src]["callbacks"] = [];
if (this.tagExists(type, src)) this.queues[type][src]["status"] = "loaded";
else this.queues[type][src]["status"] = "init";
}
this.queues[type][src]["callbacks"].push(callback);
this.process(type, src);
},
queueCSS: function(css_list, callback) {
var len = css_list.length;
if (len > 1) {
this.queue("css", css_list.shift(), this.bind(function() {
this.queueCSS(css_list, callback);
}, this));
}
else if (len == 1) {
this.queue("css", css_list.shift(), callback);
}
else
{
callback();
}
},
queueJS: function(js_list, callback) {
var len = js_list.length;
if (len > 1) {
this.queue("js", js_list.shift(), this.bind(function() {
this.queueJS(js_list, callback);
}, this));
}
else if (len == 1) {
this.queue("js", js_list.shift(), callback);
}
else
{
callback();
}
},
getHead: function() {
if (! this.head) {
this.head = document.getElementsByTagName("head")[0] || document.documentElement;
}
return this.head;
},
getJS: function(src) {
this.log("getJS: "+src);
jQuery.getScript(src, this.bind(function() {
this.finish("js", src);
}, this));
},
getCSS: function(src) {
this.log("getCSS: "+src);
var link = document.createElement('link');
link.setAttribute("href", src);
link.setAttribute("rel", "Stylesheet");
link.setAttribute("type", "text/css");
this.getHead().appendChild(link);
this.finish("css", src);
},
log: function(msg) {
}
};
var l = new loader();
return function(data, callback, context) {
return l.load(data, callback, context);
};
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment