MDL-56009 lib: update RequireJS to 2.3.2
[moodle.git] / lib / requirejs / require.js
CommitLineData
adeb96d2 1/** vim: et:ts=4:sw=4:sts=4
bc963d98
SL
2 * @license RequireJS 2.3.2 Copyright jQuery Foundation and other contributors.
3 * Released under MIT license, https://github.com/requirejs/requirejs/blob/master/LICENSE
adeb96d2
DW
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
10var requirejs, require, define;
bc963d98 11(function (global, setTimeout) {
adeb96d2
DW
12 var req, s, head, baseElement, dataMain, src,
13 interactiveScript, currentlyAddingScript, mainScript, subPath,
bc963d98
SL
14 version = '2.3.2',
15 commentRegExp = /\/\*[\s\S]*?\*\/|([^:"'=]|^)\/\/.*$/mg,
adeb96d2
DW
16 cjsRequireRegExp = /[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g,
17 jsSuffixRegExp = /\.js$/,
18 currDirRegExp = /^\.\//,
19 op = Object.prototype,
20 ostring = op.toString,
21 hasOwn = op.hasOwnProperty,
adeb96d2
DW
22 isBrowser = !!(typeof window !== 'undefined' && typeof navigator !== 'undefined' && window.document),
23 isWebWorker = !isBrowser && typeof importScripts !== 'undefined',
24 //PS3 indicates loaded and complete, but need to wait for complete
25 //specifically. Sequence is 'loading', 'loaded', execution,
26 // then 'complete'. The UA check is unfortunate, but not sure how
27 //to feature test w/o causing perf issues.
28 readyRegExp = isBrowser && navigator.platform === 'PLAYSTATION 3' ?
29 /^complete$/ : /^(complete|loaded)$/,
30 defContextName = '_',
31 //Oh the tragedy, detecting opera. See the usage of isOpera for reason.
32 isOpera = typeof opera !== 'undefined' && opera.toString() === '[object Opera]',
33 contexts = {},
34 cfg = {},
35 globalDefQueue = [],
36 useInteractive = false;
37
2f427c4c 38 //Could match something like ')//comment', do not lose the prefix to comment.
bc963d98 39 function commentReplace(match, singlePrefix) {
2f427c4c
SL
40 return singlePrefix || '';
41 }
42
adeb96d2
DW
43 function isFunction(it) {
44 return ostring.call(it) === '[object Function]';
45 }
46
47 function isArray(it) {
48 return ostring.call(it) === '[object Array]';
49 }
50
51 /**
52 * Helper function for iterating over an array. If the func returns
53 * a true value, it will break out of the loop.
54 */
55 function each(ary, func) {
56 if (ary) {
57 var i;
58 for (i = 0; i < ary.length; i += 1) {
59 if (ary[i] && func(ary[i], i, ary)) {
60 break;
61 }
62 }
63 }
64 }
65
66 /**
67 * Helper function for iterating over an array backwards. If the func
68 * returns a true value, it will break out of the loop.
69 */
70 function eachReverse(ary, func) {
71 if (ary) {
72 var i;
73 for (i = ary.length - 1; i > -1; i -= 1) {
74 if (ary[i] && func(ary[i], i, ary)) {
75 break;
76 }
77 }
78 }
79 }
80
81 function hasProp(obj, prop) {
82 return hasOwn.call(obj, prop);
83 }
84
85 function getOwn(obj, prop) {
86 return hasProp(obj, prop) && obj[prop];
87 }
88
89 /**
90 * Cycles over properties in an object and calls a function for each
91 * property value. If the function returns a truthy value, then the
92 * iteration is stopped.
93 */
94 function eachProp(obj, func) {
95 var prop;
96 for (prop in obj) {
97 if (hasProp(obj, prop)) {
98 if (func(obj[prop], prop)) {
99 break;
100 }
101 }
102 }
103 }
104
105 /**
106 * Simple function to mix in properties from source into target,
107 * but only if target does not already have a property of the same name.
108 */
109 function mixin(target, source, force, deepStringMixin) {
110 if (source) {
111 eachProp(source, function (value, prop) {
112 if (force || !hasProp(target, prop)) {
113 if (deepStringMixin && typeof value === 'object' && value &&
114 !isArray(value) && !isFunction(value) &&
115 !(value instanceof RegExp)) {
116
117 if (!target[prop]) {
118 target[prop] = {};
119 }
120 mixin(target[prop], value, force, deepStringMixin);
121 } else {
122 target[prop] = value;
123 }
124 }
125 });
126 }
127 return target;
128 }
129
130 //Similar to Function.prototype.bind, but the 'this' object is specified
131 //first, since it is easier to read/figure out what 'this' will be.
132 function bind(obj, fn) {
133 return function () {
134 return fn.apply(obj, arguments);
135 };
136 }
137
138 function scripts() {
139 return document.getElementsByTagName('script');
140 }
141
142 function defaultOnError(err) {
143 throw err;
144 }
145
146 //Allow getting a global that is expressed in
147 //dot notation, like 'a.b.c'.
148 function getGlobal(value) {
149 if (!value) {
150 return value;
151 }
152 var g = global;
153 each(value.split('.'), function (part) {
154 g = g[part];
155 });
156 return g;
157 }
158
159 /**
160 * Constructs an error with a pointer to an URL with more information.
161 * @param {String} id the error ID that maps to an ID on a web page.
162 * @param {String} message human readable error.
163 * @param {Error} [err] the original error, if there is one.
164 *
165 * @returns {Error}
166 */
167 function makeError(id, msg, err, requireModules) {
168 var e = new Error(msg + '\nhttp://requirejs.org/docs/errors.html#' + id);
169 e.requireType = id;
170 e.requireModules = requireModules;
171 if (err) {
172 e.originalError = err;
173 }
174 return e;
175 }
176
177 if (typeof define !== 'undefined') {
178 //If a define is already in play via another AMD loader,
179 //do not overwrite.
180 return;
181 }
182
183 if (typeof requirejs !== 'undefined') {
184 if (isFunction(requirejs)) {
185 //Do not overwrite an existing requirejs instance.
186 return;
187 }
188 cfg = requirejs;
189 requirejs = undefined;
190 }
191
192 //Allow for a require config object
193 if (typeof require !== 'undefined' && !isFunction(require)) {
194 //assume it is a config object.
195 cfg = require;
196 require = undefined;
197 }
198
199 function newContext(contextName) {
200 var inCheckLoaded, Module, context, handlers,
201 checkLoadedTimeoutId,
202 config = {
203 //Defaults. Do not set a default for map
204 //config to speed up normalize(), which
205 //will run faster if there is no default.
206 waitSeconds: 7,
207 baseUrl: './',
208 paths: {},
209 bundles: {},
210 pkgs: {},
211 shim: {},
212 config: {}
213 },
214 registry = {},
215 //registry of just enabled modules, to speed
216 //cycle breaking code when lots of modules
217 //are registered, but not activated.
218 enabledRegistry = {},
219 undefEvents = {},
220 defQueue = [],
221 defined = {},
222 urlFetched = {},
223 bundlesMap = {},
224 requireCounter = 1,
225 unnormalizedCounter = 1;
226
227 /**
228 * Trims the . and .. from an array of path segments.
229 * It will keep a leading path segment if a .. will become
230 * the first path segment, to help with module name lookups,
231 * which act like paths, but can be remapped. But the end result,
232 * all paths that use this function should look normalized.
233 * NOTE: this method MODIFIES the input array.
234 * @param {Array} ary the array of path segments.
235 */
236 function trimDots(ary) {
237 var i, part;
238 for (i = 0; i < ary.length; i++) {
239 part = ary[i];
240 if (part === '.') {
241 ary.splice(i, 1);
242 i -= 1;
243 } else if (part === '..') {
244 // If at the start, or previous value is still ..,
245 // keep them so that when converted to a path it may
246 // still work when converted to a path, even though
247 // as an ID it is less than ideal. In larger point
248 // releases, may be better to just kick out an error.
a3620861 249 if (i === 0 || (i === 1 && ary[2] === '..') || ary[i - 1] === '..') {
adeb96d2
DW
250 continue;
251 } else if (i > 0) {
252 ary.splice(i - 1, 2);
253 i -= 2;
254 }
255 }
256 }
257 }
258
259 /**
260 * Given a relative module name, like ./something, normalize it to
261 * a real name that can be mapped to a path.
262 * @param {String} name the relative name
263 * @param {String} baseName a real name that the name arg is relative
264 * to.
265 * @param {Boolean} applyMap apply the map config to the value. Should
266 * only be done if this normalization is for a dependency ID.
267 * @returns {String} normalized name
268 */
269 function normalize(name, baseName, applyMap) {
270 var pkgMain, mapValue, nameParts, i, j, nameSegment, lastIndex,
271 foundMap, foundI, foundStarMap, starI, normalizedBaseParts,
272 baseParts = (baseName && baseName.split('/')),
273 map = config.map,
274 starMap = map && map['*'];
275
276 //Adjust any relative paths.
277 if (name) {
278 name = name.split('/');
279 lastIndex = name.length - 1;
280
281 // If wanting node ID compatibility, strip .js from end
282 // of IDs. Have to do this here, and not in nameToUrl
283 // because node allows either .js or non .js to map
284 // to same file.
285 if (config.nodeIdCompat && jsSuffixRegExp.test(name[lastIndex])) {
286 name[lastIndex] = name[lastIndex].replace(jsSuffixRegExp, '');
287 }
288
289 // Starts with a '.' so need the baseName
290 if (name[0].charAt(0) === '.' && baseParts) {
291 //Convert baseName to array, and lop off the last part,
292 //so that . matches that 'directory' and not name of the baseName's
293 //module. For instance, baseName of 'one/two/three', maps to
294 //'one/two/three.js', but we want the directory, 'one/two' for
295 //this normalization.
296 normalizedBaseParts = baseParts.slice(0, baseParts.length - 1);
297 name = normalizedBaseParts.concat(name);
298 }
299
300 trimDots(name);
301 name = name.join('/');
302 }
303
304 //Apply map config if available.
305 if (applyMap && map && (baseParts || starMap)) {
306 nameParts = name.split('/');
307
308 outerLoop: for (i = nameParts.length; i > 0; i -= 1) {
309 nameSegment = nameParts.slice(0, i).join('/');
310
311 if (baseParts) {
312 //Find the longest baseName segment match in the config.
313 //So, do joins on the biggest to smallest lengths of baseParts.
314 for (j = baseParts.length; j > 0; j -= 1) {
315 mapValue = getOwn(map, baseParts.slice(0, j).join('/'));
316
317 //baseName segment has config, find if it has one for
318 //this name.
319 if (mapValue) {
320 mapValue = getOwn(mapValue, nameSegment);
321 if (mapValue) {
322 //Match, update name to the new value.
323 foundMap = mapValue;
324 foundI = i;
325 break outerLoop;
326 }
327 }
328 }
329 }
330
331 //Check for a star map match, but just hold on to it,
332 //if there is a shorter segment match later in a matching
333 //config, then favor over this star map.
334 if (!foundStarMap && starMap && getOwn(starMap, nameSegment)) {
335 foundStarMap = getOwn(starMap, nameSegment);
336 starI = i;
337 }
338 }
339
340 if (!foundMap && foundStarMap) {
341 foundMap = foundStarMap;
342 foundI = starI;
343 }
344
345 if (foundMap) {
346 nameParts.splice(0, foundI, foundMap);
347 name = nameParts.join('/');
348 }
349 }
350
351 // If the name points to a package's name, use
352 // the package main instead.
353 pkgMain = getOwn(config.pkgs, name);
354
355 return pkgMain ? pkgMain : name;
356 }
357
358 function removeScript(name) {
359 if (isBrowser) {
360 each(scripts(), function (scriptNode) {
361 if (scriptNode.getAttribute('data-requiremodule') === name &&
362 scriptNode.getAttribute('data-requirecontext') === context.contextName) {
363 scriptNode.parentNode.removeChild(scriptNode);
364 return true;
365 }
366 });
367 }
368 }
369
370 function hasPathFallback(id) {
371 var pathConfig = getOwn(config.paths, id);
372 if (pathConfig && isArray(pathConfig) && pathConfig.length > 1) {
373 //Pop off the first array value, since it failed, and
374 //retry
375 pathConfig.shift();
376 context.require.undef(id);
377
378 //Custom require that does not do map translation, since
379 //ID is "absolute", already mapped/resolved.
380 context.makeRequire(null, {
381 skipMap: true
382 })([id]);
383
384 return true;
385 }
386 }
387
388 //Turns a plugin!resource to [plugin, resource]
389 //with the plugin being undefined if the name
390 //did not have a plugin prefix.
391 function splitPrefix(name) {
392 var prefix,
393 index = name ? name.indexOf('!') : -1;
394 if (index > -1) {
395 prefix = name.substring(0, index);
396 name = name.substring(index + 1, name.length);
397 }
398 return [prefix, name];
399 }
400
401 /**
402 * Creates a module mapping that includes plugin prefix, module
403 * name, and path. If parentModuleMap is provided it will
404 * also normalize the name via require.normalize()
405 *
406 * @param {String} name the module name
407 * @param {String} [parentModuleMap] parent module map
408 * for the module name, used to resolve relative names.
409 * @param {Boolean} isNormalized: is the ID already normalized.
410 * This is true if this call is done for a define() module ID.
411 * @param {Boolean} applyMap: apply the map config to the ID.
412 * Should only be true if this map is for a dependency.
413 *
414 * @returns {Object}
415 */
416 function makeModuleMap(name, parentModuleMap, isNormalized, applyMap) {
417 var url, pluginModule, suffix, nameParts,
418 prefix = null,
419 parentName = parentModuleMap ? parentModuleMap.name : null,
420 originalName = name,
421 isDefine = true,
422 normalizedName = '';
423
424 //If no name, then it means it is a require call, generate an
425 //internal name.
426 if (!name) {
427 isDefine = false;
428 name = '_@r' + (requireCounter += 1);
429 }
430
431 nameParts = splitPrefix(name);
432 prefix = nameParts[0];
433 name = nameParts[1];
434
435 if (prefix) {
436 prefix = normalize(prefix, parentName, applyMap);
437 pluginModule = getOwn(defined, prefix);
438 }
439
440 //Account for relative paths if there is a base name.
441 if (name) {
442 if (prefix) {
443 if (pluginModule && pluginModule.normalize) {
444 //Plugin is loaded, use its normalize method.
445 normalizedName = pluginModule.normalize(name, function (name) {
446 return normalize(name, parentName, applyMap);
447 });
448 } else {
449 // If nested plugin references, then do not try to
450 // normalize, as it will not normalize correctly. This
451 // places a restriction on resourceIds, and the longer
452 // term solution is not to normalize until plugins are
453 // loaded and all normalizations to allow for async
454 // loading of a loader plugin. But for now, fixes the
455 // common uses. Details in #1131
456 normalizedName = name.indexOf('!') === -1 ?
457 normalize(name, parentName, applyMap) :
458 name;
459 }
460 } else {
461 //A regular module.
462 normalizedName = normalize(name, parentName, applyMap);
463
464 //Normalized name may be a plugin ID due to map config
465 //application in normalize. The map config values must
466 //already be normalized, so do not need to redo that part.
467 nameParts = splitPrefix(normalizedName);
468 prefix = nameParts[0];
469 normalizedName = nameParts[1];
470 isNormalized = true;
471
472 url = context.nameToUrl(normalizedName);
473 }
474 }
475
476 //If the id is a plugin id that cannot be determined if it needs
477 //normalization, stamp it with a unique ID so two matching relative
478 //ids that may conflict can be separate.
479 suffix = prefix && !pluginModule && !isNormalized ?
480 '_unnormalized' + (unnormalizedCounter += 1) :
481 '';
482
483 return {
484 prefix: prefix,
485 name: normalizedName,
486 parentMap: parentModuleMap,
487 unnormalized: !!suffix,
488 url: url,
489 originalName: originalName,
490 isDefine: isDefine,
491 id: (prefix ?
492 prefix + '!' + normalizedName :
493 normalizedName) + suffix
494 };
495 }
496
497 function getModule(depMap) {
498 var id = depMap.id,
499 mod = getOwn(registry, id);
500
501 if (!mod) {
502 mod = registry[id] = new context.Module(depMap);
503 }
504
505 return mod;
506 }
507
508 function on(depMap, name, fn) {
509 var id = depMap.id,
510 mod = getOwn(registry, id);
511
512 if (hasProp(defined, id) &&
513 (!mod || mod.defineEmitComplete)) {
514 if (name === 'defined') {
515 fn(defined[id]);
516 }
517 } else {
518 mod = getModule(depMap);
519 if (mod.error && name === 'error') {
520 fn(mod.error);
521 } else {
522 mod.on(name, fn);
523 }
524 }
525 }
526
527 function onError(err, errback) {
528 var ids = err.requireModules,
529 notified = false;
530
531 if (errback) {
532 errback(err);
533 } else {
534 each(ids, function (id) {
535 var mod = getOwn(registry, id);
536 if (mod) {
537 //Set error on module, so it skips timeout checks.
538 mod.error = err;
539 if (mod.events.error) {
540 notified = true;
541 mod.emit('error', err);
542 }
543 }
544 });
545
546 if (!notified) {
547 req.onError(err);
548 }
549 }
550 }
551
552 /**
553 * Internal method to transfer globalQueue items to this context's
554 * defQueue.
555 */
556 function takeGlobalQueue() {
557 //Push all the globalDefQueue items into the context's defQueue
558 if (globalDefQueue.length) {
a3620861
DW
559 each(globalDefQueue, function(queueItem) {
560 var id = queueItem[0];
561 if (typeof id === 'string') {
562 context.defQueueMap[id] = true;
563 }
564 defQueue.push(queueItem);
565 });
adeb96d2
DW
566 globalDefQueue = [];
567 }
568 }
569
570 handlers = {
571 'require': function (mod) {
572 if (mod.require) {
573 return mod.require;
574 } else {
575 return (mod.require = context.makeRequire(mod.map));
576 }
577 },
578 'exports': function (mod) {
579 mod.usingExports = true;
580 if (mod.map.isDefine) {
581 if (mod.exports) {
582 return (defined[mod.map.id] = mod.exports);
583 } else {
584 return (mod.exports = defined[mod.map.id] = {});
585 }
586 }
587 },
588 'module': function (mod) {
589 if (mod.module) {
590 return mod.module;
591 } else {
592 return (mod.module = {
593 id: mod.map.id,
594 uri: mod.map.url,
595 config: function () {
a3620861 596 return getOwn(config.config, mod.map.id) || {};
adeb96d2
DW
597 },
598 exports: mod.exports || (mod.exports = {})
599 });
600 }
601 }
602 };
603
604 function cleanRegistry(id) {
605 //Clean up machinery used for waiting modules.
606 delete registry[id];
607 delete enabledRegistry[id];
608 }
609
610 function breakCycle(mod, traced, processed) {
611 var id = mod.map.id;
612
613 if (mod.error) {
614 mod.emit('error', mod.error);
615 } else {
616 traced[id] = true;
617 each(mod.depMaps, function (depMap, i) {
618 var depId = depMap.id,
619 dep = getOwn(registry, depId);
620
621 //Only force things that have not completed
622 //being defined, so still in the registry,
623 //and only if it has not been matched up
624 //in the module already.
625 if (dep && !mod.depMatched[i] && !processed[depId]) {
626 if (getOwn(traced, depId)) {
627 mod.defineDep(i, defined[depId]);
628 mod.check(); //pass false?
629 } else {
630 breakCycle(dep, traced, processed);
631 }
632 }
633 });
634 processed[id] = true;
635 }
636 }
637
638 function checkLoaded() {
639 var err, usingPathFallback,
640 waitInterval = config.waitSeconds * 1000,
641 //It is possible to disable the wait interval by using waitSeconds of 0.
642 expired = waitInterval && (context.startTime + waitInterval) < new Date().getTime(),
643 noLoads = [],
644 reqCalls = [],
645 stillLoading = false,
646 needCycleCheck = true;
647
648 //Do not bother if this call was a result of a cycle break.
649 if (inCheckLoaded) {
650 return;
651 }
652
653 inCheckLoaded = true;
654
655 //Figure out the state of all the modules.
656 eachProp(enabledRegistry, function (mod) {
657 var map = mod.map,
658 modId = map.id;
659
660 //Skip things that are not enabled or in error state.
661 if (!mod.enabled) {
662 return;
663 }
664
665 if (!map.isDefine) {
666 reqCalls.push(mod);
667 }
668
669 if (!mod.error) {
670 //If the module should be executed, and it has not
671 //been inited and time is up, remember it.
672 if (!mod.inited && expired) {
673 if (hasPathFallback(modId)) {
674 usingPathFallback = true;
675 stillLoading = true;
676 } else {
677 noLoads.push(modId);
678 removeScript(modId);
679 }
680 } else if (!mod.inited && mod.fetched && map.isDefine) {
681 stillLoading = true;
682 if (!map.prefix) {
683 //No reason to keep looking for unfinished
684 //loading. If the only stillLoading is a
685 //plugin resource though, keep going,
686 //because it may be that a plugin resource
687 //is waiting on a non-plugin cycle.
688 return (needCycleCheck = false);
689 }
690 }
691 }
692 });
693
694 if (expired && noLoads.length) {
695 //If wait time expired, throw error of unloaded modules.
696 err = makeError('timeout', 'Load timeout for modules: ' + noLoads, null, noLoads);
697 err.contextName = context.contextName;
698 return onError(err);
699 }
700
701 //Not expired, check for a cycle.
702 if (needCycleCheck) {
703 each(reqCalls, function (mod) {
704 breakCycle(mod, {}, {});
705 });
706 }
707
708 //If still waiting on loads, and the waiting load is something
709 //other than a plugin resource, or there are still outstanding
710 //scripts, then just try back later.
711 if ((!expired || usingPathFallback) && stillLoading) {
712 //Something is still waiting to load. Wait for it, but only
713 //if a timeout is not already in effect.
714 if ((isBrowser || isWebWorker) && !checkLoadedTimeoutId) {
715 checkLoadedTimeoutId = setTimeout(function () {
716 checkLoadedTimeoutId = 0;
717 checkLoaded();
718 }, 50);
719 }
720 }
721
722 inCheckLoaded = false;
723 }
724
725 Module = function (map) {
726 this.events = getOwn(undefEvents, map.id) || {};
727 this.map = map;
728 this.shim = getOwn(config.shim, map.id);
729 this.depExports = [];
730 this.depMaps = [];
731 this.depMatched = [];
732 this.pluginMaps = {};
733 this.depCount = 0;
734
735 /* this.exports this.factory
736 this.depMaps = [],
737 this.enabled, this.fetched
738 */
739 };
740
741 Module.prototype = {
742 init: function (depMaps, factory, errback, options) {
743 options = options || {};
744
745 //Do not do more inits if already done. Can happen if there
746 //are multiple define calls for the same module. That is not
747 //a normal, common case, but it is also not unexpected.
748 if (this.inited) {
749 return;
750 }
751
752 this.factory = factory;
753
754 if (errback) {
755 //Register for errors on this module.
756 this.on('error', errback);
757 } else if (this.events.error) {
758 //If no errback already, but there are error listeners
759 //on this module, set up an errback to pass to the deps.
760 errback = bind(this, function (err) {
761 this.emit('error', err);
762 });
763 }
764
765 //Do a copy of the dependency array, so that
766 //source inputs are not modified. For example
767 //"shim" deps are passed in here directly, and
768 //doing a direct modification of the depMaps array
769 //would affect that config.
770 this.depMaps = depMaps && depMaps.slice(0);
771
772 this.errback = errback;
773
774 //Indicate this module has be initialized
775 this.inited = true;
776
777 this.ignore = options.ignore;
778
779 //Could have option to init this module in enabled mode,
780 //or could have been previously marked as enabled. However,
781 //the dependencies are not known until init is called. So
782 //if enabled previously, now trigger dependencies as enabled.
783 if (options.enabled || this.enabled) {
784 //Enable this module and dependencies.
785 //Will call this.check()
786 this.enable();
787 } else {
788 this.check();
789 }
790 },
791
792 defineDep: function (i, depExports) {
793 //Because of cycles, defined callback for a given
794 //export can be called more than once.
795 if (!this.depMatched[i]) {
796 this.depMatched[i] = true;
797 this.depCount -= 1;
798 this.depExports[i] = depExports;
799 }
800 },
801
802 fetch: function () {
803 if (this.fetched) {
804 return;
805 }
806 this.fetched = true;
807
808 context.startTime = (new Date()).getTime();
809
810 var map = this.map;
811
812 //If the manager is for a plugin managed resource,
813 //ask the plugin to load it now.
814 if (this.shim) {
815 context.makeRequire(this.map, {
816 enableBuildCallback: true
817 })(this.shim.deps || [], bind(this, function () {
818 return map.prefix ? this.callPlugin() : this.load();
819 }));
820 } else {
821 //Regular dependency.
822 return map.prefix ? this.callPlugin() : this.load();
823 }
824 },
825
826 load: function () {
827 var url = this.map.url;
828
829 //Regular dependency.
830 if (!urlFetched[url]) {
831 urlFetched[url] = true;
832 context.load(this.map.id, url);
833 }
834 },
835
836 /**
837 * Checks if the module is ready to define itself, and if so,
838 * define it.
839 */
840 check: function () {
841 if (!this.enabled || this.enabling) {
842 return;
843 }
844
845 var err, cjsModule,
846 id = this.map.id,
847 depExports = this.depExports,
848 exports = this.exports,
849 factory = this.factory;
850
851 if (!this.inited) {
a3620861
DW
852 // Only fetch if not already in the defQueue.
853 if (!hasProp(context.defQueueMap, id)) {
854 this.fetch();
855 }
adeb96d2
DW
856 } else if (this.error) {
857 this.emit('error', this.error);
858 } else if (!this.defining) {
859 //The factory could trigger another require call
860 //that would result in checking this module to
861 //define itself again. If already in the process
862 //of doing that, skip this work.
863 this.defining = true;
864
865 if (this.depCount < 1 && !this.defined) {
866 if (isFunction(factory)) {
bc963d98
SL
867 //If there is an error listener, favor passing
868 //to that instead of throwing an error. However,
869 //only do it for define()'d modules. require
870 //errbacks should not be called for failures in
871 //their callbacks (#699). However if a global
872 //onError is set, use that.
873 if ((this.events.error && this.map.isDefine) ||
874 req.onError !== defaultOnError) {
875 try {
876 exports = context.execCb(id, factory, depExports, exports);
877 } catch (e) {
878 err = e;
879 }
880 } else {
adeb96d2
DW
881 exports = context.execCb(id, factory, depExports, exports);
882 }
883
884 // Favor return value over exports. If node/cjs in play,
885 // then will not have a return value anyway. Favor
886 // module.exports assignment over exports object.
887 if (this.map.isDefine && exports === undefined) {
888 cjsModule = this.module;
889 if (cjsModule) {
890 exports = cjsModule.exports;
891 } else if (this.usingExports) {
892 //exports already set the defined value.
893 exports = this.exports;
894 }
895 }
896
897 if (err) {
bc963d98
SL
898 err.requireMap = this.map;
899 err.requireModules = this.map.isDefine ? [this.map.id] : null;
900 err.requireType = this.map.isDefine ? 'define' : 'require';
901 return onError((this.error = err));
adeb96d2 902 }
bc963d98 903
adeb96d2
DW
904 } else {
905 //Just a literal value
906 exports = factory;
907 }
908
909 this.exports = exports;
910
911 if (this.map.isDefine && !this.ignore) {
912 defined[id] = exports;
913
914 if (req.onResourceLoad) {
2f427c4c
SL
915 var resLoadMaps = [];
916 each(this.depMaps, function (depMap) {
917 resLoadMaps.push(depMap.normalizedMap || depMap);
918 });
919 req.onResourceLoad(context, this.map, resLoadMaps);
adeb96d2
DW
920 }
921 }
922
923 //Clean up
924 cleanRegistry(id);
925
926 this.defined = true;
927 }
928
929 //Finished the define stage. Allow calling check again
930 //to allow define notifications below in the case of a
931 //cycle.
932 this.defining = false;
933
934 if (this.defined && !this.defineEmitted) {
935 this.defineEmitted = true;
936 this.emit('defined', this.exports);
937 this.defineEmitComplete = true;
938 }
939
940 }
941 },
942
943 callPlugin: function () {
944 var map = this.map,
945 id = map.id,
946 //Map already normalized the prefix.
947 pluginMap = makeModuleMap(map.prefix);
948
949 //Mark this as a dependency for this plugin, so it
950 //can be traced for cycles.
951 this.depMaps.push(pluginMap);
952
953 on(pluginMap, 'defined', bind(this, function (plugin) {
954 var load, normalizedMap, normalizedMod,
955 bundleId = getOwn(bundlesMap, this.map.id),
956 name = this.map.name,
957 parentName = this.map.parentMap ? this.map.parentMap.name : null,
958 localRequire = context.makeRequire(map.parentMap, {
959 enableBuildCallback: true
960 });
961
962 //If current map is not normalized, wait for that
963 //normalized name to load instead of continuing.
964 if (this.map.unnormalized) {
965 //Normalize the ID if the plugin allows it.
966 if (plugin.normalize) {
967 name = plugin.normalize(name, function (name) {
968 return normalize(name, parentName, true);
969 }) || '';
970 }
971
972 //prefix and name should already be normalized, no need
973 //for applying map config again either.
974 normalizedMap = makeModuleMap(map.prefix + '!' + name,
975 this.map.parentMap);
976 on(normalizedMap,
977 'defined', bind(this, function (value) {
2f427c4c 978 this.map.normalizedMap = normalizedMap;
adeb96d2
DW
979 this.init([], function () { return value; }, null, {
980 enabled: true,
981 ignore: true
982 });
983 }));
984
985 normalizedMod = getOwn(registry, normalizedMap.id);
986 if (normalizedMod) {
987 //Mark this as a dependency for this plugin, so it
988 //can be traced for cycles.
989 this.depMaps.push(normalizedMap);
990
991 if (this.events.error) {
992 normalizedMod.on('error', bind(this, function (err) {
993 this.emit('error', err);
994 }));
995 }
996 normalizedMod.enable();
997 }
998
999 return;
1000 }
1001
1002 //If a paths config, then just load that file instead to
1003 //resolve the plugin, as it is built into that paths layer.
1004 if (bundleId) {
1005 this.map.url = context.nameToUrl(bundleId);
1006 this.load();
1007 return;
1008 }
1009
1010 load = bind(this, function (value) {
1011 this.init([], function () { return value; }, null, {
1012 enabled: true
1013 });
1014 });
1015
1016 load.error = bind(this, function (err) {
1017 this.inited = true;
1018 this.error = err;
1019 err.requireModules = [id];
1020
1021 //Remove temp unnormalized modules for this module,
1022 //since they will never be resolved otherwise now.
1023 eachProp(registry, function (mod) {
1024 if (mod.map.id.indexOf(id + '_unnormalized') === 0) {
1025 cleanRegistry(mod.map.id);
1026 }
1027 });
1028
1029 onError(err);
1030 });
1031
1032 //Allow plugins to load other code without having to know the
1033 //context or how to 'complete' the load.
1034 load.fromText = bind(this, function (text, textAlt) {
1035 /*jslint evil: true */
1036 var moduleName = map.name,
1037 moduleMap = makeModuleMap(moduleName),
1038 hasInteractive = useInteractive;
1039
1040 //As of 2.1.0, support just passing the text, to reinforce
1041 //fromText only being called once per resource. Still
1042 //support old style of passing moduleName but discard
1043 //that moduleName in favor of the internal ref.
1044 if (textAlt) {
1045 text = textAlt;
1046 }
1047
1048 //Turn off interactive script matching for IE for any define
1049 //calls in the text, then turn it back on at the end.
1050 if (hasInteractive) {
1051 useInteractive = false;
1052 }
1053
1054 //Prime the system by creating a module instance for
1055 //it.
1056 getModule(moduleMap);
1057
1058 //Transfer any config to this other module.
1059 if (hasProp(config.config, id)) {
1060 config.config[moduleName] = config.config[id];
1061 }
1062
1063 try {
1064 req.exec(text);
1065 } catch (e) {
1066 return onError(makeError('fromtexteval',
1067 'fromText eval for ' + id +
1068 ' failed: ' + e,
1069 e,
1070 [id]));
1071 }
1072
1073 if (hasInteractive) {
1074 useInteractive = true;
1075 }
1076
1077 //Mark this as a dependency for the plugin
1078 //resource
1079 this.depMaps.push(moduleMap);
1080
1081 //Support anonymous modules.
1082 context.completeLoad(moduleName);
1083
1084 //Bind the value of that module to the value for this
1085 //resource ID.
1086 localRequire([moduleName], load);
1087 });
1088
1089 //Use parentName here since the plugin's name is not reliable,
1090 //could be some weird string with no path that actually wants to
1091 //reference the parentName's path.
1092 plugin.load(map.name, localRequire, load, config);
1093 }));
1094
1095 context.enable(pluginMap, this);
1096 this.pluginMaps[pluginMap.id] = pluginMap;
1097 },
1098
1099 enable: function () {
1100 enabledRegistry[this.map.id] = this;
1101 this.enabled = true;
1102
1103 //Set flag mentioning that the module is enabling,
1104 //so that immediate calls to the defined callbacks
1105 //for dependencies do not trigger inadvertent load
1106 //with the depCount still being zero.
1107 this.enabling = true;
1108
1109 //Enable each dependency
1110 each(this.depMaps, bind(this, function (depMap, i) {
1111 var id, mod, handler;
1112
1113 if (typeof depMap === 'string') {
1114 //Dependency needs to be converted to a depMap
1115 //and wired up to this module.
1116 depMap = makeModuleMap(depMap,
1117 (this.map.isDefine ? this.map : this.map.parentMap),
1118 false,
1119 !this.skipMap);
1120 this.depMaps[i] = depMap;
1121
1122 handler = getOwn(handlers, depMap.id);
1123
1124 if (handler) {
1125 this.depExports[i] = handler(this);
1126 return;
1127 }
1128
1129 this.depCount += 1;
1130
1131 on(depMap, 'defined', bind(this, function (depExports) {
a3620861
DW
1132 if (this.undefed) {
1133 return;
1134 }
adeb96d2
DW
1135 this.defineDep(i, depExports);
1136 this.check();
1137 }));
1138
1139 if (this.errback) {
1140 on(depMap, 'error', bind(this, this.errback));
a3620861
DW
1141 } else if (this.events.error) {
1142 // No direct errback on this module, but something
1143 // else is listening for errors, so be sure to
1144 // propagate the error correctly.
1145 on(depMap, 'error', bind(this, function(err) {
1146 this.emit('error', err);
1147 }));
adeb96d2
DW
1148 }
1149 }
1150
1151 id = depMap.id;
1152 mod = registry[id];
1153
1154 //Skip special modules like 'require', 'exports', 'module'
1155 //Also, don't call enable if it is already enabled,
1156 //important in circular dependency cases.
1157 if (!hasProp(handlers, id) && mod && !mod.enabled) {
1158 context.enable(depMap, this);
1159 }
1160 }));
1161
1162 //Enable each plugin that is used in
1163 //a dependency
1164 eachProp(this.pluginMaps, bind(this, function (pluginMap) {
1165 var mod = getOwn(registry, pluginMap.id);
1166 if (mod && !mod.enabled) {
1167 context.enable(pluginMap, this);
1168 }
1169 }));
1170
1171 this.enabling = false;
1172
1173 this.check();
1174 },
1175
1176 on: function (name, cb) {
1177 var cbs = this.events[name];
1178 if (!cbs) {
1179 cbs = this.events[name] = [];
1180 }
1181 cbs.push(cb);
1182 },
1183
1184 emit: function (name, evt) {
1185 each(this.events[name], function (cb) {
1186 cb(evt);
1187 });
1188 if (name === 'error') {
1189 //Now that the error handler was triggered, remove
1190 //the listeners, since this broken Module instance
1191 //can stay around for a while in the registry.
1192 delete this.events[name];
1193 }
1194 }
1195 };
1196
1197 function callGetModule(args) {
1198 //Skip modules already defined.
1199 if (!hasProp(defined, args[0])) {
1200 getModule(makeModuleMap(args[0], null, true)).init(args[1], args[2]);
1201 }
1202 }
1203
1204 function removeListener(node, func, name, ieName) {
1205 //Favor detachEvent because of IE9
1206 //issue, see attachEvent/addEventListener comment elsewhere
1207 //in this file.
1208 if (node.detachEvent && !isOpera) {
1209 //Probably IE. If not it will throw an error, which will be
1210 //useful to know.
1211 if (ieName) {
1212 node.detachEvent(ieName, func);
1213 }
1214 } else {
1215 node.removeEventListener(name, func, false);
1216 }
1217 }
1218
1219 /**
1220 * Given an event from a script node, get the requirejs info from it,
1221 * and then removes the event listeners on the node.
1222 * @param {Event} evt
1223 * @returns {Object}
1224 */
1225 function getScriptData(evt) {
1226 //Using currentTarget instead of target for Firefox 2.0's sake. Not
1227 //all old browsers will be supported, but this one was easy enough
1228 //to support and still makes sense.
1229 var node = evt.currentTarget || evt.srcElement;
1230
1231 //Remove the listeners once here.
1232 removeListener(node, context.onScriptLoad, 'load', 'onreadystatechange');
1233 removeListener(node, context.onScriptError, 'error');
1234
1235 return {
1236 node: node,
1237 id: node && node.getAttribute('data-requiremodule')
1238 };
1239 }
1240
1241 function intakeDefines() {
1242 var args;
1243
1244 //Any defined modules in the global queue, intake them now.
1245 takeGlobalQueue();
1246
1247 //Make sure any remaining defQueue items get properly processed.
1248 while (defQueue.length) {
1249 args = defQueue.shift();
1250 if (args[0] === null) {
a3620861
DW
1251 return onError(makeError('mismatch', 'Mismatched anonymous define() module: ' +
1252 args[args.length - 1]));
adeb96d2
DW
1253 } else {
1254 //args are id, deps, factory. Should be normalized by the
1255 //define() function.
1256 callGetModule(args);
1257 }
1258 }
a3620861 1259 context.defQueueMap = {};
adeb96d2
DW
1260 }
1261
1262 context = {
1263 config: config,
1264 contextName: contextName,
1265 registry: registry,
1266 defined: defined,
1267 urlFetched: urlFetched,
1268 defQueue: defQueue,
a3620861 1269 defQueueMap: {},
adeb96d2
DW
1270 Module: Module,
1271 makeModuleMap: makeModuleMap,
1272 nextTick: req.nextTick,
1273 onError: onError,
1274
1275 /**
1276 * Set a configuration for the context.
1277 * @param {Object} cfg config object to integrate.
1278 */
1279 configure: function (cfg) {
1280 //Make sure the baseUrl ends in a slash.
1281 if (cfg.baseUrl) {
1282 if (cfg.baseUrl.charAt(cfg.baseUrl.length - 1) !== '/') {
1283 cfg.baseUrl += '/';
1284 }
1285 }
1286
2f427c4c
SL
1287 // Convert old style urlArgs string to a function.
1288 if (typeof cfg.urlArgs === 'string') {
1289 var urlArgs = cfg.urlArgs;
1290 cfg.urlArgs = function(id, url) {
1291 return (url.indexOf('?') === -1 ? '?' : '&') + urlArgs;
1292 };
1293 }
1294
adeb96d2
DW
1295 //Save off the paths since they require special processing,
1296 //they are additive.
1297 var shim = config.shim,
1298 objs = {
1299 paths: true,
1300 bundles: true,
1301 config: true,
1302 map: true
1303 };
1304
1305 eachProp(cfg, function (value, prop) {
1306 if (objs[prop]) {
1307 if (!config[prop]) {
1308 config[prop] = {};
1309 }
1310 mixin(config[prop], value, true, true);
1311 } else {
1312 config[prop] = value;
1313 }
1314 });
1315
1316 //Reverse map the bundles
1317 if (cfg.bundles) {
1318 eachProp(cfg.bundles, function (value, prop) {
1319 each(value, function (v) {
1320 if (v !== prop) {
1321 bundlesMap[v] = prop;
1322 }
1323 });
1324 });
1325 }
1326
1327 //Merge shim
1328 if (cfg.shim) {
1329 eachProp(cfg.shim, function (value, id) {
1330 //Normalize the structure
1331 if (isArray(value)) {
1332 value = {
1333 deps: value
1334 };
1335 }
1336 if ((value.exports || value.init) && !value.exportsFn) {
1337 value.exportsFn = context.makeShimExports(value);
1338 }
1339 shim[id] = value;
1340 });
1341 config.shim = shim;
1342 }
1343
1344 //Adjust packages if necessary.
1345 if (cfg.packages) {
1346 each(cfg.packages, function (pkgObj) {
1347 var location, name;
1348
a3620861 1349 pkgObj = typeof pkgObj === 'string' ? {name: pkgObj} : pkgObj;
adeb96d2
DW
1350
1351 name = pkgObj.name;
1352 location = pkgObj.location;
1353 if (location) {
1354 config.paths[name] = pkgObj.location;
1355 }
1356
1357 //Save pointer to main module ID for pkg name.
1358 //Remove leading dot in main, so main paths are normalized,
1359 //and remove any trailing .js, since different package
1360 //envs have different conventions: some use a module name,
1361 //some use a file name.
1362 config.pkgs[name] = pkgObj.name + '/' + (pkgObj.main || 'main')
1363 .replace(currDirRegExp, '')
1364 .replace(jsSuffixRegExp, '');
1365 });
1366 }
1367
1368 //If there are any "waiting to execute" modules in the registry,
1369 //update the maps for them, since their info, like URLs to load,
1370 //may have changed.
1371 eachProp(registry, function (mod, id) {
1372 //If module already has init called, since it is too
1373 //late to modify them, and ignore unnormalized ones
1374 //since they are transient.
1375 if (!mod.inited && !mod.map.unnormalized) {
a3620861 1376 mod.map = makeModuleMap(id, null, true);
adeb96d2
DW
1377 }
1378 });
1379
1380 //If a deps array or a config callback is specified, then call
1381 //require with those args. This is useful when require is defined as a
1382 //config object before require.js is loaded.
1383 if (cfg.deps || cfg.callback) {
1384 context.require(cfg.deps || [], cfg.callback);
1385 }
1386 },
1387
1388 makeShimExports: function (value) {
1389 function fn() {
1390 var ret;
1391 if (value.init) {
1392 ret = value.init.apply(global, arguments);
1393 }
1394 return ret || (value.exports && getGlobal(value.exports));
1395 }
1396 return fn;
1397 },
1398
1399 makeRequire: function (relMap, options) {
1400 options = options || {};
1401
1402 function localRequire(deps, callback, errback) {
1403 var id, map, requireMod;
1404
1405 if (options.enableBuildCallback && callback && isFunction(callback)) {
1406 callback.__requireJsBuild = true;
1407 }
1408
1409 if (typeof deps === 'string') {
1410 if (isFunction(callback)) {
1411 //Invalid call
1412 return onError(makeError('requireargs', 'Invalid require call'), errback);
1413 }
1414
1415 //If require|exports|module are requested, get the
1416 //value for them from the special handlers. Caveat:
1417 //this only works while module is being defined.
1418 if (relMap && hasProp(handlers, deps)) {
1419 return handlers[deps](registry[relMap.id]);
1420 }
1421
1422 //Synchronous access to one module. If require.get is
1423 //available (as in the Node adapter), prefer that.
1424 if (req.get) {
1425 return req.get(context, deps, relMap, localRequire);
1426 }
1427
1428 //Normalize module name, if it contains . or ..
1429 map = makeModuleMap(deps, relMap, false, true);
1430 id = map.id;
1431
1432 if (!hasProp(defined, id)) {
1433 return onError(makeError('notloaded', 'Module name "' +
1434 id +
1435 '" has not been loaded yet for context: ' +
1436 contextName +
1437 (relMap ? '' : '. Use require([])')));
1438 }
1439 return defined[id];
1440 }
1441
1442 //Grab defines waiting in the global queue.
1443 intakeDefines();
1444
1445 //Mark all the dependencies as needing to be loaded.
1446 context.nextTick(function () {
1447 //Some defines could have been added since the
1448 //require call, collect them.
1449 intakeDefines();
1450
1451 requireMod = getModule(makeModuleMap(null, relMap));
1452
1453 //Store if map config should be applied to this require
1454 //call for dependencies.
1455 requireMod.skipMap = options.skipMap;
1456
1457 requireMod.init(deps, callback, errback, {
1458 enabled: true
1459 });
1460
1461 checkLoaded();
1462 });
1463
1464 return localRequire;
1465 }
1466
1467 mixin(localRequire, {
1468 isBrowser: isBrowser,
1469
1470 /**
1471 * Converts a module name + .extension into an URL path.
1472 * *Requires* the use of a module name. It does not support using
1473 * plain URLs like nameToUrl.
1474 */
1475 toUrl: function (moduleNamePlusExt) {
1476 var ext,
1477 index = moduleNamePlusExt.lastIndexOf('.'),
1478 segment = moduleNamePlusExt.split('/')[0],
1479 isRelative = segment === '.' || segment === '..';
1480
1481 //Have a file extension alias, and it is not the
1482 //dots from a relative path.
1483 if (index !== -1 && (!isRelative || index > 1)) {
1484 ext = moduleNamePlusExt.substring(index, moduleNamePlusExt.length);
1485 moduleNamePlusExt = moduleNamePlusExt.substring(0, index);
1486 }
1487
1488 return context.nameToUrl(normalize(moduleNamePlusExt,
1489 relMap && relMap.id, true), ext, true);
1490 },
1491
1492 defined: function (id) {
1493 return hasProp(defined, makeModuleMap(id, relMap, false, true).id);
1494 },
1495
1496 specified: function (id) {
1497 id = makeModuleMap(id, relMap, false, true).id;
1498 return hasProp(defined, id) || hasProp(registry, id);
1499 }
1500 });
1501
1502 //Only allow undef on top level require calls
1503 if (!relMap) {
1504 localRequire.undef = function (id) {
1505 //Bind any waiting define() calls to this context,
1506 //fix for #408
1507 takeGlobalQueue();
1508
1509 var map = makeModuleMap(id, relMap, true),
1510 mod = getOwn(registry, id);
1511
a3620861 1512 mod.undefed = true;
adeb96d2
DW
1513 removeScript(id);
1514
1515 delete defined[id];
1516 delete urlFetched[map.url];
1517 delete undefEvents[id];
1518
1519 //Clean queued defines too. Go backwards
1520 //in array so that the splices do not
1521 //mess up the iteration.
1522 eachReverse(defQueue, function(args, i) {
a3620861 1523 if (args[0] === id) {
adeb96d2
DW
1524 defQueue.splice(i, 1);
1525 }
1526 });
a3620861 1527 delete context.defQueueMap[id];
adeb96d2
DW
1528
1529 if (mod) {
1530 //Hold on to listeners in case the
1531 //module will be attempted to be reloaded
1532 //using a different config.
1533 if (mod.events.defined) {
1534 undefEvents[id] = mod.events;
1535 }
1536
1537 cleanRegistry(id);
1538 }
1539 };
1540 }
1541
1542 return localRequire;
1543 },
1544
1545 /**
1546 * Called to enable a module if it is still in the registry
1547 * awaiting enablement. A second arg, parent, the parent module,
1548 * is passed in for context, when this method is overridden by
1549 * the optimizer. Not shown here to keep code compact.
1550 */
1551 enable: function (depMap) {
1552 var mod = getOwn(registry, depMap.id);
1553 if (mod) {
1554 getModule(depMap).enable();
1555 }
1556 },
1557
1558 /**
1559 * Internal method used by environment adapters to complete a load event.
1560 * A load event could be a script load or just a load pass from a synchronous
1561 * load call.
1562 * @param {String} moduleName the name of the module to potentially complete.
1563 */
1564 completeLoad: function (moduleName) {
1565 var found, args, mod,
1566 shim = getOwn(config.shim, moduleName) || {},
1567 shExports = shim.exports;
1568
1569 takeGlobalQueue();
1570
1571 while (defQueue.length) {
1572 args = defQueue.shift();
1573 if (args[0] === null) {
1574 args[0] = moduleName;
1575 //If already found an anonymous module and bound it
1576 //to this name, then this is some other anon module
1577 //waiting for its completeLoad to fire.
1578 if (found) {
1579 break;
1580 }
1581 found = true;
1582 } else if (args[0] === moduleName) {
1583 //Found matching define call for this script!
1584 found = true;
1585 }
1586
1587 callGetModule(args);
1588 }
a3620861 1589 context.defQueueMap = {};
adeb96d2
DW
1590
1591 //Do this after the cycle of callGetModule in case the result
1592 //of those calls/init calls changes the registry.
1593 mod = getOwn(registry, moduleName);
1594
1595 if (!found && !hasProp(defined, moduleName) && mod && !mod.inited) {
1596 if (config.enforceDefine && (!shExports || !getGlobal(shExports))) {
1597 if (hasPathFallback(moduleName)) {
1598 return;
1599 } else {
1600 return onError(makeError('nodefine',
1601 'No define call for ' + moduleName,
1602 null,
1603 [moduleName]));
1604 }
1605 } else {
1606 //A script that does not call define(), so just simulate
1607 //the call for it.
1608 callGetModule([moduleName, (shim.deps || []), shim.exportsFn]);
1609 }
1610 }
1611
1612 checkLoaded();
1613 },
1614
1615 /**
1616 * Converts a module name to a file path. Supports cases where
1617 * moduleName may actually be just an URL.
1618 * Note that it **does not** call normalize on the moduleName,
1619 * it is assumed to have already been normalized. This is an
1620 * internal API, not a public one. Use toUrl for the public API.
1621 */
1622 nameToUrl: function (moduleName, ext, skipExt) {
1623 var paths, syms, i, parentModule, url,
1624 parentPath, bundleId,
1625 pkgMain = getOwn(config.pkgs, moduleName);
1626
1627 if (pkgMain) {
1628 moduleName = pkgMain;
1629 }
1630
1631 bundleId = getOwn(bundlesMap, moduleName);
1632
1633 if (bundleId) {
1634 return context.nameToUrl(bundleId, ext, skipExt);
1635 }
1636
1637 //If a colon is in the URL, it indicates a protocol is used and it is just
1638 //an URL to a file, or if it starts with a slash, contains a query arg (i.e. ?)
1639 //or ends with .js, then assume the user meant to use an url and not a module id.
1640 //The slash is important for protocol-less URLs as well as full paths.
1641 if (req.jsExtRegExp.test(moduleName)) {
1642 //Just a plain path, not module name lookup, so just return it.
1643 //Add extension if it is included. This is a bit wonky, only non-.js things pass
1644 //an extension, this method probably needs to be reworked.
1645 url = moduleName + (ext || '');
1646 } else {
1647 //A module that needs to be converted to a path.
1648 paths = config.paths;
1649
1650 syms = moduleName.split('/');
1651 //For each module name segment, see if there is a path
1652 //registered for it. Start with most specific name
1653 //and work up from it.
1654 for (i = syms.length; i > 0; i -= 1) {
1655 parentModule = syms.slice(0, i).join('/');
1656
1657 parentPath = getOwn(paths, parentModule);
1658 if (parentPath) {
1659 //If an array, it means there are a few choices,
1660 //Choose the one that is desired
1661 if (isArray(parentPath)) {
1662 parentPath = parentPath[0];
1663 }
1664 syms.splice(0, i, parentPath);
1665 break;
1666 }
1667 }
1668
1669 //Join the path parts together, then figure out if baseUrl is needed.
1670 url = syms.join('/');
bc963d98 1671 url += (ext || (/^data\:|^blob\:|\?/.test(url) || skipExt ? '' : '.js'));
adeb96d2
DW
1672 url = (url.charAt(0) === '/' || url.match(/^[\w\+\.\-]+:/) ? '' : config.baseUrl) + url;
1673 }
1674
bc963d98
SL
1675 return config.urlArgs && !/^blob\:/.test(url) ?
1676 url + config.urlArgs(moduleName, url) : url;
adeb96d2
DW
1677 },
1678
1679 //Delegates to req.load. Broken out as a separate function to
1680 //allow overriding in the optimizer.
1681 load: function (id, url) {
1682 req.load(context, id, url);
1683 },
1684
1685 /**
1686 * Executes a module callback function. Broken out as a separate function
1687 * solely to allow the build system to sequence the files in the built
1688 * layer in the right sequence.
1689 *
1690 * @private
1691 */
1692 execCb: function (name, callback, args, exports) {
1693 return callback.apply(exports, args);
1694 },
1695
1696 /**
1697 * callback for script loads, used to check status of loading.
1698 *
1699 * @param {Event} evt the event from the browser for the script
1700 * that was loaded.
1701 */
1702 onScriptLoad: function (evt) {
1703 //Using currentTarget instead of target for Firefox 2.0's sake. Not
1704 //all old browsers will be supported, but this one was easy enough
1705 //to support and still makes sense.
1706 if (evt.type === 'load' ||
1707 (readyRegExp.test((evt.currentTarget || evt.srcElement).readyState))) {
1708 //Reset interactive script so a script node is not held onto for
1709 //to long.
1710 interactiveScript = null;
1711
1712 //Pull out the name of the module and the context.
1713 var data = getScriptData(evt);
1714 context.completeLoad(data.id);
1715 }
1716 },
1717
1718 /**
1719 * Callback for script errors.
1720 */
1721 onScriptError: function (evt) {
1722 var data = getScriptData(evt);
1723 if (!hasPathFallback(data.id)) {
2f427c4c
SL
1724 var parents = [];
1725 eachProp(registry, function(value, key) {
1726 if (key.indexOf('_@r') !== 0) {
1727 each(value.depMaps, function(depMap) {
1728 if (depMap.id === data.id) {
1729 parents.push(key);
1730 return true;
1731 }
1732 });
1733 }
1734 });
1735 return onError(makeError('scripterror', 'Script error for "' + data.id +
1736 (parents.length ?
1737 '", needed by: ' + parents.join(', ') :
1738 '"'), evt, [data.id]));
adeb96d2
DW
1739 }
1740 }
1741 };
1742
1743 context.require = context.makeRequire();
1744 return context;
1745 }
1746
1747 /**
1748 * Main entry point.
1749 *
1750 * If the only argument to require is a string, then the module that
1751 * is represented by that string is fetched for the appropriate context.
1752 *
1753 * If the first argument is an array, then it will be treated as an array
1754 * of dependency string names to fetch. An optional function callback can
1755 * be specified to execute when all of those dependencies are available.
1756 *
1757 * Make a local req variable to help Caja compliance (it assumes things
1758 * on a require that are not standardized), and to give a short
1759 * name for minification/local scope use.
1760 */
1761 req = requirejs = function (deps, callback, errback, optional) {
1762
1763 //Find the right context, use default
1764 var context, config,
1765 contextName = defContextName;
1766
1767 // Determine if have config object in the call.
1768 if (!isArray(deps) && typeof deps !== 'string') {
1769 // deps is a config object
1770 config = deps;
1771 if (isArray(callback)) {
1772 // Adjust args if there are dependencies
1773 deps = callback;
1774 callback = errback;
1775 errback = optional;
1776 } else {
1777 deps = [];
1778 }
1779 }
1780
1781 if (config && config.context) {
1782 contextName = config.context;
1783 }
1784
1785 context = getOwn(contexts, contextName);
1786 if (!context) {
1787 context = contexts[contextName] = req.s.newContext(contextName);
1788 }
1789
1790 if (config) {
1791 context.configure(config);
1792 }
1793
1794 return context.require(deps, callback, errback);
1795 };
1796
1797 /**
1798 * Support require.config() to make it easier to cooperate with other
1799 * AMD loaders on globally agreed names.
1800 */
1801 req.config = function (config) {
1802 return req(config);
1803 };
1804
1805 /**
1806 * Execute something after the current tick
1807 * of the event loop. Override for other envs
1808 * that have a better solution than setTimeout.
1809 * @param {Function} fn function to execute later.
1810 */
1811 req.nextTick = typeof setTimeout !== 'undefined' ? function (fn) {
1812 setTimeout(fn, 4);
1813 } : function (fn) { fn(); };
1814
1815 /**
1816 * Export require as a global, but only if it does not already exist.
1817 */
1818 if (!require) {
1819 require = req;
1820 }
1821
1822 req.version = version;
1823
1824 //Used to filter out dependencies that are already paths.
1825 req.jsExtRegExp = /^\/|:|\?|\.js$/;
1826 req.isBrowser = isBrowser;
1827 s = req.s = {
1828 contexts: contexts,
1829 newContext: newContext
1830 };
1831
1832 //Create default context.
1833 req({});
1834
1835 //Exports some context-sensitive methods on global require.
1836 each([
1837 'toUrl',
1838 'undef',
1839 'defined',
1840 'specified'
1841 ], function (prop) {
1842 //Reference from contexts instead of early binding to default context,
1843 //so that during builds, the latest instance of the default context
1844 //with its config gets used.
1845 req[prop] = function () {
1846 var ctx = contexts[defContextName];
1847 return ctx.require[prop].apply(ctx, arguments);
1848 };
1849 });
1850
1851 if (isBrowser) {
1852 head = s.head = document.getElementsByTagName('head')[0];
1853 //If BASE tag is in play, using appendChild is a problem for IE6.
1854 //When that browser dies, this can be removed. Details in this jQuery bug:
1855 //http://dev.jquery.com/ticket/2709
1856 baseElement = document.getElementsByTagName('base')[0];
1857 if (baseElement) {
1858 head = s.head = baseElement.parentNode;
1859 }
1860 }
1861
1862 /**
1863 * Any errors that require explicitly generates will be passed to this
1864 * function. Intercept/override it if you want custom error handling.
1865 * @param {Error} err the error object.
1866 */
1867 req.onError = defaultOnError;
1868
1869 /**
1870 * Creates the node for the load command. Only used in browser envs.
1871 */
1872 req.createNode = function (config, moduleName, url) {
1873 var node = config.xhtml ?
1874 document.createElementNS('http://www.w3.org/1999/xhtml', 'html:script') :
1875 document.createElement('script');
1876 node.type = config.scriptType || 'text/javascript';
1877 node.charset = 'utf-8';
1878 node.async = true;
1879 return node;
1880 };
1881
1882 /**
1883 * Does the request to load a module for the browser case.
1884 * Make this a separate function to allow other environments
1885 * to override it.
1886 *
1887 * @param {Object} context the require context to find state.
1888 * @param {String} moduleName the name of the module.
1889 * @param {Object} url the URL to the module.
1890 */
1891 req.load = function (context, moduleName, url) {
1892 var config = (context && context.config) || {},
1893 node;
1894 if (isBrowser) {
1895 //In the browser so use a script tag
1896 node = req.createNode(config, moduleName, url);
1897
1898 node.setAttribute('data-requirecontext', context.contextName);
1899 node.setAttribute('data-requiremodule', moduleName);
1900
1901 //Set up load listener. Test attachEvent first because IE9 has
1902 //a subtle issue in its addEventListener and script onload firings
1903 //that do not match the behavior of all other browsers with
1904 //addEventListener support, which fire the onload event for a
1905 //script right after the script execution. See:
1906 //https://connect.microsoft.com/IE/feedback/details/648057/script-onload-event-is-not-fired-immediately-after-script-execution
1907 //UNFORTUNATELY Opera implements attachEvent but does not follow the script
1908 //script execution mode.
1909 if (node.attachEvent &&
1910 //Check if node.attachEvent is artificially added by custom script or
1911 //natively supported by browser
2f427c4c 1912 //read https://github.com/requirejs/requirejs/issues/187
adeb96d2
DW
1913 //if we can NOT find [native code] then it must NOT natively supported.
1914 //in IE8, node.attachEvent does not have toString()
1915 //Note the test for "[native code" with no closing brace, see:
2f427c4c 1916 //https://github.com/requirejs/requirejs/issues/273
adeb96d2
DW
1917 !(node.attachEvent.toString && node.attachEvent.toString().indexOf('[native code') < 0) &&
1918 !isOpera) {
1919 //Probably IE. IE (at least 6-8) do not fire
1920 //script onload right after executing the script, so
1921 //we cannot tie the anonymous define call to a name.
1922 //However, IE reports the script as being in 'interactive'
1923 //readyState at the time of the define call.
1924 useInteractive = true;
1925
1926 node.attachEvent('onreadystatechange', context.onScriptLoad);
1927 //It would be great to add an error handler here to catch
1928 //404s in IE9+. However, onreadystatechange will fire before
1929 //the error handler, so that does not help. If addEventListener
1930 //is used, then IE will fire error before load, but we cannot
1931 //use that pathway given the connect.microsoft.com issue
1932 //mentioned above about not doing the 'script execute,
1933 //then fire the script load event listener before execute
1934 //next script' that other browsers do.
1935 //Best hope: IE10 fixes the issues,
1936 //and then destroys all installs of IE 6-9.
1937 //node.attachEvent('onerror', context.onScriptError);
1938 } else {
1939 node.addEventListener('load', context.onScriptLoad, false);
1940 node.addEventListener('error', context.onScriptError, false);
1941 }
1942 node.src = url;
1943
2f427c4c
SL
1944 //Calling onNodeCreated after all properties on the node have been
1945 //set, but before it is placed in the DOM.
1946 if (config.onNodeCreated) {
1947 config.onNodeCreated(node, config, moduleName, url);
1948 }
1949
adeb96d2
DW
1950 //For some cache cases in IE 6-8, the script executes before the end
1951 //of the appendChild execution, so to tie an anonymous define
1952 //call to the module name (which is stored on the node), hold on
1953 //to a reference to this node, but clear after the DOM insertion.
1954 currentlyAddingScript = node;
1955 if (baseElement) {
1956 head.insertBefore(node, baseElement);
1957 } else {
1958 head.appendChild(node);
1959 }
1960 currentlyAddingScript = null;
1961
1962 return node;
1963 } else if (isWebWorker) {
1964 try {
1965 //In a web worker, use importScripts. This is not a very
1966 //efficient use of importScripts, importScripts will block until
1967 //its script is downloaded and evaluated. However, if web workers
2f427c4c
SL
1968 //are in play, the expectation is that a build has been done so
1969 //that only one script needs to be loaded anyway. This may need
1970 //to be reevaluated if other use cases become common.
1971
1972 // Post a task to the event loop to work around a bug in WebKit
1973 // where the worker gets garbage-collected after calling
1974 // importScripts(): https://webkit.org/b/153317
1975 setTimeout(function() {}, 0);
adeb96d2
DW
1976 importScripts(url);
1977
1978 //Account for anonymous modules
1979 context.completeLoad(moduleName);
1980 } catch (e) {
1981 context.onError(makeError('importscripts',
1982 'importScripts failed for ' +
1983 moduleName + ' at ' + url,
1984 e,
1985 [moduleName]));
1986 }
1987 }
1988 };
1989
1990 function getInteractiveScript() {
1991 if (interactiveScript && interactiveScript.readyState === 'interactive') {
1992 return interactiveScript;
1993 }
1994
1995 eachReverse(scripts(), function (script) {
1996 if (script.readyState === 'interactive') {
1997 return (interactiveScript = script);
1998 }
1999 });
2000 return interactiveScript;
2001 }
2002
2003 //Look for a data-main script attribute, which could also adjust the baseUrl.
2004 if (isBrowser && !cfg.skipDataMain) {
2005 //Figure out baseUrl. Get it from the script tag with require.js in it.
2006 eachReverse(scripts(), function (script) {
2007 //Set the 'head' where we can append children by
2008 //using the script's parent.
2009 if (!head) {
2010 head = script.parentNode;
2011 }
2012
2013 //Look for a data-main attribute to set main script for the page
2014 //to load. If it is there, the path to data main becomes the
2015 //baseUrl, if it is not already set.
2016 dataMain = script.getAttribute('data-main');
2017 if (dataMain) {
2018 //Preserve dataMain in case it is a path (i.e. contains '?')
2019 mainScript = dataMain;
2020
bc963d98
SL
2021 //Set final baseUrl if there is not already an explicit one,
2022 //but only do so if the data-main value is not a loader plugin
2023 //module ID.
2024 if (!cfg.baseUrl && mainScript.indexOf('!') === -1) {
adeb96d2
DW
2025 //Pull off the directory of data-main for use as the
2026 //baseUrl.
2027 src = mainScript.split('/');
2028 mainScript = src.pop();
2029 subPath = src.length ? src.join('/') + '/' : './';
2030
2031 cfg.baseUrl = subPath;
2032 }
2033
2034 //Strip off any trailing .js since mainScript is now
2035 //like a module name.
2036 mainScript = mainScript.replace(jsSuffixRegExp, '');
2037
a3620861 2038 //If mainScript is still a path, fall back to dataMain
adeb96d2
DW
2039 if (req.jsExtRegExp.test(mainScript)) {
2040 mainScript = dataMain;
2041 }
2042
2043 //Put the data-main script in the files to load.
2044 cfg.deps = cfg.deps ? cfg.deps.concat(mainScript) : [mainScript];
2045
2046 return true;
2047 }
2048 });
2049 }
2050
2051 /**
2052 * The function that handles definitions of modules. Differs from
2053 * require() in that a string for the module should be the first argument,
2054 * and the function to execute after dependencies are loaded should
2055 * return a value to define the module corresponding to the first argument's
2056 * name.
2057 */
2058 define = function (name, deps, callback) {
2059 var node, context;
2060
2061 //Allow for anonymous modules
2062 if (typeof name !== 'string') {
2063 //Adjust args appropriately
2064 callback = deps;
2065 deps = name;
2066 name = null;
2067 }
2068
2069 //This module may not have dependencies
2070 if (!isArray(deps)) {
2071 callback = deps;
2072 deps = null;
2073 }
2074
2075 //If no name, and callback is a function, then figure out if it a
2076 //CommonJS thing with dependencies.
2077 if (!deps && isFunction(callback)) {
2078 deps = [];
2079 //Remove comments from the callback string,
2080 //look for require calls, and pull them into the dependencies,
2081 //but only if there are function args.
2082 if (callback.length) {
2083 callback
2084 .toString()
2f427c4c 2085 .replace(commentRegExp, commentReplace)
adeb96d2
DW
2086 .replace(cjsRequireRegExp, function (match, dep) {
2087 deps.push(dep);
2088 });
2089
2090 //May be a CommonJS thing even without require calls, but still
2091 //could use exports, and module. Avoid doing exports and module
2092 //work though if it just needs require.
2093 //REQUIRES the function to expect the CommonJS variables in the
2094 //order listed below.
2095 deps = (callback.length === 1 ? ['require'] : ['require', 'exports', 'module']).concat(deps);
2096 }
2097 }
2098
2099 //If in IE 6-8 and hit an anonymous define() call, do the interactive
2100 //work.
2101 if (useInteractive) {
2102 node = currentlyAddingScript || getInteractiveScript();
2103 if (node) {
2104 if (!name) {
2105 name = node.getAttribute('data-requiremodule');
2106 }
2107 context = contexts[node.getAttribute('data-requirecontext')];
2108 }
2109 }
2110
2111 //Always save off evaluating the def call until the script onload handler.
2112 //This allows multiple modules to be in a file without prematurely
2113 //tracing dependencies, and allows for anonymous module support,
2114 //where the module name is not known until the script onload event
2115 //occurs. If no context, use the global queue, and get it processed
2116 //in the onscript load callback.
a3620861
DW
2117 if (context) {
2118 context.defQueue.push([name, deps, callback]);
2119 context.defQueueMap[name] = true;
2120 } else {
2121 globalDefQueue.push([name, deps, callback]);
2122 }
adeb96d2
DW
2123 };
2124
2125 define.amd = {
2126 jQuery: true
2127 };
2128
adeb96d2
DW
2129 /**
2130 * Executes the text. Normally just uses eval, but can be modified
2131 * to use a better, environment-specific call. Only used for transpiling
2132 * loader plugins, not for plain JS modules.
2133 * @param {String} text the text to execute/evaluate.
2134 */
2135 req.exec = function (text) {
2136 /*jslint evil: true */
2137 return eval(text);
2138 };
2139
2140 //Set up with config info.
2141 req(cfg);
bc963d98 2142}(this, (typeof setTimeout === 'undefined' ? undefined : setTimeout)));