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