(function(win) { var _doc = win['document'], _loaded = {}, _loading = {}, _config = {mods: {}}; var loader = { load : function(url, type, charset, callback, context) { if (!url) return; var refFile = _doc.getElementsByTagName('script')[0]; if (_loaded[url]) { _loading[url] = false; if (callback) callback(url, context); return; } if (_loading[url]) { setTimeout(function() { loader.load(url, type, charset, callback, context); }, 1); return; } _loading[url] = true; var n, t = type || url.toLowerCase().substring(url.lastIndexOf('.') + 1); n =_doc.createElement('css'==t ? 'link' : 'script'); if (charset) n.charset = charset; if('css'===t){ n.type='text/css'; n.setAttribute('rel', 'stylesheet'); n.href=url; _loaded[url] = true; refFile.parentNode.insertBefore(n, refFile); if (cb) cb(url, context); return; } n.src= url; n.setAttribute('async', true); n.onload = n.onreadystatechange = function() { if (!this.readyState || this.readyState === 'loaded' || this.readyState === 'complete') { _loaded[this.getAttribute('src')] = true; if (callback) callback(this.getAttribute('src'), context); n.onload = n.onreadystatechange = null; } }; refFile.parentNode.insertBefore(n, refFile); }, clac : function(e) { if (!e || !e.length) return; var i = 0, item, result = [], mods = _config.mods, depeList = [], hasAdded = {}, getDepeList = function(e) { var j = 0, m, reqs; if (hasAdded[e]) return depeList; hasAdded[e] = true; if (mods[e].requires) { reqs = mods[e].requires; for (; typeof (m = reqs[j++]) !== 'undefined';) { if (mods[m]) getDepeList(m); depeList.push(m); } return depeList; } return depeList; }; for (; typeof (item = e[i++]) !== 'undefined'; ) { if (mods[item] && mods[item].requires && mods[item].requires[0]) { depeList = []; hasAdded = {}; result = result.concat(getDepeList(item)); } result.push(item); } return result; } }; var Thread = function(e) { if (!e || !e.length) return; this.queue = e; this.current = null; }; Thread.prototype = { start: function() { this.current = this.next(); if (!this.current) return; this.run(); }, run: function() { var o = this, mod, currentMod = this.current; if (typeof currentMod === 'function') { currentMod(); return this.start(); } else if (typeof currentMod === 'string') { if (_config.mods[currentMod]) { mod = _config.mods[currentMod]; loader.load(mod.path, mod.type, mod.charset, function(e) { o.start(); }, o); } else if (/\.js|\.css/i.test(currentMod)) { loader.load(currentMod, '', '', function(e, o) { o.start(); }, o); } else { this.start(); } } }, next: function() { return this.queue.shift(); } }; this.Ex_Loader = function() { new Thread(loader.clac(Array.prototype.slice.call(arguments))).start(); }; this.Ex_Loader.add = function(ModName, config) { if (!ModName || !config || !config.path) return; _config.mods[ModName] = config; }; })(this);