|
1 | | -!function(win, doc, timeout) { |
| 1 | +!function (win, doc, timeout) { |
2 | 2 | var head = doc.getElementsByTagName('head')[0], |
3 | | - list = {}, ids = {}, delay = {}, |
4 | | - scripts = {}, s = 'string', f = false, |
5 | | - push = 'push', domContentLoaded = 'DOMContentLoaded', readyState = 'readyState', |
| 3 | + list = {}, ids = {}, delay = {}, scripts = {}, |
| 4 | + s = 'string', f = false, push = 'push', |
| 5 | + domContentLoaded = 'DOMContentLoaded', readyState = 'readyState', |
6 | 6 | addEventListener = 'addEventListener', onreadystatechange = 'onreadystatechange', |
7 | | - every = function(ar, fn) { |
8 | | - for (var i = 0, j = ar.length; i < j; ++i) { |
9 | | - if (!fn(ar[i])) { |
10 | | - return f; |
11 | | - } |
12 | | - } |
13 | | - return 1; |
14 | | - }; |
15 | | - function each(ar, fn) { |
16 | | - every(ar, function(el) { |
17 | | - return !fn(el); |
18 | | - }); |
19 | | - } |
| 7 | + faux = doc.createElement('script'), |
| 8 | + preloadExplicit = typeof faux.preload == 'boolean', |
| 9 | + preloadReal = preloadExplicit || (faux[readyState] && faux[readyState] == 'uninitialized'), |
| 10 | + async = !preloadReal && faux.async === true |
20 | 11 |
|
21 | 12 | if (!doc[readyState] && doc[addEventListener]) { |
22 | 13 | doc[addEventListener](domContentLoaded, function fn() { |
23 | 14 | doc.removeEventListener(domContentLoaded, fn, f); |
24 | | - doc[readyState] = "complete"; |
| 15 | + doc[readyState] = 'complete'; |
25 | 16 | }, f); |
26 | | - doc[readyState] = "loading"; |
| 17 | + doc[readyState] = 'loading'; |
| 18 | + } |
| 19 | + |
| 20 | + function every(ar, fn, i) { |
| 21 | + for (i = 0, j = ar.length; i < j; ++i) if (!fn(ar[i])) return f |
| 22 | + return 1; |
27 | 23 | } |
28 | 24 |
|
29 | | - var $script = function(paths, idOrDone, optDone) { |
30 | | - paths = paths[push] ? paths : [paths]; |
| 25 | + function each(ar, fn) { |
| 26 | + every(ar, function (el) { |
| 27 | + return !fn(el); |
| 28 | + }) |
| 29 | + } |
| 30 | + |
| 31 | + function $script(paths, idOrDone, optDone) { |
| 32 | + paths = paths[push] ? paths : [paths] |
31 | 33 | var idOrDoneIsDone = idOrDone && idOrDone.call, |
| 34 | + workingPaths = paths.slice(0), loadedPaths = {}, |
32 | 35 | done = idOrDoneIsDone ? idOrDone : optDone, |
33 | 36 | id = idOrDoneIsDone ? paths.join('') : idOrDone, |
34 | | - queue = paths.length; |
35 | | - function loopFn(item) { |
36 | | - return item.call ? item() : list[item]; |
37 | | - } |
38 | | - function callback() { |
39 | | - if (!--queue) { |
40 | | - list[id] = 1; |
41 | | - done && done(); |
42 | | - for (var dset in delay) { |
43 | | - every(dset.split('|'), loopFn) && !each(delay[dset], loopFn) && (delay[dset] = []); |
44 | | - } |
45 | | - } |
| 37 | + queue = paths.length |
| 38 | + function loopFn(item) { |
| 39 | + return item.call ? item() : list[item] |
| 40 | + } |
| 41 | + function callback() { |
| 42 | + if (!--queue) { |
| 43 | + list[id] = 1 |
| 44 | + done && done() |
| 45 | + for (var dset in delay) { |
| 46 | + every(dset.split('|'), loopFn) && !each(delay[dset], loopFn) && (delay[dset] = []) |
46 | 47 | } |
47 | | - timeout(function() { |
48 | | - each(paths, function(path) { |
| 48 | + } |
| 49 | + } |
| 50 | + timeout(function () { |
| 51 | + each(paths, function (path, p) { |
| 52 | + p = $script.path ? $script.path + path + '.js' : path |
49 | 53 | if (scripts[path]) { |
50 | | - id && (ids[id] = 1); |
51 | | - callback(); |
52 | | - return; |
| 54 | + ids[id] = id || f |
| 55 | + return callback() |
53 | 56 | } |
54 | | - scripts[path] = 1; |
55 | | - id && (ids[id] = 1); |
56 | | - create($script.path ? |
57 | | - $script.path + path + '.js' : |
58 | | - path, callback); |
59 | | - }); |
60 | | - }, 0); |
61 | | - return $script; |
62 | | - }; |
| 57 | + scripts[path] = 1 |
| 58 | + ids[id] = id || f |
| 59 | + // preload(p, function (el) { |
| 60 | + !$script.order ? create(p, callback) : preload(p, function (el) { |
| 61 | + if (async) return callback() |
| 62 | + el && head.insertBefore(el, head.firstChild) |
| 63 | + loadedPaths[p] = 1 |
| 64 | + workingPaths[0] == p && create(p, callback) |
| 65 | + workingPaths.shift() |
| 66 | + while (loadedPaths[workingPaths[0]]) { |
| 67 | + create(workingPaths[0], callback) |
| 68 | + workingPaths.shift() |
| 69 | + } |
| 70 | + }) |
| 71 | + }) |
| 72 | + }, 0) |
| 73 | + return $script |
| 74 | + } |
63 | 75 |
|
64 | | - function create(path, fn) { |
65 | | - var el = doc.createElement("script"), |
66 | | - loaded = f; |
67 | | - el.onload = el.onerror = el[onreadystatechange] = function () { |
68 | | - if ((el[readyState] && !(/^c|loade/.test(el[readyState]))) || loaded) { |
69 | | - return; |
| 76 | + function create(path, fn, type) { |
| 77 | + var el = doc.createElement('script'), loaded = f |
| 78 | + console.log('create("' + path + '")'); |
| 79 | + el.type = type || 'text/javascript' |
| 80 | + el.async = !$script.order |
| 81 | + el.onload = el[onreadystatechange] = function () { |
| 82 | + if ((el[readyState] && !(/^c|loade/.test(el[readyState]))) || loaded) return |
| 83 | + el.onload = el[onreadystatechange] = null |
| 84 | + loaded = 1 |
| 85 | + fn && fn() |
| 86 | + } |
| 87 | + el.src = path |
| 88 | + head.insertBefore(el, head.firstChild) |
| 89 | + } |
| 90 | + |
| 91 | + function preload(path, fn, el) { |
| 92 | + el = doc.createElement('script') |
| 93 | + if (preloadReal) { |
| 94 | + if (preloadExplicit) { |
| 95 | + el.preload = true |
| 96 | + el.onpreload = function () { |
| 97 | + fn(el) |
| 98 | + } |
| 99 | + } else { |
| 100 | + el[onreadystatechange] = function(){ |
| 101 | + el[readyState] == 'loaded' && fn(el) |
| 102 | + el[onreadystatechange] = null |
| 103 | + } |
70 | 104 | } |
71 | | - el.onload = el[onreadystatechange] = null; |
72 | | - loaded = 1; |
73 | | - fn(); |
74 | | - }; |
75 | | - el.async = 1; |
76 | | - el.src = path; |
77 | | - head.insertBefore(el, head.firstChild); |
| 105 | + script.src = path |
| 106 | + } else if (async) { |
| 107 | + create(path, fn) |
| 108 | + } else { |
| 109 | + create(path, fn, 'text/cache-script') |
| 110 | + } |
78 | 111 | } |
79 | 112 |
|
80 | | - $script.get = create; |
| 113 | + $script.get = create |
| 114 | + $script.order = true |
81 | 115 |
|
82 | | - $script.ready = function(deps, ready, req) { |
83 | | - deps = deps[push] ? deps : [deps]; |
84 | | - var missing = []; |
85 | | - !each(deps, function(dep) { |
86 | | - list[dep] || missing[push](dep); |
87 | | - }) && every(deps, function(dep) { |
88 | | - return list[dep]; |
89 | | - }) ? ready() : !function(key) { |
90 | | - delay[key] = delay[key] || []; |
91 | | - delay[key][push](ready); |
92 | | - req && req(missing); |
93 | | - }(deps.join('|')); |
94 | | - return $script; |
| 116 | + $script.ready = function (deps, ready, req) { |
| 117 | + deps = deps[push] ? deps : [deps] |
| 118 | + var missing = [] |
| 119 | + !each(deps, function (dep) { |
| 120 | + list[dep] || missing[push](dep) |
| 121 | + }) && every(deps, function (dep) { |
| 122 | + return list[dep] |
| 123 | + }) ? ready() : !function (key) { |
| 124 | + delay[key] = delay[key] || [] |
| 125 | + delay[key][push](ready) |
| 126 | + req && req(missing) |
| 127 | + }(deps.join('|')) |
| 128 | + return $script |
95 | 129 | }; |
96 | 130 |
|
97 | 131 | var old = win.$script; |
|
0 commit comments