vendor: 71,923 bytes, lines 1-2076
1(function( 2 userConfig, 3 defaultConfig 4){ 5 // summary: 6 // This is the "source loader" and is the entry point for Dojo during development. You may also load Dojo with 7 // any AMD-compliant loader via the package main module dojo/main. 8 // description: 9 // This is the "source loader" for Dojo. It provides an AMD-compliant loader that can be configured 10 // to operate in either synchronous or asynchronous modes. After the loader is defined, dojo is loaded 11 // IAW the package main module dojo/main. In the event you wish to use a foreign loader, you may load dojo as a package 12 // via the package main module dojo/main and this loader is not required; see dojo/package.json for details. 13 // 14 // In order to keep compatibility with the v1.x line, this loader includes additional machinery that enables 15 // the dojo.provide, dojo.require et al API. This machinery is loaded by default, but may be dynamically removed 16 // via the has.js API and statically removed via the build system. 17 // 18 // This loader includes sniffing machinery to determine the environment; the following environments are supported: 19 // 20 // - browser 21 // - node.js 22 // - rhino 23 // 24 // This is the so-called "source loader". As such, it includes many optional features that may be discarded by 25 // building a customized version with the build system. 26 27 // Design and Implementation Notes 28 // 29 // This is a dojo-specific adaption of bdLoad, donated to the dojo foundation by Altoviso LLC. 30 // 31 // This function defines an AMD-compliant (http://wiki.commonjs.org/wiki/Modules/AsynchronousDefinition) 32 // loader that can be configured to operate in either synchronous or asynchronous modes. 33 // 34 // Since this machinery implements a loader, it does not have the luxury of using a load system and/or 35 // leveraging a utility library. This results in an unpleasantly long file; here is a road map of the contents: 36 // 37 // 1. Small library for use implementing the loader. 38 // 2. Define the has.js API; this is used throughout the loader to bracket features. 39 // 3. Define the node.js and rhino sniffs and sniff. 40 // 4. Define the loader's data. 41 // 5. Define the configuration machinery. 42 // 6. Define the script element sniffing machinery and sniff for configuration data. 43 // 7. Configure the loader IAW the provided user, default, and sniffing data. 44 // 8. Define the global require function. 45 // 9. Define the module resolution machinery. 46 // 10. Define the module and plugin module definition machinery 47 // 11. Define the script injection machinery. 48 // 12. Define the window load detection. 49 // 13. Define the logging API. 50 // 14. Define the tracing API. 51 // 16. Define the AMD define function. 52 // 17. Define the dojo v1.x provide/require machinery--so called "legacy" modes. 53 // 18. Publish global variables. 54 // 55 // Language and Acronyms and Idioms 56 // 57 // moduleId: a CJS module identifier, (used for public APIs) 58 // mid: moduleId (used internally) 59 // packageId: a package identifier (used for public APIs) 60 // pid: packageId (used internally); the implied system or default package has pid==="" 61 // pack: package is used internally to reference a package object (since javascript has reserved words including "package") 62 // prid: plugin resource identifier 63 // The integer constant 1 is used in place of true and 0 in place of false. 64 // 65 // The "foreign-loader" has condition is defined if another loader is being used (e.g. webpack) and this code is only 66 // needed for resolving module identifiers based on the config. In this case, only the functions require.toUrl and 67 // require.toAbsMid are supported. The require and define functions are not supported. 68 69 // define global 70 var globalObject = (function(){ 71 if (typeof global !== 'undefined' && typeof global !== 'function') { 72 // global spec defines a reference to the global object called 'global' 73 // https://github.com/tc39/proposal-global 74 // `global` is also defined in NodeJS 75 return global; 76 } 77 else if (typeof window !== 'undefined') { 78 // window is defined in browsers 79 return window; 80 } 81 else if (typeof self !== 'undefined') { 82 // self is defined in WebWorkers 83 return self; 84 } 85 return this; 86 })(); 87 88 // define a minimal library to help build the loader 89 var noop = function(){ 90 }, 91 92 isEmpty = function(it){ 93 for(var p in it){ 94 return 0; 95 } 96 return 1; 97 }, 98 99 toString = {}.toString, 100 101 isFunction = function(it){ 102 return toString.call(it) == "[object Function]"; 103 }, 104 105 isString = function(it){ 106 return toString.call(it) == "[object String]"; 107 }, 108 109 isArray = function(it){ 110 return toString.call(it) == "[object Array]"; 111 }, 112 113 forEach = function(vector, callback){ 114 if(vector){ 115 for(var i = 0; i < vector.length;){ 116 callback(vector[i++]); 117 } 118 } 119 }, 120 121 mix = function(dest, src){ 122 for(var p in src){ 123 dest[p] = src[p]; 124 } 125 return dest; 126 }, 127 128 makeError = function(error, info){ 129 return mix(new Error(error), {src:"dojoLoader", info:info}); 130 }, 131 132 uidSeed = 1, 133 134 uid = function(){ 135 // Returns a unique identifier (within the lifetime of the document) of the form /_d+/. 136 return "_" + uidSeed++; 137 }, 138 139 // FIXME: how to doc window.require() api 140 141 // this will be the global require function; define it immediately so we can start hanging things off of it 142 req = function( 143 config, //(object, optional) hash of configuration properties 144 dependencies, //(array of commonjs.moduleId, optional) list of modules to be loaded before applying callback 145 callback //(function, optional) lambda expression to apply to module values implied by dependencies 146 ){ 147 return contextRequire(config, dependencies, callback, 0, req); 148 }, 149 150 // the loader uses the has.js API to control feature inclusion/exclusion; define then use throughout 151 global = globalObject, 152 153 doc = global.document, 154 155 element = doc && doc.createElement("DiV"), 156 157 has = req.has = function(name){ 158 return isFunction(hasCache[name]) ? (hasCache[name] = hasCache[name](global, doc, element)) : hasCache[name]; 159 }, 160 161 hasCache = has.cache = defaultConfig.hasCache; 162 163 if (isFunction(userConfig)) { 164 userConfig = userConfig(globalObject); 165 } 166 167 has.add = function(name, test, now, force){ 168 (hasCache[name]===undefined || force) && (hasCache[name] = test); 169 return now && has(name); 170 }; 171 172 has.add("host-node", userConfig.has && "host-node" in userConfig.has ? 173 userConfig.has["host-node"] : 174 (typeof process == "object" && process.versions && process.versions.node && process.versions.v8)); 175 if(has("host-node")){ 176 // fixup the default config for node.js environment 177 require("./_base/configNode.js").config(defaultConfig); 178 // remember node's require (with respect to baseUrl==dojo's root) 179 defaultConfig.loaderPatch.nodeRequire = require; 180 } 181 182 has.add("host-rhino", userConfig.has && "host-rhino" in userConfig.has ? 183 userConfig.has["host-rhino"] : 184 (typeof load == "function" && (typeof Packages == "function" || typeof Packages == "object"))); 185 if(has("host-rhino")){ 186 // owing to rhino's lame feature that hides the source of the script, give the user a way to specify the baseUrl... 187 for(var baseUrl = userConfig.baseUrl || ".", arg, rhinoArgs = this.arguments, i = 0; i < rhinoArgs.length;){ 188 arg = (rhinoArgs[i++] + "").split("="); 189 if(arg[0] == "baseUrl"){ 190 baseUrl = arg[1]; 191 break; 192 } 193 } 194 load(baseUrl + "/_base/configRhino.js"); 195 rhinoDojoConfig(defaultConfig, baseUrl, rhinoArgs); 196 } 197 198 has.add("host-webworker", ((typeof WorkerGlobalScope !== 'undefined') && (self instanceof WorkerGlobalScope))); 199 if(has("host-webworker")){ 200 mix(defaultConfig.hasCache, { 201 "host-browser": 0, 202 "dom": 0, 203 "dojo-dom-ready-api": 0, 204 "dojo-sniff": 0, 205 "dojo-inject-api": 1, 206 "host-webworker": 1, 207 "dojo-guarantee-console": 0 // console is immutable in FF30+, see https://bugs.dojotoolkit.org/ticket/18100 208 }); 209 210 defaultConfig.loaderPatch = { 211 injectUrl: function(url, callback){ 212 // TODO: 213 // This is not async, nor can it be in Webworkers. It could be made better by passing 214 // the entire require array into importScripts at. This way the scripts are loaded in 215 // async mode; even if the callbacks are ran in sync. It is not a major issue as webworkers 216 // tend to be long running where initial startup is not a major factor. 217 218 try{ 219 importScripts(url); 220 callback(); 221 }catch(e){ 222 console.info("failed to load resource (" + url + ")"); 223 console.error(e); 224 } 225 } 226 }; 227 } 228 229 // userConfig has tests override defaultConfig has tests; do this after the environment detection because 230 // the environment detection usually sets some has feature values in the hasCache. 231 for(var p in userConfig.has){ 232 has.add(p, userConfig.has[p], 0, 1); 233 } 234 235 // 236 // define the loader data 237 // 238 239 // the loader will use these like symbols if the loader has the traceApi; otherwise 240 // define magic numbers so that modules can be provided as part of defaultConfig 241 var requested = 1, 242 arrived = 2, 243 nonmodule = 3, 244 executing = 4, 245 executed = 5; 246 247 if(has("dojo-trace-api")){ 248 // these make debugging nice; but using strings for symbols is a gross rookie error; don't do it for production code 249 requested = "requested"; 250 arrived = "arrived"; 251 nonmodule = "not-a-module"; 252 executing = "executing"; 253 executed = "executed"; 254 } 255 256 var legacyMode = 0, 257 sync = "sync", 258 xd = "xd", 259 syncExecStack = [], 260 dojoRequirePlugin = 0, 261 checkDojoRequirePlugin = noop, 262 transformToAmd = noop, 263 getXhr; 264 if(has("dojo-sync-loader")){ 265 req.isXdUrl = noop; 266 267 req.initSyncLoader = function(dojoRequirePlugin_, checkDojoRequirePlugin_, transformToAmd_){ 268 // the first dojo/_base/loader loaded gets to define these variables; they are designed to work 269 // in the presence of zero to many mapped dojo/_base/loaders 270 if(!dojoRequirePlugin){ 271 dojoRequirePlugin = dojoRequirePlugin_; 272 checkDojoRequirePlugin = checkDojoRequirePlugin_; 273 transformToAmd = transformToAmd_; 274 } 275 276 return { 277 sync:sync, 278 requested:requested, 279 arrived:arrived, 280 nonmodule:nonmodule, 281 executing:executing, 282 executed:executed, 283 syncExecStack:syncExecStack, 284 modules:modules, 285 execQ:execQ, 286 getModule:getModule, 287 injectModule:injectModule, 288 setArrived:setArrived, 289 signal:signal, 290 finishExec:finishExec, 291 execModule:execModule, 292 dojoRequirePlugin:dojoRequirePlugin, 293 getLegacyMode:function(){return legacyMode;}, 294 guardCheckComplete:guardCheckComplete 295 }; 296 }; 297 298 if(has("dom") || has("host-webworker")){ 299 // in legacy sync mode, the loader needs a minimal XHR library 300 301 var locationProtocol = location.protocol, 302 locationHost = location.host; 303 req.isXdUrl = function(url){ 304 if(/^\./.test(url)){ 305 // begins with a dot is always relative to page URL; therefore not xdomain 306 return false; 307 } 308 if(/^\/\//.test(url)){ 309 // for v1.6- backcompat, url starting with // indicates xdomain 310 return true; 311 } 312 // get protocol and host 313 // \/+ takes care of the typical file protocol that looks like file:///drive/path/to/file 314 // locationHost is falsy if file protocol => if locationProtocol matches and is "file:", || will return false 315 var match = url.match(/^([^\/\:]+\:)\/+([^\/]+)/); 316 return match && (match[1] != locationProtocol || (locationHost && match[2] != locationHost)); 317 }; 318 319 320 // note: to get the file:// protocol to work in FF, you must set security.fileuri.strict_origin_policy to false in about:config 321 has.add("dojo-xhr-factory", 1); 322 has.add("dojo-force-activex-xhr", has("host-browser") && !doc.addEventListener && window.location.protocol == "file:"); 323 has.add("native-xhr", typeof XMLHttpRequest != "undefined"); 324 if(has("native-xhr") && !has("dojo-force-activex-xhr")){ 325 getXhr = function(){ 326 return new XMLHttpRequest(); 327 }; 328 }else{ 329 // if in the browser an old IE; find an xhr 330 for(var XMLHTTP_PROGIDS = ['Msxml2.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.4.0'], progid, i = 0; i < 3;){ 331 try{ 332 progid = XMLHTTP_PROGIDS[i++]; 333 if(new ActiveXObject(progid)){ 334 // this progid works; therefore, use it from now on 335 break; 336 } 337 }catch(e){ 338 // squelch; we're just trying to find a good ActiveX progid 339 // if they all fail, then progid ends up as the last attempt and that will signal the error 340 // the first time the client actually tries to exec an xhr 341 } 342 } 343 getXhr = function(){ 344 return new ActiveXObject(progid); 345 }; 346 } 347 req.getXhr = getXhr; 348 349 has.add("dojo-gettext-api", 1); 350 req.getText = function(url, async, onLoad){ 351 var xhr = getXhr(); 352 xhr.open('GET', fixupUrl(url), false); 353 xhr.send(null); 354 if(xhr.status == 200 || (!location.host && !xhr.status)){ 355 if(onLoad){ 356 onLoad(xhr.responseText, async); 357 } 358 }else{ 359 throw makeError("xhrFailed", xhr.status); 360 } 361 return xhr.responseText; 362 }; 363 } 364 }else{ 365 req.async = 1; 366 } 367 368 // 369 // loader eval 370 // 371 var eval_ = has("csp-restrictions") ? 372 // noop eval if there are csp restrictions 373 function(){} : 374 // use the function constructor so our eval is scoped close to (but not in) in the global space with minimal pollution 375 new Function('return eval(arguments[0]);'); 376 377 req.eval = 378 function(text, hint){ 379 return eval_(text + "\r\n//# sourceURL=" + hint); 380 }; 381 382 // 383 // loader micro events API 384 // 385 var listenerQueues = {}, 386 error = "error", 387 signal = req.signal = function(type, args){ 388 var queue = listenerQueues[type]; 389 // notice we run a copy of the queue; this allows listeners to add/remove 390 // other listeners without affecting this particular signal 391 forEach(queue && queue.slice(0), function(listener){ 392 listener.apply(null, isArray(args) ? args : [args]); 393 }); 394 }, 395 on = req.on = function(type, listener){ 396 // notice a queue is not created until a client actually connects 397 var queue = listenerQueues[type] || (listenerQueues[type] = []); 398 queue.push(listener); 399 return { 400 remove:function(){ 401 for(var i = 0; i<queue.length; i++){ 402 if(queue[i]===listener){ 403 queue.splice(i, 1); 404 return; 405 } 406 } 407 } 408 }; 409 }; 410 411 // configuration machinery; with an optimized/built defaultConfig, all configuration machinery can be discarded 412 // lexical variables hold key loader data structures to help with minification; these may be completely, 413 // one-time initialized by defaultConfig for optimized/built versions 414 var 415 aliases 416 // a vector of pairs of [regexs or string, replacement] => (alias, actual) 417 = [], 418 419 paths 420 // CommonJS paths 421 = {}, 422 423 pathsMapProg 424 // list of (from-path, to-path, regex, length) derived from paths; 425 // a "program" to apply paths; see computeMapProg 426 = [], 427 428 packs 429 // a map from packageId to package configuration object; see fixupPackageInfo 430 = {}, 431 432 map = req.map 433 // AMD map config variable; dojo/_base/kernel needs req.map to figure out the scope map 434 = {}, 435 436 mapProgs 437 // vector of quads as described by computeMapProg; map-key is AMD map key, map-value is AMD map value 438 = [], 439 440 modules 441 // A hash:(mid) --> (module-object) the module namespace 442 // 443 // pid: the package identifier to which the module belongs (e.g., "dojo"); "" indicates the system or default package 444 // mid: the fully-resolved (i.e., mappings have been applied) module identifier without the package identifier (e.g., "dojo/io/script") 445 // url: the URL from which the module was retrieved 446 // pack: the package object of the package to which the module belongs 447 // executed: 0 => not executed; executing => in the process of traversing deps and running factory; executed => factory has been executed 448 // deps: the dependency vector for this module (vector of modules objects) 449 // def: the factory for this module 450 // result: the result of the running the factory for this module 451 // injected: (0 | requested | arrived) the status of the module; nonmodule means the resource did not call define 452 // load: plugin load function; applicable only for plugins 453 // 454 // Modules go through several phases in creation: 455 // 456 // 1. Requested: some other module's definition or a require application contained the requested module in 457 // its dependency vector or executing code explicitly demands a module via req.require. 458 // 459 // 2. Injected: a script element has been appended to the insert-point element demanding the resource implied by the URL 460 // 461 // 3. Loaded: the resource injected in [2] has been evaluated. 462 // 463 // 4. Defined: the resource contained a define statement that advised the loader about the module. Notice that some 464 // resources may just contain a bundle of code and never formally define a module via define 465 // 466 // 5. Evaluated: the module was defined via define and the loader has evaluated the factory and computed a result. 467 = {}, 468 469 cacheBust 470 // query string to append to module URLs to bust browser cache 471 = "", 472 473 cache 474 // hash:(mid | url)-->(function | string) 475 // 476 // A cache of resources. The resources arrive via a config.cache object, which is a hash from either mid --> function or 477 // url --> string. The url key is distinguished from the mid key by always containing the prefix "url:". url keys as provided 478 // by config.cache always have a string value that represents the contents of the resource at the given url. mid keys as provided 479 // by configl.cache always have a function value that causes the same code to execute as if the module was script injected. 480 // 481 // Both kinds of key-value pairs are entered into cache via the function consumePendingCache, which may relocate keys as given 482 // by any mappings *iff* the config.cache was received as part of a module resource request. 483 // 484 // Further, for mid keys, the implied url is computed and the value is entered into that key as well. This allows mapped modules 485 // to retrieve cached items that may have arrived consequent to another namespace. 486 // 487 = {}, 488 489 urlKeyPrefix 490 // the prefix to prepend to a URL key in the cache. 491 = "url:", 492 493 pendingCacheInsert 494 // hash:(mid)-->(function) 495 // 496 // Gives a set of cache modules pending entry into cache. When cached modules are published to the loader, they are 497 // entered into pendingCacheInsert; modules are then pressed into cache upon (1) AMD define or (2) upon receiving another 498 // independent set of cached modules. (1) is the usual case, and this case allows normalizing mids given in the pending 499 // cache for the local configuration, possibly relocating modules. 500 = {}, 501 502 dojoSniffConfig 503 // map of configuration variables 504 // give the data-dojo-config as sniffed from the document (if any) 505 = {}, 506 507 insertPointSibling 508 // the nodes used to locate where scripts are injected into the document 509 = 0; 510 511 if(has("dojo-config-api")){ 512 if (!has("foreign-loader")) { 513 var consumePendingCacheInsert = function(referenceModule, clear){ 514 clear = clear !== false; 515 var p, item, match, now, m; 516 for(p in pendingCacheInsert){ 517 item = pendingCacheInsert[p]; 518 match = p.match(/^url\:(.+)/); 519 if(match){ 520 cache[urlKeyPrefix + toUrl(match[1], referenceModule)] = item; 521 }else if(p=="*now"){ 522 now = item; 523 }else if(p!="*noref"){ 524 m = getModuleInfo(p, referenceModule, true); 525 cache[m.mid] = cache[urlKeyPrefix + m.url] = item; 526 } 527 } 528 if(now){ 529 now(createRequire(referenceModule)); 530 } 531 if(clear){ 532 pendingCacheInsert = {}; 533 } 534 }; 535 } 536 var escapeString = function(s){ 537 return s.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, function(c){ return "\\" + c; }); 538 }, 539 540 computeMapProg = function(map, dest){ 541 // This routine takes a map as represented by a JavaScript object and initializes dest, a vector of 542 // quads of (map-key, map-value, refex-for-map-key, length-of-map-key), sorted decreasing by length- 543 // of-map-key. The regex looks for the map-key followed by either "/" or end-of-string at the beginning 544 // of a the search source. Notice the map-value is irrelevant to the algorithm 545 dest.splice(0, dest.length); 546 for(var p in map){ 547 dest.push([ 548 p, 549 map[p], 550 new RegExp("^" + escapeString(p) + "(\/|$)"), 551 p.length]); 552 } 553 dest.sort(function(lhs, rhs){ return rhs[3] - lhs[3]; }); 554 return dest; 555 }, 556 557 computeAliases = function(config, dest){ 558 forEach(config, function(pair){ 559 // take a fixed-up copy... 560 dest.push([isString(pair[0]) ? new RegExp("^" + escapeString(pair[0]) + "$") : pair[0], pair[1]]); 561 }); 562 }, 563 564 565 fixupPackageInfo = function(packageInfo){ 566 // calculate the precise (name, location, main, mappings) for a package 567 var name = packageInfo.name; 568 if(!name){ 569 // packageInfo must be a string that gives the name 570 name = packageInfo; 571 packageInfo = {name:name}; 572 } 573 packageInfo = mix({main:"main"}, packageInfo); 574 packageInfo.location = packageInfo.location ? packageInfo.location : name; 575 576 // packageMap is deprecated in favor of AMD map 577 if(packageInfo.packageMap){ 578 map[name] = packageInfo.packageMap; 579 } 580 581 if(!packageInfo.main.indexOf("./")){ 582 packageInfo.main = packageInfo.main.substring(2); 583 } 584 585 // now that we've got a fully-resolved package object, push it into the configuration 586 packs[name] = packageInfo; 587 }, 588 589 delayedModuleConfig 590 // module config cannot be consumed until the loader is completely initialized; therefore, all 591 // module config detected during booting is memorized and applied at the end of loader initialization 592 // TODO: this is a bit of a kludge; all config should be moved to end of loader initialization, but 593 // we'll delay this chore and do it with a final loader 1.x cleanup after the 2.x loader prototyping is complete 594 = [], 595 596 597 config = function(config, booting, referenceModule){ 598 for(var p in config){ 599 if(p=="waitSeconds"){ 600 req.waitms = (config[p] || 0) * 1000; 601 } 602 if(p=="cacheBust"){ 603 cacheBust = config[p] ? (isString(config[p]) ? config[p] : (new Date()).getTime() + "") : ""; 604 } 605 if(p=="baseUrl" || p=="combo"){ 606 req[p] = config[p]; 607 } 608 if(has("dojo-sync-loader") && p=="async"){ 609 // falsy or "sync" => legacy sync loader 610 // "xd" => sync but loading xdomain tree and therefore loading asynchronously (not configurable, set automatically by the loader) 611 // "legacyAsync" => permanently in "xd" by choice 612 // "debugAtAllCosts" => trying to load everything via script injection (not implemented) 613 // otherwise, must be truthy => AMD 614 // legacyMode: sync | legacyAsync | xd | false 615 var mode = config[p]; 616 req.legacyMode = legacyMode = (isString(mode) && /sync|legacyAsync/.test(mode) ? mode : (!mode ? sync : false)); 617 req.async = !legacyMode; 618 } 619 if(config[p]!==hasCache){ 620 // accumulate raw config info for client apps which can use this to pass their own config 621 req.rawConfig[p] = config[p]; 622 p!="has" && has.add("config-"+p, config[p], 0, booting); 623 } 624 } 625 626 // make sure baseUrl exists 627 if(!req.baseUrl){ 628 req.baseUrl = "./"; 629 } 630 // make sure baseUrl ends with a slash 631 if(!/\/$/.test(req.baseUrl)){ 632 req.baseUrl += "/"; 633 } 634 635 // now do the special work for has, packages, packagePaths, paths, aliases, and cache 636 637 for(p in config.has){ 638 has.add(p, config.has[p], 0, booting); 639 } 640 641 // for each package found in any packages config item, augment the packs map owned by the loader 642 forEach(config.packages, fixupPackageInfo); 643 644 // for each packagePath found in any packagePaths config item, augment the packageConfig 645 // packagePaths is deprecated; remove in 2.0 646 for(var baseUrl in config.packagePaths){ 647 forEach(config.packagePaths[baseUrl], function(packageInfo){ 648 var location = baseUrl + "/" + packageInfo; 649 if(isString(packageInfo)){ 650 packageInfo = {name:packageInfo}; 651 } 652 packageInfo.location = location; 653 fixupPackageInfo(packageInfo); 654 }); 655 } 656 657 // notice that computeMapProg treats the dest as a reference; therefore, if/when that variable 658 // is published (see dojo-publish-privates), the published variable will always hold a valid value. 659 660 // this must come after all package processing since package processing may mutate map 661 computeMapProg(mix(map, config.map), mapProgs); 662 forEach(mapProgs, function(item){ 663 item[1] = computeMapProg(item[1], []); 664 if(item[0]=="*"){ 665 mapProgs.star = item; 666 } 667 }); 668 669 // push in any paths and recompute the internal pathmap 670 computeMapProg(mix(paths, config.paths), pathsMapProg); 671 672 // aliases 673 computeAliases(config.aliases, aliases); 674 675 if (!has("foreign-loader")) { 676 if(booting){ 677 delayedModuleConfig.push({config:config.config}); 678 }else{ 679 for(p in config.config){ 680 var module = getModule(p, referenceModule); 681 module.config = mix(module.config || {}, config.config[p]); 682 } 683 } 684 685 // push in any new cache values 686 if(config.cache){ 687 consumePendingCacheInsert(); 688 pendingCacheInsert = config.cache; 689 //inject now all depencies so cache is available for mapped module 690 consumePendingCacheInsert(0, !!config.cache["*noref"]); 691 } 692 } 693 signal("config", [config, req.rawConfig]); 694 }; 695 696 // 697 // execute the various sniffs; userConfig can override and value 698 // 699 700 if(has("dojo-cdn") || has("dojo-sniff")){ 701 // the sniff regex looks for a src attribute ending in dojo.js, optionally preceded with a path. 702 // match[3] returns the path to dojo.js (if any) without the trailing slash. This is used for the 703 // dojo location on CDN deployments and baseUrl when either/both of these are not provided 704 // explicitly in the config data; this is the 1.6- behavior. 705 706 var scripts = doc.getElementsByTagName("script"), 707 i = 0, 708 script, dojoDir, src, match; 709 while(i < scripts.length){ 710 script = scripts[i++]; 711 if((src = script.getAttribute("src")) && (match = src.match(/(((.*)\/)|^)dojo\.js(\W|$)/i))){ 712 // sniff dojoDir and baseUrl 713 dojoDir = match[3] || ""; 714 defaultConfig.baseUrl = defaultConfig.baseUrl || dojoDir; 715 716 // remember an insertPointSibling 717 insertPointSibling = script; 718 } 719 720 // sniff configuration on attribute in script element 721 if((src = (script.getAttribute("data-dojo-config") || script.getAttribute("djConfig")))){ 722 dojoSniffConfig = req.eval("({ " + src + " })", "data-dojo-config"); 723 724 // remember an insertPointSibling 725 insertPointSibling = script; 726 } 727 728 // sniff requirejs attribute 729 if(has("dojo-requirejs-api")){ 730 if((src = script.getAttribute("data-main"))){ 731 dojoSniffConfig.deps = dojoSniffConfig.deps || [src]; 732 } 733 } 734 } 735 } 736 737 if(has("dojo-test-sniff")){ 738 // pass down doh.testConfig from parent as if it were a data-dojo-config 739 try{ 740 if(window.parent != window && window.parent.require){ 741 var doh = window.parent.require("doh"); 742 doh && mix(dojoSniffConfig, doh.testConfig); 743 } 744 }catch(e){} 745 } 746 747 // configure the loader; let the user override defaults 748 req.rawConfig = {}; 749 config(defaultConfig, 1); 750 751 // do this before setting userConfig/sniffConfig to allow userConfig/sniff overrides 752 if(has("dojo-cdn")){ 753 packs.dojo.location = dojoDir; 754 if(dojoDir){ 755 dojoDir += "/"; 756 } 757 packs.dijit.location = dojoDir + "../dijit/"; 758 packs.dojox.location = dojoDir + "../dojox/"; 759 } 760 761 config(userConfig, 1); 762 config(dojoSniffConfig, 1); 763 764 }else{ 765 // no config API, assume defaultConfig has everything the loader needs...for the entire lifetime of the application 766 paths = defaultConfig.paths; 767 pathsMapProg = defaultConfig.pathsMapProg; 768 packs = defaultConfig.packs; 769 aliases = defaultConfig.aliases; 770 mapProgs = defaultConfig.mapProgs; 771 modules = defaultConfig.modules; 772 cache = defaultConfig.cache; 773 cacheBust = defaultConfig.cacheBust; 774 775 // remember the default config for other processes (e.g., dojo/config) 776 req.rawConfig = defaultConfig; 777 } 778 779 780 if (!has("foreign-loader")) { 781 if(has("dojo-combo-api")){ 782 req.combo = req.combo || {add:noop}; 783 var comboPending = 0, 784 combosPending = [], 785 comboPendingTimer = null; 786 } 787 788 789 // build the loader machinery iaw configuration, including has feature tests 790 var injectDependencies = function(module){ 791 // checkComplete!=0 holds the idle signal; we're not idle if we're injecting dependencies 792 guardCheckComplete(function(){ 793 forEach(module.deps, injectModule); 794 if(has("dojo-combo-api") && comboPending && !comboPendingTimer){ 795 comboPendingTimer = setTimeout(function() { 796 comboPending = 0; 797 comboPendingTimer = null; 798 req.combo.done(function(mids, url) { 799 var onLoadCallback= function(){ 800 // defQ is a vector of module definitions 1-to-1, onto mids 801 runDefQ(0, mids); 802 checkComplete(); 803 }; 804 combosPending.push(mids); 805 injectingModule = mids; 806 req.injectUrl(url, onLoadCallback, mids); 807 injectingModule = 0; 808 }, req); 809 }, 0); 810 } 811 }); 812 }, 813 814 contextRequire = function(a1, a2, a3, referenceModule, contextRequire){ 815 var module, syntheticMid; 816 if(isString(a1)){ 817 // signature is (moduleId) 818 module = getModule(a1, referenceModule, true); 819 if(module && module.executed){ 820 return module.result; 821 } 822 throw makeError("undefinedModule", a1); 823 } 824 if(!isArray(a1)){ 825 // a1 is a configuration 826 config(a1, 0, referenceModule); 827 828 // juggle args; (a2, a3) may be (dependencies, callback) 829 a1 = a2; 830 a2 = a3; 831 } 832 if(isArray(a1)){ 833 // signature is (requestList [,callback]) 834 if(!a1.length){ 835 a2 && a2(); 836 }else{ 837 syntheticMid = "require*" + uid(); 838 839 // resolve the request list with respect to the reference module 840 for(var mid, deps = [], i = 0; i < a1.length;){ 841 mid = a1[i++]; 842 deps.push(getModule(mid, referenceModule)); 843 } 844 845 // construct a synthetic module to control execution of the requestList, and, optionally, callback 846 module = mix(makeModuleInfo("", syntheticMid, 0, ""), { 847 injected: arrived, 848 deps: deps, 849 def: a2 || noop, 850 require: referenceModule ? referenceModule.require : req, 851 gc: 1 //garbage collect 852 }); 853 modules[module.mid] = module; 854 855 // checkComplete!=0 holds the idle signal; we're not idle if we're injecting dependencies 856 injectDependencies(module); 857 858 // try to immediately execute 859 // if already traversing a factory tree, then strict causes circular dependency to abort the execution; maybe 860 // it's possible to execute this require later after the current traversal completes and avoid the circular dependency. 861 // ...but *always* insist on immediate in synch mode 862 var strict = checkCompleteGuard && legacyMode!=sync; 863 guardCheckComplete(function(){ 864 execModule(module, strict); 865 }); 866 if(!module.executed){ 867 // some deps weren't on board or circular dependency detected and strict; therefore, push into the execQ 868 execQ.push(module); 869 } 870 checkComplete(); 871 } 872 } 873 return contextRequire; 874 }, 875 876 createRequire = function(module){ 877 if(!module){ 878 return req; 879 } 880 var result = module.require; 881 if(!result){ 882 result = function(a1, a2, a3){ 883 return contextRequire(a1, a2, a3, module, result); 884 }; 885 module.require = mix(result, req); 886 result.module = module; 887 result.toUrl = function(name){ 888 return toUrl(name, module); 889 }; 890 result.toAbsMid = function(mid){ 891 return toAbsMid(mid, module); 892 }; 893 if(has("dojo-undef-api")){ 894 result.undef = function(mid){ 895 req.undef(mid, module); 896 }; 897 } 898 if(has("dojo-sync-loader")){ 899 result.syncLoadNls = function(mid){ 900 var nlsModuleInfo = getModuleInfo(mid, module), 901 nlsModule = modules[nlsModuleInfo.mid]; 902 if(!nlsModule || !nlsModule.executed){ 903 cached = cache[nlsModuleInfo.mid] || cache[urlKeyPrefix + nlsModuleInfo.url]; 904 if(cached){ 905 evalModuleText(cached); 906 nlsModule = modules[nlsModuleInfo.mid]; 907 } 908 } 909 return nlsModule && nlsModule.executed && nlsModule.result; 910 }; 911 } 912 913 } 914 return result; 915 }, 916 917 execQ = 918 // The list of modules that need to be evaluated. 919 [], 920 921 defQ = 922 // The queue of define arguments sent to loader. 923 [], 924 925 waiting = 926 // The set of modules upon which the loader is waiting for definition to arrive 927 {}, 928 929 setRequested = function(module){ 930 module.injected = requested; 931 waiting[module.mid] = 1; 932 if(module.url){ 933 waiting[module.url] = module.pack || 1; 934 } 935 startTimer(); 936 }, 937 938 setArrived = function(module){ 939 module.injected = arrived; 940 delete waiting[module.mid]; 941 if(module.url){ 942 delete waiting[module.url]; 943 } 944 if(isEmpty(waiting)){ 945 clearTimer(); 946 has("dojo-sync-loader") && legacyMode==xd && (legacyMode = sync); 947 } 948 }, 949 950 execComplete = req.idle = 951 // says the loader has completed (or not) its work 952 function(){ 953 return !defQ.length && isEmpty(waiting) && !execQ.length && !checkCompleteGuard; 954 }; 955 } 956 957 var runMapProg = function(targetMid, map){ 958 // search for targetMid in map; return the map item if found; falsy otherwise 959 if(map){ 960 for(var i = 0; i < map.length; i++){ 961 if(map[i][2].test(targetMid)){ 962 return map[i]; 963 } 964 } 965 } 966 return 0; 967 }, 968 969 compactPath = function(path){ 970 var result = [], 971 segment, lastSegment; 972 path = path.replace(/\\/g, '/').split('/'); 973 while(path.length){ 974 segment = path.shift(); 975 if(segment==".." && result.length && lastSegment!=".."){ 976 result.pop(); 977 lastSegment = result[result.length - 1]; 978 }else if(segment!="."){ 979 result.push(lastSegment= segment); 980 } // else ignore "." 981 } 982 return result.join("/"); 983 }, 984 985 makeModuleInfo = function(pid, mid, pack, url){ 986 if(has("dojo-sync-loader")){ 987 var xd= req.isXdUrl(url); 988 return {pid:pid, mid:mid, pack:pack, url:url, executed:0, def:0, isXd:xd, isAmd:!!(xd || (packs[pid] && packs[pid].isAmd))}; 989 }else{ 990 return {pid:pid, mid:mid, pack:pack, url:url, executed:0, def:0}; 991 } 992 }, 993 994 getModuleInfo_ = function(mid, referenceModule, packs, modules, baseUrl, mapProgs, pathsMapProg, aliases, alwaysCreate, fromPendingCache){ 995 // arguments are passed instead of using lexical variables so that this function my be used independent of the loader (e.g., the builder) 996 // alwaysCreate is useful in this case so that getModuleInfo never returns references to real modules owned by the loader 997 var pid, pack, midInPackage, mapItem, url, result, isRelative, requestedMid; 998 requestedMid = mid; 999 isRelative = /^\./.test(mid); 1000 if(/(^\/)|(\:)|(\.js$)/.test(mid) || (isRelative && !referenceModule)){ 1001 // absolute path or protocol of .js filetype, or relative path but no reference module and therefore relative to page 1002 // whatever it is, it's not a module but just a URL of some sort 1003 // note: pid===0 indicates the routine is returning an unmodified mid 1004 1005 return makeModuleInfo(0, mid, 0, mid); 1006 }else{ 1007 // relative module ids are relative to the referenceModule; get rid of any dots 1008 mid = compactPath(isRelative ? (referenceModule.mid + "/../" + mid) : mid); 1009 if(/^\./.test(mid)){ 1010 throw makeError("irrationalPath", mid); 1011 } 1012 // at this point, mid is an absolute mid 1013 1014 // map the mid 1015 if(!fromPendingCache && !isRelative && mapProgs.star){ 1016 mapItem = runMapProg(mid, mapProgs.star[1]); 1017 } 1018 if(!mapItem && referenceModule){ 1019 mapItem = runMapProg(referenceModule.mid, mapProgs); 1020 mapItem = mapItem && runMapProg(mid, mapItem[1]); 1021 } 1022 1023 if(mapItem){ 1024 mid = mapItem[1] + mid.substring(mapItem[3]); 1025 } 1026 1027 match = mid.match(/^([^\/]+)(\/(.+))?$/); 1028 pid = match ? match[1] : ""; 1029 if((pack = packs[pid])){ 1030 mid = pid + "/" + (midInPackage = (match[3] || pack.main)); 1031 }else{ 1032 pid = ""; 1033 } 1034 1035 // search aliases 1036 var candidateLength = 0, 1037 candidate = 0; 1038 forEach(aliases, function(pair){ 1039 var match = mid.match(pair[0]); 1040 if(match && match.length>candidateLength){ 1041 candidate = isFunction(pair[1]) ? mid.replace(pair[0], pair[1]) : pair[1]; 1042 } 1043 }); 1044 if(candidate){ 1045 return getModuleInfo_(candidate, 0, packs, modules, baseUrl, mapProgs, pathsMapProg, aliases, alwaysCreate); 1046 } 1047 1048 result = modules[mid]; 1049 if(result){ 1050 return alwaysCreate ? makeModuleInfo(result.pid, result.mid, result.pack, result.url) : modules[mid]; 1051 } 1052 } 1053 // get here iff the sought-after module does not yet exist; therefore, we need to compute the URL given the 1054 // fully resolved (i.e., all relative indicators and package mapping resolved) module id 1055 1056 // note: pid!==0 indicates the routine is returning a url that has .js appended unmodified mid 1057 mapItem = runMapProg(mid, pathsMapProg); 1058 if(mapItem){ 1059 url = mapItem[1] + mid.substring(mapItem[3]); 1060 }else if(pid){ 1061 url = (pack.location.slice(-1) === '/' ? pack.location.slice(0, -1) : pack.location) + "/" + midInPackage; 1062 }else if(has("config-tlmSiblingOfDojo")){ 1063 url = "../" + mid; 1064 }else{ 1065 url = mid; 1066 } 1067 // if result is not absolute, add baseUrl 1068 if(!(/(^\/)|(\:)/.test(url))){ 1069 url = baseUrl + url; 1070 } 1071 url += ".js"; 1072 return makeModuleInfo(pid, mid, pack, compactPath(url)); 1073 }, 1074 1075 getModuleInfo = function(mid, referenceModule, fromPendingCache){ 1076 return getModuleInfo_(mid, referenceModule, packs, modules, req.baseUrl, mapProgs, pathsMapProg, aliases, undefined, fromPendingCache); 1077 }; 1078 1079 if (!has("foreign-loader")) { 1080 var resolvePluginResourceId = function(plugin, prid, referenceModule){ 1081 return plugin.normalize ? plugin.normalize(prid, function(mid){return toAbsMid(mid, referenceModule);}) : toAbsMid(prid, referenceModule); 1082 }, 1083 1084 dynamicPluginUidGenerator = 0, 1085 1086 getModule = function(mid, referenceModule, immediate){ 1087 // compute and optionally construct (if necessary) the module implied by the mid with respect to referenceModule 1088 var match, plugin, prid, result; 1089 match = mid.match(/^(.+?)\!(.*)$/); 1090 if(match){ 1091 // name was <plugin-module>!<plugin-resource-id> 1092 plugin = getModule(match[1], referenceModule, immediate); 1093 1094 if(has("dojo-sync-loader") && legacyMode == sync && !plugin.executed){ 1095 injectModule(plugin); 1096 if(plugin.injected===arrived && !plugin.executed){ 1097 guardCheckComplete(function(){ 1098 execModule(plugin); 1099 }); 1100 } 1101 if(plugin.executed){ 1102 promoteModuleToPlugin(plugin); 1103 }else{ 1104 // we are in xdomain mode for some reason 1105 execQ.unshift(plugin); 1106 } 1107 } 1108 1109 1110 1111 if(plugin.executed === executed && !plugin.load){ 1112 // executed the module not knowing it was a plugin 1113 promoteModuleToPlugin(plugin); 1114 } 1115 1116 // if the plugin has not been loaded, then can't resolve the prid and must assume this plugin is dynamic until we find out otherwise 1117 if(plugin.load){ 1118 prid = resolvePluginResourceId(plugin, match[2], referenceModule); 1119 mid = (plugin.mid + "!" + (plugin.dynamic ? ++dynamicPluginUidGenerator + "!" : "") + prid); 1120 }else{ 1121 prid = match[2]; 1122 mid = plugin.mid + "!" + (++dynamicPluginUidGenerator) + "!waitingForPlugin"; 1123 } 1124 result = {plugin:plugin, mid:mid, req:createRequire(referenceModule), prid:prid}; 1125 }else{ 1126 result = getModuleInfo(mid, referenceModule); 1127 } 1128 return modules[result.mid] || (!immediate && (modules[result.mid] = result)); 1129 }; 1130 } 1131 1132 var toAbsMid = req.toAbsMid = function(mid, referenceModule){ 1133 return getModuleInfo(mid, referenceModule).mid; 1134 }, 1135 1136 toUrl = req.toUrl = function(name, referenceModule){ 1137 var moduleInfo = getModuleInfo(name+"/x", referenceModule), 1138 url= moduleInfo.url; 1139 return fixupUrl(moduleInfo.pid===0 ? 1140 // if pid===0, then name had a protocol or absolute path; either way, toUrl is the identify function in such cases 1141 name : 1142 // "/x.js" since getModuleInfo automatically appends ".js" and we appended "/x" to make name look like a module id 1143 url.substring(0, url.length-5) 1144 ); 1145 }; 1146 1147 if (!has("foreign-loader")) { 1148 var nonModuleProps = { 1149 injected: arrived, 1150 executed: executed, 1151 def: nonmodule, 1152 result: nonmodule 1153 }, 1154 1155 makeCjs = function(mid){ 1156 return modules[mid] = mix({mid:mid}, nonModuleProps); 1157 }, 1158 1159 cjsRequireModule = makeCjs("require"), 1160 cjsExportsModule = makeCjs("exports"), 1161 cjsModuleModule = makeCjs("module"), 1162 1163 runFactory = function(module, args){ 1164 req.trace("loader-run-factory", [module.mid]); 1165 var factory = module.def, 1166 result; 1167 has("dojo-sync-loader") && syncExecStack.unshift(module); 1168 if(has("config-dojo-loader-catches")){ 1169 try{ 1170 result= isFunction(factory) ? factory.apply(null, args) : factory; 1171 }catch(e){ 1172 signal(error, module.result = makeError("factoryThrew", [module, e])); 1173 } 1174 }else{ 1175 result= isFunction(factory) ? factory.apply(null, args) : factory; 1176 } 1177 module.result = result===undefined && module.cjs ? module.cjs.exports : result; 1178 has("dojo-sync-loader") && syncExecStack.shift(module); 1179 }, 1180 1181 abortExec = {}, 1182 1183 defOrder = 0, 1184 1185 promoteModuleToPlugin = function(pluginModule){ 1186 var plugin = pluginModule.result; 1187 pluginModule.dynamic = plugin.dynamic; 1188 pluginModule.normalize = plugin.normalize; 1189 pluginModule.load = plugin.load; 1190 return pluginModule; 1191 }, 1192 1193 resolvePluginLoadQ = function(plugin){ 1194 // plugins is a newly executed module that has a loadQ waiting to run 1195 1196 // step 1: traverse the loadQ and fixup the mid and prid; remember the map from original mid to new mid 1197 // recall the original mid was created before the plugin was on board and therefore it was impossible to 1198 // compute the final mid; accordingly, prid may or may not change, but the mid will definitely change 1199 var map = {}; 1200 forEach(plugin.loadQ, function(pseudoPluginResource){ 1201 // manufacture and insert the real module in modules 1202 var prid = resolvePluginResourceId(plugin, pseudoPluginResource.prid, pseudoPluginResource.req.module), 1203 mid = plugin.dynamic ? pseudoPluginResource.mid.replace(/waitingForPlugin$/, prid) : (plugin.mid + "!" + prid), 1204 pluginResource = mix(mix({}, pseudoPluginResource), {mid:mid, prid:prid, injected:0}); 1205 if(!modules[mid] || !modules[mid].injected /*for require.undef*/){ 1206 // create a new (the real) plugin resource and inject it normally now that the plugin is on board 1207 injectPlugin(modules[mid] = pluginResource); 1208 } // else this was a duplicate request for the same (plugin, rid) for a nondynamic plugin 1209 1210 // pluginResource is really just a placeholder with the wrong mid (because we couldn't calculate it until the plugin was on board) 1211 // mark is as arrived and delete it from modules; the real module was requested above 1212 map[pseudoPluginResource.mid] = modules[mid]; 1213 setArrived(pseudoPluginResource); 1214 delete modules[pseudoPluginResource.mid]; 1215 }); 1216 plugin.loadQ = 0; 1217 1218 // step2: replace all references to any placeholder modules with real modules 1219 var substituteModules = function(module){ 1220 for(var replacement, deps = module.deps || [], i = 0; i<deps.length; i++){ 1221 replacement = map[deps[i].mid]; 1222 if(replacement){ 1223 deps[i] = replacement; 1224 } 1225 } 1226 }; 1227 for(var p in modules){ 1228 substituteModules(modules[p]); 1229 } 1230 forEach(execQ, substituteModules); 1231 }, 1232 1233 finishExec = function(module){ 1234 req.trace("loader-finish-exec", [module.mid]); 1235 module.executed = executed; 1236 module.defOrder = defOrder++; 1237 has("dojo-sync-loader") && forEach(module.provides, function(cb){ cb(); }); 1238 if(module.loadQ){ 1239 // the module was a plugin 1240 promoteModuleToPlugin(module); 1241 resolvePluginLoadQ(module); 1242 } 1243 // remove all occurrences of this module from the execQ 1244 for(i = 0; i < execQ.length;){ 1245 if(execQ[i] === module){ 1246 execQ.splice(i, 1); 1247 }else{ 1248 i++; 1249 } 1250 } 1251 // delete references to synthetic modules 1252 if (/^require\*/.test(module.mid)) { 1253 delete modules[module.mid]; 1254 } 1255 }, 1256 1257 circleTrace = [], 1258 1259 execModule = function(module, strict){ 1260 // run the dependency vector, then run the factory for module 1261 if(module.executed === executing){ 1262 req.trace("loader-circular-dependency", [circleTrace.concat(module.mid).join("->")]); 1263 return (!module.def || strict) ? abortExec : (module.cjs && module.cjs.exports); 1264 } 1265 // at this point the module is either not executed or fully executed 1266 1267 1268 if(!module.executed){ 1269 if(!module.def){ 1270 return abortExec; 1271 } 1272 var mid = module.mid, 1273 deps = module.deps || [], 1274 arg, argResult, 1275 args = [], 1276 i = 0; 1277 1278 if(has("dojo-trace-api")){ 1279 circleTrace.push(mid); 1280 req.trace("loader-exec-module", ["exec", circleTrace.length, mid]); 1281 } 1282 1283 // for circular dependencies, assume the first module encountered was executed OK 1284 // modules that circularly depend on a module that has not run its factory will get 1285 // the pre-made cjs.exports===module.result. They can take a reference to this object and/or 1286 // add properties to it. When the module finally runs its factory, the factory can 1287 // read/write/replace this object. Notice that so long as the object isn't replaced, any 1288 // reference taken earlier while walking the deps list is still valid. 1289 module.executed = executing; 1290 while((arg = deps[i++])){ 1291 argResult = ((arg === cjsRequireModule) ? createRequire(module) : 1292 ((arg === cjsExportsModule) ? module.cjs.exports : 1293 ((arg === cjsModuleModule) ? module.cjs : 1294 execModule(arg, strict)))); 1295 if(argResult === abortExec){ 1296 module.executed = 0; 1297 req.trace("loader-exec-module", ["abort", mid]); 1298 has("dojo-trace-api") && circleTrace.pop(); 1299 return abortExec; 1300 } 1301 args.push(argResult); 1302 } 1303 runFactory(module, args); 1304 finishExec(module); 1305 has("dojo-trace-api") && circleTrace.pop(); 1306 } 1307 // at this point the module is guaranteed fully executed 1308 1309 return module.result; 1310 }, 1311 1312 1313 checkCompleteGuard = 0, 1314 1315 guardCheckComplete = function(proc){ 1316 try{ 1317 checkCompleteGuard++; 1318 proc(); 1319 }catch(e){ 1320 // https://bugs.dojotoolkit.org/ticket/16617 1321 throw e; 1322 }finally{ 1323 checkCompleteGuard--; 1324 } 1325 if(execComplete()){ 1326 signal("idle", []); 1327 } 1328 }, 1329 1330 checkComplete = function(){ 1331 // keep going through the execQ as long as at least one factory is executed 1332 // plugins, recursion, cached modules all make for many execution path possibilities 1333 if(checkCompleteGuard){ 1334 return; 1335 } 1336 guardCheckComplete(function(){ 1337 checkDojoRequirePlugin(); 1338 for(var currentDefOrder, module, i = 0; i < execQ.length;){ 1339 currentDefOrder = defOrder; 1340 module = execQ[i]; 1341 execModule(module); 1342 if(currentDefOrder!=defOrder){ 1343 // defOrder was bumped one or more times indicating something was executed (note, this indicates 1344 // the execQ was modified, maybe a lot (for example a later module causes an earlier module to execute) 1345 checkDojoRequirePlugin(); 1346 i = 0; 1347 }else{ 1348 // nothing happened; check the next module in the exec queue 1349 i++; 1350 } 1351 } 1352 }); 1353 }; 1354 } 1355 1356 var fixupUrl= typeof userConfig.fixupUrl == "function" ? userConfig.fixupUrl : function(url){ 1357 url += ""; // make sure url is a Javascript string (some paths may be a Java string) 1358 return url + (cacheBust ? ((/\?/.test(url) ? "&" : "?") + cacheBust) : ""); 1359 }; 1360 1361 1362 1363 if(has("dojo-undef-api")){ 1364 req.undef = function(moduleId, referenceModule){ 1365 // In order to reload a module, it must be undefined (this routine) and then re-requested. 1366 // This is useful for testing frameworks (at least). 1367 var module = getModule(moduleId, referenceModule); 1368 setArrived(module); 1369 mix(module, {def:0, executed:0, injected:0, node:0, load:0}); 1370 }; 1371 } 1372 1373 if(has("dojo-inject-api")){ 1374 if(has("dojo-loader-eval-hint-url")===undefined){ 1375 has.add("dojo-loader-eval-hint-url", 1); 1376 } 1377 1378 var injectPlugin = function( 1379 module 1380 ){ 1381 // injects the plugin module given by module; may have to inject the plugin itself 1382 var plugin = module.plugin; 1383 1384 if(plugin.executed === executed && !plugin.load){ 1385 // executed the module not knowing it was a plugin 1386 promoteModuleToPlugin(plugin); 1387 } 1388 1389 var onLoad = function(def){ 1390 module.result = def; 1391 setArrived(module); 1392 finishExec(module); 1393 checkComplete(); 1394 }; 1395 1396 if(plugin.load){ 1397 plugin.load(module.prid, module.req, onLoad); 1398 }else if(plugin.loadQ){ 1399 plugin.loadQ.push(module); 1400 }else{ 1401 // the unshift instead of push is important: we don't want plugins to execute as 1402 // dependencies of some other module because this may cause circles when the plugin 1403 // loadQ is run; also, generally, we want plugins to run early since they may load 1404 // several other modules and therefore can potentially unblock many modules 1405 plugin.loadQ = [module]; 1406 execQ.unshift(plugin); 1407 injectModule(plugin); 1408 } 1409 }, 1410 1411 // for IE, injecting a module may result in a recursive execution if the module is in the cache 1412 1413 cached = 0, 1414 1415 injectingModule = 0, 1416 1417 injectingCachedModule = 0, 1418 1419 evalModuleText = function(text, module){ 1420 // see def() for the injectingCachedModule bracket; it simply causes a short, safe circuit 1421 if(has("config-stripStrict")){ 1422 text = text.replace(/(["'])use strict\1/g, ''); 1423 } 1424 injectingCachedModule = 1; 1425 if(has("config-dojo-loader-catches")){ 1426 try{ 1427 if(text===cached){ 1428 cached.call(null); 1429 }else{ 1430 req.eval(text, has("dojo-loader-eval-hint-url") ? module.url : module.mid); 1431 } 1432 }catch(e){ 1433 signal(error, makeError("evalModuleThrew", module)); 1434 } 1435 }else{ 1436 if(text===cached){ 1437 cached.call(null); 1438 }else{ 1439 req.eval(text, has("dojo-loader-eval-hint-url") ? module.url : module.mid); 1440 } 1441 } 1442 injectingCachedModule = 0; 1443 }, 1444 1445 injectModule = function(module){ 1446 // Inject the module. In the browser environment, this means appending a script element into 1447 // the document; in other environments, it means loading a file. 1448 // 1449 // If in synchronous mode, then get the module synchronously if it's not xdomainLoading. 1450 1451 var mid = module.mid, 1452 url = module.url; 1453 if(module.executed || module.injected || waiting[mid] || (module.url && ((module.pack && waiting[module.url]===module.pack) || waiting[module.url]==1))){ 1454 return; 1455 } 1456 setRequested(module); 1457 1458 if(has("dojo-combo-api")){ 1459 var viaCombo = 0; 1460 if(module.plugin && module.plugin.isCombo){ 1461 // a combo plugin; therefore, must be handled by combo service 1462 // the prid should have already been converted to a URL (if required by the plugin) during 1463 // the normalize process; in any event, there is no way for the loader to know how to 1464 // to the conversion; therefore the third argument is zero 1465 req.combo.add(module.plugin.mid, module.prid, 0, req); 1466 viaCombo = 1; 1467 }else if(!module.plugin){ 1468 viaCombo = req.combo.add(0, module.mid, module.url, req); 1469 } 1470 if(viaCombo){ 1471 comboPending= 1; 1472 return; 1473 } 1474 } 1475 1476 if(module.plugin){ 1477 injectPlugin(module); 1478 return; 1479 } // else a normal module (not a plugin) 1480 1481 1482 var onLoadCallback = function(){ 1483 runDefQ(module); 1484 if(module.injected !== arrived){ 1485 // the script that contained the module arrived and has been executed yet 1486 // nothing was added to the defQ (so it wasn't an AMD module) and the module 1487 // wasn't marked as arrived by dojo.provide (so it wasn't a v1.6- module); 1488 // therefore, it must not have been a module; adjust state accordingly 1489 if(has("dojo-enforceDefine")){ 1490 signal(error, makeError("noDefine", module)); 1491 return; 1492 } 1493 setArrived(module); 1494 mix(module, nonModuleProps); 1495 req.trace("loader-define-nonmodule", [module.url]); 1496 } 1497 1498 if(has("dojo-sync-loader") && legacyMode){ 1499 // must call checkComplete even in for sync loader because we may be in xdomainLoading mode; 1500 // but, if xd loading, then don't call checkComplete until out of the current sync traversal 1501 // in order to preserve order of execution of the dojo.required modules 1502 !syncExecStack.length && checkComplete(); 1503 }else{ 1504 checkComplete(); 1505 } 1506 }; 1507 cached = cache[mid] || cache[urlKeyPrefix + module.url]; 1508 if(cached){ 1509 req.trace("loader-inject", ["cache", module.mid, url]); 1510 evalModuleText(cached, module); 1511 onLoadCallback(); 1512 return; 1513 } 1514 if(has("dojo-sync-loader") && legacyMode){ 1515 if(module.isXd){ 1516 // switch to async mode temporarily; if current legacyMode!=sync, then is must be one of {legacyAsync, xd, false} 1517 legacyMode==sync && (legacyMode = xd); 1518 // fall through and load via script injection 1519 }else if(module.isAmd && legacyMode!=sync){ 1520 // fall through and load via script injection 1521 }else{ 1522 // mode may be sync, xd/legacyAsync, or async; module may be AMD or legacy; but module is always located on the same domain 1523 var xhrCallback = function(text){ 1524 if(legacyMode==sync){ 1525 // the top of syncExecStack gives the current synchronously executing module; the loader needs 1526 // to know this if it has to switch to async loading in the middle of evaluating a legacy module 1527 // this happens when a modules dojo.require's a module that must be loaded async because it's xdomain 1528 // (using unshift/shift because there is no back() methods for Javascript arrays) 1529 syncExecStack.unshift(module); 1530 evalModuleText(text, module); 1531 syncExecStack.shift(); 1532 1533 // maybe the module was an AMD module 1534 runDefQ(module); 1535 1536 // legacy modules never get to defineModule() => cjs and injected never set; also evaluation implies executing 1537 if(!module.cjs){ 1538 setArrived(module); 1539 finishExec(module); 1540 } 1541 1542 if(module.finish){ 1543 // while synchronously evaluating this module, dojo.require was applied referencing a module 1544 // that had to be loaded async; therefore, the loader stopped answering all dojo.require 1545 // requests so they could be answered completely in the correct sequence; module.finish gives 1546 // the list of dojo.requires that must be re-applied once all target modules are available; 1547 // make a synthetic module to execute the dojo.require's in the correct order 1548 1549 // compute a guaranteed-unique mid for the synthetic finish module; remember the finish vector; remove it from the reference module 1550 // TODO: can we just leave the module.finish...what's it hurting? 1551 var finishMid = mid + "*finish", 1552 finish = module.finish; 1553 delete module.finish; 1554 1555 def(finishMid, ["dojo", ("dojo/require!" + finish.join(",")).replace(/\./g, "/")], function(dojo){ 1556 forEach(finish, function(mid){ dojo.require(mid); }); 1557 }); 1558 // unshift, not push, which causes the current traversal to be reattempted from the top 1559 execQ.unshift(getModule(finishMid)); 1560 } 1561 onLoadCallback(); 1562 }else{ 1563 text = transformToAmd(module, text); 1564 if(text){ 1565 evalModuleText(text, module); 1566 onLoadCallback(); 1567 }else{ 1568 // if transformToAmd returned falsy, then the module was already AMD and it can be script-injected 1569 // do so to improve debugability(even though it means another download...which probably won't happen with a good browser cache) 1570 injectingModule = module; 1571 req.injectUrl(fixupUrl(url), onLoadCallback, module); 1572 injectingModule = 0; 1573 } 1574 } 1575 }; 1576 1577 req.trace("loader-inject", ["xhr", module.mid, url, legacyMode!=sync]); 1578 if(has("config-dojo-loader-catches")){ 1579 try{ 1580 req.getText(url, legacyMode!=sync, xhrCallback); 1581 }catch(e){ 1582 signal(error, makeError("xhrInjectFailed", [module, e])); 1583 } 1584 }else{ 1585 req.getText(url, legacyMode!=sync, xhrCallback); 1586 } 1587 return; 1588 } 1589 } // else async mode or fell through in xdomain loading mode; either way, load by script injection 1590 req.trace("loader-inject", ["script", module.mid, url]); 1591 injectingModule = module; 1592 req.injectUrl(fixupUrl(url), onLoadCallback, module); 1593 injectingModule = 0; 1594 }, 1595 1596 defineModule = function(module, deps, def){ 1597 req.trace("loader-define-module", [module.mid, deps]); 1598 1599 if(has("dojo-combo-api") && module.plugin && module.plugin.isCombo){ 1600 // the module is a plugin resource loaded by the combo service 1601 // note: check for module.plugin should be enough since normal plugin resources should 1602 // not follow this path; module.plugin.isCombo is future-proofing belt and suspenders 1603 module.result = isFunction(def) ? def() : def; 1604 setArrived(module); 1605 finishExec(module); 1606 return module; 1607 } 1608 1609 var mid = module.mid; 1610 if(module.injected === arrived){ 1611 signal(error, makeError("multipleDefine", module)); 1612 return module; 1613 } 1614 mix(module, { 1615 deps: deps, 1616 def: def, 1617 cjs: { 1618 id: module.mid, 1619 uri: module.url, 1620 exports: (module.result = {}), 1621 setExports: function(exports){ 1622 module.cjs.exports = exports; 1623 }, 1624 config:function(){ 1625 return module.config; 1626 } 1627 } 1628 }); 1629 1630 // resolve deps with respect to this module 1631 for(var i = 0; deps[i]; i++){ 1632 deps[i] = getModule(deps[i], module); 1633 } 1634 1635 if(has("dojo-sync-loader") && legacyMode && !waiting[mid]){ 1636 // the module showed up without being asked for; it was probably in a <script> element 1637 injectDependencies(module); 1638 execQ.push(module); 1639 checkComplete(); 1640 } 1641 setArrived(module); 1642 1643 if(!isFunction(def) && !deps.length){ 1644 module.result = def; 1645 finishExec(module); 1646 } 1647 1648 return module; 1649 }, 1650 1651 runDefQ = function(referenceModule, mids){ 1652 // defQ is an array of [id, dependencies, factory] 1653 // mids (if any) is a vector of mids given by a combo service 1654 var definedModules = [], 1655 module, args; 1656 while(defQ.length){ 1657 args = defQ.shift(); 1658 mids && (args[0]= mids.shift()); 1659 // explicit define indicates possible multiple modules in a single file; delay injecting dependencies until defQ fully 1660 // processed since modules earlier in the queue depend on already-arrived modules that are later in the queue 1661 // TODO: what if no args[0] and no referenceModule 1662 module = (args[0] && getModule(args[0])) || referenceModule; 1663 definedModules.push([module, args[1], args[2]]); 1664 } 1665 consumePendingCacheInsert(referenceModule); 1666 forEach(definedModules, function(args){ 1667 injectDependencies(defineModule.apply(null, args)); 1668 }); 1669 }; 1670 } 1671 1672 var timerId = 0, 1673 clearTimer = noop, 1674 startTimer = noop; 1675 if(has("dojo-timeout-api")){ 1676 // Timer machinery that monitors how long the loader is waiting and signals an error when the timer runs out. 1677 clearTimer = function(){ 1678 timerId && clearTimeout(timerId); 1679 timerId = 0; 1680 }; 1681 1682 startTimer = function(){ 1683 clearTimer(); 1684 if(req.waitms){ 1685 timerId = global.setTimeout(function(){ 1686 clearTimer(); 1687 signal(error, makeError("timeout", waiting)); 1688 }, req.waitms); 1689 } 1690 }; 1691 } 1692 1693 if (has("dom")) { 1694 // Test for IE's different way of signaling when scripts finish loading. Note that according to 1695 // http://bugs.dojotoolkit.org/ticket/15096#comment:14, IE9 also needs to follow the 1696 // IE specific code path even though it has an addEventListener() method. 1697 // Unknown if special path needed on IE10+, which also has a document.attachEvent() method. 1698 // Should evaluate to false for Opera and Windows 8 apps, even though they document.attachEvent() 1699 // is defined in both those environments. 1700 has.add("ie-event-behavior", doc.attachEvent && typeof Windows === "undefined" && 1701 (typeof opera === "undefined" || opera.toString() != "[object Opera]")); 1702 } 1703 1704 if(has("dom") && (has("dojo-inject-api") || has("dojo-dom-ready-api"))){ 1705 var domOn = function(node, eventName, ieEventName, handler){ 1706 // Add an event listener to a DOM node using the API appropriate for the current browser; 1707 // return a function that will disconnect the listener. 1708 if(!has("ie-event-behavior")){ 1709 node.addEventListener(eventName, handler, false); 1710 return function(){ 1711 node.removeEventListener(eventName, handler, false); 1712 }; 1713 }else{ 1714 node.attachEvent(ieEventName, handler); 1715 return function(){ 1716 node.detachEvent(ieEventName, handler); 1717 }; 1718 } 1719 }, 1720 windowOnLoadListener = domOn(window, "load", "onload", function(){ 1721 req.pageLoaded = 1; 1722 // https://bugs.dojotoolkit.org/ticket/16248 1723 try{ 1724 doc.readyState!="complete" && (doc.readyState = "complete"); 1725 }catch(e){ 1726 } 1727 windowOnLoadListener(); 1728 }); 1729 1730 if(has("dojo-inject-api")){ 1731 // if the loader is on the page, there must be at least one script element 1732 // getting its parent and then doing insertBefore solves the "Operation Aborted" 1733 // error in IE from appending to a node that isn't properly closed; see 1734 // dojo/tests/_base/loader/requirejs/simple-badbase.html for an example 1735 // don't use scripts with type dojo/... since these may be removed; see #15809 1736 // prefer to use the insertPoint computed during the config sniff in case a script is removed; see #16958 1737 var scripts = doc.getElementsByTagName("script"), 1738 i = 0, 1739 script; 1740 while(!insertPointSibling){ 1741 if(!/^dojo/.test((script = scripts[i++]) && script.type)){ 1742 insertPointSibling= script; 1743 } 1744 } 1745 1746 req.injectUrl = function(url, callback, owner){ 1747 // insert a script element to the insert-point element with src=url; 1748 // apply callback upon detecting the script has loaded. 1749 1750 var node = owner.node = doc.createElement("script"), 1751 onLoad = function(e){ 1752 e = e || window.event; 1753 var node = e.target || e.srcElement; 1754 if(e.type === "load" || /complete|loaded/.test(node.readyState)){ 1755 loadDisconnector(); 1756 errorDisconnector(); 1757 callback && callback(); 1758 } 1759 }, 1760 loadDisconnector = domOn(node, "load", "onreadystatechange", onLoad), 1761 errorDisconnector = domOn(node, "error", "onerror", function(e){ 1762 loadDisconnector(); 1763 errorDisconnector(); 1764 signal(error, makeError("scriptError: " + url, [url, e])); 1765 }); 1766 1767 node.type = "text/javascript"; 1768 node.charset = "utf-8"; 1769 node.src = url; 1770 insertPointSibling.parentNode.insertBefore(node, insertPointSibling); 1771 return node; 1772 }; 1773 } 1774 } 1775 1776 if(has("dojo-log-api")){ 1777 req.log = function(){ 1778 try{ 1779 for(var i = 0; i < arguments.length; i++){ 1780 console.log(arguments[i]); 1781 } 1782 }catch(e){} 1783 }; 1784 }else{ 1785 req.log = noop; 1786 } 1787 1788 if(has("dojo-trace-api")){ 1789 var trace = req.trace = function( 1790 group, // the trace group to which this application belongs 1791 args // the contents of the trace 1792 ){ 1793 /// 1794 // Tracing interface by group. 1795 // 1796 // Sends the contents of args to the console iff (req.trace.on && req.trace[group]) 1797 1798 if(trace.on && trace.group[group]){ 1799 signal("trace", [group, args]); 1800 for(var arg, dump = [], text= "trace:" + group + (args.length ? (":" + args[0]) : ""), i= 1; i<args.length;){ 1801 arg = args[i++]; 1802 if(isString(arg)){ 1803 text += ", " + arg; 1804 }else{ 1805 dump.push(arg); 1806 } 1807 } 1808 req.log(text); 1809 dump.length && dump.push("."); 1810 req.log.apply(req, dump); 1811 } 1812 }; 1813 mix(trace, { 1814 on:1, 1815 group:{}, 1816 set:function(group, value){ 1817 if(isString(group)){ 1818 trace.group[group]= value; 1819 }else{ 1820 mix(trace.group, group); 1821 } 1822 } 1823 }); 1824 trace.set(mix(mix(mix({}, defaultConfig.trace), userConfig.trace), dojoSniffConfig.trace)); 1825 on("config", function(config){ 1826 config.trace && trace.set(config.trace); 1827 }); 1828 }else{ 1829 req.trace = noop; 1830 } 1831 if (!has("foreign-loader")) { 1832 var def = function( 1833 mid, //(commonjs.moduleId, optional) 1834 dependencies, //(array of commonjs.moduleId, optional) list of modules to be loaded before running factory 1835 factory //(any) 1836 ){ 1837 /// 1838 // Advises the loader of a module factory. //Implements http://wiki.commonjs.org/wiki/Modules/AsynchronousDefinition. 1839 /// 1840 //note 1841 // CommonJS factory scan courtesy of http://requirejs.org 1842 1843 var arity = arguments.length, 1844 defaultDeps = ["require", "exports", "module"], 1845 // the predominate signature... 1846 args = [0, mid, dependencies]; 1847 if(arity==1){ 1848 args = [0, (isFunction(mid) ? defaultDeps : []), mid]; 1849 }else if(arity==2 && isString(mid)){ 1850 args = [mid, (isFunction(dependencies) ? defaultDeps : []), dependencies]; 1851 }else if(arity==3){ 1852 args = [mid, dependencies, factory]; 1853 } 1854 1855 if(has("dojo-amd-factory-scan") && args[1]===defaultDeps){ 1856 args[2].toString() 1857 .replace(/(\/\*([\s\S]*?)\*\/|\/\/(.*)$)/mg, "") 1858 .replace(/require\(["']([\w\!\-_\.\/]+)["']\)/g, function(match, dep){ 1859 args[1].push(dep); 1860 }); 1861 } 1862 1863 req.trace("loader-define", args.slice(0, 2)); 1864 var targetModule = args[0] && getModule(args[0]), 1865 module; 1866 if(targetModule && !waiting[targetModule.mid]){ 1867 // given a mid that hasn't been requested; therefore, defined through means other than injecting 1868 // consequent to a require() or define() application; examples include defining modules on-the-fly 1869 // due to some code path or including a module in a script element. In any case, 1870 // there is no callback waiting to finish processing and nothing to trigger the defQ and the 1871 // dependencies are never requested; therefore, do it here. 1872 injectDependencies(defineModule(targetModule, args[1], args[2])); 1873 }else if(!has("ie-event-behavior") || !has("host-browser") || injectingCachedModule){ 1874 // not IE path: anonymous module and therefore must have been injected; therefore, onLoad will fire immediately 1875 // after script finishes being evaluated and the defQ can be run from that callback to detect the module id 1876 defQ.push(args); 1877 }else{ 1878 // IE path: possibly anonymous module and therefore injected; therefore, cannot depend on 1-to-1, 1879 // in-order exec of onLoad with script eval (since it's IE) and must manually detect here 1880 targetModule = targetModule || injectingModule; 1881 if(!targetModule){ 1882 for(mid in waiting){ 1883 module = modules[mid]; 1884 if(module && module.node && module.node.readyState === 'interactive'){ 1885 targetModule = module; 1886 break; 1887 } 1888 } 1889 if(has("dojo-combo-api") && !targetModule){ 1890 for(var i = 0; i<combosPending.length; i++){ 1891 targetModule = combosPending[i]; 1892 if(targetModule.node && targetModule.node.readyState === 'interactive'){ 1893 break; 1894 } 1895 targetModule= 0; 1896 } 1897 } 1898 } 1899 if(has("dojo-combo-api") && isArray(targetModule)){ 1900 injectDependencies(defineModule(getModule(targetModule.shift()), args[1], args[2])); 1901 if(!targetModule.length){ 1902 combosPending.splice(i, 1); 1903 } 1904 }else if(targetModule){ 1905 consumePendingCacheInsert(targetModule); 1906 injectDependencies(defineModule(targetModule, args[1], args[2])); 1907 }else{ 1908 signal(error, makeError("ieDefineFailed", args[0])); 1909 } 1910 checkComplete(); 1911 } 1912 }; 1913 def.amd = { 1914 vendor:"dojotoolkit.org" 1915 }; 1916 1917 if(has("dojo-requirejs-api")){ 1918 req.def = def; 1919 } 1920 } else { 1921 var def = noop; 1922 } 1923 // allow config to override default implementation of named functions; this is useful for 1924 // non-browser environments, e.g., overriding injectUrl, getText, log, etc. in node.js, Rhino, etc. 1925 // also useful for testing and monkey patching loader 1926 mix(mix(req, defaultConfig.loaderPatch), userConfig.loaderPatch); 1927 1928 // now that req is fully initialized and won't change, we can hook it up to the error signal 1929 on(error, function(arg){ 1930 try{ 1931 console.error(arg); 1932 if(arg instanceof Error){ 1933 for(var p in arg){ 1934 console.log(p + ":", arg[p]); 1935 } 1936 console.log("."); 1937 } 1938 }catch(e){} 1939 }); 1940 1941 // always publish these 1942 mix(req, { 1943 uid:uid, 1944 cache:cache, 1945 packs:packs 1946 }); 1947 1948 1949 if(has("dojo-publish-privates")){ 1950 mix(req, { 1951 // these may be interesting to look at when debugging 1952 paths:paths, 1953 aliases:aliases, 1954 modules:modules, 1955 legacyMode:legacyMode, 1956 execQ:execQ, 1957 defQ:defQ, 1958 waiting:waiting, 1959 1960 // these are used for testing 1961 // TODO: move testing infrastructure to a different has feature 1962 packs:packs, 1963 mapProgs:mapProgs, 1964 pathsMapProg:pathsMapProg, 1965 listenerQueues:listenerQueues, 1966 1967 // these are used by the builder (at least) 1968 computeMapProg:computeMapProg, 1969 computeAliases:computeAliases, 1970 runMapProg:runMapProg, 1971 compactPath:compactPath, 1972 getModuleInfo:getModuleInfo_ 1973 }); 1974 } 1975 1976 // the loader can be defined exactly once; look for global define which is the symbol AMD loaders are 1977 // *required* to define (as opposed to require, which is optional) 1978 if(global.define){ 1979 if(has("dojo-log-api")){ 1980 signal(error, makeError("defineAlreadyDefined", 0)); 1981 } 1982 return; 1983 }else{ 1984 global.define = def; 1985 global.require = req; 1986 if(has("host-node")){ 1987 require = req; 1988 } 1989 } 1990 1991 if(has("dojo-combo-api") && req.combo && req.combo.plugins){ 1992 var plugins = req.combo.plugins, 1993 pluginName; 1994 for(pluginName in plugins){ 1995 mix(mix(getModule(pluginName), plugins[pluginName]), {isCombo:1, executed:"executed", load:1}); 1996 } 1997 } 1998 1999 if(has("dojo-config-api") && !has("foreign-loader")){ 2000 forEach(delayedModuleConfig, function(c){ config(c); }); 2001 var bootDeps = dojoSniffConfig.deps || userConfig.deps || defaultConfig.deps, 2002 bootCallback = dojoSniffConfig.callback || userConfig.callback || defaultConfig.callback; 2003 req.boot = (bootDeps || bootCallback) ? [bootDeps || [], bootCallback] : 0; 2004 } 2005 if(!has("dojo-built")){ 2006 !req.async && req(["dojo"]); 2007 req.boot && req.apply(null, req.boot); 2008 } 2009}) 2010//>>excludeStart("replaceLoaderConfig", kwArgs.replaceLoaderConfig); 2011( 2012 // userConfig 2013 function(global){ return global.dojoConfig || global.djConfig || global.require || {}; }, 2014 2015 // defaultConfig 2016 { 2017 // the default configuration for a browser; this will be modified by other environments 2018 hasCache:{ 2019 "host-browser":1, 2020 "dom":1, 2021 "dojo-amd-factory-scan":1, 2022 "dojo-loader":1, 2023 "dojo-has-api":1, 2024 "dojo-inject-api":1, 2025 "dojo-timeout-api":1, 2026 "dojo-trace-api":1, 2027 "dojo-log-api":1, 2028 "dojo-dom-ready-api":1, 2029 "dojo-publish-privates":1, 2030 "dojo-config-api":1, 2031 "dojo-sniff":1, 2032 "dojo-sync-loader":1, 2033 "dojo-test-sniff":1, 2034 "config-deferredInstrumentation":1, 2035 "config-tlmSiblingOfDojo":1, 2036 "foreign-loader":0 2037 }, 2038 packages:[{ 2039 // note: like v1.6-, this bootstrap computes baseUrl to be the dojo directory 2040 name:'dojo', 2041 location:'.' 2042 },{ 2043 name:'tests', 2044 location:'./tests' 2045 },{ 2046 name:'dijit', 2047 location:'../dijit' 2048 },{ 2049 name:'build', 2050 location:'../util/build' 2051 },{ 2052 name:'doh', 2053 location:'../util/doh' 2054 },{ 2055 name:'dojox', 2056 location:'../dojox' 2057 },{ 2058 name:'demos', 2059 location:'../demos' 2060 }], 2061 trace:{ 2062 // these are listed so it's simple to turn them on/off while debugging loading 2063 "loader-inject":0, 2064 "loader-define":0, 2065 "loader-exec-module":0, 2066 "loader-run-factory":0, 2067 "loader-finish-exec":0, 2068 "loader-define-module":0, 2069 "loader-circular-dependency":0, 2070 "loader-define-nonmodule":0 2071 }, 2072 async:0, 2073 waitSeconds:15 2074 } 2075); 2076//>>excludeEnd("replaceLoaderConfig")
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.