OLD | NEW |
| (Empty) |
1 /** vim: et:ts=4:sw=4:sts=4 | |
2 * @license RequireJS 2.2.0 Copyright jQuery Foundation and other contributors. | |
3 * Released under MIT license, http://github.com/requirejs/requirejs/LICENSE | |
4 */ | |
5 //Not using strict: uneven strict support in browsers, #392, and causes | |
6 //problems with requirejs.exec()/transpiler plugins that may not be strict. | |
7 /*jslint regexp: true, nomen: true, sloppy: true */ | |
8 /*global window, navigator, document, importScripts, setTimeout, opera */ | |
9 | |
10 goog.provide('__crWeb.webUIRequire'); | |
11 | |
12 goog.require('__crWeb.webUIModuleLoadNotifier'); | |
13 | |
14 | |
15 __crWeb.webUIModuleLoadNotifier = new WebUIModuleLoadNotifier(); | |
16 | |
17 | |
18 var requirejs, define; | |
19 (function() { | |
20 var req, s, | |
21 commentRegExp = /(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg, | |
22 cjsRequireRegExp = /[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g, | |
23 op = Object.prototype, | |
24 ostring = op.toString, | |
25 hasOwn = op.hasOwnProperty, | |
26 defContextName = '_', | |
27 contexts = {}, | |
28 globalDefQueue = [], | |
29 anonymousModuleId = 0; | |
30 | |
31 // Could match something like ')//comment', do not lose the prefix to | |
32 // comment. | |
33 function commentReplace(match, multi, multiText, singlePrefix) { | |
34 return singlePrefix || ''; | |
35 } | |
36 | |
37 function isFunction(it) { | |
38 return ostring.call(it) === '[object Function]'; | |
39 } | |
40 | |
41 function isArray(it) { | |
42 return ostring.call(it) === '[object Array]'; | |
43 } | |
44 | |
45 /** | |
46 * Helper function for iterating over an array. If the func returns | |
47 * a true value, it will break out of the loop. | |
48 */ | |
49 function each(ary, func) { | |
50 if (ary) { | |
51 var i; | |
52 for (i = 0; i < ary.length; i += 1) { | |
53 if (ary[i] && func(ary[i], i, ary)) { | |
54 break; | |
55 } | |
56 } | |
57 } | |
58 } | |
59 | |
60 function hasProp(obj, prop) { | |
61 return hasOwn.call(obj, prop); | |
62 } | |
63 | |
64 function getOwn(obj, prop) { | |
65 return hasProp(obj, prop) && obj[prop]; | |
66 } | |
67 | |
68 /** | |
69 * Cycles over properties in an object and calls a function for each | |
70 * property value. If the function returns a truthy value, then the | |
71 * iteration is stopped. | |
72 */ | |
73 function eachProp(obj, func) { | |
74 var prop; | |
75 for (prop in obj) { | |
76 if (hasProp(obj, prop)) { | |
77 if (func(obj[prop], prop)) { | |
78 break; | |
79 } | |
80 } | |
81 } | |
82 } | |
83 | |
84 // Similar to Function.prototype.bind, but the 'this' object is specified | |
85 // first, since it is easier to read/figure out what 'this' will be. | |
86 function bind(obj, fn) { | |
87 return function() { | |
88 return fn.apply(obj, arguments); | |
89 }; | |
90 } | |
91 | |
92 function defaultOnError(err) { | |
93 throw err; | |
94 } | |
95 | |
96 /** | |
97 * Constructs an error with a pointer to an URL with more information. | |
98 * @param {String} id the error ID that maps to an ID on a web page. | |
99 * @param {String} message human readable error. | |
100 * @param {Error} [err] the original error, if there is one. | |
101 * | |
102 * @returns {Error} | |
103 */ | |
104 function makeError(id, msg, err, requireModules) { | |
105 var e = new Error(msg + '\nhttp://requirejs.org/docs/errors.html#' + id); | |
106 e.requireType = id; | |
107 e.requireModules = requireModules; | |
108 if (err) { | |
109 e.originalError = err; | |
110 } | |
111 return e; | |
112 } | |
113 | |
114 function newContext(contextName) { | |
115 var inCheckLoaded, Module, context, handlers, | |
116 checkLoadedTimeoutId, | |
117 config = { | |
118 // Defaults. Do not set a default for map | |
119 // config to speed up normalize(), which | |
120 // will run faster if there is no default. | |
121 waitSeconds: 7, | |
122 baseUrl: './' | |
123 }, | |
124 registry = {}, | |
125 // registry of just enabled modules, to speed | |
126 // cycle breaking code when lots of modules | |
127 // are registered, but not activated. | |
128 enabledRegistry = {}, | |
129 defQueue = [], | |
130 defined = {}, | |
131 urlFetched = {}, | |
132 requireCounter = 1; | |
133 | |
134 /** | |
135 * Creates a module mapping that includes, module name, and path. | |
136 * | |
137 * @param {String} name the module name | |
138 * @param {String} [parentModuleMap] parent module map | |
139 * for the module name, used to resolve relative names. | |
140 * This is true if this call is done for a define() module ID. | |
141 * @param {Boolean} applyMap: apply the map config to the ID. | |
142 * Should only be true if this map is for a dependency. | |
143 * | |
144 * @returns {Object} | |
145 */ | |
146 function makeModuleMap(name, parentModuleMap, applyMap) { | |
147 var url, | |
148 parentName = parentModuleMap ? parentModuleMap.name : null, | |
149 isDefine = true; | |
150 | |
151 // If no name, then it means it is a require call, generate an | |
152 // internal name. | |
153 if (!name) { | |
154 isDefine = false; | |
155 name = '_@r' + (requireCounter += 1); | |
156 } | |
157 | |
158 // Account for relative paths if there is a base name. | |
159 url = context.nameToUrl(name); | |
160 | |
161 return { | |
162 name: name, | |
163 parentMap: parentModuleMap, | |
164 url: url, | |
165 isDefine: isDefine, | |
166 id: name | |
167 }; | |
168 } | |
169 | |
170 function getModule(depMap) { | |
171 var id = depMap.id, | |
172 mod = getOwn(registry, id); | |
173 | |
174 if (!mod) { | |
175 mod = registry[id] = new context.Module(depMap); | |
176 } | |
177 | |
178 return mod; | |
179 } | |
180 | |
181 function on(depMap, name, fn) { | |
182 var id = depMap.id, | |
183 mod = getOwn(registry, id); | |
184 | |
185 if (hasProp(defined, id) && (!mod || mod.defineEmitComplete)) { | |
186 if (name === 'defined') { | |
187 fn(defined[id]); | |
188 } | |
189 } else { | |
190 mod = getModule(depMap); | |
191 if (mod.error && name === 'error') { | |
192 fn(mod.error); | |
193 } else { | |
194 mod.on(name, fn); | |
195 } | |
196 } | |
197 } | |
198 | |
199 function onError(err, errback) { | |
200 var ids = err.requireModules, | |
201 notified = false; | |
202 | |
203 if (errback) { | |
204 errback(err); | |
205 } else { | |
206 each(ids, function(id) { | |
207 var mod = getOwn(registry, id); | |
208 if (mod) { | |
209 // Set error on module, so it skips timeout checks. | |
210 mod.error = err; | |
211 if (mod.events.error) { | |
212 notified = true; | |
213 mod.emit('error', err); | |
214 } | |
215 } | |
216 }); | |
217 | |
218 if (!notified) { | |
219 req.onError(err); | |
220 } | |
221 } | |
222 } | |
223 | |
224 /** | |
225 * Internal method to transfer globalQueue items to this context's | |
226 * defQueue. | |
227 */ | |
228 function takeGlobalQueue() { | |
229 // Push all the globalDefQueue items into the context's defQueue | |
230 if (globalDefQueue.length) { | |
231 each(globalDefQueue, function(queueItem) { | |
232 var id = queueItem[0]; | |
233 if (typeof id === 'string') { | |
234 context.defQueueMap[id] = true; | |
235 } | |
236 defQueue.push(queueItem); | |
237 }); | |
238 globalDefQueue = []; | |
239 } | |
240 } | |
241 | |
242 handlers = { | |
243 'require': function(mod) { | |
244 if (mod.require) { | |
245 return mod.require; | |
246 } else { | |
247 return (mod.require = context.makeRequire()); | |
248 } | |
249 }, | |
250 'exports': function(mod) { | |
251 mod.usingExports = true; | |
252 if (mod.map.isDefine) { | |
253 if (mod.exports) { | |
254 return (defined[mod.map.id] = mod.exports); | |
255 } else { | |
256 return (mod.exports = defined[mod.map.id] = {}); | |
257 } | |
258 } | |
259 }, | |
260 'module': function(mod) { | |
261 if (mod.module) { | |
262 return mod.module; | |
263 } else { | |
264 return (mod.module = { | |
265 id: mod.map.id, | |
266 uri: mod.map.url, | |
267 config: function() { | |
268 return getOwn(config.config, mod.map.id) || {}; | |
269 }, | |
270 exports: mod.exports || (mod.exports = {}) | |
271 }); | |
272 } | |
273 } | |
274 }; | |
275 | |
276 function cleanRegistry(id) { | |
277 // Clean up machinery used for waiting modules. | |
278 delete registry[id]; | |
279 delete enabledRegistry[id]; | |
280 } | |
281 | |
282 function breakCycle(mod, traced, processed) { | |
283 var id = mod.map.id; | |
284 | |
285 if (mod.error) { | |
286 mod.emit('error', mod.error); | |
287 } else { | |
288 traced[id] = true; | |
289 each(mod.depMaps, function(depMap, i) { | |
290 var depId = depMap.id, | |
291 dep = getOwn(registry, depId); | |
292 | |
293 // Only force things that have not completed | |
294 // being defined, so still in the registry, | |
295 // and only if it has not been matched up | |
296 // in the module already. | |
297 if (dep && !mod.depMatched[i] && !processed[depId]) { | |
298 if (getOwn(traced, depId)) { | |
299 mod.defineDep(i, defined[depId]); | |
300 mod.check(); //pass false? | |
301 } else { | |
302 breakCycle(dep, traced, processed); | |
303 } | |
304 } | |
305 }); | |
306 processed[id] = true; | |
307 } | |
308 } | |
309 | |
310 function checkLoaded() { | |
311 var err, | |
312 waitInterval = config.waitSeconds * 1000, | |
313 // It is possible to disable the wait interval by using | |
314 // waitSeconds of 0. | |
315 expired = waitInterval && | |
316 (context.startTime + waitInterval) < new Date().getTime(), | |
317 noLoads = [], | |
318 reqCalls = [], | |
319 stillLoading = false, | |
320 needCycleCheck = true; | |
321 | |
322 // Do not bother if this call was a result of a cycle break. | |
323 if (inCheckLoaded) { | |
324 return; | |
325 } | |
326 | |
327 inCheckLoaded = true; | |
328 | |
329 // Figure out the state of all the modules. | |
330 eachProp(enabledRegistry, function(mod) { | |
331 var map = mod.map, | |
332 modId = map.id; | |
333 | |
334 // Skip things that are not enabled or in error state. | |
335 if (!mod.enabled) { | |
336 return; | |
337 } | |
338 | |
339 if (!map.isDefine) { | |
340 reqCalls.push(mod); | |
341 } | |
342 | |
343 if (!mod.error) { | |
344 // If the module should be executed, and it has not | |
345 // been inited and time is up, remember it. | |
346 if (!mod.inited && expired) { | |
347 noLoads.push(modId); | |
348 } else if (!mod.inited && mod.fetched && map.isDefine) { | |
349 stillLoading = true; | |
350 return (needCycleCheck = false); | |
351 } | |
352 } | |
353 }); | |
354 | |
355 if (expired && noLoads.length) { | |
356 // If wait time expired, throw error of unloaded modules. | |
357 err = makeError('timeout', | |
358 'Load timeout for modules: ' + noLoads, | |
359 null, | |
360 noLoads); | |
361 err.contextName = context.contextName; | |
362 return onError(err); | |
363 } | |
364 | |
365 // Not expired, check for a cycle. | |
366 if (needCycleCheck) { | |
367 each(reqCalls, function(mod) { | |
368 breakCycle(mod, {}, {}); | |
369 }); | |
370 } | |
371 | |
372 // If still waiting on loads, and the waiting load is something | |
373 // other than a plugin resource, or there are still outstanding | |
374 // scripts, then just try back later. | |
375 if (!expired && stillLoading) { | |
376 // Something is still waiting to load. Wait for it, but only | |
377 // if a timeout is not already in effect. | |
378 if (!checkLoadedTimeoutId) { | |
379 checkLoadedTimeoutId = setTimeout(function() { | |
380 checkLoadedTimeoutId = 0; | |
381 checkLoaded(); | |
382 }, 50); | |
383 } | |
384 } | |
385 | |
386 inCheckLoaded = false; | |
387 } | |
388 | |
389 Module = function(map) { | |
390 this.events = {}; | |
391 this.map = map; | |
392 this.depExports = []; | |
393 this.depMaps = []; | |
394 this.depMatched = []; | |
395 this.depCount = 0; | |
396 | |
397 /* this.exports this.factory | |
398 this.depMaps = [], | |
399 this.enabled, this.fetched | |
400 */ | |
401 }; | |
402 | |
403 Module.prototype = { | |
404 init: function(depMaps, factory, errback, options) { | |
405 options = options || {}; | |
406 | |
407 // Do not do more inits if already done. Can happen if there | |
408 // are multiple define calls for the same module. That is not | |
409 // a normal, common case, but it is also not unexpected. | |
410 if (this.inited) { | |
411 return; | |
412 } | |
413 | |
414 this.factory = factory; | |
415 | |
416 if (errback) { | |
417 // Register for errors on this module. | |
418 this.on('error', errback); | |
419 } else if (this.events.error) { | |
420 // If no errback already, but there are error listeners | |
421 // on this module, set up an errback to pass to the deps. | |
422 errback = bind(this, function(err) { | |
423 this.emit('error', err); | |
424 }); | |
425 } | |
426 | |
427 // Do a copy of the dependency array, so that | |
428 // source inputs are not modified. | |
429 this.depMaps = depMaps && depMaps.slice(0); | |
430 | |
431 this.errback = errback; | |
432 | |
433 // Indicate this module has be initialized | |
434 this.inited = true; | |
435 | |
436 this.ignore = options.ignore; | |
437 | |
438 // Could have option to init this module in enabled mode, | |
439 // or could have been previously marked as enabled. However, | |
440 // the dependencies are not known until init is called. So | |
441 // if enabled previously, now trigger dependencies as enabled. | |
442 if (options.enabled || this.enabled) { | |
443 // Enable this module and dependencies. | |
444 // Will call this.check() | |
445 this.enable(); | |
446 } else { | |
447 this.check(); | |
448 } | |
449 }, | |
450 | |
451 defineDep: function(i, depExports) { | |
452 // Because of cycles, defined callback for a given | |
453 // export can be called more than once. | |
454 if (!this.depMatched[i]) { | |
455 this.depMatched[i] = true; | |
456 this.depCount -= 1; | |
457 this.depExports[i] = depExports; | |
458 } | |
459 }, | |
460 | |
461 fetch: function() { | |
462 if (this.fetched) { | |
463 return; | |
464 } | |
465 this.fetched = true; | |
466 | |
467 context.startTime = (new Date()).getTime(); | |
468 | |
469 return this.load(); | |
470 }, | |
471 | |
472 load: function() { | |
473 var url = this.map.url; | |
474 | |
475 // Regular dependency. | |
476 if (!urlFetched[url]) { | |
477 urlFetched[url] = true; | |
478 context.load(this.map.id, url); | |
479 } | |
480 }, | |
481 | |
482 /** | |
483 * Checks if the module is ready to define itself, and if so, | |
484 * define it. | |
485 */ | |
486 check: function() { | |
487 if (!this.enabled || this.enabling) { | |
488 return; | |
489 } | |
490 | |
491 var err, cjsModule, | |
492 id = this.map.id, | |
493 depExports = this.depExports, | |
494 exports = this.exports, | |
495 factory = this.factory; | |
496 | |
497 if (!this.inited) { | |
498 // Only fetch if not already in the defQueue and not 'main' module. | |
499 if (!hasProp(context.defQueueMap, id) && this.map.name != 'main') { | |
500 this.fetch(); | |
501 } | |
502 } else if (this.error) { | |
503 this.emit('error', this.error); | |
504 } else if (!this.defining) { | |
505 // The factory could trigger another require call | |
506 // that would result in checking this module to | |
507 // define itself again. If already in the process | |
508 // of doing that, skip this work. | |
509 this.defining = true; | |
510 | |
511 if (this.depCount < 1 && !this.defined) { | |
512 if (isFunction(factory)) { | |
513 // If there is an error listener, favor passing | |
514 // to that instead of throwing an error. However, | |
515 // only do it for define()'d modules. require | |
516 // errbacks should not be called for failures in | |
517 // their callbacks (#699). However if a global | |
518 // onError is set, use that. | |
519 if ((this.events.error && this.map.isDefine) || | |
520 req.onError !== defaultOnError) { | |
521 try { | |
522 exports = context.execCb(id, factory, depExports, exports); | |
523 } catch (e) { | |
524 err = e; | |
525 } | |
526 } else { | |
527 exports = context.execCb(id, factory, depExports, exports); | |
528 } | |
529 | |
530 // Favor return value over exports. If node/cjs in | |
531 // play, then will not have a return value anyway. | |
532 // Favor module.exports assignment over exports | |
533 // object. | |
534 if (this.map.isDefine && exports === undefined) { | |
535 cjsModule = this.module; | |
536 if (cjsModule) { | |
537 exports = cjsModule.exports; | |
538 } else if (this.usingExports) { | |
539 // exports already set the defined value. | |
540 exports = this.exports; | |
541 } | |
542 } | |
543 | |
544 if (err) { | |
545 err.requireMap = this.map; | |
546 err.requireModules = this.map.isDefine ? [this.map.id] : null; | |
547 err.requireType = this.map.isDefine ? 'define' : 'require'; | |
548 return onError((this.error = err)); | |
549 } | |
550 } else { | |
551 // Just a literal value | |
552 exports = factory; | |
553 } | |
554 | |
555 this.exports = exports; | |
556 | |
557 if (this.map.isDefine && !this.ignore) { | |
558 defined[id] = exports; | |
559 | |
560 if (req.onResourceLoad) { | |
561 var resLoadMaps = []; | |
562 each(this.depMaps, function(depMap) { | |
563 resLoadMaps.push(depMap.normalizedMap || depMap); | |
564 }); | |
565 req.onResourceLoad(context, this.map, resLoadMaps); | |
566 } | |
567 } | |
568 | |
569 // Clean up | |
570 cleanRegistry(id); | |
571 | |
572 this.defined = true; | |
573 } | |
574 | |
575 // Finished the define stage. Allow calling check again | |
576 // to allow define notifications below in the case of a | |
577 // cycle. | |
578 this.defining = false; | |
579 | |
580 if (this.defined && !this.defineEmitted) { | |
581 this.defineEmitted = true; | |
582 this.emit('defined', this.exports); | |
583 this.defineEmitComplete = true; | |
584 } | |
585 } | |
586 }, | |
587 | |
588 enable: function() { | |
589 enabledRegistry[this.map.id] = this; | |
590 this.enabled = true; | |
591 | |
592 // Set flag mentioning that the module is enabling, | |
593 // so that immediate calls to the defined callbacks | |
594 // for dependencies do not trigger inadvertent load | |
595 // with the depCount still being zero. | |
596 this.enabling = true; | |
597 | |
598 // Enable each dependency | |
599 each(this.depMaps, bind(this, function(depMap, i) { | |
600 var id, mod, handler; | |
601 | |
602 if (typeof depMap === 'string') { | |
603 // Dependency needs to be converted to a depMap | |
604 // and wired up to this module. | |
605 depMap = makeModuleMap( | |
606 depMap, | |
607 (this.map.isDefine ? this.map : this.map.parentMap), | |
608 true); | |
609 this.depMaps[i] = depMap; | |
610 | |
611 this.depCount += 1; | |
612 | |
613 on(depMap, 'defined', bind(this, function(depExports) { | |
614 if (this.undefed) { | |
615 return; | |
616 } | |
617 this.defineDep(i, depExports); | |
618 this.check(); | |
619 })); | |
620 | |
621 if (this.errback) { | |
622 on(depMap, 'error', bind(this, this.errback)); | |
623 } else if (this.events.error) { | |
624 // No direct errback on this module, but something | |
625 // else is listening for errors, so be sure to | |
626 // propagate the error correctly. | |
627 on(depMap, 'error', bind(this, function(err) { | |
628 this.emit('error', err); | |
629 })); | |
630 } | |
631 } | |
632 | |
633 id = depMap.id; | |
634 mod = registry[id]; | |
635 | |
636 // Skip special modules like 'require', 'exports', 'module' | |
637 // Also, don't call enable if it is already enabled, | |
638 // important in circular dependency cases. | |
639 if (!hasProp(handlers, id) && mod && !mod.enabled) { | |
640 context.enable(depMap, this); | |
641 } | |
642 })); | |
643 | |
644 this.enabling = false; | |
645 | |
646 this.check(); | |
647 }, | |
648 | |
649 on: function(name, cb) { | |
650 var cbs = this.events[name]; | |
651 if (!cbs) { | |
652 cbs = this.events[name] = []; | |
653 } | |
654 cbs.push(cb); | |
655 }, | |
656 | |
657 emit: function(name, evt) { | |
658 each(this.events[name], function(cb) { | |
659 cb(evt); | |
660 }); | |
661 if (name === 'error') { | |
662 // Now that the error handler was triggered, remove | |
663 // the listeners, since this broken Module instance | |
664 // can stay around for a while in the registry. | |
665 delete this.events[name]; | |
666 } | |
667 } | |
668 }; | |
669 | |
670 function callGetModule(args) { | |
671 // Skip modules already defined. | |
672 if (!hasProp(defined, args[0])) { | |
673 getModule(makeModuleMap(args[0], null)).init(args[1], args[2]); | |
674 } | |
675 } | |
676 | |
677 function intakeDefines() { | |
678 var args; | |
679 | |
680 // Any defined modules in the global queue, intake them now. | |
681 takeGlobalQueue(); | |
682 | |
683 // Make sure any remaining defQueue items get properly processed. | |
684 while (defQueue.length) { | |
685 args = defQueue.shift(); | |
686 if (args[0] === null) { | |
687 return onError(makeError('mismatch', | |
688 'Mismatched anonymous define() module: ' + | |
689 args[args.length - 1])); | |
690 } else { | |
691 // args are id, deps, factory. Should be normalized by the | |
692 // define() function. | |
693 callGetModule(args); | |
694 } | |
695 } | |
696 context.defQueueMap = {}; | |
697 } | |
698 | |
699 context = { | |
700 config: config, | |
701 contextName: contextName, | |
702 registry: registry, | |
703 defined: defined, | |
704 urlFetched: urlFetched, | |
705 defQueue: defQueue, | |
706 defQueueMap: {}, | |
707 Module: Module, | |
708 makeModuleMap: makeModuleMap, | |
709 nextTick: req.nextTick, | |
710 onError: onError, | |
711 | |
712 /** | |
713 * Set a configuration for the context. | |
714 */ | |
715 configure: function() { | |
716 // If there are any "waiting to execute" modules in the registry, | |
717 // update the maps for them, since their info, like URLs to load, | |
718 // may have changed. | |
719 eachProp(registry, function(mod, id) { | |
720 // If module already has init called, since it is too | |
721 // late to modify them. | |
722 if (!mod.inited) { | |
723 mod.map = makeModuleMap(id, null); | |
724 } | |
725 }); | |
726 }, | |
727 | |
728 makeRequire: function() { | |
729 function localRequire(deps, callback, errback) { | |
730 var id, map, requireMod; | |
731 | |
732 if (typeof deps === 'string') { | |
733 if (isFunction(callback)) { | |
734 // Invalid call | |
735 return onError(makeError('requireargs', 'Invalid require call'), | |
736 errback); | |
737 } | |
738 | |
739 // Synchronous access to one module. If require.get is | |
740 // available (as in the Node adapter), prefer that. | |
741 if (req.get) { | |
742 return req.get(context, deps, null, localRequire); | |
743 } | |
744 | |
745 // Normalize module name, if it contains . or .. | |
746 map = makeModuleMap(deps, null, true); | |
747 id = map.id; | |
748 | |
749 if (!hasProp(defined, id)) { | |
750 return onError(makeError( | |
751 'notloaded', 'Module name "' + id + | |
752 '" has not been loaded yet for context: ' + | |
753 contextName + '. Use require([])')); | |
754 } | |
755 return defined[id]; | |
756 } | |
757 | |
758 // Grab defines waiting in the global queue. | |
759 intakeDefines(); | |
760 | |
761 // Mark all the dependencies as needing to be loaded. | |
762 context.nextTick(function() { | |
763 // Some defines could have been added since the | |
764 // require call, collect them. | |
765 intakeDefines(); | |
766 | |
767 requireMod = getModule(makeModuleMap(null)); | |
768 | |
769 requireMod.init(deps, callback, errback, { | |
770 enabled: true | |
771 }); | |
772 | |
773 checkLoaded(); | |
774 }); | |
775 | |
776 return localRequire; | |
777 } | |
778 | |
779 return localRequire; | |
780 }, | |
781 | |
782 /** | |
783 * Called to enable a module if it is still in the registry | |
784 * awaiting enablement. A second arg, parent, the parent module, | |
785 * is passed in for context, when this method is overridden by | |
786 * the optimizer. Not shown here to keep code compact. | |
787 */ | |
788 enable: function(depMap) { | |
789 var mod = getOwn(registry, depMap.id); | |
790 if (mod) { | |
791 getModule(depMap).enable(); | |
792 } | |
793 }, | |
794 | |
795 /** | |
796 * Internal method used by environment adapters to complete a load event. | |
797 * A load event could be a script load or just a load pass from a | |
798 * synchronous load call. | |
799 * @param {String} moduleName the name of the module to potentially | |
800 * complete. | |
801 */ | |
802 completeLoad: function(moduleName) { | |
803 var found, args, mod; | |
804 takeGlobalQueue(); | |
805 | |
806 while (defQueue.length) { | |
807 args = defQueue.shift(); | |
808 if (args[0] === null) { | |
809 args[0] = moduleName; | |
810 // If already found an anonymous module and bound it | |
811 // to this name, then this is some other anon module | |
812 // waiting for its completeLoad to fire. | |
813 if (found) { | |
814 break; | |
815 } | |
816 found = true; | |
817 } else if (args[0] === moduleName) { | |
818 // Found matching define call for this script! | |
819 found = true; | |
820 } | |
821 | |
822 callGetModule(args); | |
823 } | |
824 context.defQueueMap = {}; | |
825 | |
826 // Do this after the cycle of callGetModule in case the result | |
827 // of those calls/init calls changes the registry. | |
828 mod = getOwn(registry, moduleName); | |
829 | |
830 if (!found && !hasProp(defined, moduleName) && mod && !mod.inited) { | |
831 // A script that does not call define(), so just simulate | |
832 // the call for it. | |
833 callGetModule([moduleName, [], null]); | |
834 } | |
835 | |
836 checkLoaded(); | |
837 }, | |
838 | |
839 /** | |
840 * Converts a module name to a file path. Supports cases where | |
841 * moduleName may actually be just an URL. | |
842 */ | |
843 nameToUrl: function(moduleName, ext) { | |
844 var syms, i, url, parentPath, bundleId; | |
845 | |
846 // If a colon is in the URL, it indicates a protocol is used and it | |
847 // is just an URL to a file, or if it starts with a slash, contains a | |
848 // query arg (i.e. ?) or ends with .js, then assume the user meant to | |
849 // use an url and not a module id. The slash is important for | |
850 // protocol-less URLs as well as full paths. | |
851 if (req.jsExtRegExp.test(moduleName)) { | |
852 // Just a plain path, not module name lookup, so just return it. | |
853 // Add extension if it is included. This is a bit wonky, only | |
854 // non-.js things pass an extension, this method probably needs | |
855 // to be reworked. | |
856 url = moduleName; | |
857 } else { | |
858 syms = moduleName.split('/'); | |
859 // Join the path parts together, then figure out if baseUrl is needed. | |
860 url = syms.join('/'); | |
861 url += (/^data\:|\?/.test(url) || '.js'); | |
862 url = (url.charAt(0) === '/' || | |
863 url.match(/^[\w\+\.\-]+:/) ? '' : config.baseUrl) + url; | |
864 } | |
865 | |
866 return url; | |
867 }, | |
868 | |
869 // Delegates to req.load. Broken out as a separate function to | |
870 // allow overriding in the optimizer. | |
871 load: function(id, url) { | |
872 req.load(context, id, url); | |
873 }, | |
874 | |
875 /** | |
876 * Executes a module callback function. Broken out as a separate function | |
877 * solely to allow the build system to sequence the files in the built | |
878 * layer in the right sequence. | |
879 * | |
880 * @private | |
881 */ | |
882 execCb: function(name, callback, args, exports) { | |
883 return callback.apply(exports, args); | |
884 }, | |
885 | |
886 /** | |
887 * Direct callback for load error. | |
888 */ | |
889 onScriptFailure: function(moduleName) { | |
890 onError(makeError('scripterror', 'Script error for "' + | |
891 moduleName + '"'), null, [moduleName]); | |
892 }, | |
893 }; | |
894 | |
895 context.require = context.makeRequire(); | |
896 return context; | |
897 } | |
898 | |
899 /** | |
900 * Main entry point. | |
901 * | |
902 * If the only argument to require is a string, then the module that | |
903 * is represented by that string is fetched for the appropriate context. | |
904 * | |
905 * If the first argument is an array, then it will be treated as an array | |
906 * of dependency string names to fetch. An optional function callback can | |
907 * be specified to execute when all of those dependencies are available. | |
908 * | |
909 * Make a local req variable to help Caja compliance (it assumes things | |
910 * on a require that are not standardized), and to give a short | |
911 * name for minification/local scope use. | |
912 */ | |
913 req = requirejs = function(deps, callback, errback, optional) { | |
914 | |
915 // Find the right context, use default | |
916 var context, config, | |
917 contextName = defContextName; | |
918 | |
919 // Determine if have config object in the call. | |
920 if (!isArray(deps) && typeof deps !== 'string') { | |
921 // deps is a config object | |
922 config = deps; | |
923 if (isArray(callback)) { | |
924 // Adjust args if there are dependencies | |
925 deps = callback; | |
926 callback = errback; | |
927 errback = optional; | |
928 } else { | |
929 deps = []; | |
930 } | |
931 } | |
932 | |
933 context = getOwn(contexts, contextName); | |
934 if (!context) { | |
935 context = contexts[contextName] = req.s.newContext(contextName); | |
936 } | |
937 | |
938 if (config) { | |
939 context.configure(config); | |
940 } | |
941 | |
942 return context.require(deps, callback, errback); | |
943 }; | |
944 | |
945 /** | |
946 * Execute something after the current tick | |
947 * of the event loop. Override for other envs | |
948 * that have a better solution than setTimeout. | |
949 * @param {Function} fn function to execute later. | |
950 */ | |
951 req.nextTick = typeof setTimeout !== 'undefined' ? function(fn) { | |
952 setTimeout(fn, 4); | |
953 } : function(fn) { fn(); }; | |
954 | |
955 // Used to filter out dependencies that are already paths. | |
956 req.jsExtRegExp = /^\/|:|\?|\.js$/; | |
957 s = req.s = { | |
958 contexts: contexts, | |
959 newContext: newContext | |
960 }; | |
961 | |
962 // Create default context. | |
963 req({}); | |
964 | |
965 /** | |
966 * Any errors that require explicitly generates will be passed to this | |
967 * function. Intercept/override it if you want custom error handling. | |
968 * @param {Error} err the error object. | |
969 */ | |
970 req.onError = defaultOnError; | |
971 | |
972 /** | |
973 * Does the request to load a module for the browser case. | |
974 * Make this a separate function to allow other environments | |
975 * to override it. | |
976 * | |
977 * @param {Object} context the require context to find state. | |
978 * @param {String} moduleName the name of the module. | |
979 * @param {Object} url the URL to the module. | |
980 */ | |
981 req.load = function(context, moduleName, url) { | |
982 var config = (context && context.config) || {}; | |
983 var loadId = __crWeb.webUIModuleLoadNotifier.addPendingContext( | |
984 moduleName, context); | |
985 chrome.send('webui.loadMojo', [moduleName, loadId]); | |
986 }; | |
987 | |
988 /** | |
989 * The function that handles definitions of modules. Differs from | |
990 * require() in that a string for the module should be the first argument, | |
991 * and the function to execute after dependencies are loaded should | |
992 * return a value to define the module corresponding to the first argument's | |
993 * name. | |
994 */ | |
995 define = function(name, deps, callback) { | |
996 var node, context; | |
997 | |
998 // Allow for anonymous modules, which load automatically | |
999 if (typeof name !== 'string') { | |
1000 // Adjust args appropriately | |
1001 callback = deps; | |
1002 deps = name; | |
1003 name = 'ios.chrome.anonymous' + (anonymousModuleId++); | |
1004 | |
1005 requirejs([name], null, function(error) { | |
1006 throw error; | |
1007 }); | |
1008 } | |
1009 | |
1010 // This module may not have dependencies | |
1011 if (!isArray(deps)) { | |
1012 callback = deps; | |
1013 deps = null; | |
1014 } | |
1015 | |
1016 // If no name, and callback is a function, then figure out if it a | |
1017 // CommonJS thing with dependencies. | |
1018 if (!deps && isFunction(callback)) { | |
1019 deps = []; | |
1020 // Remove comments from the callback string, | |
1021 // look for require calls, and pull them into the dependencies, | |
1022 // but only if there are function args. | |
1023 if (callback.length) { | |
1024 callback | |
1025 .toString() | |
1026 .replace(commentRegExp, commentReplace) | |
1027 .replace(cjsRequireRegExp, function(match, dep) { | |
1028 deps.push(dep); | |
1029 }); | |
1030 | |
1031 // May be a CommonJS thing even without require calls, but still | |
1032 // could use exports, and module. Avoid doing exports and module | |
1033 // work though if it just needs require. | |
1034 // REQUIRES the function to expect the CommonJS variables in the | |
1035 // order listed below. | |
1036 deps = (callback.length === 1 ? | |
1037 ['require'] : | |
1038 ['require', 'exports', 'module']).concat(deps); | |
1039 } | |
1040 } | |
1041 | |
1042 // Always save off evaluating the def call until the script onload | |
1043 // handler. This allows multiple modules to be in a file without | |
1044 // prematurely tracing dependencies, and allows for anonymous module | |
1045 // support, where the module name is not known until the script onload | |
1046 // event occurs. If no context, use the global queue, and get it | |
1047 // processed in the onscript load callback. | |
1048 if (context) { | |
1049 context.defQueue.push([name, deps, callback]); | |
1050 context.defQueueMap[name] = true; | |
1051 } else { | |
1052 globalDefQueue.push([name, deps, callback]); | |
1053 } | |
1054 }; | |
1055 | |
1056 req(); | |
1057 }(this)); | |
1058 | |
1059 document.addEventListener("DOMContentLoaded", function(event) { | |
1060 requirejs(['main'], function(main) { | |
1061 main(); | |
1062 }, function(error) { | |
1063 throw error; | |
1064 }); | |
1065 }); | |
OLD | NEW |