1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
|
(function() { var map = {}, root = [], reqs = {}, q = [], CREATED = 0, QUEUED = 1, REQUESTED = 2, LOADED = 3, COMPLETE = 4, FAILED = 5;
function Requirement(url) { this.url = url; this.listeners = []; this.status = CREATED; this.children = []; reqs[url] = this; }
Requirement.prototype = { push: function push(child) { this.children.push(child); }, check: function check() { var list = this.children, i = list.length, l; while (i) { if (list[--i].status !== COMPLETE) return; }
this.status = COMPLETE; for (list = this.listeners, l = list.length; i < l; ++i) { list[i](); } }, loaded: function loaded() { this.status = LOADED; this.check(); if (q.shift() === this && q.length) q[0].load(); }, failed: function failed() { this.status = FAILED; if (q.shift() === this && q.length) q[0].load(); }, load: function load() { var r = this, d = document, s = d.createElement('script'); s.type = 'text/javascript'; s.src = r.url; s.requirement = r; function cleanup() { if (!s.onload) return true; s.onload = s.onerror = s.onreadystatechange = null; d.body.removeChild(s); } s.onload = function onload() { if (!cleanup()) r.loaded(); }; s.onerror = function onerror() { if (!cleanup()) r.failed(); }; if (s.readyState) { s.onreadystatechange = function () { if (s.readyState === 'complete' || s.readyState === 'loaded') s.onload(); }; } r.status = REQUESTED; d.body.appendChild(s); }, request: function request(onready) { this.listeners.push(onready); if (this.status === COMPLETE) { onready(); return; }
var tags = document.getElementsByTagName('script'), i = tags.length, parent = 0; while (i && !parent) { parent = tags[--i].requirement; } (parent || root).push(this); if (parent) this.listeners.push(function() { parent.check(); });
if (this.status === CREATED) { this.status = QUEUED; if (q.push(this) === 1) { this.load(); } } } };
function resolve(name) { if (/\/|\\|\.js$/.test(name)) return name; if (map[name]) return map[name]; var parts = name.split('.'), used = [], ns; while (parts.length) { if (map[ns = parts.join('.')]) return map[ns] + used.reverse().join('/') + '.js'; used.push(parts.pop()); } return used.reverse().join('/') + '.js'; }
function absolutize(url) { if (/^(https?|ftp|file):/.test(url)) return url; return (/^\//.test(url) ? absolutize.base : absolutize.path) + url; } (function () { var tags = document.getElementsByTagName('base'), href = (tags.length ? tags.get(tags.length - 1) : location).href; absolutize.path = href.substr(0, href.lastIndexOf('/') + 1) || href; absolutize.base = href.split(/\\|\//).slice(0, 3).join('/'); })();
function require(arr, onready) { if (typeof arr === 'string') arr = [ arr ]; if (typeof onready !== 'function') onready = false; var left = arr.length, i = arr.length; if (!left && onready) onready(); while (i) { var url = absolutize(resolve(arr[--i])), req = reqs[url] || new Requirement(url); req.request(function check() { if (!--left && onready) onready(); }); } }
require.map = function mapto(name, loc) { map[name] = loc; }; require.unmap = function unmap(name) { delete map[name]; }; require.tree = root; jQuery.require = require; })();
|