Skip to content

Instantly share code, notes, and snippets.

@ianva
Created January 25, 2011 02:02
Show Gist options
  • Save ianva/794389 to your computer and use it in GitHub Desktop.
Save ianva/794389 to your computer and use it in GitHub Desktop.
mod load
(function(window){
//----------------------------------------------------------------------------
// Global variables and related helpers
//----------------------------------------------------------------------------
var PATH_EXPR = /(?:([a-zA-Z0-9-._]*)\/)?(?:(?:([a-zA-Z0-9-._]+)\.js(?:\?(.*))?)|([a-zA-Z0-9-._]+))/,
uuid = 0,
_scriptTimeout = 10000,
mods = {};
function addMod(k,v){
var id = url2modID(k);
if(mods[id]){
for( i in v){
mods[id][i] = v[i];
}
}else{
++uuid;
if( k === '' || $type(k)==='object' ){
v = k
k = id = '_anonymous_'+uuid;
}
var vn = url2version(k);
mods[id] = mix({
name:url2modName(k),
path:'',
package:'',
path:'',
uuid:uuid,
package:'',
factory:function(){},
parent:null,
count:0,
dependencies:[],
exports:{},
status:0
},v);
if(mods[id].status === 1){
mods[id].path = id+'.js'+(vn?('?'+vn):'');
mods[id].package = url2pkgName(k);
}
}
return mods[id];
}
function delMod(key){
delete mods[key];
}
function loadMod(mod){
if(mod.dependencies === 0 || mod.count === mod.dependencies.length){
execMod(mod);
}
$each(mod.dependencies,function(i){
var m = addMod(i,{
parent:mod,
status:1
});
getScript(m.path,function(){
loadMod(m);
});
});
}
function execMod(mod){
mod.status = 2;
mod.factory(require,mod.exports);
if(mod.parent){
var t = true,i = 0,deps = mod.parent.dependencies,l = deps.length;
for(;i<l;i++){
if(mods[deps[i]].status !==2 )t= false;
}
if(t){
execMod(mod.parent);
}
}
}
//----------------------------------------------------------------------------
// Members
//----------------------------------------------------------------------------
function define( id, deps, factory ){
switch($type(id)){
case 'array':
factory = deps;
deps = id;
id = '';
break;
case 'function':
factory = id;
id = '';
break;
}
var m = {},d = [];
id = url2modID(id);
if(deps){
$each(deps,function(i){
d.push(url2modID(i));
});
}
if(mods[id]){
mods[id].dependencies = d;
mods[id].factory = factory || function(){};
}else{
m = addMod(id,{
dependencies : d,
factory : factory || function(){}
});
loadMod(m);
}
}
function require(id){
return mods[url2modID(id)].exports;
}
//----------------------------------------------------------------------------
// Static helpers
//----------------------------------------------------------------------------
function getScript(src,callback){
var s = document.createElement('script');
var hd = document.getElementsByTagName('head')[0];
s.type = "text/javascript";
s.src = src;
s.async = true;
var done = false;
s.onload = s.onreadystatechange = loadScript(s);
s.scriptTimer(s,callback);
hd.insertBefore(s, hd.firstChild);
}
function loadScript(s,callback){
if ( !done && (!this.readyState || this.readyState == "loaded" || this.readyState == "complete") ) {
if (s._timer)
clearTimeout(s._timer);
done = true;
s.onerror = s.onload = s.onreadystatechange = null;
if (s.clearAttributes)
try { s.clearAttributes(); }
catch (x) {}
hd.removeChild(s);
callback();
}
}
function scriptTimer(s,callback) {
function timeout() {
if (s.readyState === "interactive") {
s._timer = setTimeout(timeout, 200);
}
else if (!s._timer) {
s._timer = setTimeout(timeout, _scriptTimeout);
}
else {
s._timer = 0;
loadScript(s,callback);
}
}
timeout();
}
function url2modName(url){
return PATH_EXPR.exec(url)[2]||PATH_EXPR.exec(url)[4]||'';
}
function url2modID(url){
return url.replace(/\.js.*/,'');
}
function url2pkgName(url){
return PATH_EXPR.exec(url)[1]||'';
}
function url2version(url){
return PATH_EXPR.exec(url)[3]||'';
}
//----------------------------------------------------------------------------
// Language enhancement
//----------------------------------------------------------------------------
function mix(target) {
var objs = arguments, l = objs.length, o, copy;
if (l == 1) {
objs[1] = target;
l = 2;
target = oz;
}
for (var i = 1; i < l; i++) {
o = objs[i];
for (var n in o) {
copy = o[n];
if (copy != null)
target[n] = copy;
}
}
return target;
}
function $type(o){
if(o === undefined) return false;
if(o === null) return false;
if(o === window)return 'window';
if(o === document)return 'document';
switch(Object.prototype.toString.apply(o)){
case '[object Boolean]': return 'boolean';
case '[object Array]':return 'array';
case '[object Function]':return 'function';
case '[object Date]':return 'date';
case '[object RegExp]':return 'regexp';
case '[object String]':return 'string';
case '[object Number]':
if(isFinite(o)){
return 'number'
}else{
if(o===Infinity)return 'infinity';
if(o===-Infinity)return '-infinity';
return false
}
}
if (o.nodeName) {
switch (o.nodeType) {
case 1: return 'element';
case 3: return (/\S/).test(o.nodeValue) ? 'textnode' : 'whitespace';
}
} else if (typeof o.length === 'number') {
if (o.callee) return 'arguments';
else if (o.item) return 'collection';
}
if(typeof o === 'object')return 'object';
return false;
};
function $each(iterable,fn, bind){
var type = $type(iterable);
if(type == 'arguments' || type == 'collection' || type == 'array'){
for (var i = 0, l = iterable.length; i < l; i++) fn.call(bind, iterable[i], i, iterable);
}else{
for (var key in iterable){
if (iterable.hasOwnProperty(key)) fn.call(bind, iterable[key], key, iterable);
}
}
}
window.define = define;
})(window);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment