Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / test / data / third_party / spaceport / js / unrequire.js
bloba0bb83cbf66c8118c0e0a25757afec7582b82054
1 /** @preserve
2  * unrequire.js
3  *
4  * Copyright 2011 Sibblingz, Inc.
5  *
6  * Licensed under MIT
7  */
9 // XXX Lines between comments with @{{{ and @}}} are removed when building
11 //@{{{
12 (function () {
13 //@}}}
15     // MIT: http://trac.webkit.org/wiki/DetectingWebKit
16     var IS_WEBKIT = typeof navigator !== 'undefined' && navigator && / AppleWebKit\//.test(navigator.userAgent);
18     var HAS_SETTIMEOUT = typeof setTimeout === 'function';
20     //@{{{
22     // Logging support
23     var LOGGING = false;
25     // Show debug warnings
26     var WARNINGS = true;
28     // Aliases support
29     var ENABLE_ALIASES = true;
31     // Packages support
32     var ENABLE_PACKAGES = true;
34     // Web browser support
35     var ENABLE_BROWSER = true;
37     // Web browser should try to make synchronous requests
38     var BROWSER_SYNC = false;
40     // Node.JS support
41     var ENABLE_NODEJS = true;
43     // Spaceport support
44     var ENABLE_SPACEPORT = true;
46     // CommonJS compatibility
47     var COMMONJS_COMPAT = true;
49     // Check for circular dependencies
50     var CHECK_CYCLES = true;
52     //@}}}
54     // Utility functions {{{
55     var hasOwnProperty = ({ }).hasOwnProperty;
56     var toString = ({ }).toString;
58     // For minification
59     var dot = '.';
60     var dotdot = '..';
62     function hasOwn(obj, name) {
63         return obj && hasOwnProperty.call(obj, name);
64     }
66     function isArray(x) {
67         return toString.call(x) === '[object Array]';
68     }
70     function isPlainOldObject(x) {
71         return toString.call(x) === '[object Object]';
72     }
74     function map(array, fn, context) {
75         // TODO Fallback if Function.prototype.map is missing
76         return array.map(fn, context);
77     }
79     var forEach = map;
81     function extend(base, extension) {
82         var key;
84         for (key in extension) {
85             if (hasOwn(extension, key)) {
86                 base[key] = extension[key];
87             }
88         }
90         return base;
91     }
93     function clone(object, extension) {
94         return extend(extend({ }, object), extension || { });
95     }
96     // Utility functions }}}
98     // Path functions {{{
99     function stringToPath(parts) {
100         parts = isArray(parts) ? parts : [ parts ];
102         var splitParts = [ ];
103         var i;
105         for (i = 0; i < parts.length; ++i) {
106             splitParts = splitParts.concat(parts[i].split(/\//g));
107         }
109         return splitParts;
110     }
112     function pathToString(path) {
113         var s = path
114             .join('/')
115             .replace(/\/+/g, '/');
117         if (path.length === 0 && path[0] === '') {
118             s = '/' + s;
119         }
121         return s;
122     }
124     function normalizePath(path) {
125         var newPath = [ ];
126         var i;
128         for (i = 0; i < path.length; ++i) {
129             if (!path[i]) {
130                 // Root
131                 newPath = [ '' ];
132             } else if (path[i] === dotdot) {
133                 // Go back
134                 if (!newPath.length) {
135                     newPath = [ dotdot ];
136                 } else if (newPath.length === 1) {
137                     if (newPath[0] === dot || !newPath[0]) {
138                         newPath = [ dotdot ];
139                     } else {
140                         newPath.pop();
141                     }
142                 } else {
143                     newPath.pop();
144                 }
145             } else if (path[i] === dot) {
146                 // Go here
147                 if (!newPath.length) {
148                     newPath = [ dot ];
149                 }
150             } else {
151                 // Everything else
152                 newPath.push(path[i]);
153             }
154         }
156         return newPath;
157     }
159     function resolveUrl(cwd, baseUrl, path) {
160         var cwdPath = normalizePath(stringToPath(cwd));
161         var basePath = normalizePath(stringToPath(baseUrl || dot));
162         var npath = normalizePath(stringToPath(path));
164         if (npath[0] === dotdot || npath[0] === dot) {
165             // Relative paths are based on cwd
166             return pathToString(normalizePath(cwdPath.concat(npath)));
167         } else if (npath[0] === '') {
168             // Absolute path stays absolute
169             return pathToString(npath);
170         } else {
171             // Implicit relative paths are based on baseUrl
172             return pathToString(basePath.concat(npath));
173         }
174     }
176     function resolveCwd(baseUrl, cwd) {
177         var basePath = normalizePath(stringToPath(baseUrl || dot));
178         var npath = normalizePath(stringToPath(cwd));
180         if (npath[0] === dotdot || npath[0] === dot) {
181             // Relative paths are absolute
182             return pathToString(npath);
183         } else if (npath[0] === '') {
184             // Absolute path stays absolute
185             return pathToString(npath);
186         } else {
187             // Implicit relative paths are based on baseUrl
188             return pathToString(basePath.concat(npath));
189         }
190     }
192     function dirname(url) {
193         var path = stringToPath(url);
194         path = path.slice(0, path.length - 1);
195         return pathToString(path);
196     }
197     // Path functions }}}
199     // Argument extraction functions {{{
200     function defArgs(name, config, deps, callback) {
201         if (typeof name !== 'string') {
202             // Name omitted
203             callback = deps;
204             deps = config;
205             config = name;
206             name = null;
207         }
209         if (!isPlainOldObject(config)) {
210             // Config omitted
211             callback = deps;
212             deps = config;
213             config = { };
214         }
216         if (!isArray(deps)) {
217             // Dependencies omitted
218             callback = deps;
219             deps = [ ];
220         }
222         return {
223             name: name,
224             config: config,
225             deps: deps,
226             callback: callback
227         };
228     }
230     function reqArgs(config, deps, callback) {
231         // TODO require(string)
232         if (typeof config === 'string') {
233             throw new Error('Not supported');
234         }
236         if (!isPlainOldObject(config)) {
237             // Config omitted
238             callback = deps;
239             deps = config;
240             config = { };
241         }
243         if (!isArray(deps)) {
244             // Dependencies omitted
245             callback = deps;
246             deps = [ ];
247         }
249         return {
250             config: config,
251             deps: deps,
252             callback: callback
253         };
254     }
255     // Argument extraction functions }}}
257     function getScriptName(moduleName, config) {
258         if (ENABLE_ALIASES) {
259             if (hasOwn(config._aliases, moduleName)) {
260                 return config._aliases[moduleName];
261             }
262         }
264         var scriptName = resolveUrl(config.cwd, config.baseUrl, moduleName);
265         scriptName = scriptName + (/\.js$/i.test(scriptName) ? '' : '.js');
266         return scriptName;
267     }
269     function mergeConfigInto(base, augmentation) {
270         // The order of these checks are important, because changes cascade
272         if (hasOwn(augmentation, 'baseUrl')) {
273             base.baseUrl = resolveUrl(base.cwd, base.baseUrl, augmentation.baseUrl);
274         }
276         if (hasOwn(augmentation, 'cwd')) {
277             base.cwd = augmentation.cwd;
278             //base.cwd = resolveCwd(base.baseUrl, augmentation.cwd);
279         }
281         if (ENABLE_ALIASES) {
282             if (hasOwn(base, '_aliases')) {
283                 base._aliases = clone(base._aliases);
284             } else {
285                 base._aliases = { };
286             }
288             if (hasOwn(augmentation, '_aliases')) {
289                 extend(base._aliases, augmentation._aliases);
290             }
292             if (hasOwn(augmentation, 'aliases')) {
293                 var aliasName;
294                 for (aliasName in augmentation.aliases) {
295                     if (!hasOwn(augmentation.aliases, aliasName)) {
296                         continue;
297                     }
299                     var aliasTarget = augmentation.aliases[aliasName];
301                     // Aliases are stored as their full script name
302                     base._aliases[aliasName] = getScriptName(aliasTarget, base);
303                 }
304             }
305         }
307         if (ENABLE_PACKAGES) {
308             if (hasOwn(base, '_packageOwners')) {
309                 base._packageOwners = clone(base._packageOwners);
310             } else {
311                 base._packageOwners = { };
312             }
314             if (hasOwn(augmentation, '_packageOwners')) {
315                 extend(base._packageOwners, augmentation._packageOwners);
316             }
318             if (hasOwn(augmentation, 'packages')) {
319                 var packageName;
320                 for (packageName in augmentation.packages) {
321                     if (!hasOwn(augmentation.packages, packageName)) {
322                         continue;
323                     }
325                     var packageOwner = getScriptName(packageName, base);
326                     forEach(augmentation.packages[packageName], function (moduleName) {
327                         base._packageOwners[getScriptName(moduleName, base)] = packageOwner;
328                     });
329                 }
330             }
331         }
332     }
334     function mergeConfigs(first, second) {
335         var base = clone(first);
336         mergeConfigInto(base, second);
337         return base;
338     }
340     function findCycles(graph, vertices) {
341         var vertexIndices = { };
342         var vertexLowLinks = { };
344         var index = 0;
345         var stack = [ ];
347         var cycles = [ ];
349         function strongConnect(v) {
350             vertexIndices[v] = index;
351             vertexLowLinks[v] = index;
352             ++index;
353             stack.push(v);
355             if (hasOwn(graph, v)) {
356                 graph[v].forEach(function (w) {
357                     if (!hasOwn(vertexIndices, w)) {
358                         strongConnect(w);
359                         vertexLowLinks[v] = Math.min(vertexLowLinks[v], vertexLowLinks[w]);
360                     } else if (stack.indexOf(w) >= 0) {
361                         vertexLowLinks[v] = Math.min(vertexLowLinks[v], vertexIndices[w]);
362                     }
363                 });
364             }
366             if (vertexLowLinks[v] === vertexIndices[v]) {
367                 var cycle = [ ];
368                 var w;
369                 do {
370                     w = stack.pop();
371                     cycle.push(w);
372                 } while (w !== v);
373                 cycles.push(cycle);
374             }
375         }
377         vertices.forEach(function (vertex) {
378             if (!hasOwn(vertexIndices, vertex)) {
379                 strongConnect(vertex);
380             }
381         });
383         return cycles;
384     }
386     // dependencyGraph :: Map String [String]
387     var dependencyGraph = { };
389     // pulledScripts :: [String]
390     var pulledScripts = [ ];
392     function addDependency(from, to) {
393         if (hasOwn(dependencyGraph, from)) {
394             dependencyGraph[from].push(to);
395         } else {
396             dependencyGraph[from] = [ to ];
397         }
398     }
400     function checkCircularDependencies() {
401         var cycles = findCycles(dependencyGraph, pulledScripts);
403         cycles.forEach(function (cycle) {
404             if (cycle.length > 1) {
405                 throw new Error('Circular dependency detected between scripts: ' + cycle.join(' '));
406             }
407         });
408     }
410     function getScriptsDependingUpon(scriptName) {
411         var scripts = [ ];
413         for (var curScript in dependencyGraph) {
414             if (hasOwn(dependencyGraph, curScript)) {
415                 if (dependencyGraph[curScript].indexOf(scriptName) >= 0) {
416                     scripts.push(curScript);
417                 }
418             }
419         }
421         return scripts;
422     }
424     // requestedScripts :: Map String Bool
425     var requestedScripts = { };
427     // requestingScriptCount :: Int
428     var requestingScriptCount = 0;
430     // We have two queues here.
431     //
432     // The script complete queue is built up while executing scripts.  A define
433     // call adds to this queue.  The queue is flushed when the script completes
434     // execution.  This allows us to determine which script was executed
435     // exactly for asynchronous loads.
436     //
437     // A load callback queue is built up after a define call knows its complete
438     // name configuration.  It is executed when that defined module is
439     // requested.  This allows for lazy loading of defiend modules, and also
440     // allows for asynchronous module definitions.  There is a mapping of
441     // script name to load callback queue, thus this queue is a hash and not an
442     // array.
444     // scriptCompleteQueue :: [Maybe Error -> Configuration -> IO ()]
445     var scriptCompleteQueue = [ ];
447     // loadCallbackQueues :: Map String [IO ()]
448     var loadCallbackQueues = { };
450     // The push-pull mechanism decouples requesters of a module from definers
451     // of a module.  When a module is defined, it is "pushed"; when a module is
452     // requested, it is "pulled".  If a pull is made on an already-pushed
453     // module name, the pull callback is executed immediately.  Else, the pull
454     // callback is executed immediately when the appropriate push is made.
456     // pushed :: Map String a
457     var pushed = { };
459     // pulling :: Map String [Maybe Error -> a -> IO ()]
460     var pulling = { };
462     function checkPullForLoadCallback(scriptName) {
463         if (hasOwn(pulling, scriptName) && hasOwn(loadCallbackQueues, scriptName)) {
464             var callbacks = loadCallbackQueues[scriptName];
465             delete loadCallbackQueues[scriptName];
467             forEach(callbacks, function (callback) {
468                 callback();
469             });
470         }
471     }
473     function checkPullForPush(scriptName, value) {
474         if (hasOwn(pulling, scriptName) && hasOwn(pushed, scriptName)) {
475             var callbacks = pulling[scriptName];
476             delete pulling[scriptName];
478             forEach(callbacks, function (callback) {
479                 callback(null, pushed[scriptName]);
480             });
481         }
482     }
484     function enqueueLoadCallback(scriptName, callback) {
485         if (hasOwn(loadCallbackQueues, scriptName)) {
486             loadCallbackQueues[scriptName].push(callback);
487         } else {
488             loadCallbackQueues[scriptName] = [ callback ];
489         }
491         checkPullForLoadCallback(scriptName);
492     }
494     function enqueueScriptCompleteCallback(callback) {
495         if (requestingScriptCount > 0) {
496             scriptCompleteQueue.push(callback);
497         } else {
498             callback(null, { });
499         }
500     }
502     function push(scriptName, value) {
503         if (hasOwn(pushed, scriptName)) {
504             throw new Error('Should not push value for ' + scriptName + ' again');
505         }
507         pushed[scriptName] = value;
509         checkPullForPush(scriptName);
510     }
512     function pull(scriptName, callback) {
513         if (CHECK_CYCLES) {
514             pulledScripts.push(scriptName);
515         }
517         if (hasOwn(pulling, scriptName)) {
518             pulling[scriptName].push(callback);
519         } else {
520             pulling[scriptName] = [ callback ];
521         }
523         checkPullForLoadCallback(scriptName);
524         checkPullForPush(scriptName);
525     }
527     function needsRequest(scriptName) {
528         return !hasOwn(requestedScripts, scriptName) && !hasOwn(pushed, scriptName) && !hasOwn(loadCallbackQueues, scriptName);
529     }
531     // Entry points {{{
532     function create(configuration) {
533         var context = extend({
534             'require': req,
535             'define': def,
536             'reconfigure': reconfigure,
537             'userCallback': defaultUserCallback
538         }, configuration);
540         var baseConfig = {
541             cwd: '.',
542             baseUrl: '.'
543         };
545         context.configuration = configuration;
546         req.config = config;
547         req.debug = debug;
549         return context;
551         function config(config) {
552             mergeConfigInto(baseConfig, config);
553         }
555         function defaultUserCallback(scriptName, data, moduleValues, moduleScripts, moduleNames, callback) {
556             if (LOGGING) {
557                 console.log('Executing', scriptName);
558             }
560             var moduleValue;
561             if (typeof data === 'function') {
562                 if (COMMONJS_COMPAT && data.length === 3 && moduleNames.length === 0) {
563                     moduleValues = [
564                         // require
565                         function () {
566                             throw new Error('Not supported');
567                         },
569                         // exports
570                         { },
572                         // module
573                         { } // TODO
574                     ];
575                 }
577                 moduleValue = data.apply(null, moduleValues);
579                 if (COMMONJS_COMPAT && data.length === 3 && moduleNames.length === 0) {
580                     if (typeof moduleValue === 'undefined') {
581                         moduleValue = moduleValues[1]; // exports
582                     }
583                 }
584             } else {
585                 moduleValue = data;
586             }
588             callback(null, moduleValue);
589         }
591         function reconfigure(configuration) {
592             extend(context, configuration);
593         }
595         function getRequestScriptName(scriptName, config) {
596             if (ENABLE_PACKAGES) {
597                 if (hasOwn(config._packageOwners, scriptName)) {
598                     return config._packageOwners[scriptName];
599                 }
600             }
602             return scriptName;
603         }
605         function request(scriptName, config, callback) {
606             if (!needsRequest(scriptName)) {
607                 throw new Error('Should not request ' + scriptName + ' again');
608             }
610             if (LOGGING) {
611                 console.log('Requesting script ' + scriptName);
612             }
614             requestedScripts[scriptName] = true;
615             ++requestingScriptCount;
617             function done(err) {
618                 --requestingScriptCount;
620                 var scriptCompleteCallbacks = scriptCompleteQueue;
621                 scriptCompleteQueue = [ ];
623                 if (!err) {
624                     if (scriptCompleteCallbacks.length === 0) {
625                         console.warn('Possibly missing define for script ' + scriptName);
626                     }
627                 }
629                 callback(err, scriptCompleteCallbacks);
630             }
632             function tryAsync() {
633             }
635             // Try a sync load first
636             if (context.loadScriptSync) {
637                 // We have this setTimeout logic to handle exceptions thrown by
638                 // loadScriptSync.  We do not catch exceptions (so debugging is
639                 // easier for users), or deal with the 'finally' mess, but
640                 // still call done().
641                 var timer;
642                 if (HAS_SETTIMEOUT) {
643                     timer = setTimeout(function () {
644                         done(new Error('Script threw exception'));
645                     }, 0);
646                 }
648                 var success = context.loadScriptSync(scriptName, config);
650                 if (HAS_SETTIMEOUT) {
651                     clearTimeout(timer);
652                 }
654                 if (success) {
655                     done(null);
656                     return;
657                 }
658             }
660             if (context.loadScriptAsync) {
661                 return context.loadScriptAsync(scriptName, done, config);
662             }
664             done(new Error('Failed to load script'));
665         }
667         function requestAndPullMany(scriptNames, config, callback) {
668             var loaded = [ ];
669             var values = [ ];
670             var i;
671             var called = false;
673             function checkValues() {
674                 if (called) return;
676                 var i;
678                 for (i = 0; i < scriptNames.length; ++i) {
679                     if (!loaded[i]) return;
680                 }
682                 called = true;
683                 callback(null, values, scriptNames);
684             }
686             forEach(scriptNames, function (scriptName, i) {
687                 var requestScriptName = getRequestScriptName(scriptName, config);
689                 if (needsRequest(requestScriptName)) {
690                     request(requestScriptName, config, function (err, callbacks) {
691                         var neoConfig = mergeConfigs(config, { });
692                         neoConfig.cwd = dirname(requestScriptName);
693                         neoConfig.scriptName = scriptName;
695                         forEach(callbacks, function (callback) {
696                             callback(err, neoConfig);
697                         });
699                         if (err) {
700                             var errorString = 'Failed to load ' + requestScriptName;
702                             var dependers = getScriptsDependingUpon(requestScriptName);
703                             if (dependers.length) {
704                                 errorString += ' (depended upon by ' + dependers.join(', ') + ')';
705                             }
707                             console.error(errorString, err);
708                         }
709                     });
710                 }
712                 pull(scriptName, function (err, value) {
713                     if (err) throw err;
715                     loaded[i] = true;
716                     values[i] = value;
717                     checkValues();
718                 });
719             });
721             // In case we have no scripts to load
722             checkValues();
723         }
725         function req() {
726             // TODO require(string)
728             var args = reqArgs.apply(null, arguments);
729             var config = args.config;
730             var deps = args.deps;
731             var callback = args.callback;
733             if (LOGGING) {
734                 console.log('Requiring [ ' + (deps || [ ]).join(', ') + ' ]');
735             }
737             var effectiveConfig = mergeConfigs(baseConfig, config);
739             enqueueScriptCompleteCallback(function (err, config) {
740                 if (err) throw err;
742                 mergeConfigInto(effectiveConfig, config);
744                 var scriptNames = map(deps, function (dep) {
745                     return getScriptName(dep, effectiveConfig);
746                 });
748                 requestAndPullMany(scriptNames, effectiveConfig, function (err, values) {
749                     if (err) throw err;
751                     context.userCallback(null, callback, values, scriptNames, deps.slice(), function (err, value) {
752                         if (err) throw err;
754                         // Ignore value
755                     });
756                 });
757             });
758         }
760         function def() {
761             var args = defArgs.apply(null, arguments);
762             var name = args.name;
763             var config = args.config;
764             var deps = args.deps;
765             var callback = args.callback;
767             if (LOGGING) {
768                 console.log('Defining ' + (name || 'unnamed package') + ' with dependencies [ ' + (deps || [ ]).join(', ') + ' ]');
769             }
771             var effectiveConfig = mergeConfigs(baseConfig, config);
773             enqueueScriptCompleteCallback(function (err, config) {
774                 if (err) throw err;
776                 var oldEffectiveConfig = clone(effectiveConfig);
778                 // Script name resolution should occur *before* merging config into
779                 // effectiveConfig
780                 mergeConfigInto(effectiveConfig, config);
782                 var scriptName;
783                 if (name) {
784                     scriptName = getScriptName(name, effectiveConfig);
785                 } else {
786                     scriptName = config.scriptName;
787                 }
789                 enqueueLoadCallback(scriptName, function () {
790                     var scriptNames = map(deps, function (dep) {
791                         return getScriptName(dep, effectiveConfig);
792                     });
794                     if (CHECK_CYCLES) {
795                         map(scriptNames, function (dep) {
796                             addDependency(scriptName, dep);
797                         });
798                     }
800                     checkCircularDependencies();
802                     requestAndPullMany(scriptNames, effectiveConfig, function (err, values) {
803                         if (err) throw err;
805                         context.userCallback(scriptName, callback, values, scriptNames, deps.slice(), function (err, value) {
806                             if (err) throw err;
808                             push(scriptName, value);
809                         });
810                     });
811                 });
812             });
813         }
815         function debug() {
816             console.log('Pulling:', pulling);
817         }
818     }
819     // Entry points }}}
821     (function () {
822         var un;
824         if (ENABLE_SPACEPORT && typeof loadScript === 'function') {
825             // Must be first, because Spaceport has the window object, too.
826             un = create({
827                 'loadScriptAsync': function (scriptName, callback) {
828                     loadScript(scriptName, function () {
829                         callback(null);
830                     });
831                 },
832                 'loadScriptSync': function (scriptName) {
833                     return false;
834                 }
835             });
837             // Set globals
838             require = un['require'];
839             define = un['define'];
840         } else if (ENABLE_BROWSER && typeof window !== 'undefined') {
841             var goodResponseCodes = [ 200, 204, 206, 301, 302, 303, 304, 307 ];
842             var doc = window.document;
844             var onreadystatechange = 'onreadystatechange';
845             var onload = 'onload';
846             var onerror = 'onerror';
848             function isCleanPath(scriptName) {
849                 // If the path is "back" too much, it's not clean.
850                 var x = stringToPath(dirname(window.location.pathname))
851                     .concat(stringToPath(scriptName));
852                 x = normalizePath(x);
853                 return x[0] !== '..';
854             }
856             var webkitOnloadFlag = false;
858             un = create({
859                 'loadScriptAsync': function loadScriptAsync(scriptName, callback) {
860                     if (!isCleanPath(scriptName)) {
861                         setTimeout(function () {
862                             callback(new Error('Path ' + scriptName + ' is not clean'));
863                         }, 0);
864                         return;
865                     }
867                     var script = doc.createElement('script');
868                     script.async = true;
870                     // Modelled after jQuery (src/ajax/script.js)
871                     script[onload] = script[onreadystatechange] = function () {
872                         if (!script.readyState || /loaded|complete/.test(script.readyState)) {
873                             // Remove from DOM
874                             var parent = script.parentNode;
875                             if (parent) {
876                                 parent.removeChild(script);
877                             }
879                             // IE likes memleaks
880                             script[onload] = script[onreadystatechange] = script[onerror] = null;
881                             script = null;
883                             callback(null);
884                         }
885                     };
887                     script[onerror] = function () {
888                         callback(new Error('Failed to load script'));
889                     };
891                     // Remember: we need to attach event handlers before
892                     // assigning `src`.  Events may be fired as soon as we set
893                     // `src`.
894                     script.src = scriptName;
896                     doc['head'].appendChild(script);
897                 },
898                 'loadScriptSync': function loadScriptSync(scriptName) {
899                     // We provide synchronous script loading via XHR for
900                     // browsers specifically to work around a Webkit bug.
901                     // After document.onload is called, any script dynamically
902                     // loaded will be loaded from Webkit's local cache; *no
903                     // HTTP request is made at all*.
905                     if (!BROWSER_SYNC) {
906                         if (IS_WEBKIT) {
907                             if (/loaded|complete/.test(document.readyState)) {
908                                 // Don't load synchronously if the document has already loaded
909                                 if (WARNINGS && !webkitOnloadFlag) {
910                                     console.warn('Scripts being loaded after document.onload; scripts may be loaded from out-of-date cache');
911                                     webkitOnloadFlag = true;
912                                 }
914                                 if (WARNINGS) {
915                                     console.warn('Script possibly loaded from out-of-date cache: ' + scriptName);
916                                 }
918                                 return false;
919                             }
921                             // Fall through; load synchronously anyway
922                         } else {
923                             return false;
924                         }
925                     }
927                     if (!isCleanPath(scriptName)) {
928                         return false;
929                     }
931                     var scriptSource;
933                     try {
934                         var xhr = new XMLHttpRequest();
935                         xhr.open('GET', scriptName, false);
936                         xhr.send(null);
938                         if (goodResponseCodes.indexOf(xhr.status) < 0) {
939                             return false;
940                         }
942                         scriptSource = xhr.responseText;
943                         scriptSource += '\n\n//*/\n//@ sourceURL=' + scriptName;
944                     } catch (e) {
945                         return false;
946                     }
948                     var fn;
949                     try {
950                         fn = Function(scriptSource);
951                     } catch (e) {
952                         return false;
953                     }
955                     // Don't wrap user code in try/catch
956                     fn();
958                     return true;
959                 }
960             });
962             window['require'] = un['require'];
963             window['define'] = un['define'];
964         } else if (ENABLE_NODEJS && typeof module !== 'undefined') {
965             un = module.exports = create({
966                 'context': { },
967                 'loadScriptSync': function (scriptName) {
968                     // require here is the Node.JS-provided require
970                     var code;
971                     try {
972                         code = require('fs')['readFileSync'](scriptName, 'utf8');
973                     } catch (e) {
974                         // TODO Detect file-not-found errors only
975                         return false;
976                     }
978                     require('vm')['runInNewContext'](code, un['context'] || { }, scriptName);
980                     return true;
981                 }
982             });
984             un['context']['define'] = un['define'];
985             un['context']['require'] = un['require'];
986         } else {
987             throw new Error('Unsupported environment');
988         }
989     }());
991 //@{{{
992 }());
993 //@}}}