react 0.6.1 → 0.7.1

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