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