sea-debug.js 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983
  1. /**
  2. * Sea.js 3.0.3 | seajs.org/LICENSE.md
  3. */
  4. (function(global, undefined) {
  5. // Avoid conflicting when `sea.js` is loaded multiple times
  6. if (global.seajs) {
  7. return
  8. }
  9. var seajs = global.seajs = {
  10. // The current version of Sea.js being used
  11. version: "3.0.3"
  12. }
  13. var data = seajs.data = {}
  14. /**
  15. * util-lang.js - The minimal language enhancement
  16. */
  17. function isType(type) {
  18. return function(obj) {
  19. return {}.toString.call(obj) == "[object " + type + "]"
  20. }
  21. }
  22. var isObject = isType("Object")
  23. var isString = isType("String")
  24. var isArray = Array.isArray || isType("Array")
  25. var isFunction = isType("Function")
  26. var isUndefined = isType("Undefined")
  27. var _cid = 0
  28. function cid() {
  29. return _cid++
  30. }
  31. /**
  32. * util-events.js - The minimal events support
  33. */
  34. var events = data.events = {}
  35. // Bind event
  36. seajs.on = function(name, callback) {
  37. var list = events[name] || (events[name] = [])
  38. list.push(callback)
  39. return seajs
  40. }
  41. // Remove event. If `callback` is undefined, remove all callbacks for the
  42. // event. If `event` and `callback` are both undefined, remove all callbacks
  43. // for all events
  44. seajs.off = function(name, callback) {
  45. // Remove *all* events
  46. if (!(name || callback)) {
  47. events = data.events = {}
  48. return seajs
  49. }
  50. var list = events[name]
  51. if (list) {
  52. if (callback) {
  53. for (var i = list.length - 1; i >= 0; i--) {
  54. if (list[i] === callback) {
  55. list.splice(i, 1)
  56. }
  57. }
  58. }
  59. else {
  60. delete events[name]
  61. }
  62. }
  63. return seajs
  64. }
  65. // Emit event, firing all bound callbacks. Callbacks receive the same
  66. // arguments as `emit` does, apart from the event name
  67. var emit = seajs.emit = function(name, data) {
  68. var list = events[name]
  69. if (list) {
  70. // Copy callback lists to prevent modification
  71. list = list.slice()
  72. // Execute event callbacks, use index because it's the faster.
  73. for(var i = 0, len = list.length; i < len; i++) {
  74. list[i](data)
  75. }
  76. }
  77. return seajs
  78. }
  79. /**
  80. * util-path.js - The utilities for operating path such as id, uri
  81. */
  82. var DIRNAME_RE = /[^?#]*\//
  83. var DOT_RE = /\/\.\//g
  84. var DOUBLE_DOT_RE = /\/[^/]+\/\.\.\//
  85. var MULTI_SLASH_RE = /([^:/])\/+\//g
  86. // Extract the directory portion of a path
  87. // dirname("a/b/c.js?t=123#xx/zz") ==> "a/b/"
  88. // ref: http://jsperf.com/regex-vs-split/2
  89. function dirname(path) {
  90. return path.match(DIRNAME_RE)[0]
  91. }
  92. // Canonicalize a path
  93. // realpath("http://test.com/a//./b/../c") ==> "http://test.com/a/c"
  94. function realpath(path) {
  95. // /a/b/./c/./d ==> /a/b/c/d
  96. path = path.replace(DOT_RE, "/")
  97. /*
  98. @author wh1100717
  99. a//b/c ==> a/b/c
  100. a///b/////c ==> a/b/c
  101. DOUBLE_DOT_RE matches a/b/c//../d path correctly only if replace // with / first
  102. */
  103. path = path.replace(MULTI_SLASH_RE, "$1/")
  104. // a/b/c/../../d ==> a/b/../d ==> a/d
  105. while (path.match(DOUBLE_DOT_RE)) {
  106. path = path.replace(DOUBLE_DOT_RE, "/")
  107. }
  108. return path
  109. }
  110. // Normalize an id
  111. // normalize("path/to/a") ==> "path/to/a.js"
  112. // NOTICE: substring is faster than negative slice and RegExp
  113. function normalize(path) {
  114. var last = path.length - 1
  115. var lastC = path.charCodeAt(last)
  116. // If the uri ends with `#`, just return it without '#'
  117. if (lastC === 35 /* "#" */) {
  118. return path.substring(0, last)
  119. }
  120. return (path.substring(last - 2) === ".js" ||
  121. path.indexOf("?") > 0 ||
  122. lastC === 47 /* "/" */) ? path : path + ".js"
  123. }
  124. var PATHS_RE = /^([^/:]+)(\/.+)$/
  125. var VARS_RE = /{([^{]+)}/g
  126. function parseAlias(id) {
  127. var alias = data.alias
  128. return alias && isString(alias[id]) ? alias[id] : id
  129. }
  130. function parsePaths(id) {
  131. var paths = data.paths
  132. var m
  133. if (paths && (m = id.match(PATHS_RE)) && isString(paths[m[1]])) {
  134. id = paths[m[1]] + m[2]
  135. }
  136. return id
  137. }
  138. function parseVars(id) {
  139. var vars = data.vars
  140. if (vars && id.indexOf("{") > -1) {
  141. id = id.replace(VARS_RE, function(m, key) {
  142. return isString(vars[key]) ? vars[key] : m
  143. })
  144. }
  145. return id
  146. }
  147. function parseMap(uri) {
  148. var map = data.map
  149. var ret = uri
  150. if (map) {
  151. for (var i = 0, len = map.length; i < len; i++) {
  152. var rule = map[i]
  153. ret = isFunction(rule) ?
  154. (rule(uri) || uri) :
  155. uri.replace(rule[0], rule[1])
  156. // Only apply the first matched rule
  157. if (ret !== uri) break
  158. }
  159. }
  160. return ret
  161. }
  162. var ABSOLUTE_RE = /^\/\/.|:\//
  163. var ROOT_DIR_RE = /^.*?\/\/.*?\//
  164. function addBase(id, refUri) {
  165. var ret
  166. var first = id.charCodeAt(0)
  167. // Absolute
  168. if (ABSOLUTE_RE.test(id)) {
  169. ret = id
  170. }
  171. // Relative
  172. else if (first === 46 /* "." */) {
  173. ret = (refUri ? dirname(refUri) : data.cwd) + id
  174. }
  175. // Root
  176. else if (first === 47 /* "/" */) {
  177. var m = data.cwd.match(ROOT_DIR_RE)
  178. ret = m ? m[0] + id.substring(1) : id
  179. }
  180. // Top-level
  181. else {
  182. ret = data.base + id
  183. }
  184. // Add default protocol when uri begins with "//"
  185. if (ret.indexOf("//") === 0) {
  186. ret = location.protocol + ret
  187. }
  188. return realpath(ret)
  189. }
  190. function id2Uri(id, refUri) {
  191. if (!id) return ""
  192. id = parseAlias(id)
  193. id = parsePaths(id)
  194. id = parseAlias(id)
  195. id = parseVars(id)
  196. id = parseAlias(id)
  197. id = normalize(id)
  198. id = parseAlias(id)
  199. var uri = addBase(id, refUri)
  200. uri = parseAlias(uri)
  201. uri = parseMap(uri)
  202. return uri
  203. }
  204. // For Developers
  205. seajs.resolve = id2Uri
  206. // Check environment
  207. var isWebWorker = typeof window === 'undefined' && typeof importScripts !== 'undefined' && isFunction(importScripts)
  208. // Ignore about:xxx and blob:xxx
  209. var IGNORE_LOCATION_RE = /^(about|blob):/
  210. var loaderDir
  211. // Sea.js's full path
  212. var loaderPath
  213. // Location is read-only from web worker, should be ok though
  214. var cwd = (!location.href || IGNORE_LOCATION_RE.test(location.href)) ? '' : dirname(location.href)
  215. if (isWebWorker) {
  216. // Web worker doesn't create DOM object when loading scripts
  217. // Get sea.js's path by stack trace.
  218. var stack
  219. try {
  220. var up = new Error()
  221. throw up
  222. } catch (e) {
  223. // IE won't set Error.stack until thrown
  224. stack = e.stack.split('\n')
  225. }
  226. // First line is 'Error'
  227. stack.shift()
  228. var m
  229. // Try match `url:row:col` from stack trace line. Known formats:
  230. // Chrome: ' at http://localhost:8000/script/sea-worker-debug.js:294:25'
  231. // FireFox: '@http://localhost:8000/script/sea-worker-debug.js:1082:1'
  232. // IE11: ' at Anonymous function (http://localhost:8000/script/sea-worker-debug.js:295:5)'
  233. // Don't care about older browsers since web worker is an HTML5 feature
  234. var TRACE_RE = /.*?((?:http|https|file)(?::\/{2}[\w]+)(?:[\/|\.]?)(?:[^\s"]*)).*?/i
  235. // Try match `url` (Note: in IE there will be a tailing ')')
  236. var URL_RE = /(.*?):\d+:\d+\)?$/
  237. // Find url of from stack trace.
  238. // Cannot simply read the first one because sometimes we will get:
  239. // Error
  240. // at Error (native) <- Here's your problem
  241. // at http://localhost:8000/_site/dist/sea.js:2:4334 <- What we want
  242. // at http://localhost:8000/_site/dist/sea.js:2:8386
  243. // at http://localhost:8000/_site/tests/specs/web-worker/worker.js:3:1
  244. while (stack.length > 0) {
  245. var top = stack.shift()
  246. m = TRACE_RE.exec(top)
  247. if (m != null) {
  248. break
  249. }
  250. }
  251. var url
  252. if (m != null) {
  253. // Remove line number and column number
  254. // No need to check, can't be wrong at this point
  255. var url = URL_RE.exec(m[1])[1]
  256. }
  257. // Set
  258. loaderPath = url
  259. // Set loaderDir
  260. loaderDir = dirname(url || cwd)
  261. // This happens with inline worker.
  262. // When entrance script's location.href is a blob url,
  263. // cwd will not be available.
  264. // Fall back to loaderDir.
  265. if (cwd === '') {
  266. cwd = loaderDir
  267. }
  268. }
  269. else {
  270. var doc = document
  271. var scripts = doc.scripts
  272. // Recommend to add `seajsnode` id for the `sea.js` script element
  273. var loaderScript = doc.getElementById("seajsnode") ||
  274. scripts[scripts.length - 1]
  275. function getScriptAbsoluteSrc(node) {
  276. return node.hasAttribute ? // non-IE6/7
  277. node.src :
  278. // see http://msdn.microsoft.com/en-us/library/ms536429(VS.85).aspx
  279. node.getAttribute("src", 4)
  280. }
  281. loaderPath = getScriptAbsoluteSrc(loaderScript)
  282. // When `sea.js` is inline, set loaderDir to current working directory
  283. loaderDir = dirname(loaderPath || cwd)
  284. }
  285. /**
  286. * util-request.js - The utilities for requesting script and style files
  287. * ref: tests/research/load-js-css/test.html
  288. */
  289. if (isWebWorker) {
  290. function requestFromWebWorker(url, callback, charset, crossorigin) {
  291. // Load with importScripts
  292. var error
  293. try {
  294. importScripts(url)
  295. } catch (e) {
  296. error = e
  297. }
  298. callback(error)
  299. }
  300. // For Developers
  301. seajs.request = requestFromWebWorker
  302. }
  303. else {
  304. var doc = document
  305. var head = doc.head || doc.getElementsByTagName("head")[0] || doc.documentElement
  306. var baseElement = head.getElementsByTagName("base")[0]
  307. var currentlyAddingScript
  308. function request(url, callback, charset, crossorigin) {
  309. var node = doc.createElement("script")
  310. if (charset) {
  311. node.charset = charset
  312. }
  313. if (!isUndefined(crossorigin)) {
  314. node.setAttribute("crossorigin", crossorigin)
  315. }
  316. addOnload(node, callback, url)
  317. node.async = true
  318. node.src = url
  319. // For some cache cases in IE 6-8, the script executes IMMEDIATELY after
  320. // the end of the insert execution, so use `currentlyAddingScript` to
  321. // hold current node, for deriving url in `define` call
  322. currentlyAddingScript = node
  323. // ref: #185 & http://dev.jquery.com/ticket/2709
  324. baseElement ?
  325. head.insertBefore(node, baseElement) :
  326. head.appendChild(node)
  327. currentlyAddingScript = null
  328. }
  329. function addOnload(node, callback, url) {
  330. var supportOnload = "onload" in node
  331. if (supportOnload) {
  332. node.onload = onload
  333. node.onerror = function() {
  334. emit("error", { uri: url, node: node })
  335. onload(true)
  336. }
  337. }
  338. else {
  339. node.onreadystatechange = function() {
  340. if (/loaded|complete/.test(node.readyState)) {
  341. onload()
  342. }
  343. }
  344. }
  345. function onload(error) {
  346. // Ensure only run once and handle memory leak in IE
  347. node.onload = node.onerror = node.onreadystatechange = null
  348. // Remove the script to reduce memory leak
  349. if (!data.debug) {
  350. head.removeChild(node)
  351. }
  352. // Dereference the node
  353. node = null
  354. callback(error)
  355. }
  356. }
  357. // For Developers
  358. seajs.request = request
  359. }
  360. var interactiveScript
  361. function getCurrentScript() {
  362. if (currentlyAddingScript) {
  363. return currentlyAddingScript
  364. }
  365. // For IE6-9 browsers, the script onload event may not fire right
  366. // after the script is evaluated. Kris Zyp found that it
  367. // could query the script nodes and the one that is in "interactive"
  368. // mode indicates the current script
  369. // ref: http://goo.gl/JHfFW
  370. if (interactiveScript && interactiveScript.readyState === "interactive") {
  371. return interactiveScript
  372. }
  373. var scripts = head.getElementsByTagName("script")
  374. for (var i = scripts.length - 1; i >= 0; i--) {
  375. var script = scripts[i]
  376. if (script.readyState === "interactive") {
  377. interactiveScript = script
  378. return interactiveScript
  379. }
  380. }
  381. }
  382. /**
  383. * util-deps.js - The parser for dependencies
  384. * ref: tests/research/parse-dependencies/test.html
  385. * ref: https://github.com/seajs/crequire
  386. */
  387. var REQUIRE_RE = /"(?:\\"|[^"])*"|'(?:\\'|[^'])*'|\/\*[\S\s]*?\*\/|\/(?:\\\/|[^\/\r\n])+\/(?=[^\/])|\/\/.*|\.\s*require|(?:^|[^$])\brequire\s*\(\s*(["'])(.+?)\1\s*\)/g
  388. var SLASH_RE = /\\\\/g
  389. function parseDependencies(code) {
  390. var ret = []
  391. code.replace(SLASH_RE, "")
  392. .replace(REQUIRE_RE, function(m, m1, m2) {
  393. if (m2) {
  394. ret.push(m2)
  395. }
  396. })
  397. return ret
  398. }
  399. /**
  400. * module.js - The core of module loader
  401. */
  402. var cachedMods = seajs.cache = {}
  403. var anonymousMeta
  404. var fetchingList = {}
  405. var fetchedList = {}
  406. var callbackList = {}
  407. var STATUS = Module.STATUS = {
  408. // 1 - The `module.uri` is being fetched
  409. FETCHING: 1,
  410. // 2 - The meta data has been saved to cachedMods
  411. SAVED: 2,
  412. // 3 - The `module.dependencies` are being loaded
  413. LOADING: 3,
  414. // 4 - The module are ready to execute
  415. LOADED: 4,
  416. // 5 - The module is being executed
  417. EXECUTING: 5,
  418. // 6 - The `module.exports` is available
  419. EXECUTED: 6,
  420. // 7 - 404
  421. ERROR: 7
  422. }
  423. function Module(uri, deps) {
  424. this.uri = uri
  425. this.dependencies = deps || []
  426. this.deps = {} // Ref the dependence modules
  427. this.status = 0
  428. this._entry = []
  429. }
  430. // Resolve module.dependencies
  431. Module.prototype.resolve = function() {
  432. var mod = this
  433. var ids = mod.dependencies
  434. var uris = []
  435. for (var i = 0, len = ids.length; i < len; i++) {
  436. uris[i] = Module.resolve(ids[i], mod.uri)
  437. }
  438. return uris
  439. }
  440. Module.prototype.pass = function() {
  441. var mod = this
  442. var len = mod.dependencies.length
  443. for (var i = 0; i < mod._entry.length; i++) {
  444. var entry = mod._entry[i]
  445. var count = 0
  446. for (var j = 0; j < len; j++) {
  447. var m = mod.deps[mod.dependencies[j]]
  448. // If the module is unload and unused in the entry, pass entry to it
  449. if (m.status < STATUS.LOADED && !entry.history.hasOwnProperty(m.uri)) {
  450. entry.history[m.uri] = true
  451. count++
  452. m._entry.push(entry)
  453. if(m.status === STATUS.LOADING) {
  454. m.pass()
  455. }
  456. }
  457. }
  458. // If has passed the entry to it's dependencies, modify the entry's count and del it in the module
  459. if (count > 0) {
  460. entry.remain += count - 1
  461. mod._entry.shift()
  462. i--
  463. }
  464. }
  465. }
  466. // Load module.dependencies and fire onload when all done
  467. Module.prototype.load = function() {
  468. var mod = this
  469. // If the module is being loaded, just wait it onload call
  470. if (mod.status >= STATUS.LOADING) {
  471. return
  472. }
  473. mod.status = STATUS.LOADING
  474. // Emit `load` event for plugins such as combo plugin
  475. var uris = mod.resolve()
  476. emit("load", uris)
  477. for (var i = 0, len = uris.length; i < len; i++) {
  478. mod.deps[mod.dependencies[i]] = Module.get(uris[i])
  479. }
  480. // Pass entry to it's dependencies
  481. mod.pass()
  482. // If module has entries not be passed, call onload
  483. if (mod._entry.length) {
  484. mod.onload()
  485. return
  486. }
  487. // Begin parallel loading
  488. var requestCache = {}
  489. var m
  490. for (i = 0; i < len; i++) {
  491. m = cachedMods[uris[i]]
  492. if (m.status < STATUS.FETCHING) {
  493. m.fetch(requestCache)
  494. }
  495. else if (m.status === STATUS.SAVED) {
  496. m.load()
  497. }
  498. }
  499. // Send all requests at last to avoid cache bug in IE6-9. Issues#808
  500. for (var requestUri in requestCache) {
  501. if (requestCache.hasOwnProperty(requestUri)) {
  502. requestCache[requestUri]()
  503. }
  504. }
  505. }
  506. // Call this method when module is loaded
  507. Module.prototype.onload = function() {
  508. var mod = this
  509. mod.status = STATUS.LOADED
  510. // When sometimes cached in IE, exec will occur before onload, make sure len is an number
  511. for (var i = 0, len = (mod._entry || []).length; i < len; i++) {
  512. var entry = mod._entry[i]
  513. if (--entry.remain === 0) {
  514. entry.callback()
  515. }
  516. }
  517. delete mod._entry
  518. }
  519. // Call this method when module is 404
  520. Module.prototype.error = function() {
  521. var mod = this
  522. mod.onload()
  523. mod.status = STATUS.ERROR
  524. }
  525. // Execute a module
  526. Module.prototype.exec = function () {
  527. var mod = this
  528. // When module is executed, DO NOT execute it again. When module
  529. // is being executed, just return `module.exports` too, for avoiding
  530. // circularly calling
  531. if (mod.status >= STATUS.EXECUTING) {
  532. return mod.exports
  533. }
  534. mod.status = STATUS.EXECUTING
  535. if (mod._entry && !mod._entry.length) {
  536. delete mod._entry
  537. }
  538. //non-cmd module has no property factory and exports
  539. if (!mod.hasOwnProperty('factory')) {
  540. mod.non = true
  541. return
  542. }
  543. // Create require
  544. var uri = mod.uri
  545. function require(id) {
  546. var m = mod.deps[id] || Module.get(require.resolve(id))
  547. if (m.status == STATUS.ERROR) {
  548. throw new Error('module was broken: ' + m.uri)
  549. }
  550. return m.exec()
  551. }
  552. require.resolve = function(id) {
  553. return Module.resolve(id, uri)
  554. }
  555. require.async = function(ids, callback) {
  556. Module.use(ids, callback, uri + "_async_" + cid())
  557. return require
  558. }
  559. // Exec factory
  560. var factory = mod.factory
  561. var exports = isFunction(factory) ?
  562. factory.call(mod.exports = {}, require, mod.exports, mod) :
  563. factory
  564. if (exports === undefined) {
  565. exports = mod.exports
  566. }
  567. // Reduce memory leak
  568. delete mod.factory
  569. mod.exports = exports
  570. mod.status = STATUS.EXECUTED
  571. // Emit `exec` event
  572. emit("exec", mod)
  573. return mod.exports
  574. }
  575. // Fetch a module
  576. Module.prototype.fetch = function(requestCache) {
  577. var mod = this
  578. var uri = mod.uri
  579. mod.status = STATUS.FETCHING
  580. // Emit `fetch` event for plugins such as combo plugin
  581. var emitData = { uri: uri }
  582. emit("fetch", emitData)
  583. var requestUri = emitData.requestUri || uri
  584. // Empty uri or a non-CMD module
  585. if (!requestUri || fetchedList.hasOwnProperty(requestUri)) {
  586. mod.load()
  587. return
  588. }
  589. if (fetchingList.hasOwnProperty(requestUri)) {
  590. callbackList[requestUri].push(mod)
  591. return
  592. }
  593. fetchingList[requestUri] = true
  594. callbackList[requestUri] = [mod]
  595. // Emit `request` event for plugins such as text plugin
  596. emit("request", emitData = {
  597. uri: uri,
  598. requestUri: requestUri,
  599. onRequest: onRequest,
  600. charset: isFunction(data.charset) ? data.charset(requestUri) : data.charset,
  601. crossorigin: isFunction(data.crossorigin) ? data.crossorigin(requestUri) : data.crossorigin
  602. })
  603. if (!emitData.requested) {
  604. requestCache ?
  605. requestCache[emitData.requestUri] = sendRequest :
  606. sendRequest()
  607. }
  608. function sendRequest() {
  609. seajs.request(emitData.requestUri, emitData.onRequest, emitData.charset, emitData.crossorigin)
  610. }
  611. function onRequest(error) {
  612. delete fetchingList[requestUri]
  613. fetchedList[requestUri] = true
  614. // Save meta data of anonymous module
  615. if (anonymousMeta) {
  616. Module.save(uri, anonymousMeta)
  617. anonymousMeta = null
  618. }
  619. // Call callbacks
  620. var m, mods = callbackList[requestUri]
  621. delete callbackList[requestUri]
  622. while ((m = mods.shift())) {
  623. // When 404 occurs, the params error will be true
  624. if(error === true) {
  625. m.error()
  626. }
  627. else {
  628. m.load()
  629. }
  630. }
  631. }
  632. }
  633. // Resolve id to uri
  634. Module.resolve = function(id, refUri) {
  635. // Emit `resolve` event for plugins such as text plugin
  636. var emitData = { id: id, refUri: refUri }
  637. emit("resolve", emitData)
  638. return emitData.uri || seajs.resolve(emitData.id, refUri)
  639. }
  640. // Define a module
  641. Module.define = function (id, deps, factory) {
  642. var argsLen = arguments.length
  643. // define(factory)
  644. if (argsLen === 1) {
  645. factory = id
  646. id = undefined
  647. }
  648. else if (argsLen === 2) {
  649. factory = deps
  650. // define(deps, factory)
  651. if (isArray(id)) {
  652. deps = id
  653. id = undefined
  654. }
  655. // define(id, factory)
  656. else {
  657. deps = undefined
  658. }
  659. }
  660. // Parse dependencies according to the module factory code
  661. if (!isArray(deps) && isFunction(factory)) {
  662. deps = typeof parseDependencies === "undefined" ? [] : parseDependencies(factory.toString())
  663. }
  664. var meta = {
  665. id: id,
  666. uri: Module.resolve(id),
  667. deps: deps,
  668. factory: factory
  669. }
  670. // Try to derive uri in IE6-9 for anonymous modules
  671. if (!isWebWorker && !meta.uri && doc.attachEvent && typeof getCurrentScript !== "undefined") {
  672. var script = getCurrentScript()
  673. if (script) {
  674. meta.uri = script.src
  675. }
  676. // NOTE: If the id-deriving methods above is failed, then falls back
  677. // to use onload event to get the uri
  678. }
  679. // Emit `define` event, used in nocache plugin, seajs node version etc
  680. emit("define", meta)
  681. meta.uri ? Module.save(meta.uri, meta) :
  682. // Save information for "saving" work in the script onload event
  683. anonymousMeta = meta
  684. }
  685. // Save meta data to cachedMods
  686. Module.save = function(uri, meta) {
  687. var mod = Module.get(uri)
  688. // Do NOT override already saved modules
  689. if (mod.status < STATUS.SAVED) {
  690. mod.id = meta.id || uri
  691. mod.dependencies = meta.deps || []
  692. mod.factory = meta.factory
  693. mod.status = STATUS.SAVED
  694. emit("save", mod)
  695. }
  696. }
  697. // Get an existed module or create a new one
  698. Module.get = function(uri, deps) {
  699. return cachedMods[uri] || (cachedMods[uri] = new Module(uri, deps))
  700. }
  701. // Use function is equal to load a anonymous module
  702. Module.use = function (ids, callback, uri) {
  703. var mod = Module.get(uri, isArray(ids) ? ids : [ids])
  704. mod._entry.push(mod)
  705. mod.history = {}
  706. mod.remain = 1
  707. mod.callback = function() {
  708. var exports = []
  709. var uris = mod.resolve()
  710. for (var i = 0, len = uris.length; i < len; i++) {
  711. exports[i] = cachedMods[uris[i]].exec()
  712. }
  713. if (callback) {
  714. callback.apply(global, exports)
  715. }
  716. delete mod.callback
  717. delete mod.history
  718. delete mod.remain
  719. delete mod._entry
  720. }
  721. mod.load()
  722. }
  723. // Public API
  724. seajs.use = function(ids, callback) {
  725. Module.use(ids, callback, data.cwd + "_use_" + cid())
  726. return seajs
  727. }
  728. Module.define.cmd = {}
  729. global.define = Module.define
  730. // For Developers
  731. seajs.Module = Module
  732. data.fetchedList = fetchedList
  733. data.cid = cid
  734. seajs.require = function(id) {
  735. var mod = Module.get(Module.resolve(id))
  736. if (mod.status < STATUS.EXECUTING) {
  737. mod.onload()
  738. mod.exec()
  739. }
  740. return mod.exports
  741. }
  742. /**
  743. * config.js - The configuration for the loader
  744. */
  745. // The root path to use for id2uri parsing
  746. data.base = loaderDir
  747. // The loader directory
  748. data.dir = loaderDir
  749. // The loader's full path
  750. data.loader = loaderPath
  751. // The current working directory
  752. data.cwd = cwd
  753. // The charset for requesting files
  754. data.charset = "utf-8"
  755. // @Retention(RetentionPolicy.SOURCE)
  756. // The CORS options, Don't set CORS on default.
  757. //
  758. //data.crossorigin = undefined
  759. // data.alias - An object containing shorthands of module id
  760. // data.paths - An object containing path shorthands in module id
  761. // data.vars - The {xxx} variables in module id
  762. // data.map - An array containing rules to map module uri
  763. // data.debug - Debug mode. The default value is false
  764. seajs.config = function(configData) {
  765. for (var key in configData) {
  766. var curr = configData[key]
  767. var prev = data[key]
  768. // Merge object config such as alias, vars
  769. if (prev && isObject(prev)) {
  770. for (var k in curr) {
  771. prev[k] = curr[k]
  772. }
  773. }
  774. else {
  775. // Concat array config such as map
  776. if (isArray(prev)) {
  777. curr = prev.concat(curr)
  778. }
  779. // Make sure that `data.base` is an absolute path
  780. else if (key === "base") {
  781. // Make sure end with "/"
  782. if (curr.slice(-1) !== "/") {
  783. curr += "/"
  784. }
  785. curr = addBase(curr)
  786. }
  787. // Set config
  788. data[key] = curr
  789. }
  790. }
  791. emit("config", configData)
  792. return seajs
  793. }
  794. })(this);