This repository has been archived by the owner on May 4, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathrequire.js
932 lines (812 loc) · 30.9 KB
/
require.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
// athena/require 1.2.0
// https://github.com/athenahealth/athena-require
// (c) 2016-2019 athenahealth, Inc.
//
// Author: Raymond Lam ([email protected])
//
// athena/require may be freely distributed under the MIT license
(function(undefined) { "use strict";
// The 'root' object, which is the global this (which is window in the context
// of the browser).
var _root = this;
// If a define is already present via another AMD loader or there is an existing
// requirejs instance, do not overwrite.
if (_root.define || _root.requirejs) {
return;
}
// If we have to traverse this many nodes in a dependency tree, assume it has a
// cycle, and abort.
var MAX_TRAVERSAL = 1000000;
var _configuration = {
delayBetweenRequireCallbacks: undefined, // If set, the delay in milliseconds
// between each require callback.
onReady: undefined, // If set, called after require is ready
// and has handled all queued callbacks.
recordModuleTimes: true, // Record time it takes to build modules if true.
recordModuleTimeThreshold: 5.0, // Record timing for construction time of
// individual module only if the time exceeds
// this many milliseconds. (The individual
// time will always be added to the
// totalModuleTime.)
warnings: true // Suppress console warnings if false.
};
// true if all of the defines on the page have had a chance to execute.
var _isReady = false;
// true if require is ready and all queued callbacks have finished.
var _readyCallbacksFinished = false;
// true if require callback handling is in the middle of a delay between callbacks.
var _flushNextTickCallbacksPaused = false;
// defined modules, in the form of:
// {
// 'module/one' : {
// dependencies: [
// 'dep/one',
// 'dep/two'
// ],
// factory: function(..) {
// ...
// }
// },
// 'module/two' : {
// ...
// }
// }
var _moduleMap = {};
// array of callback functions, to be called in order by _flushNextTickCallbacks
var _nextTickCallbacks = [];
// array of callback functions, to be called in order on page load
var _onLoadCallbacks = [];
// resolved modules, in the form of:
// {
// 'module/one' : resolution value,
// 'module/two' : resolution value
// }
var _resolved = {};
// track number of resolved modules
var _resolvedModuleCount = 0;
// timings on how long it took to resolve each module and corresponding dep tree
// in the form of:
// {
// modules: {
// 'my/module' : {
// ordering: in what order this module was resolved
// time: number of millisconds spent resolving this module and its
// dependencies
// },
// 'my/other/module' : { ... },
// ...
// }
// totalModuleTime: total time spent resolving in milliseconds,
// totalNumberOfModules: total number of modules whose times are reflected in totalModuleTime
// }
var _moduleTimes = {
totalModuleTime: 0.0,
totalNumberOfModules: 0,
modules: {}
};
// Given a string that looks like a path to the module, returns the portion
// of the path that represents the 'directory' that contains the module. For
// example, given 'path/to/some/module', returns 'path/to/some'. Given
// 'my-module', returns an empty string
var _dirName = (function() {
var cache = {};
return function(path) {
path = path || '';
if (path in cache) {
return cache[path];
}
var match = path.match(/(.+)\/[^\/]+/);
var ret = (match
? match[1]
: ''
);
cache[path] = ret;
return ret;
};
})();
// Sets a parameter in athena/require's configuration.
function _config(args) {
if (args) {
for (var key in args) {
if (args.hasOwnProperty(key)) {
_configuration[key] = args[key];
}
}
}
return _configuration;
}
// Given a module name, a list of dependencies, and a factory function,
// defines the module as such.
function _define() {
var anonymousWarning = 'Encountered anonymously defined module. Modules must be properly compiled into named modules. Proceeding without defining this module.';
var moduleName;
var dependencies;
var factory;
var prebuilt;
moduleName = arguments[0];
if (arguments.length === 3) {
dependencies = arguments[1];
if ((typeof arguments[2]) === 'function') {
factory = arguments[2];
}
else {
prebuilt = arguments[2];
factory = function() { return prebuilt; };
}
}
else if (arguments.length === 2) {
if (Object.prototype.toString.call(moduleName) !== '[object String]') {
_warn(anonymousWarning);
return;
}
dependencies = [];
if ((typeof arguments[1]) === 'function') {
factory = arguments[1];
}
else {
prebuilt = arguments[1];
factory = function() { return prebuilt; };
}
}
else if (arguments.length === 1) {
if ((typeof arguments[0]) === 'function') {
_warn(anonymousWarning);
return;
}
}
if (arguments.length < 2) {
throw new Error('Missing arguments.');
}
if (
arguments.length > 3
|| !(
Object.prototype.toString.call(moduleName) === '[object String]'
&& Object.prototype.toString.call(dependencies) === '[object Array]'
&& (typeof factory) === 'function'
)
) {
throw new Error('Invalid arguments.');
}
if (_moduleMap.hasOwnProperty(moduleName)) {
_warn(moduleName + ' is already defined.');
}
else {
_moduleMap[moduleName] = {
dependencies: dependencies,
factory: factory
}
}
}
// Returns whether or not a module has already been defined. Does not determine
// if a module has been resolved yet.
function _defined(moduleName) {
return _moduleMap[moduleName] ? true : false;
}
// Manually and immediately flushes require callbacks waiting to be executed
function _flushNextTickCallbacks() {
// This function can relinquish control of the JS thread, so
// we explicitly disallow multiple simultaneous instances by
// preventing new instances from starting while another is
// active but in the middle of a delay between callbacks.
if (_flushNextTickCallbacksPaused) return;
(function _flush () {
_flushNextTickCallbacksPaused = false;
while (_nextTickCallbacks.length) {
var callback = _nextTickCallbacks.pop();
var success = callback();
if (!success) {
// non-fatal failure. Put back in the queue to be
// tried again at the next invocation of
// _flushNextTickCallbacks
_nextTickCallbacks.push(callback);
return;
}
// If a require callback delay is configured, relinquish
// control of the JS thread and continue later.
if (
typeof _configuration.delayBetweenRequireCallbacks === 'number'
&& _nextTickCallbacks.length
) {
_flushNextTickCallbacksPaused = true;
setTimeout(_flush, _configuration.delayBetweenRequireCallbacks);
return;
}
}
// If require is ready and all callbacks have been handled,
// trigger the onReady callback if applicable.
if (_isReady && !_readyCallbacksFinished) {
_readyCallbacksFinished = true;
if (typeof _configuration.onReady === 'function') {
_configuration.onReady.apply(_root);
}
}
})();
}
// in the form of:
// {
// totalModuleTime: total time in milliseconds spent building modules,
// totalNumberOfModules: total number of modules built,
// modules: {
// 'my/module' : {
// ordering: in what order this module was resolved
// time: number of milliseconds spent building this module
// (not including dependencies).
// },
// 'my/other/module' : { ... },
// ...
// }
// }
function _getModuleTimes() {
return _moduleTimes;
}
// If _root.performance is available, returns the time since epoch to
// microsecond. precision. Otherwise, returns the time since epoch to
// millisecond precision, with no guarantee of monotonicity.
var _getNow = (_root.performance && _root.performance.now
? _root.performance.now.bind(_root.performance)
: function() {
return (new Date().getTime());
}
);
// Given a module path, if it is a relative module path, returns the
// absolute form of the relative path given another module path. Otherwise
// simply returns that module path.
function _normalizeModulePath(modulePath, relativeToModulePath) {
relativeToModulePath = relativeToModulePath || '';
var currentPath;
if (modulePath.substr(0, 2) === './') {
currentPath = _dirName(relativeToModulePath);
return (currentPath
? currentPath + modulePath.substr(1)
: modulePath.substr(2)
);
}
else if (modulePath.substr(0, 3) === '../') {
currentPath = _dirName(relativeToModulePath);
if (!currentPath) {
throw new Error('Cannot resolve module path ' + modulePath + ' relative to' + relativeToModulePath);
}
var parentPath = _dirName(currentPath);
return (parentPath
? parentPath + modulePath.substr(2)
: modulePath.substr(3)
);
}
else {
return modulePath;
}
}
// Queues up the given function to be executed at the next clock tick or
// manual flush.
//
// The given function should return true if it executed successfully, or
// false if it executed unsuccessfully but non-fatally and should be put
// back in the queue in front to be tried again later.
function _nextTick(func) {
// If _nextTickCallbacks is populated, we don't need to setTimeout,
// because _nextTickCallbacks being populated means we already invoked
// a setTimeout.
if (!_nextTickCallbacks.length) {
setTimeout(_flushNextTickCallbacks, 0);
}
_nextTickCallbacks.unshift(func);
}
// Execute the given callback when the 'load' event fires on the _root,
// or immediately if the document's readyState is 'complete'.
function _onLoad(callback) {
var flushOnLoadCallbacks = function() {
while (_onLoadCallbacks.length) {
_onLoadCallbacks.pop()();
}
};
if (
!_onLoadCallbacks.length // If we have onLoad callbacks queued, it means
// that we've already called _onLoad before the
// document was complete, which means that we
// already have the load handlers attached to flush
// the call backs, so we don't need to attach the
// load handlers again.
&& _root.document // Attaching load handlers only really makes sense where
// we are in a browser context with a document.
&& _root.document.readyState !== 'complete' // Don't bother attaching load
// handlers if the document is
// already complete, because
// they'll never fire.
) {
if (_root.addEventListener) {
_root.addEventListener('load', flushOnLoadCallbacks);
}
else if (_root.attachEvent) {
_root.attachEvent('onload', flushOnLoadCallbacks);
}
}
_onLoadCallbacks.unshift(callback);
// If the document is already complete, flush the callbacks.
if (_root.document && _root.document.readyState === 'complete') {
flushOnLoadCallbacks();
}
// If we are oddly in a situation where there is no document (like we're not a
// browser?), just defer flushing of the callbacks.
else if (!_root.document) {
setTimeout(flushOnLoadCallbacks, 0);
}
}
// Sets _isReady to true and flushes the next tick callback queue. When
// _isReady is false and a module is not found, it is assumed that all the
// defines have not yet had a chance to execute, and pending resolutions
// waiting on the module should wait until _ready() is invoked (either
// manually or on page load). When _isReady is true, modules not found is
// a fatal error.
function _ready() {
_isReady = true;
_flushNextTickCallbacks();
}
// If given a module name as its only argument, resolves that module and
// returns it. If given as arguments an array of module names and a
// callback function, asynchronously resolves all of the modules, and then
// calls the callback function with the resolved modules as arguments in order.
function _require() {
if (arguments.length === 1) {
// synchronous require call -- attempt to return module immediately
var modulePath = arguments[0];
var resolveStatus = _resolveTree({ modulePaths: [modulePath] });
if (resolveStatus.success) {
return _resolved[modulePath];
}
else {
_throwResolveError(resolveStatus);
}
}
else if (arguments.length <= 3) {
var modulePaths = arguments[0];
var callback = arguments[1];
var errorCallback = arguments[2];
// asynchronous require call -- wait until the next tick, when
// in theory all of the defines on the have executed, before
// executing the given callback.
_nextTick(function() {
var resolveStatus = _resolveTree({
modulePaths: modulePaths,
onSuccess: function() {
var callbackArgs = [];
for (var i = 0; i < modulePaths.length; ++i) {
callbackArgs.push(_resolved[modulePaths[i]]);
}
callback.apply(_root, callbackArgs);
}
});
// If the tree is resolved immediately or will be resolved later, return true
// to move on to the next item in the callback queue.
if (resolveStatus.success || resolveStatus.deferred) {
return true;
}
// If all modules have been defined and we can't find the one we're
// looking for, throw an error.
else if (_isReady && resolveStatus.moduleNotDefined) {
if (errorCallback) {
errorCallback(_getResolveErrorMessage(resolveStatus));
return true;
}
else {
_throwResolveError(resolveStatus);
}
}
// If all modules have not yet been defined, and the resolve status is
// something other than success or deferred, return false to put this
// callback back into the queue, to be tried again later.
else {
return false;
}
});
}
else {
throw new Error('Invalid arguments.');
}
}
// Resolves the dependency tree of the given modules. Takes an args object:
// {
// modulePaths: an array to the paths of modules whose dependency trees are to
// be resolved,
//
// resolveStack: alternative to modulePaths. pass in a resolve stack in order
// to have _resolveTree continue resolving a dependency tree
// given the state of the stack.
//
// onSuccess: a function to execute when the dependency tree has been
// successfully resolved.
//
// }
//
// Returns an object:
// {
// success: true if resolution was a complete and immediate success,
//
// moduleNotDefined: set to the full path of a module which has not (yet) been
// defined,
//
// deferred: set to the full path of a dependency which could not be
// immediately resolved. dependency tree resolution will
// automatically continue where it left off when this
// module is available. This status is for when the dependency is
// actually a plugin invocation which is deferred and asynchronously
// executed.
// }
function _resolveTree(args) {
var i;
var resolveStack;
// The general algorithm for module resolution is a DFS tree-traversal, iteratively
// using a stack.
// If a resolveStack is passed in, it's as if _resolveTree is continuing where
// it previously left off.
if (args.resolveStack) {
resolveStack = args.resolveStack;
}
// If there's only one modulePath, and it is already resolved, short-circuit
// everything
else if (
args.modulePaths.length === 1
&& _resolved.hasOwnProperty(args.modulePaths[0])
) {
if (args.onSuccess) {
args.onSuccess();
}
return { success: true };
}
// Start the DFS rooted at the passed in module paths
else {
resolveStack = [];
i = args.modulePaths.length;
while (i--) {
resolveStack.push({
modulePath: args.modulePaths[i]
});
}
}
var currentNode;
var numberOfTraversedNodes = 0;
// This is a pretty long loop block, and one might expect such a long block of
// code to be broken up into smaller functions, but the intent here is to keep
// as much code inline as possible (while staying reasonably DRY), in order to
// maximize performance.
// Keep traversing while we still have nodes to traverse.
while (currentNode = resolveStack.pop()) {
// ! indicates the invocation of a plugin.
var bangIndex;
// Will be true if currentNode.modulePath is an exact match for an entry in
// _moduleMap.
var modulePathIsExactMatch;
// If the given module path matches exactly to a resolved module, we can
// assume it is a full module path, and skip the work of resolving.
if (_resolved.hasOwnProperty(currentNode.modulePath)) {
currentNode.fullModulePath = currentNode.modulePath;
// The module is already resolved, so there are no dependencies that need
// resolving.
currentNode.numberOfDependencies = 0;
}
// It is possible to hit this branch due to a previous invocation of
// _resolveTree that was deferred and then continued.
else if (
currentNode.fullModulePath
&& _resolved.hasOwnProperty(currentNode.fullModulePath)
) {
// The module is already resolved, so there are no dependencies that need
// resolving.
currentNode.numberOfDependencies = 0;
}
// if ordinary module dependency (i.e., not a plugin invocation)
else if (
// Track if the modulePath happens to be an exact match in _moduleMap
(modulePathIsExactMatch = _moduleMap.hasOwnProperty(currentNode.modulePath))
// If modulePath is in the _moduleMap, definitely not a plugin invocation,
// so short circuit and don't bother checking for bangIndex.
|| (bangIndex = currentNode.modulePath.indexOf('!')) < 1
) {
// Normalize the module path to its full module path. We will from now on
// only be referring to the module by its full path.
// Don't bother checking to see if we need to normalize the module path
// if the module path is an exact match for a module definition.
if (!modulePathIsExactMatch && currentNode.modulePath.charAt(0) === '.') {
currentNode.fullModulePath = _normalizeModulePath(currentNode.modulePath, currentNode.parentNode ? currentNode.parentNode.fullModulePath : '');
}
else {
currentNode.fullModulePath = currentNode.modulePath;
}
// Return if the module is not yet defined. All the scripts might not have
// been loaded yet, or the module definitions may simply be missing.
if (!_moduleMap.hasOwnProperty(currentNode.fullModulePath)) {
return { moduleNotDefined: currentNode.fullModulePath };
}
}
// else is a plugin invocation
else {
// Break out the path to the plugin, and the plugin argument, which is likely
// to be a module path. bangIndex is already defined above.
var pluginPath = currentNode.modulePath.substr(0, bangIndex);
var pluginArg = currentNode.modulePath.substr(bangIndex + 1);
// Always normalize the plugin path.
if (pluginPath.charAt(0) === '.') {
pluginPath = _normalizeModulePath(pluginPath, currentNode.parentNode
? currentNode.parentNode.fullModulePath
: ''
);
}
// If the plugin module is already resolved, just retrieve it. Otherwise,
// we must resolve it.
var plugin = _resolved[pluginPath];
if (!plugin) {
// Resolve the plugin. We don't need to pass a success handler because
// we need the resolve to return sucess, or else we are just going to
// return immediately with non-success.
var pluginStatus = _resolveTree({
modulePaths: [pluginPath]
});
// If we've succeeded in resolving the plugin right away, we can
// retrieve it and continue.
if (pluginStatus.success) {
plugin = _resolved[pluginPath];
}
// Otherwise, we'll have to pause resolving until later.
else {
return pluginStatus;
}
}
// If the plugin has a normalize function, apply it to the plugin
// argument,which needs to be normalized using the built-in normalizer
// first.
if (plugin.normalize) {
pluginArg = plugin.normalize(pluginArg, function(arg) {
if (arg.charAt(0) === '.') {
return _normalizeModulePath(arg, currentNode.parentNode ? currentNode.parentNode.fullModulePath : '');
}
else {
return arg;
}
});
}
// Otherwise, just normalize the plugin argument.
else if (pluginArg.charAt(0) === '.') {
pluginArg = _normalizeModulePath(pluginArg, currentNode.parentNode ? currentNode.parentNode.fullModulePath : '');
}
// fullModulePath is both normalized paths separated by a !. This is how
// the result of the plugin invocation will be stored in _resolved.
currentNode.fullModulePath = pluginPath + '!' + pluginArg;
// Plugin invocations never have dependencies directly.
currentNode.numberOfDependencies = 0;
// Now, actually apply the plugin to the argument, unless we have already
// done so.
if (!_resolved.hasOwnProperty(currentNode.fullModulePath)) {
var pluginLoadIsSynchronous = true;
plugin.load(pluginArg, _require, function(result) {
// Store the result of the plugin invocation by the
// normalized paths.
_resolved[currentNode.fullModulePath] = result;
++_resolvedModuleCount;
// If the plugin is applied immediately and synchronously,
// pluginLoadIsSynchronous will still be true by the time
// we reach this line. If pluginLoadIsSynchronous is false,
// then that means we are executing this line at some point
// after the outer _resolveTree call has already returned
// with a deferred status, so we must start the _resolveTree
// again, using the resolveStack in the state that it was at,
// and the same success handler.
if (!pluginLoadIsSynchronous) {
// Put the current node back on the resolveStack, because
// when we continue to resolve, we will need to finish
// processing it.
resolveStack.push(currentNode);
_resolveTree({
resolveStack: resolveStack,
onSuccess: args.onSuccess
});
}
}, _configuration);
// If we get this far and have not stored the result of the
// plugin invocation into _resolved, it means that the plugin
// invocation will be asynchronous, so set the flag as such,
// and return with a deferred status. _resolveTree will continue
// when the plugin has been applied.
if (!_resolved.hasOwnProperty(currentNode.fullModulePath)) {
pluginLoadIsSynchronous = false;
return { deferred: currentNode.fullModulePath };
}
}
}
// By this point, currentNode must have a fullModulePath.
if (_resolved.hasOwnProperty(currentNode.fullModulePath)) {
// The module is already resolved, so there are no dependencies that need
// resolving.
currentNode.numberOfDependencies = 0;
}
else {
currentNode.factory = _moduleMap[currentNode.fullModulePath].factory;
currentNode.numberOfDependencies = _moduleMap[currentNode.fullModulePath].dependencies.length;
// Pre-sized array, which will be filled with resolved dependencies, in
// the order that they were injected in the define statement.
currentNode.resolvedDependencies = new Array(currentNode.numberOfDependencies);
currentNode.numberOfResolvedDependencies = 0;
// The fastest way to loop though an array is backwards, using the
// decrement operator
i = currentNode.numberOfDependencies;
while (i--) {
var dependencyString = _moduleMap[currentNode.fullModulePath].dependencies[i];
// If the dependency is already resolved, simply put it into our list
// of resolved dependencies.
if (_resolved.hasOwnProperty(dependencyString)) {
currentNode.resolvedDependencies[i] = _resolved[dependencyString];
++currentNode.numberOfResolvedDependencies;
}
// CommonJS style exports.
else if (
dependencyString === 'module'
|| dependencyString === 'exports'
) {
currentNode.commonJS = currentNode.commonJS || {
id: currentNode.fullModulePath,
exports: {}
};
currentNode.resolvedDependencies[i] = (dependencyString === 'module'
? currentNode.commonJS
: currentNode.commonJS.exports
);
++currentNode.numberOfResolvedDependencies;
}
// Else, the dependency may or may not be resolved already.
else {
// Push the node onto the resolve stack for traversal. If it turns out
// that the dependencyString is a relative module path, and we
// actually have already resolved it, we will discover this at the top
// of this loop when we pop the node and normalize the modulePath.
// Make sure this child node has a link back to the parent (the
// current node),and that it knows its position in the current node's
// list of dependencies.
resolveStack.push({
modulePath: dependencyString,
parentNode: currentNode,
dependencyPosition: i
});
}
}
}
// If all of the the current node's are resolved...
while (
currentNode
&& (currentNode.numberOfResolvedDependencies || 0) === currentNode.numberOfDependencies
) {
// By this point, currentNode must have a at a minimum modulePath,
// factory, fullModulePath, resolvedDependencies, and numberOfDependencies
// defined.If currentNode has a parentNode, it must also have a
// dependencyPosition.
var fullModulePath = currentNode.fullModulePath;
// Only resolve the module once.
if (!_resolved.hasOwnProperty(fullModulePath)) {
var startTime = _getNow();
_resolved[fullModulePath]= currentNode.factory.apply(_root, currentNode.resolvedDependencies);
var moduleTime = (_getNow() - startTime);
++_resolvedModuleCount;
if (_configuration.recordModuleTimes) {
_moduleTimes.totalModuleTime += moduleTime;
++_moduleTimes.totalNumberOfModules;
if (moduleTime > _configuration.recordModuleTimeThreshold) {
_moduleTimes.modules[fullModulePath] = {
time: moduleTime,
ordering: _resolvedModuleCount
};
}
}
// Apply the CommonJS style exports only if there is no return from the
// factory.
if ((typeof _resolved[fullModulePath]) === 'undefined' && currentNode.commonJS) {
_resolved[fullModulePath] = currentNode.commonJS.exports;
}
}
// If the currentNode is a child (dependency) of another node, save the
// resolved module into the dependency list of the parent in the correct
// position.
var parentNode = currentNode.parentNode;
if (parentNode) {
parentNode.resolvedDependencies[currentNode.dependencyPosition] = _resolved[fullModulePath];
++parentNode.numberOfResolvedDependencies;
// Conservative garbage collectors sometimes fail to collect objects
// which are collectable. If currentNode fails to be collected, better
// better to leak just currentNode rather than it and all of its
// parents, so dismantle the dependency tree on the way up.
delete currentNode.parentNode;
}
// The resolution of the currentNode might mean that the parent node can
// also be resolved, so go up the dependency tree.
currentNode = parentNode;
}
// If we've traversed an unreasonable number of nodes, there's probably a
// cycle.
if (++numberOfTraversedNodes > MAX_TRAVERSAL) {
throw new Error(
'Traversed too many nodes in the dependency tree. Possible cycle at module '
+ (currentNode.fullModulePath || currentNode.modulePath)
+ ' or at a related module.'
);
}
}
// If we get this far, the dependency resolution was a complete success.
if (args.onSuccess) {
args.onSuccess();
}
return { success: true };
}
// Stop timing the module building, and returns the timings that have been recorded
function _stopTimer () {
_config({ recordModuleTimes: false });
return _getModuleTimes();
}
// Throws an error with consistent messaging. Takes as its output the return of
// _resolveTree
function _throwResolveError(resolveStatus) {
throw new Error(_getResolveErrorMessage(resolveStatus))
}
// Gets the message for a resolve error, but does not throw it.
function _getResolveErrorMessage(resolveStatus) {
if (resolveStatus.moduleNotDefined) {
return (
'Module '
+ resolveStatus.moduleNotDefined
+ ' or one of its dependencies is not '
+ (_isReady
? ''
: 'yet '
)
+ 'defined.'
);
}
else if (resolveStatus.deferred) {
return resolveStatus.deferred + ' is not yet ready.';
}
else {
return 'Unknown error: ' + JSON.stringify(resolveStatus);
}
}
// A minimal implementation of require.toUrl, because athena/require is designed
// to work in compiled JavaScript, so turning module paths into URLs for the
// most part makes no sense. Simply returns the given path plus the '.js'
// extension if there does not appear to be an extension.
function _toUrl(modulePath) {
var match = modulePath.match(/\.[^\/]+$/);
if (match) {
return modulePath;
}
else {
return modulePath + '.js';
}
}
// Warns to the console the given message, unless there is no console, or unless
// warnings are turned off.
function _warn(message) {
if (_configuration.warnings && _root.console && _root.console.warn) {
_root.console.warn(message);
}
}
// If config options were specified in advance, set them now.
if (_root && _root.require && typeof _root.require === 'object') _config(require);
// publish our functions
_root.define = _define;
_root.require = _require;
_root.require.ready = _ready;
_root.require.getTimes = _getModuleTimes;
_root.require.stopTimer = _stopTimer;
_root.require.defined = _defined;
_root.require.config = _config;
_root.require.toUrl = _toUrl;
_root.requirejs = _root.require;
// Expose the resolved module registry
_root.require._resolved = _resolved;
// Mark define as the AMD define, specifying that this is the Athena flavor of
// AMD.
_root.define.amd = {
athena: true
};
// when the page is fully loaded, all defines should have executed, so indicate
// that we are ready
_onLoad(_ready);
// Make require available as a module..
_define('require', function() {
return _require;
});
}).call(this); // Pass _root or whatever 'this' is into the IIFE