]> git.wh0rd.org - tt-rss.git/blob - lib/dojo/dojo.js.uncompressed.js
0d3bb7dcf6a3d8be8943c7e8d0daa69027e54443
[tt-rss.git] / lib / dojo / dojo.js.uncompressed.js
1 /*
2 Copyright (c) 2004-2012, The Dojo Foundation All Rights Reserved.
3 Available via Academic Free License >= 2.1 OR the modified BSD license.
4 see: http://dojotoolkit.org/license for details
5 */
6
7 /*
8 This is an optimized version of Dojo, built for deployment and not for
9 development. To get sources and documentation, please visit:
10
11 http://dojotoolkit.org
12 */
13
14 (function(
15 userConfig,
16 defaultConfig
17 ){
18 // summary:
19 // This is the "source loader" and is the entry point for Dojo during development. You may also load Dojo with
20 // any AMD-compliant loader via the package main module dojo/main.
21 // description:
22 // This is the "source loader" for Dojo. It provides an AMD-compliant loader that can be configured
23 // to operate in either synchronous or asynchronous modes. After the loader is defined, dojo is loaded
24 // IAW the package main module dojo/main. In the event you wish to use a foreign loader, you may load dojo as a package
25 // via the package main module dojo/main and this loader is not required; see dojo/package.json for details.
26 //
27 // In order to keep compatibility with the v1.x line, this loader includes additional machinery that enables
28 // the dojo.provide, dojo.require et al API. This machinery is loaded by default, but may be dynamically removed
29 // via the has.js API and statically removed via the build system.
30 //
31 // This loader includes sniffing machinery to determine the environment; the following environments are supported:
32 //
33 // - browser
34 // - node.js
35 // - rhino
36 //
37 // This is the so-called "source loader". As such, it includes many optional features that may be discadred by
38 // building a customized verion with the build system.
39
40 // Design and Implementation Notes
41 //
42 // This is a dojo-specific adaption of bdLoad, donated to the dojo foundation by Altoviso LLC.
43 //
44 // This function defines an AMD-compliant (http://wiki.commonjs.org/wiki/Modules/AsynchronousDefinition)
45 // loader that can be configured to operate in either synchronous or asynchronous modes.
46 //
47 // Since this machinery implements a loader, it does not have the luxury of using a load system and/or
48 // leveraging a utility library. This results in an unpleasantly long file; here is a road map of the contents:
49 //
50 // 1. Small library for use implementing the loader.
51 // 2. Define the has.js API; this is used throughout the loader to bracket features.
52 // 3. Define the node.js and rhino sniffs and sniff.
53 // 4. Define the loader's data.
54 // 5. Define the configuration machinery.
55 // 6. Define the script element sniffing machinery and sniff for configuration data.
56 // 7. Configure the loader IAW the provided user, default, and sniffing data.
57 // 8. Define the global require function.
58 // 9. Define the module resolution machinery.
59 // 10. Define the module and plugin module definition machinery
60 // 11. Define the script injection machinery.
61 // 12. Define the window load detection.
62 // 13. Define the logging API.
63 // 14. Define the tracing API.
64 // 16. Define the AMD define function.
65 // 17. Define the dojo v1.x provide/require machinery--so called "legacy" modes.
66 // 18. Publish global variables.
67 //
68 // Language and Acronyms and Idioms
69 //
70 // moduleId: a CJS module identifier, (used for public APIs)
71 // mid: moduleId (used internally)
72 // packageId: a package identifier (used for public APIs)
73 // pid: packageId (used internally); the implied system or default package has pid===""
74 // pack: package is used internally to reference a package object (since javascript has reserved words including "package")
75 // prid: plugin resource identifier
76 // The integer constant 1 is used in place of true and 0 in place of false.
77
78 // define a minimal library to help build the loader
79 var noop = function(){
80 },
81
82 isEmpty = function(it){
83 for(var p in it){
84 return 0;
85 }
86 return 1;
87 },
88
89 toString = {}.toString,
90
91 isFunction = function(it){
92 return toString.call(it) == "[object Function]";
93 },
94
95 isString = function(it){
96 return toString.call(it) == "[object String]";
97 },
98
99 isArray = function(it){
100 return toString.call(it) == "[object Array]";
101 },
102
103 forEach = function(vector, callback){
104 if(vector){
105 for(var i = 0; i < vector.length;){
106 callback(vector[i++]);
107 }
108 }
109 },
110
111 mix = function(dest, src){
112 for(var p in src){
113 dest[p] = src[p];
114 }
115 return dest;
116 },
117
118 makeError = function(error, info){
119 return mix(new Error(error), {src:"dojoLoader", info:info});
120 },
121
122 uidSeed = 1,
123
124 uid = function(){
125 // Returns a unique indentifier (within the lifetime of the document) of the form /_d+/.
126 return "_" + uidSeed++;
127 },
128
129 // FIXME: how to doc window.require() api
130
131 // this will be the global require function; define it immediately so we can start hanging things off of it
132 req = function(
133 config, //(object, optional) hash of configuration properties
134 dependencies, //(array of commonjs.moduleId, optional) list of modules to be loaded before applying callback
135 callback //(function, optional) lamda expression to apply to module values implied by dependencies
136 ){
137 return contextRequire(config, dependencies, callback, 0, req);
138 },
139
140 // the loader uses the has.js API to control feature inclusion/exclusion; define then use throughout
141 global = this,
142
143 doc = global.document,
144
145 element = doc && doc.createElement("DiV"),
146
147 has = req.has = function(name){
148 return isFunction(hasCache[name]) ? (hasCache[name] = hasCache[name](global, doc, element)) : hasCache[name];
149 },
150
151 hasCache = has.cache = defaultConfig.hasCache;
152
153 has.add = function(name, test, now, force){
154 (hasCache[name]===undefined || force) && (hasCache[name] = test);
155 return now && has(name);
156 };
157
158 0 && has.add("host-node", userConfig.has && "host-node" in userConfig.has ?
159 userConfig.has["host-node"] :
160 (typeof process == "object" && process.versions && process.versions.node && process.versions.v8));
161 if( 0 ){
162 // fixup the default config for node.js environment
163 require("./_base/configNode.js").config(defaultConfig);
164 // remember node's require (with respect to baseUrl==dojo's root)
165 defaultConfig.loaderPatch.nodeRequire = require;
166 }
167
168 0 && has.add("host-rhino", userConfig.has && "host-rhino" in userConfig.has ?
169 userConfig.has["host-rhino"] :
170 (typeof load == "function" && (typeof Packages == "function" || typeof Packages == "object")));
171 if( 0 ){
172 // owing to rhino's lame feature that hides the source of the script, give the user a way to specify the baseUrl...
173 for(var baseUrl = userConfig.baseUrl || ".", arg, rhinoArgs = this.arguments, i = 0; i < rhinoArgs.length;){
174 arg = (rhinoArgs[i++] + "").split("=");
175 if(arg[0] == "baseUrl"){
176 baseUrl = arg[1];
177 break;
178 }
179 }
180 load(baseUrl + "/_base/configRhino.js");
181 rhinoDojoConfig(defaultConfig, baseUrl, rhinoArgs);
182 }
183
184 // userConfig has tests override defaultConfig has tests; do this after the environment detection because
185 // the environment detection usually sets some has feature values in the hasCache.
186 for(var p in userConfig.has){
187 has.add(p, userConfig.has[p], 0, 1);
188 }
189
190 //
191 // define the loader data
192 //
193
194 // the loader will use these like symbols if the loader has the traceApi; otherwise
195 // define magic numbers so that modules can be provided as part of defaultConfig
196 var requested = 1,
197 arrived = 2,
198 nonmodule = 3,
199 executing = 4,
200 executed = 5;
201
202 if( 0 ){
203 // these make debugging nice; but using strings for symbols is a gross rookie error; don't do it for production code
204 requested = "requested";
205 arrived = "arrived";
206 nonmodule = "not-a-module";
207 executing = "executing";
208 executed = "executed";
209 }
210
211 var legacyMode = 0,
212 sync = "sync",
213 xd = "xd",
214 syncExecStack = [],
215 dojoRequirePlugin = 0,
216 checkDojoRequirePlugin = noop,
217 transformToAmd = noop,
218 getXhr;
219 if( 1 ){
220 req.isXdUrl = noop;
221
222 req.initSyncLoader = function(dojoRequirePlugin_, checkDojoRequirePlugin_, transformToAmd_){
223 // the first dojo/_base/loader loaded gets to define these variables; they are designed to work
224 // in the presense of zero to many mapped dojo/_base/loaders
225 if(!dojoRequirePlugin){
226 dojoRequirePlugin = dojoRequirePlugin_;
227 checkDojoRequirePlugin = checkDojoRequirePlugin_;
228 transformToAmd = transformToAmd_;
229 }
230
231 return {
232 sync:sync,
233 requested:requested,
234 arrived:arrived,
235 nonmodule:nonmodule,
236 executing:executing,
237 executed:executed,
238 syncExecStack:syncExecStack,
239 modules:modules,
240 execQ:execQ,
241 getModule:getModule,
242 injectModule:injectModule,
243 setArrived:setArrived,
244 signal:signal,
245 finishExec:finishExec,
246 execModule:execModule,
247 dojoRequirePlugin:dojoRequirePlugin,
248 getLegacyMode:function(){return legacyMode;},
249 guardCheckComplete:guardCheckComplete
250 };
251 };
252
253 if( 1 ){
254 // in legacy sync mode, the loader needs a minimal XHR library
255
256 var locationProtocol = location.protocol,
257 locationHost = location.host;
258 req.isXdUrl = function(url){
259 if(/^\./.test(url)){
260 // begins with a dot is always relative to page URL; therefore not xdomain
261 return false;
262 }
263 if(/^\/\//.test(url)){
264 // for v1.6- backcompat, url starting with // indicates xdomain
265 return true;
266 }
267 // get protocol and host
268 // \/+ takes care of the typical file protocol that looks like file:///drive/path/to/file
269 // locationHost is falsy if file protocol => if locationProtocol matches and is "file:", || will return false
270 var match = url.match(/^([^\/\:]+\:)\/+([^\/]+)/);
271 return match && (match[1] != locationProtocol || (locationHost && match[2] != locationHost));
272 };
273
274
275 // note: to get the file:// protocol to work in FF, you must set security.fileuri.strict_origin_policy to false in about:config
276 1 || has.add("dojo-xhr-factory", 1);
277 has.add("dojo-force-activex-xhr", 1 && !doc.addEventListener && window.location.protocol == "file:");
278 has.add("native-xhr", typeof XMLHttpRequest != "undefined");
279 if(has("native-xhr") && !has("dojo-force-activex-xhr")){
280 getXhr = function(){
281 return new XMLHttpRequest();
282 };
283 }else{
284 // if in the browser an old IE; find an xhr
285 for(var XMLHTTP_PROGIDS = ['Msxml2.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.4.0'], progid, i = 0; i < 3;){
286 try{
287 progid = XMLHTTP_PROGIDS[i++];
288 if(new ActiveXObject(progid)){
289 // this progid works; therefore, use it from now on
290 break;
291 }
292 }catch(e){
293 // squelch; we're just trying to find a good ActiveX progid
294 // if they all fail, then progid ends up as the last attempt and that will signal the error
295 // the first time the client actually tries to exec an xhr
296 }
297 }
298 getXhr = function(){
299 return new ActiveXObject(progid);
300 };
301 }
302 req.getXhr = getXhr;
303
304 has.add("dojo-gettext-api", 1);
305 req.getText = function(url, async, onLoad){
306 var xhr = getXhr();
307 xhr.open('GET', fixupUrl(url), false);
308 xhr.send(null);
309 if(xhr.status == 200 || (!location.host && !xhr.status)){
310 if(onLoad){
311 onLoad(xhr.responseText, async);
312 }
313 }else{
314 throw makeError("xhrFailed", xhr.status);
315 }
316 return xhr.responseText;
317 };
318 }
319 }else{
320 req.async = 1;
321 }
322
323 //
324 // loader eval
325 //
326 var eval_ =
327 // use the function constructor so our eval is scoped close to (but not in) in the global space with minimal pollution
328 new Function('return eval(arguments[0]);');
329
330 req.eval =
331 function(text, hint){
332 return eval_(text + "\r\n////@ sourceURL=" + hint);
333 };
334
335 //
336 // loader micro events API
337 //
338 var listenerQueues = {},
339 error = "error",
340 signal = req.signal = function(type, args){
341 var queue = listenerQueues[type];
342 // notice we run a copy of the queue; this allows listeners to add/remove
343 // other listeners without affecting this particular signal
344 forEach(queue && queue.slice(0), function(listener){
345 listener.apply(null, isArray(args) ? args : [args]);
346 });
347 },
348 on = req.on = function(type, listener){
349 // notice a queue is not created until a client actually connects
350 var queue = listenerQueues[type] || (listenerQueues[type] = []);
351 queue.push(listener);
352 return {
353 remove:function(){
354 for(var i = 0; i<queue.length; i++){
355 if(queue[i]===listener){
356 queue.splice(i, 1);
357 return;
358 }
359 }
360 }
361 };
362 };
363
364 // configuration machinery; with an optimized/built defaultConfig, all configuration machinery can be discarded
365 // lexical variables hold key loader data structures to help with minification; these may be completely,
366 // one-time initialized by defaultConfig for optimized/built versions
367 var
368 aliases
369 // a vector of pairs of [regexs or string, replacement] => (alias, actual)
370 = [],
371
372 paths
373 // CommonJS paths
374 = {},
375
376 pathsMapProg
377 // list of (from-path, to-path, regex, length) derived from paths;
378 // a "program" to apply paths; see computeMapProg
379 = [],
380
381 packs
382 // a map from packageId to package configuration object; see fixupPackageInfo
383 = {},
384
385 map = req.map
386 // AMD map config variable; dojo/_base/kernel needs req.map to figure out the scope map
387 = {},
388
389 mapProgs
390 // vector of quads as described by computeMapProg; map-key is AMD map key, map-value is AMD map value
391 = [],
392
393 modules
394 // A hash:(mid) --> (module-object) the module namespace
395 //
396 // pid: the package identifier to which the module belongs (e.g., "dojo"); "" indicates the system or default package
397 // mid: the fully-resolved (i.e., mappings have been applied) module identifier without the package identifier (e.g., "dojo/io/script")
398 // url: the URL from which the module was retrieved
399 // pack: the package object of the package to which the module belongs
400 // executed: 0 => not executed; executing => in the process of tranversing deps and running factory; executed => factory has been executed
401 // deps: the dependency vector for this module (vector of modules objects)
402 // def: the factory for this module
403 // result: the result of the running the factory for this module
404 // injected: (0 | requested | arrived) the status of the module; nonmodule means the resource did not call define
405 // load: plugin load function; applicable only for plugins
406 //
407 // Modules go through several phases in creation:
408 //
409 // 1. Requested: some other module's definition or a require application contained the requested module in
410 // its dependency vector or executing code explicitly demands a module via req.require.
411 //
412 // 2. Injected: a script element has been appended to the insert-point element demanding the resource implied by the URL
413 //
414 // 3. Loaded: the resource injected in [2] has been evalated.
415 //
416 // 4. Defined: the resource contained a define statement that advised the loader about the module. Notice that some
417 // resources may just contain a bundle of code and never formally define a module via define
418 //
419 // 5. Evaluated: the module was defined via define and the loader has evaluated the factory and computed a result.
420 = {},
421
422 cacheBust
423 // query string to append to module URLs to bust browser cache
424 = "",
425
426 cache
427 // hash:(mid | url)-->(function | string)
428 //
429 // A cache of resources. The resources arrive via a config.cache object, which is a hash from either mid --> function or
430 // url --> string. The url key is distinguished from the mid key by always containing the prefix "url:". url keys as provided
431 // by config.cache always have a string value that represents the contents of the resource at the given url. mid keys as provided
432 // by configl.cache always have a function value that causes the same code to execute as if the module was script injected.
433 //
434 // Both kinds of key-value pairs are entered into cache via the function consumePendingCache, which may relocate keys as given
435 // by any mappings *iff* the config.cache was received as part of a module resource request.
436 //
437 // Further, for mid keys, the implied url is computed and the value is entered into that key as well. This allows mapped modules
438 // to retrieve cached items that may have arrived consequent to another namespace.
439 //
440 = {},
441
442 urlKeyPrefix
443 // the prefix to prepend to a URL key in the cache.
444 = "url:",
445
446 pendingCacheInsert
447 // hash:(mid)-->(function)
448 //
449 // Gives a set of cache modules pending entry into cache. When cached modules are published to the loader, they are
450 // entered into pendingCacheInsert; modules are then pressed into cache upon (1) AMD define or (2) upon receiving another
451 // independent set of cached modules. (1) is the usual case, and this case allows normalizing mids given in the pending
452 // cache for the local configuration, possibly relocating modules.
453 = {},
454
455 dojoSniffConfig
456 // map of configuration variables
457 // give the data-dojo-config as sniffed from the document (if any)
458 = {};
459
460 if( 1 ){
461 var consumePendingCacheInsert = function(referenceModule){
462 var p, item, match, now, m;
463 for(p in pendingCacheInsert){
464 item = pendingCacheInsert[p];
465 match = p.match(/^url\:(.+)/);
466 if(match){
467 cache[urlKeyPrefix + toUrl(match[1], referenceModule)] = item;
468 }else if(p=="*now"){
469 now = item;
470 }else if(p!="*noref"){
471 m = getModuleInfo(p, referenceModule);
472 cache[m.mid] = cache[urlKeyPrefix + m.url] = item;
473 }
474 }
475 if(now){
476 now(createRequire(referenceModule));
477 }
478 pendingCacheInsert = {};
479 },
480
481 escapeString = function(s){
482 return s.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, function(c){ return "\\" + c; });
483 },
484
485 computeMapProg = function(map, dest){
486 // This routine takes a map as represented by a JavaScript object and initializes dest, a vector of
487 // quads of (map-key, map-value, refex-for-map-key, length-of-map-key), sorted decreasing by length-
488 // of-map-key. The regex looks for the map-key followed by either "/" or end-of-string at the beginning
489 // of a the search source. Notice the map-value is irrelevent to the algorithm
490 dest.splice(0, dest.length);
491 for(var p in map){
492 dest.push([
493 p,
494 map[p],
495 new RegExp("^" + escapeString(p) + "(\/|$)"),
496 p.length]);
497 }
498 dest.sort(function(lhs, rhs){ return rhs[3] - lhs[3]; });
499 return dest;
500 },
501
502 fixupPackageInfo = function(packageInfo){
503 // calculate the precise (name, location, main, mappings) for a package
504 var name = packageInfo.name;
505 if(!name){
506 // packageInfo must be a string that gives the name
507 name = packageInfo;
508 packageInfo = {name:name};
509 }
510 packageInfo = mix({main:"main"}, packageInfo);
511 packageInfo.location = packageInfo.location ? packageInfo.location : name;
512
513 // packageMap is depricated in favor of AMD map
514 if(packageInfo.packageMap){
515 map[name] = packageInfo.packageMap;
516 }
517
518 if(!packageInfo.main.indexOf("./")){
519 packageInfo.main = packageInfo.main.substring(2);
520 }
521
522 // now that we've got a fully-resolved package object, push it into the configuration
523 packs[name] = packageInfo;
524 },
525
526 delayedModuleConfig
527 // module config cannot be consummed until the loader is completely initialized; therefore, all
528 // module config detected during booting is memorized and applied at the end of loader initialization
529 // TODO: this is a bit of a kludge; all config should be moved to end of loader initialization, but
530 // we'll delay this chore and do it with a final loader 1.x cleanup after the 2.x loader prototyping is complete
531 = [],
532
533
534 config = function(config, booting, referenceModule){
535 for(var p in config){
536 if(p=="waitSeconds"){
537 req.waitms = (config[p] || 0) * 1000;
538 }
539 if(p=="cacheBust"){
540 cacheBust = config[p] ? (isString(config[p]) ? config[p] : (new Date()).getTime() + "") : "";
541 }
542 if(p=="baseUrl" || p=="combo"){
543 req[p] = config[p];
544 }
545 if( 1 && p=="async"){
546 // falsy or "sync" => legacy sync loader
547 // "xd" => sync but loading xdomain tree and therefore loading asynchronously (not configurable, set automatically by the loader)
548 // "legacyAsync" => permanently in "xd" by choice
549 // "debugAtAllCosts" => trying to load everything via script injection (not implemented)
550 // otherwise, must be truthy => AMD
551 // legacyMode: sync | legacyAsync | xd | false
552 var mode = config[p];
553 req.legacyMode = legacyMode = (isString(mode) && /sync|legacyAsync/.test(mode) ? mode : (!mode ? sync : false));
554 req.async = !legacyMode;
555 }
556 if(config[p]!==hasCache){
557 // accumulate raw config info for client apps which can use this to pass their own config
558 req.rawConfig[p] = config[p];
559 p!="has" && has.add("config-"+p, config[p], 0, booting);
560 }
561 }
562
563 // make sure baseUrl exists
564 if(!req.baseUrl){
565 req.baseUrl = "./";
566 }
567 // make sure baseUrl ends with a slash
568 if(!/\/$/.test(req.baseUrl)){
569 req.baseUrl += "/";
570 }
571
572 // now do the special work for has, packages, packagePaths, paths, aliases, and cache
573
574 for(p in config.has){
575 has.add(p, config.has[p], 0, booting);
576 }
577
578 // for each package found in any packages config item, augment the packs map owned by the loader
579 forEach(config.packages, fixupPackageInfo);
580
581 // for each packagePath found in any packagePaths config item, augment the packageConfig
582 // packagePaths is depricated; remove in 2.0
583 for(baseUrl in config.packagePaths){
584 forEach(config.packagePaths[baseUrl], function(packageInfo){
585 var location = baseUrl + "/" + packageInfo;
586 if(isString(packageInfo)){
587 packageInfo = {name:packageInfo};
588 }
589 packageInfo.location = location;
590 fixupPackageInfo(packageInfo);
591 });
592 }
593
594 // notice that computeMapProg treats the dest as a reference; therefore, if/when that variable
595 // is published (see dojo-publish-privates), the published variable will always hold a valid value.
596
597 // this must come after all package processing since package processing may mutate map
598 computeMapProg(mix(map, config.map), mapProgs);
599 forEach(mapProgs, function(item){
600 item[1] = computeMapProg(item[1], []);
601 if(item[0]=="*"){
602 mapProgs.star = item;
603 }
604 });
605
606 // push in any paths and recompute the internal pathmap
607 computeMapProg(mix(paths, config.paths), pathsMapProg);
608
609 // aliases
610 forEach(config.aliases, function(pair){
611 if(isString(pair[0])){
612 pair[0] = new RegExp("^" + escapeString(pair[0]) + "$");
613 }
614 aliases.push(pair);
615 });
616
617 if(booting){
618 delayedModuleConfig.push({config:config.config});
619 }else{
620 for(p in config.config){
621 var module = getModule(p, referenceModule);
622 module.config = mix(module.config || {}, config.config[p]);
623 }
624 }
625
626 // push in any new cache values
627 if(config.cache){
628 consumePendingCacheInsert();
629 pendingCacheInsert = config.cache;
630 if(config.cache["*noref"]){
631 consumePendingCacheInsert();
632 }
633 }
634
635 signal("config", [config, req.rawConfig]);
636 };
637
638 //
639 // execute the various sniffs; userConfig can override and value
640 //
641
642 if(has("dojo-cdn") || 1 ){
643 // the sniff regex looks for a src attribute ending in dojo.js, optionally preceeded with a path.
644 // match[3] returns the path to dojo.js (if any) without the trailing slash. This is used for the
645 // dojo location on CDN deployments and baseUrl when either/both of these are not provided
646 // explicitly in the config data; this is the 1.6- behavior.
647
648 var scripts = doc.getElementsByTagName("script"),
649 i = 0,
650 script, dojoDir, src, match;
651 while(i < scripts.length){
652 script = scripts[i++];
653 if((src = script.getAttribute("src")) && (match = src.match(/(((.*)\/)|^)dojo\.js(\W|$)/i))){
654 // sniff dojoDir and baseUrl
655 dojoDir = match[3] || "";
656 defaultConfig.baseUrl = defaultConfig.baseUrl || dojoDir;
657
658 // sniff configuration on attribute in script element
659 src = (script.getAttribute("data-dojo-config") || script.getAttribute("djConfig"));
660 if(src){
661 dojoSniffConfig = req.eval("({ " + src + " })", "data-dojo-config");
662 }
663
664 // sniff requirejs attribute
665 if( 0 ){
666 var dataMain = script.getAttribute("data-main");
667 if(dataMain){
668 dojoSniffConfig.deps = dojoSniffConfig.deps || [dataMain];
669 }
670 }
671 break;
672 }
673 }
674 }
675
676 if( 0 ){
677 // pass down doh.testConfig from parent as if it were a data-dojo-config
678 try{
679 if(window.parent != window && window.parent.require){
680 var doh = window.parent.require("doh");
681 doh && mix(dojoSniffConfig, doh.testConfig);
682 }
683 }catch(e){}
684 }
685
686 // configure the loader; let the user override defaults
687 req.rawConfig = {};
688 config(defaultConfig, 1);
689
690 // do this before setting userConfig/sniffConfig to allow userConfig/sniff overrides
691 if(has("dojo-cdn")){
692 packs.dojo.location = dojoDir;
693 if(dojoDir){
694 dojoDir += "/";
695 }
696 packs.dijit.location = dojoDir + "../dijit/";
697 packs.dojox.location = dojoDir + "../dojox/";
698 }
699
700 config(userConfig, 1);
701 config(dojoSniffConfig, 1);
702
703 }else{
704 // no config API, assume defaultConfig has everything the loader needs...for the entire lifetime of the application
705 paths = defaultConfig.paths;
706 pathsMapProg = defaultConfig.pathsMapProg;
707 packs = defaultConfig.packs;
708 aliases = defaultConfig.aliases;
709 mapProgs = defaultConfig.mapProgs;
710 modules = defaultConfig.modules;
711 cache = defaultConfig.cache;
712 cacheBust = defaultConfig.cacheBust;
713
714 // remember the default config for other processes (e.g., dojo/config)
715 req.rawConfig = defaultConfig;
716 }
717
718
719 if( 0 ){
720 req.combo = req.combo || {add:noop};
721 var comboPending = 0,
722 combosPending = [],
723 comboPendingTimer = null;
724 }
725
726
727 // build the loader machinery iaw configuration, including has feature tests
728 var injectDependencies = function(module){
729 // checkComplete!=0 holds the idle signal; we're not idle if we're injecting dependencies
730 guardCheckComplete(function(){
731 forEach(module.deps, injectModule);
732 if( 0 && comboPending && !comboPendingTimer){
733 comboPendingTimer = setTimeout(function() {
734 comboPending = 0;
735 comboPendingTimer = null;
736 req.combo.done(function(mids, url) {
737 var onLoadCallback= function(){
738 // defQ is a vector of module definitions 1-to-1, onto mids
739 runDefQ(0, mids);
740 checkComplete();
741 };
742 combosPending.push(mids);
743 injectingModule = mids;
744 req.injectUrl(url, onLoadCallback, mids);
745 injectingModule = 0;
746 }, req);
747 }, 0);
748 }
749 });
750 },
751
752 contextRequire = function(a1, a2, a3, referenceModule, contextRequire){
753 var module, syntheticMid;
754 if(isString(a1)){
755 // signature is (moduleId)
756 module = getModule(a1, referenceModule, true);
757 if(module && module.executed){
758 return module.result;
759 }
760 throw makeError("undefinedModule", a1);
761 }
762 if(!isArray(a1)){
763 // a1 is a configuration
764 config(a1, 0, referenceModule);
765
766 // juggle args; (a2, a3) may be (dependencies, callback)
767 a1 = a2;
768 a2 = a3;
769 }
770 if(isArray(a1)){
771 // signature is (requestList [,callback])
772 if(!a1.length){
773 a2 && a2();
774 }else{
775 syntheticMid = "require*" + uid();
776
777 // resolve the request list with respect to the reference module
778 for(var mid, deps = [], i = 0; i < a1.length;){
779 mid = a1[i++];
780 deps.push(getModule(mid, referenceModule));
781 }
782
783 // construct a synthetic module to control execution of the requestList, and, optionally, callback
784 module = mix(makeModuleInfo("", syntheticMid, 0, ""), {
785 injected: arrived,
786 deps: deps,
787 def: a2 || noop,
788 require: referenceModule ? referenceModule.require : req,
789 gc: 1 //garbage collect
790 });
791 modules[module.mid] = module;
792
793 // checkComplete!=0 holds the idle signal; we're not idle if we're injecting dependencies
794 injectDependencies(module);
795
796 // try to immediately execute
797 // if already traversing a factory tree, then strict causes circular dependency to abort the execution; maybe
798 // it's possible to execute this require later after the current traversal completes and avoid the circular dependency.
799 // ...but *always* insist on immediate in synch mode
800 var strict = checkCompleteGuard && legacyMode!=sync;
801 guardCheckComplete(function(){
802 execModule(module, strict);
803 });
804 if(!module.executed){
805 // some deps weren't on board or circular dependency detected and strict; therefore, push into the execQ
806 execQ.push(module);
807 }
808 checkComplete();
809 }
810 }
811 return contextRequire;
812 },
813
814 createRequire = function(module){
815 if(!module){
816 return req;
817 }
818 var result = module.require;
819 if(!result){
820 result = function(a1, a2, a3){
821 return contextRequire(a1, a2, a3, module, result);
822 };
823 module.require = mix(result, req);
824 result.module = module;
825 result.toUrl = function(name){
826 return toUrl(name, module);
827 };
828 result.toAbsMid = function(mid){
829 return toAbsMid(mid, module);
830 };
831 if( 0 ){
832 result.undef = function(mid){
833 req.undef(mid, module);
834 };
835 }
836 if( 1 ){
837 result.syncLoadNls = function(mid){
838 var nlsModuleInfo = getModuleInfo(mid, module),
839 nlsModule = modules[nlsModuleInfo.mid];
840 if(!nlsModule || !nlsModule.executed){
841 cached = cache[nlsModuleInfo.mid] || cache[urlKeyPrefix + nlsModuleInfo.url];
842 if(cached){
843 evalModuleText(cached);
844 nlsModule = modules[nlsModuleInfo.mid];
845 }
846 }
847 return nlsModule && nlsModule.executed && nlsModule.result;
848 };
849 }
850
851 }
852 return result;
853 },
854
855 execQ =
856 // The list of modules that need to be evaluated.
857 [],
858
859 defQ =
860 // The queue of define arguments sent to loader.
861 [],
862
863 waiting =
864 // The set of modules upon which the loader is waiting for definition to arrive
865 {},
866
867 setRequested = function(module){
868 module.injected = requested;
869 waiting[module.mid] = 1;
870 if(module.url){
871 waiting[module.url] = module.pack || 1;
872 }
873 startTimer();
874 },
875
876 setArrived = function(module){
877 module.injected = arrived;
878 delete waiting[module.mid];
879 if(module.url){
880 delete waiting[module.url];
881 }
882 if(isEmpty(waiting)){
883 clearTimer();
884 1 && legacyMode==xd && (legacyMode = sync);
885 }
886 },
887
888 execComplete = req.idle =
889 // says the loader has completed (or not) its work
890 function(){
891 return !defQ.length && isEmpty(waiting) && !execQ.length && !checkCompleteGuard;
892 },
893
894 runMapProg = function(targetMid, map){
895 // search for targetMid in map; return the map item if found; falsy otherwise
896 if(map){
897 for(var i = 0; i < map.length; i++){
898 if(map[i][2].test(targetMid)){
899 return map[i];
900 }
901 }
902 }
903 return 0;
904 },
905
906 compactPath = function(path){
907 var result = [],
908 segment, lastSegment;
909 path = path.replace(/\\/g, '/').split('/');
910 while(path.length){
911 segment = path.shift();
912 if(segment==".." && result.length && lastSegment!=".."){
913 result.pop();
914 lastSegment = result[result.length - 1];
915 }else if(segment!="."){
916 result.push(lastSegment= segment);
917 } // else ignore "."
918 }
919 return result.join("/");
920 },
921
922 makeModuleInfo = function(pid, mid, pack, url){
923 if( 1 ){
924 var xd= req.isXdUrl(url);
925 return {pid:pid, mid:mid, pack:pack, url:url, executed:0, def:0, isXd:xd, isAmd:!!(xd || (packs[pid] && packs[pid].isAmd))};
926 }else{
927 return {pid:pid, mid:mid, pack:pack, url:url, executed:0, def:0};
928 }
929 },
930
931 getModuleInfo_ = function(mid, referenceModule, packs, modules, baseUrl, mapProgs, pathsMapProg, alwaysCreate){
932 // arguments are passed instead of using lexical variables so that this function my be used independent of the loader (e.g., the builder)
933 // alwaysCreate is useful in this case so that getModuleInfo never returns references to real modules owned by the loader
934 var pid, pack, midInPackage, mapProg, mapItem, url, result, isRelative, requestedMid;
935 requestedMid = mid;
936 isRelative = /^\./.test(mid);
937 if(/(^\/)|(\:)|(\.js$)/.test(mid) || (isRelative && !referenceModule)){
938 // absolute path or protocol of .js filetype, or relative path but no reference module and therefore relative to page
939 // whatever it is, it's not a module but just a URL of some sort
940 // note: pid===0 indicates the routine is returning an unmodified mid
941
942 return makeModuleInfo(0, mid, 0, mid);
943 }else{
944 // relative module ids are relative to the referenceModule; get rid of any dots
945 mid = compactPath(isRelative ? (referenceModule.mid + "/../" + mid) : mid);
946 if(/^\./.test(mid)){
947 throw makeError("irrationalPath", mid);
948 }
949 // at this point, mid is an absolute mid
950
951 // map the mid
952 if(referenceModule){
953 mapItem = runMapProg(referenceModule.mid, mapProgs);
954 }
955 mapItem = mapItem || mapProgs.star;
956 mapItem = mapItem && runMapProg(mid, mapItem[1]);
957
958 if(mapItem){
959 mid = mapItem[1] + mid.substring(mapItem[3]);
960 }
961
962 match = mid.match(/^([^\/]+)(\/(.+))?$/);
963 pid = match ? match[1] : "";
964 if((pack = packs[pid])){
965 mid = pid + "/" + (midInPackage = (match[3] || pack.main));
966 }else{
967 pid = "";
968 }
969
970 // search aliases
971 var candidateLength = 0,
972 candidate = 0;
973 forEach(aliases, function(pair){
974 var match = mid.match(pair[0]);
975 if(match && match.length>candidateLength){
976 candidate = isFunction(pair[1]) ? mid.replace(pair[0], pair[1]) : pair[1];
977 }
978 });
979 if(candidate){
980 return getModuleInfo_(candidate, 0, packs, modules, baseUrl, mapProgs, pathsMapProg, alwaysCreate);
981 }
982
983 result = modules[mid];
984 if(result){
985 return alwaysCreate ? makeModuleInfo(result.pid, result.mid, result.pack, result.url) : modules[mid];
986 }
987 }
988 // get here iff the sought-after module does not yet exist; therefore, we need to compute the URL given the
989 // fully resolved (i.e., all relative indicators and package mapping resolved) module id
990
991 // note: pid!==0 indicates the routine is returning a url that has .js appended unmodified mid
992 mapItem = runMapProg(mid, pathsMapProg);
993 if(mapItem){
994 url = mapItem[1] + mid.substring(mapItem[3]);
995 }else if(pid){
996 url = pack.location + "/" + midInPackage;
997 }else if(has("config-tlmSiblingOfDojo")){
998 url = "../" + mid;
999 }else{
1000 url = mid;
1001 }
1002 // if result is not absolute, add baseUrl
1003 if(!(/(^\/)|(\:)/.test(url))){
1004 url = baseUrl + url;
1005 }
1006 url += ".js";
1007 return makeModuleInfo(pid, mid, pack, compactPath(url));
1008 },
1009
1010 getModuleInfo = function(mid, referenceModule){
1011 return getModuleInfo_(mid, referenceModule, packs, modules, req.baseUrl, mapProgs, pathsMapProg);
1012 },
1013
1014 resolvePluginResourceId = function(plugin, prid, referenceModule){
1015 return plugin.normalize ? plugin.normalize(prid, function(mid){return toAbsMid(mid, referenceModule);}) : toAbsMid(prid, referenceModule);
1016 },
1017
1018 dynamicPluginUidGenerator = 0,
1019
1020 getModule = function(mid, referenceModule, immediate){
1021 // compute and optionally construct (if necessary) the module implied by the mid with respect to referenceModule
1022 var match, plugin, prid, result;
1023 match = mid.match(/^(.+?)\!(.*)$/);
1024 if(match){
1025 // name was <plugin-module>!<plugin-resource-id>
1026 plugin = getModule(match[1], referenceModule, immediate);
1027
1028 if( 1 && legacyMode == sync && !plugin.executed){
1029 injectModule(plugin);
1030 if(plugin.injected===arrived && !plugin.executed){
1031 guardCheckComplete(function(){
1032 execModule(plugin);
1033 });
1034 }
1035 if(plugin.executed){
1036 promoteModuleToPlugin(plugin);
1037 }else{
1038 // we are in xdomain mode for some reason
1039 execQ.unshift(plugin);
1040 }
1041 }
1042
1043
1044
1045 if(plugin.executed === executed && !plugin.load){
1046 // executed the module not knowing it was a plugin
1047 promoteModuleToPlugin(plugin);
1048 }
1049
1050 // 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
1051 if(plugin.load){
1052 prid = resolvePluginResourceId(plugin, match[2], referenceModule);
1053 mid = (plugin.mid + "!" + (plugin.dynamic ? ++dynamicPluginUidGenerator + "!" : "") + prid);
1054 }else{
1055 prid = match[2];
1056 mid = plugin.mid + "!" + (++dynamicPluginUidGenerator) + "!waitingForPlugin";
1057 }
1058 result = {plugin:plugin, mid:mid, req:createRequire(referenceModule), prid:prid};
1059 }else{
1060 result = getModuleInfo(mid, referenceModule);
1061 }
1062 return modules[result.mid] || (!immediate && (modules[result.mid] = result));
1063 },
1064
1065 toAbsMid = req.toAbsMid = function(mid, referenceModule){
1066 return getModuleInfo(mid, referenceModule).mid;
1067 },
1068
1069 toUrl = req.toUrl = function(name, referenceModule){
1070 var moduleInfo = getModuleInfo(name+"/x", referenceModule),
1071 url= moduleInfo.url;
1072 return fixupUrl(moduleInfo.pid===0 ?
1073 // if pid===0, then name had a protocol or absolute path; either way, toUrl is the identify function in such cases
1074 name :
1075 // "/x.js" since getModuleInfo automatically appends ".js" and we appended "/x" to make name look likde a module id
1076 url.substring(0, url.length-5)
1077 );
1078 },
1079
1080 nonModuleProps = {
1081 injected: arrived,
1082 executed: executed,
1083 def: nonmodule,
1084 result: nonmodule
1085 },
1086
1087 makeCjs = function(mid){
1088 return modules[mid] = mix({mid:mid}, nonModuleProps);
1089 },
1090
1091 cjsRequireModule = makeCjs("require"),
1092 cjsExportsModule = makeCjs("exports"),
1093 cjsModuleModule = makeCjs("module"),
1094
1095 runFactory = function(module, args){
1096 req.trace("loader-run-factory", [module.mid]);
1097 var factory = module.def,
1098 result;
1099 1 && syncExecStack.unshift(module);
1100 if(has("config-dojo-loader-catches")){
1101 try{
1102 result= isFunction(factory) ? factory.apply(null, args) : factory;
1103 }catch(e){
1104 signal(error, module.result = makeError("factoryThrew", [module, e]));
1105 }
1106 }else{
1107 result= isFunction(factory) ? factory.apply(null, args) : factory;
1108 }
1109 module.result = result===undefined && module.cjs ? module.cjs.exports : result;
1110 1 && syncExecStack.shift(module);
1111 },
1112
1113 abortExec = {},
1114
1115 defOrder = 0,
1116
1117 promoteModuleToPlugin = function(pluginModule){
1118 var plugin = pluginModule.result;
1119 pluginModule.dynamic = plugin.dynamic;
1120 pluginModule.normalize = plugin.normalize;
1121 pluginModule.load = plugin.load;
1122 return pluginModule;
1123 },
1124
1125 resolvePluginLoadQ = function(plugin){
1126 // plugins is a newly executed module that has a loadQ waiting to run
1127
1128 // step 1: traverse the loadQ and fixup the mid and prid; remember the map from original mid to new mid
1129 // recall the original mid was created before the plugin was on board and therefore it was impossible to
1130 // compute the final mid; accordingly, prid may or may not change, but the mid will definitely change
1131 var map = {};
1132 forEach(plugin.loadQ, function(pseudoPluginResource){
1133 // manufacture and insert the real module in modules
1134 var prid = resolvePluginResourceId(plugin, pseudoPluginResource.prid, pseudoPluginResource.req.module),
1135 mid = plugin.dynamic ? pseudoPluginResource.mid.replace(/waitingForPlugin$/, prid) : (plugin.mid + "!" + prid),
1136 pluginResource = mix(mix({}, pseudoPluginResource), {mid:mid, prid:prid, injected:0});
1137 if(!modules[mid]){
1138 // create a new (the real) plugin resource and inject it normally now that the plugin is on board
1139 injectPlugin(modules[mid] = pluginResource);
1140 } // else this was a duplicate request for the same (plugin, rid) for a nondynamic plugin
1141
1142 // pluginResource is really just a placeholder with the wrong mid (because we couldn't calculate it until the plugin was on board)
1143 // mark is as arrived and delete it from modules; the real module was requested above
1144 map[pseudoPluginResource.mid] = modules[mid];
1145 setArrived(pseudoPluginResource);
1146 delete modules[pseudoPluginResource.mid];
1147 });
1148 plugin.loadQ = 0;
1149
1150 // step2: replace all references to any placeholder modules with real modules
1151 var substituteModules = function(module){
1152 for(var replacement, deps = module.deps || [], i = 0; i<deps.length; i++){
1153 replacement = map[deps[i].mid];
1154 if(replacement){
1155 deps[i] = replacement;
1156 }
1157 }
1158 };
1159 for(var p in modules){
1160 substituteModules(modules[p]);
1161 }
1162 forEach(execQ, substituteModules);
1163 },
1164
1165 finishExec = function(module){
1166 req.trace("loader-finish-exec", [module.mid]);
1167 module.executed = executed;
1168 module.defOrder = defOrder++;
1169 1 && forEach(module.provides, function(cb){ cb(); });
1170 if(module.loadQ){
1171 // the module was a plugin
1172 promoteModuleToPlugin(module);
1173 resolvePluginLoadQ(module);
1174 }
1175 // remove all occurences of this module from the execQ
1176 for(i = 0; i < execQ.length;){
1177 if(execQ[i] === module){
1178 execQ.splice(i, 1);
1179 }else{
1180 i++;
1181 }
1182 }
1183 // delete references to synthetic modules
1184 if (/^require\*/.test(module.mid)) {
1185 delete modules[module.mid];
1186 }
1187 },
1188
1189 circleTrace = [],
1190
1191 execModule = function(module, strict){
1192 // run the dependency vector, then run the factory for module
1193 if(module.executed === executing){
1194 req.trace("loader-circular-dependency", [circleTrace.concat(module.mid).join("->")]);
1195 return (!module.def || strict) ? abortExec : (module.cjs && module.cjs.exports);
1196 }
1197 // at this point the module is either not executed or fully executed
1198
1199
1200 if(!module.executed){
1201 if(!module.def){
1202 return abortExec;
1203 }
1204 var mid = module.mid,
1205 deps = module.deps || [],
1206 arg, argResult,
1207 args = [],
1208 i = 0;
1209
1210 if( 0 ){
1211 circleTrace.push(mid);
1212 req.trace("loader-exec-module", ["exec", circleTrace.length, mid]);
1213 }
1214
1215 // for circular dependencies, assume the first module encountered was executed OK
1216 // modules that circularly depend on a module that has not run its factory will get
1217 // the premade cjs.exports===module.result. They can take a reference to this object and/or
1218 // add properties to it. When the module finally runs its factory, the factory can
1219 // read/write/replace this object. Notice that so long as the object isn't replaced, any
1220 // reference taken earlier while walking the deps list is still valid.
1221 module.executed = executing;
1222 while(i < deps.length){
1223 arg = deps[i++];
1224 argResult = ((arg === cjsRequireModule) ? createRequire(module) :
1225 ((arg === cjsExportsModule) ? module.cjs.exports :
1226 ((arg === cjsModuleModule) ? module.cjs :
1227 execModule(arg, strict))));
1228 if(argResult === abortExec){
1229 module.executed = 0;
1230 req.trace("loader-exec-module", ["abort", mid]);
1231 0 && circleTrace.pop();
1232 return abortExec;
1233 }
1234 args.push(argResult);
1235 }
1236 runFactory(module, args);
1237 finishExec(module);
1238 0 && circleTrace.pop();
1239 }
1240 // at this point the module is guaranteed fully executed
1241
1242 return module.result;
1243 },
1244
1245
1246 checkCompleteGuard = 0,
1247
1248 guardCheckComplete = function(proc){
1249 try{
1250 checkCompleteGuard++;
1251 proc();
1252 }finally{
1253 checkCompleteGuard--;
1254 }
1255 if(execComplete()){
1256 signal("idle", []);
1257 }
1258 },
1259
1260 checkComplete = function(){
1261 // keep going through the execQ as long as at least one factory is executed
1262 // plugins, recursion, cached modules all make for many execution path possibilities
1263 if(checkCompleteGuard){
1264 return;
1265 }
1266 guardCheckComplete(function(){
1267 checkDojoRequirePlugin();
1268 for(var currentDefOrder, module, i = 0; i < execQ.length;){
1269 currentDefOrder = defOrder;
1270 module = execQ[i];
1271 execModule(module);
1272 if(currentDefOrder!=defOrder){
1273 // defOrder was bumped one or more times indicating something was executed (note, this indicates
1274 // the execQ was modified, maybe a lot (for example a later module causes an earlier module to execute)
1275 checkDojoRequirePlugin();
1276 i = 0;
1277 }else{
1278 // nothing happened; check the next module in the exec queue
1279 i++;
1280 }
1281 }
1282 });
1283 };
1284
1285
1286 if( 0 ){
1287 req.undef = function(moduleId, referenceModule){
1288 // In order to reload a module, it must be undefined (this routine) and then re-requested.
1289 // This is useful for testing frameworks (at least).
1290 var module = getModule(moduleId, referenceModule);
1291 setArrived(module);
1292 delete modules[module.mid];
1293 };
1294 }
1295
1296 if( 1 ){
1297 if(has("dojo-loader-eval-hint-url")===undefined){
1298 has.add("dojo-loader-eval-hint-url", 1);
1299 }
1300
1301 var fixupUrl= function(url){
1302 url += ""; // make sure url is a Javascript string (some paths may be a Java string)
1303 return url + (cacheBust ? ((/\?/.test(url) ? "&" : "?") + cacheBust) : "");
1304 },
1305
1306 injectPlugin = function(
1307 module
1308 ){
1309 // injects the plugin module given by module; may have to inject the plugin itself
1310 var plugin = module.plugin;
1311
1312 if(plugin.executed === executed && !plugin.load){
1313 // executed the module not knowing it was a plugin
1314 promoteModuleToPlugin(plugin);
1315 }
1316
1317 var onLoad = function(def){
1318 module.result = def;
1319 setArrived(module);
1320 finishExec(module);
1321 checkComplete();
1322 };
1323
1324 if(plugin.load){
1325 plugin.load(module.prid, module.req, onLoad);
1326 }else if(plugin.loadQ){
1327 plugin.loadQ.push(module);
1328 }else{
1329 // the unshift instead of push is important: we don't want plugins to execute as
1330 // dependencies of some other module because this may cause circles when the plugin
1331 // loadQ is run; also, generally, we want plugins to run early since they may load
1332 // several other modules and therefore can potentially unblock many modules
1333 plugin.loadQ = [module];
1334 execQ.unshift(plugin);
1335 injectModule(plugin);
1336 }
1337 },
1338
1339 // for IE, injecting a module may result in a recursive execution if the module is in the cache
1340
1341 cached = 0,
1342
1343 injectingModule = 0,
1344
1345 injectingCachedModule = 0,
1346
1347 evalModuleText = function(text, module){
1348 // see def() for the injectingCachedModule bracket; it simply causes a short, safe curcuit
1349 if(has("config-stripStrict")){
1350 text = text.replace(/"use strict"/g, '');
1351 }
1352 injectingCachedModule = 1;
1353 if(has("config-dojo-loader-catches")){
1354 try{
1355 if(text===cached){
1356 cached.call(null);
1357 }else{
1358 req.eval(text, has("dojo-loader-eval-hint-url") ? module.url : module.mid);
1359 }
1360 }catch(e){
1361 signal(error, makeError("evalModuleThrew", module));
1362 }
1363 }else{
1364 if(text===cached){
1365 cached.call(null);
1366 }else{
1367 req.eval(text, has("dojo-loader-eval-hint-url") ? module.url : module.mid);
1368 }
1369 }
1370 injectingCachedModule = 0;
1371 },
1372
1373 injectModule = function(module){
1374 // Inject the module. In the browser environment, this means appending a script element into
1375 // the document; in other environments, it means loading a file.
1376 //
1377 // If in synchronous mode, then get the module synchronously if it's not xdomainLoading.
1378
1379 var mid = module.mid,
1380 url = module.url;
1381 if(module.executed || module.injected || waiting[mid] || (module.url && ((module.pack && waiting[module.url]===module.pack) || waiting[module.url]==1))){
1382 return;
1383 }
1384 setRequested(module);
1385
1386 if( 0 ){
1387 var viaCombo = 0;
1388 if(module.plugin && module.plugin.isCombo){
1389 // a combo plugin; therefore, must be handled by combo service
1390 // the prid should have already been converted to a URL (if required by the plugin) during
1391 // the normalze process; in any event, there is no way for the loader to know how to
1392 // to the conversion; therefore the third argument is zero
1393 req.combo.add(module.plugin.mid, module.prid, 0, req);
1394 viaCombo = 1;
1395 }else if(!module.plugin){
1396 viaCombo = req.combo.add(0, module.mid, module.url, req);
1397 }
1398 if(viaCombo){
1399 comboPending= 1;
1400 return;
1401 }
1402 }
1403
1404 if(module.plugin){
1405 injectPlugin(module);
1406 return;
1407 } // else a normal module (not a plugin)
1408
1409
1410 var onLoadCallback = function(){
1411 runDefQ(module);
1412 if(module.injected !== arrived){
1413 // the script that contained the module arrived and has been executed yet
1414 // nothing was added to the defQ (so it wasn't an AMD module) and the module
1415 // wasn't marked as arrived by dojo.provide (so it wasn't a v1.6- module);
1416 // therefore, it must not have been a module; adjust state accordingly
1417 setArrived(module);
1418 mix(module, nonModuleProps);
1419 req.trace("loader-define-nonmodule", [module.url]);
1420 }
1421
1422 if( 1 && legacyMode){
1423 // must call checkComplete even in for sync loader because we may be in xdomainLoading mode;
1424 // but, if xd loading, then don't call checkComplete until out of the current sync traversal
1425 // in order to preserve order of execution of the dojo.required modules
1426 !syncExecStack.length && checkComplete();
1427 }else{
1428 checkComplete();
1429 }
1430 };
1431 cached = cache[mid] || cache[urlKeyPrefix + module.url];
1432 if(cached){
1433 req.trace("loader-inject", ["cache", module.mid, url]);
1434 evalModuleText(cached, module);
1435 onLoadCallback();
1436 return;
1437 }
1438 if( 1 && legacyMode){
1439 if(module.isXd){
1440 // switch to async mode temporarily; if current legacyMode!=sync, then is must be one of {legacyAsync, xd, false}
1441 legacyMode==sync && (legacyMode = xd);
1442 // fall through and load via script injection
1443 }else if(module.isAmd && legacyMode!=sync){
1444 // fall through and load via script injection
1445 }else{
1446 // mode may be sync, xd/legacyAsync, or async; module may be AMD or legacy; but module is always located on the same domain
1447 var xhrCallback = function(text){
1448 if(legacyMode==sync){
1449 // the top of syncExecStack gives the current synchronously executing module; the loader needs
1450 // to know this if it has to switch to async loading in the middle of evaluating a legacy module
1451 // this happens when a modules dojo.require's a module that must be loaded async because it's xdomain
1452 // (using unshift/shift because there is no back() methods for Javascript arrays)
1453 syncExecStack.unshift(module);
1454 evalModuleText(text, module);
1455 syncExecStack.shift();
1456
1457 // maybe the module was an AMD module
1458 runDefQ(module);
1459
1460 // legacy modules never get to defineModule() => cjs and injected never set; also evaluation implies executing
1461 if(!module.cjs){
1462 setArrived(module);
1463 finishExec(module);
1464 }
1465
1466 if(module.finish){
1467 // while synchronously evaluating this module, dojo.require was applied referencing a module
1468 // that had to be loaded async; therefore, the loader stopped answering all dojo.require
1469 // requests so they could be answered completely in the correct sequence; module.finish gives
1470 // the list of dojo.requires that must be re-applied once all target modules are available;
1471 // make a synthetic module to execute the dojo.require's in the correct order
1472
1473 // compute a guarnateed-unique mid for the synthetic finish module; remember the finish vector; remove it from the reference module
1474 // TODO: can we just leave the module.finish...what's it hurting?
1475 var finishMid = mid + "*finish",
1476 finish = module.finish;
1477 delete module.finish;
1478
1479 def(finishMid, ["dojo", ("dojo/require!" + finish.join(",")).replace(/\./g, "/")], function(dojo){
1480 forEach(finish, function(mid){ dojo.require(mid); });
1481 });
1482 // unshift, not push, which causes the current traversal to be reattempted from the top
1483 execQ.unshift(getModule(finishMid));
1484 }
1485 onLoadCallback();
1486 }else{
1487 text = transformToAmd(module, text);
1488 if(text){
1489 evalModuleText(text, module);
1490 onLoadCallback();
1491 }else{
1492 // if transformToAmd returned falsy, then the module was already AMD and it can be script-injected
1493 // do so to improve debugability(even though it means another download...which probably won't happen with a good browser cache)
1494 injectingModule = module;
1495 req.injectUrl(fixupUrl(url), onLoadCallback, module);
1496 injectingModule = 0;
1497 }
1498 }
1499 };
1500
1501 req.trace("loader-inject", ["xhr", module.mid, url, legacyMode!=sync]);
1502 if(has("config-dojo-loader-catches")){
1503 try{
1504 req.getText(url, legacyMode!=sync, xhrCallback);
1505 }catch(e){
1506 signal(error, makeError("xhrInjectFailed", [module, e]));
1507 }
1508 }else{
1509 req.getText(url, legacyMode!=sync, xhrCallback);
1510 }
1511 return;
1512 }
1513 } // else async mode or fell through in xdomain loading mode; either way, load by script injection
1514 req.trace("loader-inject", ["script", module.mid, url]);
1515 injectingModule = module;
1516 req.injectUrl(fixupUrl(url), onLoadCallback, module);
1517 injectingModule = 0;
1518 },
1519
1520 defineModule = function(module, deps, def){
1521 req.trace("loader-define-module", [module.mid, deps]);
1522
1523 if( 0 && module.plugin && module.plugin.isCombo){
1524 // the module is a plugin resource loaded by the combo service
1525 // note: check for module.plugin should be enough since normal plugin resources should
1526 // not follow this path; module.plugin.isCombo is future-proofing belt and suspenders
1527 module.result = isFunction(def) ? def() : def;
1528 setArrived(module);
1529 finishExec(module);
1530 return module;
1531 };
1532
1533 var mid = module.mid;
1534 if(module.injected === arrived){
1535 signal(error, makeError("multipleDefine", module));
1536 return module;
1537 }
1538 mix(module, {
1539 deps: deps,
1540 def: def,
1541 cjs: {
1542 id: module.mid,
1543 uri: module.url,
1544 exports: (module.result = {}),
1545 setExports: function(exports){
1546 module.cjs.exports = exports;
1547 },
1548 config:function(){
1549 return module.config;
1550 }
1551 }
1552 });
1553
1554 // resolve deps with respect to this module
1555 for(var i = 0; i < deps.length; i++){
1556 deps[i] = getModule(deps[i], module);
1557 }
1558
1559 if( 1 && legacyMode && !waiting[mid]){
1560 // the module showed up without being asked for; it was probably in a <script> element
1561 injectDependencies(module);
1562 execQ.push(module);
1563 checkComplete();
1564 }
1565 setArrived(module);
1566
1567 if(!isFunction(def) && !deps.length){
1568 module.result = def;
1569 finishExec(module);
1570 }
1571
1572 return module;
1573 },
1574
1575 runDefQ = function(referenceModule, mids){
1576 // defQ is an array of [id, dependencies, factory]
1577 // mids (if any) is a vector of mids given by a combo service
1578 var definedModules = [],
1579 module, args;
1580 while(defQ.length){
1581 args = defQ.shift();
1582 mids && (args[0]= mids.shift());
1583 // explicit define indicates possible multiple modules in a single file; delay injecting dependencies until defQ fully
1584 // processed since modules earlier in the queue depend on already-arrived modules that are later in the queue
1585 // TODO: what if no args[0] and no referenceModule
1586 module = (args[0] && getModule(args[0])) || referenceModule;
1587 definedModules.push([module, args[1], args[2]]);
1588 }
1589 consumePendingCacheInsert(referenceModule);
1590 forEach(definedModules, function(args){
1591 injectDependencies(defineModule.apply(null, args));
1592 });
1593 };
1594 }
1595
1596 var timerId = 0,
1597 clearTimer = noop,
1598 startTimer = noop;
1599 if( 1 ){
1600 // Timer machinery that monitors how long the loader is waiting and signals an error when the timer runs out.
1601 clearTimer = function(){
1602 timerId && clearTimeout(timerId);
1603 timerId = 0;
1604 },
1605
1606 startTimer = function(){
1607 clearTimer();
1608 if(req.waitms){
1609 timerId = window.setTimeout(function(){
1610 clearTimer();
1611 signal(error, makeError("timeout", waiting));
1612 }, req.waitms);
1613 }
1614 };
1615 }
1616
1617 if( 1 ){
1618 // the typically unnecessary !! in front of doc.attachEvent is due to an opera bug; see #15096
1619 has.add("ie-event-behavior", !!doc.attachEvent && (typeof opera === "undefined" || opera.toString() != "[object Opera]"));
1620 }
1621
1622 if( 1 && ( 1 || 1 )){
1623 var domOn = function(node, eventName, ieEventName, handler){
1624 // Add an event listener to a DOM node using the API appropriate for the current browser;
1625 // return a function that will disconnect the listener.
1626 if(!has("ie-event-behavior")){
1627 node.addEventListener(eventName, handler, false);
1628 return function(){
1629 node.removeEventListener(eventName, handler, false);
1630 };
1631 }else{
1632 node.attachEvent(ieEventName, handler);
1633 return function(){
1634 node.detachEvent(ieEventName, handler);
1635 };
1636 }
1637 },
1638 windowOnLoadListener = domOn(window, "load", "onload", function(){
1639 req.pageLoaded = 1;
1640 doc.readyState!="complete" && (doc.readyState = "complete");
1641 windowOnLoadListener();
1642 });
1643
1644 if( 1 ){
1645 // if the loader is on the page, there must be at least one script element
1646 // getting its parent and then doing insertBefore solves the "Operation Aborted"
1647 // error in IE from appending to a node that isn't properly closed; see
1648 // dojo/tests/_base/loader/requirejs/simple-badbase.html for an example
1649 var sibling = doc.getElementsByTagName("script")[0],
1650 insertPoint= sibling.parentNode;
1651 req.injectUrl = function(url, callback, owner){
1652 // insert a script element to the insert-point element with src=url;
1653 // apply callback upon detecting the script has loaded.
1654
1655 var node = owner.node = doc.createElement("script"),
1656 onLoad = function(e){
1657 e = e || window.event;
1658 var node = e.target || e.srcElement;
1659 if(e.type === "load" || /complete|loaded/.test(node.readyState)){
1660 loadDisconnector();
1661 errorDisconnector();
1662 callback && callback();
1663 }
1664 },
1665 loadDisconnector = domOn(node, "load", "onreadystatechange", onLoad),
1666 errorDisconnector = domOn(node, "error", "onerror", function(e){
1667 loadDisconnector();
1668 errorDisconnector();
1669 signal(error, makeError("scriptError", [url, e]));
1670 });
1671
1672 node.type = "text/javascript";
1673 node.charset = "utf-8";
1674 node.src = url;
1675 insertPoint.insertBefore(node, sibling);
1676 return node;
1677 };
1678 }
1679 }
1680
1681 if( 1 ){
1682 req.log = function(){
1683 try{
1684 for(var i = 0; i < arguments.length; i++){
1685 console.log(arguments[i]);
1686 }
1687 }catch(e){}
1688 };
1689 }else{
1690 req.log = noop;
1691 }
1692
1693 if( 0 ){
1694 var trace = req.trace = function(
1695 group, // the trace group to which this application belongs
1696 args // the contents of the trace
1697 ){
1698 ///
1699 // Tracing interface by group.
1700 //
1701 // Sends the contents of args to the console iff (req.trace.on && req.trace[group])
1702
1703 if(trace.on && trace.group[group]){
1704 signal("trace", [group, args]);
1705 for(var arg, dump = [], text= "trace:" + group + (args.length ? (":" + args[0]) : ""), i= 1; i<args.length;){
1706 arg = args[i++];
1707 if(isString(arg)){
1708 text += ", " + arg;
1709 }else{
1710 dump.push(arg);
1711 }
1712 }
1713 req.log(text);
1714 dump.length && dump.push(".");
1715 req.log.apply(req, dump);
1716 }
1717 };
1718 mix(trace, {
1719 on:1,
1720 group:{},
1721 set:function(group, value){
1722 if(isString(group)){
1723 trace.group[group]= value;
1724 }else{
1725 mix(trace.group, group);
1726 }
1727 }
1728 });
1729 trace.set(mix(mix(mix({}, defaultConfig.trace), userConfig.trace), dojoSniffConfig.trace));
1730 on("config", function(config){
1731 config.trace && trace.set(config.trace);
1732 });
1733 }else{
1734 req.trace = noop;
1735 }
1736
1737 var def = function(
1738 mid, //(commonjs.moduleId, optional) list of modules to be loaded before running factory
1739 dependencies, //(array of commonjs.moduleId, optional)
1740 factory //(any)
1741 ){
1742 ///
1743 // Advises the loader of a module factory. //Implements http://wiki.commonjs.org/wiki/Modules/AsynchronousDefinition.
1744 ///
1745 //note
1746 // CommonJS factory scan courtesy of http://requirejs.org
1747
1748 var arity = arguments.length,
1749 defaultDeps = ["require", "exports", "module"],
1750 // the predominate signature...
1751 args = [0, mid, dependencies];
1752 if(arity==1){
1753 args = [0, (isFunction(mid) ? defaultDeps : []), mid];
1754 }else if(arity==2 && isString(mid)){
1755 args = [mid, (isFunction(dependencies) ? defaultDeps : []), dependencies];
1756 }else if(arity==3){
1757 args = [mid, dependencies, factory];
1758 }
1759
1760 if( 0 && args[1]===defaultDeps){
1761 args[2].toString()
1762 .replace(/(\/\*([\s\S]*?)\*\/|\/\/(.*)$)/mg, "")
1763 .replace(/require\(["']([\w\!\-_\.\/]+)["']\)/g, function(match, dep){
1764 args[1].push(dep);
1765 });
1766 }
1767
1768 req.trace("loader-define", args.slice(0, 2));
1769 var targetModule = args[0] && getModule(args[0]),
1770 module;
1771 if(targetModule && !waiting[targetModule.mid]){
1772 // given a mid that hasn't been requested; therefore, defined through means other than injecting
1773 // consequent to a require() or define() application; examples include defining modules on-the-fly
1774 // due to some code path or including a module in a script element. In any case,
1775 // there is no callback waiting to finish processing and nothing to trigger the defQ and the
1776 // dependencies are never requested; therefore, do it here.
1777 injectDependencies(defineModule(targetModule, args[1], args[2]));
1778 }else if(!has("ie-event-behavior") || ! 1 || injectingCachedModule){
1779 // not IE path: anonymous module and therefore must have been injected; therefore, onLoad will fire immediately
1780 // after script finishes being evaluated and the defQ can be run from that callback to detect the module id
1781 defQ.push(args);
1782 }else{
1783 // IE path: possibly anonymous module and therefore injected; therefore, cannot depend on 1-to-1,
1784 // in-order exec of onLoad with script eval (since it's IE) and must manually detect here
1785 targetModule = targetModule || injectingModule;
1786 if(!targetModule){
1787 for(mid in waiting){
1788 module = modules[mid];
1789 if(module && module.node && module.node.readyState === 'interactive'){
1790 targetModule = module;
1791 break;
1792 }
1793 }
1794 if( 0 && !targetModule){
1795 for(var i = 0; i<combosPending.length; i++){
1796 targetModule = combosPending[i];
1797 if(targetModule.node && targetModule.node.readyState === 'interactive'){
1798 break;
1799 }
1800 targetModule= 0;
1801 }
1802 }
1803 }
1804 if( 0 && isArray(targetModule)){
1805 injectDependencies(defineModule(getModule(targetModule.shift()), args[1], args[2]));
1806 if(!targetModule.length){
1807 combosPending.splice(i, 1);
1808 }
1809 }else if(targetModule){
1810 consumePendingCacheInsert(targetModule);
1811 injectDependencies(defineModule(targetModule, args[1], args[2]));
1812 }else{
1813 signal(error, makeError("ieDefineFailed", args[0]));
1814 }
1815 checkComplete();
1816 }
1817 };
1818 def.amd = {
1819 vendor:"dojotoolkit.org"
1820 };
1821
1822 if( 0 ){
1823 req.def = def;
1824 }
1825
1826 // allow config to override default implemention of named functions; this is useful for
1827 // non-browser environments, e.g., overriding injectUrl, getText, log, etc. in node.js, Rhino, etc.
1828 // also useful for testing and monkey patching loader
1829 mix(mix(req, defaultConfig.loaderPatch), userConfig.loaderPatch);
1830
1831 // now that req is fully initialized and won't change, we can hook it up to the error signal
1832 on(error, function(arg){
1833 try{
1834 console.error(arg);
1835 if(arg instanceof Error){
1836 for(var p in arg){
1837 console.log(p + ":", arg[p]);
1838 }
1839 console.log(".");
1840 }
1841 }catch(e){}
1842 });
1843
1844 // always publish these
1845 mix(req, {
1846 uid:uid,
1847 cache:cache,
1848 packs:packs
1849 });
1850
1851
1852 if( 0 ){
1853 mix(req, {
1854 // these may be interesting to look at when debugging
1855 paths:paths,
1856 aliases:aliases,
1857 modules:modules,
1858 legacyMode:legacyMode,
1859 execQ:execQ,
1860 defQ:defQ,
1861 waiting:waiting,
1862
1863 // these are used for testing
1864 // TODO: move testing infrastructure to a different has feature
1865 packs:packs,
1866 mapProgs:mapProgs,
1867 pathsMapProg:pathsMapProg,
1868 listenerQueues:listenerQueues,
1869
1870 // these are used by the builder (at least)
1871 computeMapProg:computeMapProg,
1872 runMapProg:runMapProg,
1873 compactPath:compactPath,
1874 getModuleInfo:getModuleInfo_
1875 });
1876 }
1877
1878 // the loader can be defined exactly once; look for global define which is the symbol AMD loaders are
1879 // *required* to define (as opposed to require, which is optional)
1880 if(global.define){
1881 if( 1 ){
1882 signal(error, makeError("defineAlreadyDefined", 0));
1883 }
1884 return;
1885 }else{
1886 global.define = def;
1887 global.require = req;
1888 if( 0 ){
1889 require= req;
1890 }
1891 }
1892
1893 if( 0 && req.combo && req.combo.plugins){
1894 var plugins = req.combo.plugins,
1895 pluginName;
1896 for(pluginName in plugins){
1897 mix(mix(getModule(pluginName), plugins[pluginName]), {isCombo:1, executed:"executed", load:1});
1898 }
1899 }
1900
1901 if( 1 ){
1902 forEach(delayedModuleConfig, function(c){ config(c); });
1903 var bootDeps = dojoSniffConfig.deps || userConfig.deps || defaultConfig.deps,
1904 bootCallback = dojoSniffConfig.callback || userConfig.callback || defaultConfig.callback;
1905 req.boot = (bootDeps || bootCallback) ? [bootDeps || [], bootCallback] : 0;
1906 }
1907 if(! 1 ){
1908 !req.async && req(["dojo"]);
1909 req.boot && req.apply(null, req.boot);
1910 }
1911 })
1912 (this.dojoConfig || this.djConfig || this.require || {}, {
1913 async:0,
1914 hasCache:{
1915 'config-selectorEngine':"acme",
1916 'config-tlmSiblingOfDojo':1,
1917 'dojo-built':1,
1918 'dojo-loader':1,
1919 dom:1,
1920 'host-browser':1
1921 },
1922 packages:[
1923 {
1924 location:"../dijit",
1925 name:"dijit"
1926 },
1927 {
1928 location:".",
1929 name:"dojo"
1930 }
1931 ]
1932 });require({cache:{
1933 'dojo/_base/fx':function(){
1934 define(["./kernel", "./config", /*===== "./declare", =====*/ "./lang", "../Evented", "./Color", "./connect", "./sniff", "../dom", "../dom-style"],
1935 function(dojo, config, /*===== declare, =====*/ lang, Evented, Color, connect, has, dom, style){
1936 // module:
1937 // dojo/_base/fx
1938 // notes:
1939 // Animation loosely package based on Dan Pupius' work, contributed under CLA; see
1940 // http://pupius.co.uk/js/Toolkit.Drawing.js
1941
1942 var _mixin = lang.mixin;
1943
1944 // Module export
1945 var basefx = {
1946 // summary:
1947 // This module defines the base dojo/_base/fx implementation.
1948 };
1949
1950 var _Line = basefx._Line = function(/*int*/ start, /*int*/ end){
1951 // summary:
1952 // Object used to generate values from a start value to an end value
1953 // start: int
1954 // Beginning value for range
1955 // end: int
1956 // Ending value for range
1957 this.start = start;
1958 this.end = end;
1959 };
1960
1961 _Line.prototype.getValue = function(/*float*/ n){
1962 // summary:
1963 // Returns the point on the line
1964 // n:
1965 // a floating point number greater than 0 and less than 1
1966 return ((this.end - this.start) * n) + this.start; // Decimal
1967 };
1968
1969 var Animation = basefx.Animation = function(args){
1970 // summary:
1971 // A generic animation class that fires callbacks into its handlers
1972 // object at various states.
1973 // description:
1974 // A generic animation class that fires callbacks into its handlers
1975 // object at various states. Nearly all dojo animation functions
1976 // return an instance of this method, usually without calling the
1977 // .play() method beforehand. Therefore, you will likely need to
1978 // call .play() on instances of `Animation` when one is
1979 // returned.
1980 // args: Object
1981 // The 'magic argument', mixing all the properties into this
1982 // animation instance.
1983
1984 _mixin(this, args);
1985 if(lang.isArray(this.curve)){
1986 this.curve = new _Line(this.curve[0], this.curve[1]);
1987 }
1988
1989 };
1990 Animation.prototype = new Evented();
1991
1992 lang.extend(Animation, {
1993 // duration: Integer
1994 // The time in milliseconds the animation will take to run
1995 duration: 350,
1996
1997 /*=====
1998 // curve: _Line|Array
1999 // A two element array of start and end values, or a `_Line` instance to be
2000 // used in the Animation.
2001 curve: null,
2002
2003 // easing: Function?
2004 // A Function to adjust the acceleration (or deceleration) of the progress
2005 // across a _Line
2006 easing: null,
2007 =====*/
2008
2009 // repeat: Integer?
2010 // The number of times to loop the animation
2011 repeat: 0,
2012
2013 // rate: Integer?
2014 // the time in milliseconds to wait before advancing to next frame
2015 // (used as a fps timer: 1000/rate = fps)
2016 rate: 20 /* 50 fps */,
2017
2018 /*=====
2019 // delay: Integer?
2020 // The time in milliseconds to wait before starting animation after it
2021 // has been .play()'ed
2022 delay: null,
2023
2024 // beforeBegin: Event?
2025 // Synthetic event fired before a Animation begins playing (synchronous)
2026 beforeBegin: null,
2027
2028 // onBegin: Event?
2029 // Synthetic event fired as a Animation begins playing (useful?)
2030 onBegin: null,
2031
2032 // onAnimate: Event?
2033 // Synthetic event fired at each interval of the Animation
2034 onAnimate: null,
2035
2036 // onEnd: Event?
2037 // Synthetic event fired after the final frame of the Animation
2038 onEnd: null,
2039
2040 // onPlay: Event?
2041 // Synthetic event fired any time the Animation is play()'ed
2042 onPlay: null,
2043
2044 // onPause: Event?
2045 // Synthetic event fired when the Animation is paused
2046 onPause: null,
2047
2048 // onStop: Event
2049 // Synthetic event fires when the Animation is stopped
2050 onStop: null,
2051
2052 =====*/
2053
2054 _percent: 0,
2055 _startRepeatCount: 0,
2056
2057 _getStep: function(){
2058 var _p = this._percent,
2059 _e = this.easing
2060 ;
2061 return _e ? _e(_p) : _p;
2062 },
2063 _fire: function(/*Event*/ evt, /*Array?*/ args){
2064 // summary:
2065 // Convenience function. Fire event "evt" and pass it the
2066 // arguments specified in "args".
2067 // description:
2068 // Convenience function. Fire event "evt" and pass it the
2069 // arguments specified in "args".
2070 // Fires the callback in the scope of this Animation
2071 // instance.
2072 // evt:
2073 // The event to fire.
2074 // args:
2075 // The arguments to pass to the event.
2076 var a = args||[];
2077 if(this[evt]){
2078 if(config.debugAtAllCosts){
2079 this[evt].apply(this, a);
2080 }else{
2081 try{
2082 this[evt].apply(this, a);
2083 }catch(e){
2084 // squelch and log because we shouldn't allow exceptions in
2085 // synthetic event handlers to cause the internal timer to run
2086 // amuck, potentially pegging the CPU. I'm not a fan of this
2087 // squelch, but hopefully logging will make it clear what's
2088 // going on
2089 console.error("exception in animation handler for:", evt);
2090 console.error(e);
2091 }
2092 }
2093 }
2094 return this; // Animation
2095 },
2096
2097 play: function(/*int?*/ delay, /*Boolean?*/ gotoStart){
2098 // summary:
2099 // Start the animation.
2100 // delay:
2101 // How many milliseconds to delay before starting.
2102 // gotoStart:
2103 // If true, starts the animation from the beginning; otherwise,
2104 // starts it from its current position.
2105 // returns: Animation
2106 // The instance to allow chaining.
2107
2108 var _t = this;
2109 if(_t._delayTimer){ _t._clearTimer(); }
2110 if(gotoStart){
2111 _t._stopTimer();
2112 _t._active = _t._paused = false;
2113 _t._percent = 0;
2114 }else if(_t._active && !_t._paused){
2115 return _t;
2116 }
2117
2118 _t._fire("beforeBegin", [_t.node]);
2119
2120 var de = delay || _t.delay,
2121 _p = lang.hitch(_t, "_play", gotoStart);
2122
2123 if(de > 0){
2124 _t._delayTimer = setTimeout(_p, de);
2125 return _t;
2126 }
2127 _p();
2128 return _t; // Animation
2129 },
2130
2131 _play: function(gotoStart){
2132 var _t = this;
2133 if(_t._delayTimer){ _t._clearTimer(); }
2134 _t._startTime = new Date().valueOf();
2135 if(_t._paused){
2136 _t._startTime -= _t.duration * _t._percent;
2137 }
2138
2139 _t._active = true;
2140 _t._paused = false;
2141 var value = _t.curve.getValue(_t._getStep());
2142 if(!_t._percent){
2143 if(!_t._startRepeatCount){
2144 _t._startRepeatCount = _t.repeat;
2145 }
2146 _t._fire("onBegin", [value]);
2147 }
2148
2149 _t._fire("onPlay", [value]);
2150
2151 _t._cycle();
2152 return _t; // Animation
2153 },
2154
2155 pause: function(){
2156 // summary:
2157 // Pauses a running animation.
2158 var _t = this;
2159 if(_t._delayTimer){ _t._clearTimer(); }
2160 _t._stopTimer();
2161 if(!_t._active){ return _t; /*Animation*/ }
2162 _t._paused = true;
2163 _t._fire("onPause", [_t.curve.getValue(_t._getStep())]);
2164 return _t; // Animation
2165 },
2166
2167 gotoPercent: function(/*Decimal*/ percent, /*Boolean?*/ andPlay){
2168 // summary:
2169 // Sets the progress of the animation.
2170 // percent:
2171 // A percentage in decimal notation (between and including 0.0 and 1.0).
2172 // andPlay:
2173 // If true, play the animation after setting the progress.
2174 var _t = this;
2175 _t._stopTimer();
2176 _t._active = _t._paused = true;
2177 _t._percent = percent;
2178 if(andPlay){ _t.play(); }
2179 return _t; // Animation
2180 },
2181
2182 stop: function(/*boolean?*/ gotoEnd){
2183 // summary:
2184 // Stops a running animation.
2185 // gotoEnd:
2186 // If true, the animation will end.
2187 var _t = this;
2188 if(_t._delayTimer){ _t._clearTimer(); }
2189 if(!_t._timer){ return _t; /* Animation */ }
2190 _t._stopTimer();
2191 if(gotoEnd){
2192 _t._percent = 1;
2193 }
2194 _t._fire("onStop", [_t.curve.getValue(_t._getStep())]);
2195 _t._active = _t._paused = false;
2196 return _t; // Animation
2197 },
2198
2199 status: function(){
2200 // summary:
2201 // Returns a string token representation of the status of
2202 // the animation, one of: "paused", "playing", "stopped"
2203 if(this._active){
2204 return this._paused ? "paused" : "playing"; // String
2205 }
2206 return "stopped"; // String
2207 },
2208
2209 _cycle: function(){
2210 var _t = this;
2211 if(_t._active){
2212 var curr = new Date().valueOf();
2213 // Allow durations of 0 (instant) by setting step to 1 - see #13798
2214 var step = _t.duration === 0 ? 1 : (curr - _t._startTime) / (_t.duration);
2215
2216 if(step >= 1){
2217 step = 1;
2218 }
2219 _t._percent = step;
2220
2221 // Perform easing
2222 if(_t.easing){
2223 step = _t.easing(step);
2224 }
2225
2226 _t._fire("onAnimate", [_t.curve.getValue(step)]);
2227
2228 if(_t._percent < 1){
2229 _t._startTimer();
2230 }else{
2231 _t._active = false;
2232
2233 if(_t.repeat > 0){
2234 _t.repeat--;
2235 _t.play(null, true);
2236 }else if(_t.repeat == -1){
2237 _t.play(null, true);
2238 }else{
2239 if(_t._startRepeatCount){
2240 _t.repeat = _t._startRepeatCount;
2241 _t._startRepeatCount = 0;
2242 }
2243 }
2244 _t._percent = 0;
2245 _t._fire("onEnd", [_t.node]);
2246 !_t.repeat && _t._stopTimer();
2247 }
2248 }
2249 return _t; // Animation
2250 },
2251
2252 _clearTimer: function(){
2253 // summary:
2254 // Clear the play delay timer
2255 clearTimeout(this._delayTimer);
2256 delete this._delayTimer;
2257 }
2258
2259 });
2260
2261 // the local timer, stubbed into all Animation instances
2262 var ctr = 0,
2263 timer = null,
2264 runner = {
2265 run: function(){}
2266 };
2267
2268 lang.extend(Animation, {
2269
2270 _startTimer: function(){
2271 if(!this._timer){
2272 this._timer = connect.connect(runner, "run", this, "_cycle");
2273 ctr++;
2274 }
2275 if(!timer){
2276 timer = setInterval(lang.hitch(runner, "run"), this.rate);
2277 }
2278 },
2279
2280 _stopTimer: function(){
2281 if(this._timer){
2282 connect.disconnect(this._timer);
2283 this._timer = null;
2284 ctr--;
2285 }
2286 if(ctr <= 0){
2287 clearInterval(timer);
2288 timer = null;
2289 ctr = 0;
2290 }
2291 }
2292
2293 });
2294
2295 var _makeFadeable =
2296 has("ie") ? function(node){
2297 // only set the zoom if the "tickle" value would be the same as the
2298 // default
2299 var ns = node.style;
2300 // don't set the width to auto if it didn't already cascade that way.
2301 // We don't want to f anyones designs
2302 if(!ns.width.length && style.get(node, "width") == "auto"){
2303 ns.width = "auto";
2304 }
2305 } :
2306 function(){};
2307
2308 basefx._fade = function(/*Object*/ args){
2309 // summary:
2310 // Returns an animation that will fade the node defined by
2311 // args.node from the start to end values passed (args.start
2312 // args.end) (end is mandatory, start is optional)
2313
2314 args.node = dom.byId(args.node);
2315 var fArgs = _mixin({ properties: {} }, args),
2316 props = (fArgs.properties.opacity = {});
2317
2318 props.start = !("start" in fArgs) ?
2319 function(){
2320 return +style.get(fArgs.node, "opacity")||0;
2321 } : fArgs.start;
2322 props.end = fArgs.end;
2323
2324 var anim = basefx.animateProperty(fArgs);
2325 connect.connect(anim, "beforeBegin", lang.partial(_makeFadeable, fArgs.node));
2326
2327 return anim; // Animation
2328 };
2329
2330 /*=====
2331 var __FadeArgs = declare(null, {
2332 // node: DOMNode|String
2333 // The node referenced in the animation
2334 // duration: Integer?
2335 // Duration of the animation in milliseconds.
2336 // easing: Function?
2337 // An easing function.
2338 });
2339 =====*/
2340
2341 basefx.fadeIn = function(/*__FadeArgs*/ args){
2342 // summary:
2343 // Returns an animation that will fade node defined in 'args' from
2344 // its current opacity to fully opaque.
2345 return basefx._fade(_mixin({ end: 1 }, args)); // Animation
2346 };
2347
2348 basefx.fadeOut = function(/*__FadeArgs*/ args){
2349 // summary:
2350 // Returns an animation that will fade node defined in 'args'
2351 // from its current opacity to fully transparent.
2352 return basefx._fade(_mixin({ end: 0 }, args)); // Animation
2353 };
2354
2355 basefx._defaultEasing = function(/*Decimal?*/ n){
2356 // summary:
2357 // The default easing function for Animation(s)
2358 return 0.5 + ((Math.sin((n + 1.5) * Math.PI)) / 2); // Decimal
2359 };
2360
2361 var PropLine = function(properties){
2362 // PropLine is an internal class which is used to model the values of
2363 // an a group of CSS properties across an animation lifecycle. In
2364 // particular, the "getValue" function handles getting interpolated
2365 // values between start and end for a particular CSS value.
2366 this._properties = properties;
2367 for(var p in properties){
2368 var prop = properties[p];
2369 if(prop.start instanceof Color){
2370 // create a reusable temp color object to keep intermediate results
2371 prop.tempColor = new Color();
2372 }
2373 }
2374 };
2375
2376 PropLine.prototype.getValue = function(r){
2377 var ret = {};
2378 for(var p in this._properties){
2379 var prop = this._properties[p],
2380 start = prop.start;
2381 if(start instanceof Color){
2382 ret[p] = Color.blendColors(start, prop.end, r, prop.tempColor).toCss();
2383 }else if(!lang.isArray(start)){
2384 ret[p] = ((prop.end - start) * r) + start + (p != "opacity" ? prop.units || "px" : 0);
2385 }
2386 }
2387 return ret;
2388 };
2389
2390 /*=====
2391 var __AnimArgs = declare(__FadeArgs, {
2392 // properties: Object?
2393 // A hash map of style properties to Objects describing the transition,
2394 // such as the properties of _Line with an additional 'units' property
2395 properties: {}
2396
2397 //TODOC: add event callbacks
2398 });
2399 =====*/
2400
2401 basefx.animateProperty = function(/*__AnimArgs*/ args){
2402 // summary:
2403 // Returns an animation that will transition the properties of
2404 // node defined in `args` depending how they are defined in
2405 // `args.properties`
2406 //
2407 // description:
2408 // Foundation of most `dojo/_base/fx`
2409 // animations. It takes an object of "properties" corresponding to
2410 // style properties, and animates them in parallel over a set
2411 // duration.
2412 //
2413 // example:
2414 // A simple animation that changes the width of the specified node.
2415 // | basefx.animateProperty({
2416 // | node: "nodeId",
2417 // | properties: { width: 400 },
2418 // | }).play();
2419 // Dojo figures out the start value for the width and converts the
2420 // integer specified for the width to the more expressive but
2421 // verbose form `{ width: { end: '400', units: 'px' } }` which you
2422 // can also specify directly. Defaults to 'px' if omitted.
2423 //
2424 // example:
2425 // Animate width, height, and padding over 2 seconds... the
2426 // pedantic way:
2427 // | basefx.animateProperty({ node: node, duration:2000,
2428 // | properties: {
2429 // | width: { start: '200', end: '400', units:"px" },
2430 // | height: { start:'200', end: '400', units:"px" },
2431 // | paddingTop: { start:'5', end:'50', units:"px" }
2432 // | }
2433 // | }).play();
2434 // Note 'paddingTop' is used over 'padding-top'. Multi-name CSS properties
2435 // are written using "mixed case", as the hyphen is illegal as an object key.
2436 //
2437 // example:
2438 // Plug in a different easing function and register a callback for
2439 // when the animation ends. Easing functions accept values between
2440 // zero and one and return a value on that basis. In this case, an
2441 // exponential-in curve.
2442 // | basefx.animateProperty({
2443 // | node: "nodeId",
2444 // | // dojo figures out the start value
2445 // | properties: { width: { end: 400 } },
2446 // | easing: function(n){
2447 // | return (n==0) ? 0 : Math.pow(2, 10 * (n - 1));
2448 // | },
2449 // | onEnd: function(node){
2450 // | // called when the animation finishes. The animation
2451 // | // target is passed to this function
2452 // | }
2453 // | }).play(500); // delay playing half a second
2454 //
2455 // example:
2456 // Like all `Animation`s, animateProperty returns a handle to the
2457 // Animation instance, which fires the events common to Dojo FX. Use `aspect.after`
2458 // to access these events outside of the Animation definition:
2459 // | var anim = basefx.animateProperty({
2460 // | node:"someId",
2461 // | properties:{
2462 // | width:400, height:500
2463 // | }
2464 // | });
2465 // | aspect.after(anim, "onEnd", function(){
2466 // | console.log("animation ended");
2467 // | }, true);
2468 // | // play the animation now:
2469 // | anim.play();
2470 //
2471 // example:
2472 // Each property can be a function whose return value is substituted along.
2473 // Additionally, each measurement (eg: start, end) can be a function. The node
2474 // reference is passed directly to callbacks.
2475 // | basefx.animateProperty({
2476 // | node:"mine",
2477 // | properties:{
2478 // | height:function(node){
2479 // | // shrink this node by 50%
2480 // | return domGeom.position(node).h / 2
2481 // | },
2482 // | width:{
2483 // | start:function(node){ return 100; },
2484 // | end:function(node){ return 200; }
2485 // | }
2486 // | }
2487 // | }).play();
2488 //
2489
2490 var n = args.node = dom.byId(args.node);
2491 if(!args.easing){ args.easing = dojo._defaultEasing; }
2492
2493 var anim = new Animation(args);
2494 connect.connect(anim, "beforeBegin", anim, function(){
2495 var pm = {};
2496 for(var p in this.properties){
2497 // Make shallow copy of properties into pm because we overwrite
2498 // some values below. In particular if start/end are functions
2499 // we don't want to overwrite them or the functions won't be
2500 // called if the animation is reused.
2501 if(p == "width" || p == "height"){
2502 this.node.display = "block";
2503 }
2504 var prop = this.properties[p];
2505 if(lang.isFunction(prop)){
2506 prop = prop(n);
2507 }
2508 prop = pm[p] = _mixin({}, (lang.isObject(prop) ? prop: { end: prop }));
2509
2510 if(lang.isFunction(prop.start)){
2511 prop.start = prop.start(n);
2512 }
2513 if(lang.isFunction(prop.end)){
2514 prop.end = prop.end(n);
2515 }
2516 var isColor = (p.toLowerCase().indexOf("color") >= 0);
2517 function getStyle(node, p){
2518 // domStyle.get(node, "height") can return "auto" or "" on IE; this is more reliable:
2519 var v = { height: node.offsetHeight, width: node.offsetWidth }[p];
2520 if(v !== undefined){ return v; }
2521 v = style.get(node, p);
2522 return (p == "opacity") ? +v : (isColor ? v : parseFloat(v));
2523 }
2524 if(!("end" in prop)){
2525 prop.end = getStyle(n, p);
2526 }else if(!("start" in prop)){
2527 prop.start = getStyle(n, p);
2528 }
2529
2530 if(isColor){
2531 prop.start = new Color(prop.start);
2532 prop.end = new Color(prop.end);
2533 }else{
2534 prop.start = (p == "opacity") ? +prop.start : parseFloat(prop.start);
2535 }
2536 }
2537 this.curve = new PropLine(pm);
2538 });
2539 connect.connect(anim, "onAnimate", lang.hitch(style, "set", anim.node));
2540 return anim; // Animation
2541 };
2542
2543 basefx.anim = function( /*DOMNode|String*/ node,
2544 /*Object*/ properties,
2545 /*Integer?*/ duration,
2546 /*Function?*/ easing,
2547 /*Function?*/ onEnd,
2548 /*Integer?*/ delay){
2549 // summary:
2550 // A simpler interface to `animateProperty()`, also returns
2551 // an instance of `Animation` but begins the animation
2552 // immediately, unlike nearly every other Dojo animation API.
2553 // description:
2554 // Simpler (but somewhat less powerful) version
2555 // of `animateProperty`. It uses defaults for many basic properties
2556 // and allows for positional parameters to be used in place of the
2557 // packed "property bag" which is used for other Dojo animation
2558 // methods.
2559 //
2560 // The `Animation` object returned will be already playing, so
2561 // calling play() on it again is (usually) a no-op.
2562 // node:
2563 // a DOM node or the id of a node to animate CSS properties on
2564 // duration:
2565 // The number of milliseconds over which the animation
2566 // should run. Defaults to the global animation default duration
2567 // (350ms).
2568 // easing:
2569 // An easing function over which to calculate acceleration
2570 // and deceleration of the animation through its duration.
2571 // A default easing algorithm is provided, but you may
2572 // plug in any you wish. A large selection of easing algorithms
2573 // are available in `dojo/fx/easing`.
2574 // onEnd:
2575 // A function to be called when the animation finishes
2576 // running.
2577 // delay:
2578 // The number of milliseconds to delay beginning the
2579 // animation by. The default is 0.
2580 // example:
2581 // Fade out a node
2582 // | basefx.anim("id", { opacity: 0 });
2583 // example:
2584 // Fade out a node over a full second
2585 // | basefx.anim("id", { opacity: 0 }, 1000);
2586 return basefx.animateProperty({ // Animation
2587 node: node,
2588 duration: duration || Animation.prototype.duration,
2589 properties: properties,
2590 easing: easing,
2591 onEnd: onEnd
2592 }).play(delay || 0);
2593 };
2594
2595
2596 if( 1 ){
2597 _mixin(dojo, basefx);
2598 // Alias to drop come 2.0:
2599 dojo._Animation = Animation;
2600 }
2601
2602 return basefx;
2603 });
2604
2605 },
2606 'dojo/dom-form':function(){
2607 define(["./_base/lang", "./dom", "./io-query", "./json"], function(lang, dom, ioq, json){
2608 // module:
2609 // dojo/dom-form
2610
2611 function setValue(/*Object*/ obj, /*String*/ name, /*String*/ value){
2612 // summary:
2613 // For the named property in object, set the value. If a value
2614 // already exists and it is a string, convert the value to be an
2615 // array of values.
2616
2617 // Skip it if there is no value
2618 if(value === null){
2619 return;
2620 }
2621
2622 var val = obj[name];
2623 if(typeof val == "string"){ // inline'd type check
2624 obj[name] = [val, value];
2625 }else if(lang.isArray(val)){
2626 val.push(value);
2627 }else{
2628 obj[name] = value;
2629 }
2630 }
2631
2632 var exclude = "file|submit|image|reset|button";
2633
2634 var form = {
2635 // summary:
2636 // This module defines form-processing functions.
2637
2638 fieldToObject: function fieldToObject(/*DOMNode|String*/ inputNode){
2639 // summary:
2640 // Serialize a form field to a JavaScript object.
2641 // description:
2642 // Returns the value encoded in a form field as
2643 // as a string or an array of strings. Disabled form elements
2644 // and unchecked radio and checkboxes are skipped. Multi-select
2645 // elements are returned as an array of string values.
2646 // inputNode: DOMNode|String
2647 // returns: Object
2648
2649 var ret = null;
2650 inputNode = dom.byId(inputNode);
2651 if(inputNode){
2652 var _in = inputNode.name, type = (inputNode.type || "").toLowerCase();
2653 if(_in && type && !inputNode.disabled){
2654 if(type == "radio" || type == "checkbox"){
2655 if(inputNode.checked){
2656 ret = inputNode.value;
2657 }
2658 }else if(inputNode.multiple){
2659 ret = [];
2660 var nodes = [inputNode.firstChild];
2661 while(nodes.length){
2662 for(var node = nodes.pop(); node; node = node.nextSibling){
2663 if(node.nodeType == 1 && node.tagName.toLowerCase() == "option"){
2664 if(node.selected){
2665 ret.push(node.value);
2666 }
2667 }else{
2668 if(node.nextSibling){
2669 nodes.push(node.nextSibling);
2670 }
2671 if(node.firstChild){
2672 nodes.push(node.firstChild);
2673 }
2674 break;
2675 }
2676 }
2677 }
2678 }else{
2679 ret = inputNode.value;
2680 }
2681 }
2682 }
2683 return ret; // Object
2684 },
2685
2686 toObject: function formToObject(/*DOMNode|String*/ formNode){
2687 // summary:
2688 // Serialize a form node to a JavaScript object.
2689 // description:
2690 // Returns the values encoded in an HTML form as
2691 // string properties in an object which it then returns. Disabled form
2692 // elements, buttons, and other non-value form elements are skipped.
2693 // Multi-select elements are returned as an array of string values.
2694 // formNode: DOMNode|String
2695 // example:
2696 // This form:
2697 // | <form id="test_form">
2698 // | <input type="text" name="blah" value="blah">
2699 // | <input type="text" name="no_value" value="blah" disabled>
2700 // | <input type="button" name="no_value2" value="blah">
2701 // | <select type="select" multiple name="multi" size="5">
2702 // | <option value="blah">blah</option>
2703 // | <option value="thud" selected>thud</option>
2704 // | <option value="thonk" selected>thonk</option>
2705 // | </select>
2706 // | </form>
2707 //
2708 // yields this object structure as the result of a call to
2709 // formToObject():
2710 //
2711 // | {
2712 // | blah: "blah",
2713 // | multi: [
2714 // | "thud",
2715 // | "thonk"
2716 // | ]
2717 // | };
2718
2719 var ret = {}, elems = dom.byId(formNode).elements;
2720 for(var i = 0, l = elems.length; i < l; ++i){
2721 var item = elems[i], _in = item.name, type = (item.type || "").toLowerCase();
2722 if(_in && type && exclude.indexOf(type) < 0 && !item.disabled){
2723 setValue(ret, _in, form.fieldToObject(item));
2724 if(type == "image"){
2725 ret[_in + ".x"] = ret[_in + ".y"] = ret[_in].x = ret[_in].y = 0;
2726 }
2727 }
2728 }
2729 return ret; // Object
2730 },
2731
2732 toQuery: function formToQuery(/*DOMNode|String*/ formNode){
2733 // summary:
2734 // Returns a URL-encoded string representing the form passed as either a
2735 // node or string ID identifying the form to serialize
2736 // formNode: DOMNode|String
2737 // returns: String
2738
2739 return ioq.objectToQuery(form.toObject(formNode)); // String
2740 },
2741
2742 toJson: function formToJson(/*DOMNode|String*/ formNode, /*Boolean?*/ prettyPrint){
2743 // summary:
2744 // Create a serialized JSON string from a form node or string
2745 // ID identifying the form to serialize
2746 // formNode: DOMNode|String
2747 // prettyPrint: Boolean?
2748 // returns: String
2749
2750 return json.stringify(form.toObject(formNode), null, prettyPrint ? 4 : 0); // String
2751 }
2752 };
2753
2754 return form;
2755 });
2756
2757 },
2758 'dojo/promise/tracer':function(){
2759 define([
2760 "../_base/lang",
2761 "./Promise",
2762 "../Evented"
2763 ], function(lang, Promise, Evented){
2764 "use strict";
2765
2766 // module:
2767 // dojo/promise/tracer
2768
2769 /*=====
2770 return {
2771 // summary:
2772 // Trace promise fulfillment.
2773 // description:
2774 // Trace promise fulfillment. Calling `.trace()` or `.traceError()` on a
2775 // promise enables tracing. Will emit `resolved`, `rejected` or `progress`
2776 // events.
2777
2778 on: function(type, listener){
2779 // summary:
2780 // Subscribe to traces.
2781 // description:
2782 // See `dojo/Evented#on()`.
2783 // type: String
2784 // `resolved`, `rejected`, or `progress`
2785 // listener: Function
2786 // The listener is passed the traced value and any arguments
2787 // that were used with the `.trace()` call.
2788 }
2789 };
2790 =====*/
2791
2792 var evented = new Evented;
2793 var emit = evented.emit;
2794 evented.emit = null;
2795 // Emit events asynchronously since they should not change the promise state.
2796 function emitAsync(args){
2797 setTimeout(function(){
2798 emit.apply(evented, args);
2799 }, 0);
2800 }
2801
2802 Promise.prototype.trace = function(){
2803 // summary:
2804 // Trace the promise.
2805 // description:
2806 // Tracing allows you to transparently log progress,
2807 // resolution and rejection of promises, without affecting the
2808 // promise itself. Any arguments passed to `trace()` are
2809 // emitted in trace events. See `dojo/promise/tracer` on how
2810 // to handle traces.
2811 // returns: dojo/promise/Promise
2812 // The promise instance `trace()` is called on.
2813
2814 var args = lang._toArray(arguments);
2815 this.then(
2816 function(value){ emitAsync(["resolved", value].concat(args)); },
2817 function(error){ emitAsync(["rejected", error].concat(args)); },
2818 function(update){ emitAsync(["progress", update].concat(args)); }
2819 );
2820 return this;
2821 };
2822
2823 Promise.prototype.traceRejected = function(){
2824 // summary:
2825 // Trace rejection of the promise.
2826 // description:
2827 // Tracing allows you to transparently log progress,
2828 // resolution and rejection of promises, without affecting the
2829 // promise itself. Any arguments passed to `trace()` are
2830 // emitted in trace events. See `dojo/promise/tracer` on how
2831 // to handle traces.
2832 // returns: dojo/promise/Promise
2833 // The promise instance `traceRejected()` is called on.
2834
2835 var args = lang._toArray(arguments);
2836 this.otherwise(function(error){
2837 emitAsync(["rejected", error].concat(args));
2838 });
2839 return this;
2840 };
2841
2842 return evented;
2843 });
2844
2845 },
2846 'dojo/errors/RequestError':function(){
2847 define(['./create'], function(create){
2848 // module:
2849 // dojo/errors/RequestError
2850
2851 /*=====
2852 return function(){
2853 // summary:
2854 // TODOC
2855 };
2856 =====*/
2857
2858 return create("RequestError", function(message, response){
2859 this.response = response;
2860 });
2861 });
2862
2863 },
2864 'dojo/_base/html':function(){
2865 define("dojo/_base/html", ["./kernel", "../dom", "../dom-style", "../dom-attr", "../dom-prop", "../dom-class", "../dom-construct", "../dom-geometry"], function(dojo, dom, style, attr, prop, cls, ctr, geom){
2866 // module:
2867 // dojo/dom
2868
2869 /*=====
2870 return {
2871 // summary:
2872 // This module is a stub for the core dojo DOM API.
2873 };
2874 =====*/
2875
2876 // mix-in dom
2877 dojo.byId = dom.byId;
2878 dojo.isDescendant = dom.isDescendant;
2879 dojo.setSelectable = dom.setSelectable;
2880
2881 // mix-in dom-attr
2882 dojo.getAttr = attr.get;
2883 dojo.setAttr = attr.set;
2884 dojo.hasAttr = attr.has;
2885 dojo.removeAttr = attr.remove;
2886 dojo.getNodeProp = attr.getNodeProp;
2887
2888 dojo.attr = function(node, name, value){
2889 // summary:
2890 // Gets or sets an attribute on an HTML element.
2891 // description:
2892 // Handles normalized getting and setting of attributes on DOM
2893 // Nodes. If 2 arguments are passed, and a the second argument is a
2894 // string, acts as a getter.
2895 //
2896 // If a third argument is passed, or if the second argument is a
2897 // map of attributes, acts as a setter.
2898 //
2899 // When passing functions as values, note that they will not be
2900 // directly assigned to slots on the node, but rather the default
2901 // behavior will be removed and the new behavior will be added
2902 // using `dojo.connect()`, meaning that event handler properties
2903 // will be normalized and that some caveats with regards to
2904 // non-standard behaviors for onsubmit apply. Namely that you
2905 // should cancel form submission using `dojo.stopEvent()` on the
2906 // passed event object instead of returning a boolean value from
2907 // the handler itself.
2908 // node: DOMNode|String
2909 // id or reference to the element to get or set the attribute on
2910 // name: String|Object
2911 // the name of the attribute to get or set.
2912 // value: String?
2913 // The value to set for the attribute
2914 // returns:
2915 // when used as a getter, the value of the requested attribute
2916 // or null if that attribute does not have a specified or
2917 // default value;
2918 //
2919 // when used as a setter, the DOM node
2920 //
2921 // example:
2922 // | // get the current value of the "foo" attribute on a node
2923 // | dojo.attr(dojo.byId("nodeId"), "foo");
2924 // | // or we can just pass the id:
2925 // | dojo.attr("nodeId", "foo");
2926 //
2927 // example:
2928 // | // use attr() to set the tab index
2929 // | dojo.attr("nodeId", "tabIndex", 3);
2930 // |
2931 //
2932 // example:
2933 // Set multiple values at once, including event handlers:
2934 // | dojo.attr("formId", {
2935 // | "foo": "bar",
2936 // | "tabIndex": -1,
2937 // | "method": "POST",
2938 // | "onsubmit": function(e){
2939 // | // stop submitting the form. Note that the IE behavior
2940 // | // of returning true or false will have no effect here
2941 // | // since our handler is connect()ed to the built-in
2942 // | // onsubmit behavior and so we need to use
2943 // | // dojo.stopEvent() to ensure that the submission
2944 // | // doesn't proceed.
2945 // | dojo.stopEvent(e);
2946 // |
2947 // | // submit the form with Ajax
2948 // | dojo.xhrPost({ form: "formId" });
2949 // | }
2950 // | });
2951 //
2952 // example:
2953 // Style is s special case: Only set with an object hash of styles
2954 // | dojo.attr("someNode",{
2955 // | id:"bar",
2956 // | style:{
2957 // | width:"200px", height:"100px", color:"#000"
2958 // | }
2959 // | });
2960 //
2961 // example:
2962 // Again, only set style as an object hash of styles:
2963 // | var obj = { color:"#fff", backgroundColor:"#000" };
2964 // | dojo.attr("someNode", "style", obj);
2965 // |
2966 // | // though shorter to use `dojo.style()` in this case:
2967 // | dojo.style("someNode", obj);
2968
2969 if(arguments.length == 2){
2970 return attr[typeof name == "string" ? "get" : "set"](node, name);
2971 }
2972 return attr.set(node, name, value);
2973 };
2974
2975 // mix-in dom-class
2976 dojo.hasClass = cls.contains;
2977 dojo.addClass = cls.add;
2978 dojo.removeClass = cls.remove;
2979 dojo.toggleClass = cls.toggle;
2980 dojo.replaceClass = cls.replace;
2981
2982 // mix-in dom-construct
2983 dojo._toDom = dojo.toDom = ctr.toDom;
2984 dojo.place = ctr.place;
2985 dojo.create = ctr.create;
2986 dojo.empty = function(node){ ctr.empty(node); };
2987 dojo._destroyElement = dojo.destroy = function(node){ ctr.destroy(node); };
2988
2989 // mix-in dom-geometry
2990 dojo._getPadExtents = dojo.getPadExtents = geom.getPadExtents;
2991 dojo._getBorderExtents = dojo.getBorderExtents = geom.getBorderExtents;
2992 dojo._getPadBorderExtents = dojo.getPadBorderExtents = geom.getPadBorderExtents;
2993 dojo._getMarginExtents = dojo.getMarginExtents = geom.getMarginExtents;
2994 dojo._getMarginSize = dojo.getMarginSize = geom.getMarginSize;
2995 dojo._getMarginBox = dojo.getMarginBox = geom.getMarginBox;
2996 dojo.setMarginBox = geom.setMarginBox;
2997 dojo._getContentBox = dojo.getContentBox = geom.getContentBox;
2998 dojo.setContentSize = geom.setContentSize;
2999 dojo._isBodyLtr = dojo.isBodyLtr = geom.isBodyLtr;
3000 dojo._docScroll = dojo.docScroll = geom.docScroll;
3001 dojo._getIeDocumentElementOffset = dojo.getIeDocumentElementOffset = geom.getIeDocumentElementOffset;
3002 dojo._fixIeBiDiScrollLeft = dojo.fixIeBiDiScrollLeft = geom.fixIeBiDiScrollLeft;
3003 dojo.position = geom.position;
3004
3005 dojo.marginBox = function marginBox(/*DomNode|String*/node, /*Object?*/box){
3006 // summary:
3007 // Getter/setter for the margin-box of node.
3008 // description:
3009 // Getter/setter for the margin-box of node.
3010 // Returns an object in the expected format of box (regardless
3011 // if box is passed). The object might look like:
3012 // `{ l: 50, t: 200, w: 300: h: 150 }`
3013 // for a node offset from its parent 50px to the left, 200px from
3014 // the top with a margin width of 300px and a margin-height of
3015 // 150px.
3016 // node:
3017 // id or reference to DOM Node to get/set box for
3018 // box:
3019 // If passed, denotes that dojo.marginBox() should
3020 // update/set the margin box for node. Box is an object in the
3021 // above format. All properties are optional if passed.
3022 // example:
3023 // Retrieve the margin box of a passed node
3024 // | var box = dojo.marginBox("someNodeId");
3025 // | console.dir(box);
3026 //
3027 // example:
3028 // Set a node's margin box to the size of another node
3029 // | var box = dojo.marginBox("someNodeId");
3030 // | dojo.marginBox("someOtherNode", box);
3031 return box ? geom.setMarginBox(node, box) : geom.getMarginBox(node); // Object
3032 };
3033
3034 dojo.contentBox = function contentBox(/*DomNode|String*/node, /*Object?*/box){
3035 // summary:
3036 // Getter/setter for the content-box of node.
3037 // description:
3038 // Returns an object in the expected format of box (regardless if box is passed).
3039 // The object might look like:
3040 // `{ l: 50, t: 200, w: 300: h: 150 }`
3041 // for a node offset from its parent 50px to the left, 200px from
3042 // the top with a content width of 300px and a content-height of
3043 // 150px. Note that the content box may have a much larger border
3044 // or margin box, depending on the box model currently in use and
3045 // CSS values set/inherited for node.
3046 // While the getter will return top and left values, the
3047 // setter only accepts setting the width and height.
3048 // node:
3049 // id or reference to DOM Node to get/set box for
3050 // box:
3051 // If passed, denotes that dojo.contentBox() should
3052 // update/set the content box for node. Box is an object in the
3053 // above format, but only w (width) and h (height) are supported.
3054 // All properties are optional if passed.
3055 return box ? geom.setContentSize(node, box) : geom.getContentBox(node); // Object
3056 };
3057
3058 dojo.coords = function(/*DomNode|String*/node, /*Boolean?*/includeScroll){
3059 // summary:
3060 // Deprecated: Use position() for border-box x/y/w/h
3061 // or marginBox() for margin-box w/h/l/t.
3062 //
3063 // Returns an object that measures margin-box (w)idth/(h)eight
3064 // and absolute position x/y of the border-box. Also returned
3065 // is computed (l)eft and (t)op values in pixels from the
3066 // node's offsetParent as returned from marginBox().
3067 // Return value will be in the form:
3068 //| { l: 50, t: 200, w: 300: h: 150, x: 100, y: 300 }
3069 // Does not act as a setter. If includeScroll is passed, the x and
3070 // y params are affected as one would expect in dojo.position().
3071 dojo.deprecated("dojo.coords()", "Use dojo.position() or dojo.marginBox().");
3072 node = dom.byId(node);
3073 var s = style.getComputedStyle(node), mb = geom.getMarginBox(node, s);
3074 var abs = geom.position(node, includeScroll);
3075 mb.x = abs.x;
3076 mb.y = abs.y;
3077 return mb; // Object
3078 };
3079
3080 // mix-in dom-prop
3081 dojo.getProp = prop.get;
3082 dojo.setProp = prop.set;
3083
3084 dojo.prop = function(/*DomNode|String*/node, /*String|Object*/name, /*String?*/value){
3085 // summary:
3086 // Gets or sets a property on an HTML element.
3087 // description:
3088 // Handles normalized getting and setting of properties on DOM
3089 // Nodes. If 2 arguments are passed, and a the second argument is a
3090 // string, acts as a getter.
3091 //
3092 // If a third argument is passed, or if the second argument is a
3093 // map of attributes, acts as a setter.
3094 //
3095 // When passing functions as values, note that they will not be
3096 // directly assigned to slots on the node, but rather the default
3097 // behavior will be removed and the new behavior will be added
3098 // using `dojo.connect()`, meaning that event handler properties
3099 // will be normalized and that some caveats with regards to
3100 // non-standard behaviors for onsubmit apply. Namely that you
3101 // should cancel form submission using `dojo.stopEvent()` on the
3102 // passed event object instead of returning a boolean value from
3103 // the handler itself.
3104 // node:
3105 // id or reference to the element to get or set the property on
3106 // name:
3107 // the name of the property to get or set.
3108 // value:
3109 // The value to set for the property
3110 // returns:
3111 // when used as a getter, the value of the requested property
3112 // or null if that attribute does not have a specified or
3113 // default value;
3114 //
3115 // when used as a setter, the DOM node
3116 //
3117 // example:
3118 // | // get the current value of the "foo" property on a node
3119 // | dojo.prop(dojo.byId("nodeId"), "foo");
3120 // | // or we can just pass the id:
3121 // | dojo.prop("nodeId", "foo");
3122 //
3123 // example:
3124 // | // use prop() to set the tab index
3125 // | dojo.prop("nodeId", "tabIndex", 3);
3126 // |
3127 //
3128 // example:
3129 // Set multiple values at once, including event handlers:
3130 // | dojo.prop("formId", {
3131 // | "foo": "bar",
3132 // | "tabIndex": -1,
3133 // | "method": "POST",
3134 // | "onsubmit": function(e){
3135 // | // stop submitting the form. Note that the IE behavior
3136 // | // of returning true or false will have no effect here
3137 // | // since our handler is connect()ed to the built-in
3138 // | // onsubmit behavior and so we need to use
3139 // | // dojo.stopEvent() to ensure that the submission
3140 // | // doesn't proceed.
3141 // | dojo.stopEvent(e);
3142 // |
3143 // | // submit the form with Ajax
3144 // | dojo.xhrPost({ form: "formId" });
3145 // | }
3146 // | });
3147 //
3148 // example:
3149 // Style is s special case: Only set with an object hash of styles
3150 // | dojo.prop("someNode",{
3151 // | id:"bar",
3152 // | style:{
3153 // | width:"200px", height:"100px", color:"#000"
3154 // | }
3155 // | });
3156 //
3157 // example:
3158 // Again, only set style as an object hash of styles:
3159 // | var obj = { color:"#fff", backgroundColor:"#000" };
3160 // | dojo.prop("someNode", "style", obj);
3161 // |
3162 // | // though shorter to use `dojo.style()` in this case:
3163 // | dojo.style("someNode", obj);
3164
3165 if(arguments.length == 2){
3166 return prop[typeof name == "string" ? "get" : "set"](node, name);
3167 }
3168 // setter
3169 return prop.set(node, name, value);
3170 };
3171
3172 // mix-in dom-style
3173 dojo.getStyle = style.get;
3174 dojo.setStyle = style.set;
3175 dojo.getComputedStyle = style.getComputedStyle;
3176 dojo.__toPixelValue = dojo.toPixelValue = style.toPixelValue;
3177
3178 dojo.style = function(node, name, value){
3179 // summary:
3180 // Accesses styles on a node. If 2 arguments are
3181 // passed, acts as a getter. If 3 arguments are passed, acts
3182 // as a setter.
3183 // description:
3184 // Getting the style value uses the computed style for the node, so the value
3185 // will be a calculated value, not just the immediate node.style value.
3186 // Also when getting values, use specific style names,
3187 // like "borderBottomWidth" instead of "border" since compound values like
3188 // "border" are not necessarily reflected as expected.
3189 // If you want to get node dimensions, use `dojo.marginBox()`,
3190 // `dojo.contentBox()` or `dojo.position()`.
3191 // node: DOMNode|String
3192 // id or reference to node to get/set style for
3193 // name: String|Object?
3194 // the style property to set in DOM-accessor format
3195 // ("borderWidth", not "border-width") or an object with key/value
3196 // pairs suitable for setting each property.
3197 // value: String?
3198 // If passed, sets value on the node for style, handling
3199 // cross-browser concerns. When setting a pixel value,
3200 // be sure to include "px" in the value. For instance, top: "200px".
3201 // Otherwise, in some cases, some browsers will not apply the style.
3202 // returns:
3203 // when used as a getter, return the computed style of the node if passing in an ID or node,
3204 // or return the normalized, computed value for the property when passing in a node and a style property
3205 // example:
3206 // Passing only an ID or node returns the computed style object of
3207 // the node:
3208 // | dojo.style("thinger");
3209 // example:
3210 // Passing a node and a style property returns the current
3211 // normalized, computed value for that property:
3212 // | dojo.style("thinger", "opacity"); // 1 by default
3213 //
3214 // example:
3215 // Passing a node, a style property, and a value changes the
3216 // current display of the node and returns the new computed value
3217 // | dojo.style("thinger", "opacity", 0.5); // == 0.5
3218 //
3219 // example:
3220 // Passing a node, an object-style style property sets each of the values in turn and returns the computed style object of the node:
3221 // | dojo.style("thinger", {
3222 // | "opacity": 0.5,
3223 // | "border": "3px solid black",
3224 // | "height": "300px"
3225 // | });
3226 //
3227 // example:
3228 // When the CSS style property is hyphenated, the JavaScript property is camelCased.
3229 // font-size becomes fontSize, and so on.
3230 // | dojo.style("thinger",{
3231 // | fontSize:"14pt",
3232 // | letterSpacing:"1.2em"
3233 // | });
3234 //
3235 // example:
3236 // dojo/NodeList implements .style() using the same syntax, omitting the "node" parameter, calling
3237 // dojo.style() on every element of the list. See: `dojo/query` and `dojo/NodeList`
3238 // | dojo.query(".someClassName").style("visibility","hidden");
3239 // | // or
3240 // | dojo.query("#baz > div").style({
3241 // | opacity:0.75,
3242 // | fontSize:"13pt"
3243 // | });
3244
3245 switch(arguments.length){
3246 case 1:
3247 return style.get(node);
3248 case 2:
3249 return style[typeof name == "string" ? "get" : "set"](node, name);
3250 }
3251 // setter
3252 return style.set(node, name, value);
3253 };
3254
3255 return dojo;
3256 });
3257
3258 },
3259 'dojo/_base/kernel':function(){
3260 define(["../has", "./config", "require", "module"], function(has, config, require, module){
3261 // module:
3262 // dojo/_base/kernel
3263
3264 // This module is the foundational module of the dojo boot sequence; it defines the dojo object.
3265
3266 var
3267 // loop variables for this module
3268 i, p,
3269
3270 // create dojo, dijit, and dojox
3271 // FIXME: in 2.0 remove dijit, dojox being created by dojo
3272 dijit = {},
3273 dojox = {},
3274 dojo = {
3275 // summary:
3276 // This module is the foundational module of the dojo boot sequence; it defines the dojo object.
3277
3278 // notice dojo takes ownership of the value of the config module
3279 config:config,
3280 global:this,
3281 dijit:dijit,
3282 dojox:dojox
3283 };
3284
3285
3286 // Configure the scope map. For a 100% AMD application, the scope map is not needed other than to provide
3287 // a _scopeName property for the dojo, dijit, and dojox root object so those packages can create
3288 // unique names in the global space.
3289 //
3290 // Built, legacy modules use the scope map to allow those modules to be expressed as if dojo, dijit, and dojox,
3291 // where global when in fact they are either global under different names or not global at all. In v1.6-, the
3292 // config variable "scopeMap" was used to map names as used within a module to global names. This has been
3293 // subsumed by the AMD map configuration variable which can relocate packages to different names. For backcompat,
3294 // only the "*" mapping is supported. See http://livedocs.dojotoolkit.org/developer/design/loader#legacy-cross-domain-mode for details.
3295 //
3296 // The following computations contort the packageMap for this dojo instance into a scopeMap.
3297 var scopeMap =
3298 // a map from a name used in a legacy module to the (global variable name, object addressed by that name)
3299 // always map dojo, dijit, and dojox
3300 {
3301 dojo:["dojo", dojo],
3302 dijit:["dijit", dijit],
3303 dojox:["dojox", dojox]
3304 },
3305
3306 packageMap =
3307 // the package map for this dojo instance; note, a foreign loader or no pacakgeMap results in the above default config
3308 (require.map && require.map[module.id.match(/[^\/]+/)[0]]),
3309
3310 item;
3311
3312
3313 // process all mapped top-level names for this instance of dojo
3314 for(p in packageMap){
3315 if(scopeMap[p]){
3316 // mapped dojo, dijit, or dojox
3317 scopeMap[p][0] = packageMap[p];
3318 }else{
3319 // some other top-level name
3320 scopeMap[p] = [packageMap[p], {}];
3321 }
3322 }
3323
3324 // publish those names to _scopeName and, optionally, the global namespace
3325 for(p in scopeMap){
3326 item = scopeMap[p];
3327 item[1]._scopeName = item[0];
3328 if(!config.noGlobals){
3329 this[item[0]] = item[1];
3330 }
3331 }
3332 dojo.scopeMap = scopeMap;
3333
3334 /*===== dojo.__docParserConfigureScopeMap(scopeMap); =====*/
3335
3336 // FIXME: dojo.baseUrl and dojo.config.baseUrl should be deprecated
3337 dojo.baseUrl = dojo.config.baseUrl = require.baseUrl;
3338 dojo.isAsync = ! 1 || require.async;
3339 dojo.locale = config.locale;
3340
3341 var rev = "$Rev: 30226 $".match(/\d+/);
3342 dojo.version = {
3343 // summary:
3344 // Version number of the Dojo Toolkit
3345 // description:
3346 // Hash about the version, including
3347 //
3348 // - major: Integer: Major version. If total version is "1.2.0beta1", will be 1
3349 // - minor: Integer: Minor version. If total version is "1.2.0beta1", will be 2
3350 // - patch: Integer: Patch version. If total version is "1.2.0beta1", will be 0
3351 // - flag: String: Descriptor flag. If total version is "1.2.0beta1", will be "beta1"
3352 // - revision: Number: The SVN rev from which dojo was pulled
3353
3354 major: 1, minor: 8, patch: 3, flag: "",
3355 revision: rev ? +rev[0] : NaN,
3356 toString: function(){
3357 var v = dojo.version;
3358 return v.major + "." + v.minor + "." + v.patch + v.flag + " (" + v.revision + ")"; // String
3359 }
3360 };
3361
3362 // If 1 is truthy, then as a dojo module is defined it should push it's definitions
3363 // into the dojo object, and conversely. In 2.0, it will likely be unusual to augment another object
3364 // as a result of defining a module. This has feature gives a way to force 2.0 behavior as the code
3365 // is migrated. Absent specific advice otherwise, set extend-dojo to truthy.
3366 1 || has.add("extend-dojo", 1);
3367
3368
3369 (Function("d", "d.eval = function(){return d.global.eval ? d.global.eval(arguments[0]) : eval(arguments[0]);}"))(dojo);
3370 /*=====
3371 dojo.eval = function(scriptText){
3372 // summary:
3373 // A legacy method created for use exclusively by internal Dojo methods. Do not use this method
3374 // directly unless you understand its possibly-different implications on the platforms your are targeting.
3375 // description:
3376 // Makes an attempt to evaluate scriptText in the global scope. The function works correctly for browsers
3377 // that support indirect eval.
3378 //
3379 // As usual, IE does not. On IE, the only way to implement global eval is to
3380 // use execScript. Unfortunately, execScript does not return a value and breaks some current usages of dojo.eval.
3381 // This implementation uses the technique of executing eval in the scope of a function that is a single scope
3382 // frame below the global scope; thereby coming close to the global scope. Note carefully that
3383 //
3384 // dojo.eval("var pi = 3.14;");
3385 //
3386 // will define global pi in non-IE environments, but define pi only in a temporary local scope for IE. If you want
3387 // to define a global variable using dojo.eval, write something like
3388 //
3389 // dojo.eval("window.pi = 3.14;")
3390 // scriptText:
3391 // The text to evaluation.
3392 // returns:
3393 // The result of the evaluation. Often `undefined`
3394 };
3395 =====*/
3396
3397
3398 if( 0 ){
3399 dojo.exit = function(exitcode){
3400 quit(exitcode);
3401 };
3402 }else{
3403 dojo.exit = function(){
3404 };
3405 }
3406
3407 1 || has.add("dojo-guarantee-console",
3408 // ensure that console.log, console.warn, etc. are defined
3409 1
3410 );
3411 if( 1 ){
3412 typeof console != "undefined" || (console = {});
3413 // Be careful to leave 'log' always at the end
3414 var cn = [
3415 "assert", "count", "debug", "dir", "dirxml", "error", "group",
3416 "groupEnd", "info", "profile", "profileEnd", "time", "timeEnd",
3417 "trace", "warn", "log"
3418 ];
3419 var tn;
3420 i = 0;
3421 while((tn = cn[i++])){
3422 if(!console[tn]){
3423 (function(){
3424 var tcn = tn + "";
3425 console[tcn] = ('log' in console) ? function(){
3426 var a = Array.apply({}, arguments);
3427 a.unshift(tcn + ":");
3428 console["log"](a.join(" "));
3429 } : function(){};
3430 console[tcn]._fake = true;
3431 })();
3432 }
3433 }
3434 }
3435
3436 has.add("dojo-debug-messages",
3437 // include dojo.deprecated/dojo.experimental implementations
3438 !!config.isDebug
3439 );
3440 dojo.deprecated = dojo.experimental = function(){};
3441 if(has("dojo-debug-messages")){
3442 dojo.deprecated = function(/*String*/ behaviour, /*String?*/ extra, /*String?*/ removal){
3443 // summary:
3444 // Log a debug message to indicate that a behavior has been
3445 // deprecated.
3446 // behaviour: String
3447 // The API or behavior being deprecated. Usually in the form
3448 // of "myApp.someFunction()".
3449 // extra: String?
3450 // Text to append to the message. Often provides advice on a
3451 // new function or facility to achieve the same goal during
3452 // the deprecation period.
3453 // removal: String?
3454 // Text to indicate when in the future the behavior will be
3455 // removed. Usually a version number.
3456 // example:
3457 // | dojo.deprecated("myApp.getTemp()", "use myApp.getLocaleTemp() instead", "1.0");
3458
3459 var message = "DEPRECATED: " + behaviour;
3460 if(extra){ message += " " + extra; }
3461 if(removal){ message += " -- will be removed in version: " + removal; }
3462 console.warn(message);
3463 };
3464
3465 dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
3466 // summary:
3467 // Marks code as experimental.
3468 // description:
3469 // This can be used to mark a function, file, or module as
3470 // experimental. Experimental code is not ready to be used, and the
3471 // APIs are subject to change without notice. Experimental code may be
3472 // completed deleted without going through the normal deprecation
3473 // process.
3474 // moduleName: String
3475 // The name of a module, or the name of a module file or a specific
3476 // function
3477 // extra: String?
3478 // some additional message for the user
3479 // example:
3480 // | dojo.experimental("dojo.data.Result");
3481 // example:
3482 // | dojo.experimental("dojo.weather.toKelvin()", "PENDING approval from NOAA");
3483
3484 var message = "EXPERIMENTAL: " + moduleName + " -- APIs subject to change without notice.";
3485 if(extra){ message += " " + extra; }
3486 console.warn(message);
3487 };
3488 }
3489
3490 1 || has.add("dojo-modulePaths",
3491 // consume dojo.modulePaths processing
3492 1
3493 );
3494 if( 1 ){
3495 // notice that modulePaths won't be applied to any require's before the dojo/_base/kernel factory is run;
3496 // this is the v1.6- behavior.
3497 if(config.modulePaths){
3498 dojo.deprecated("dojo.modulePaths", "use paths configuration");
3499 var paths = {};
3500 for(p in config.modulePaths){
3501 paths[p.replace(/\./g, "/")] = config.modulePaths[p];
3502 }
3503 require({paths:paths});
3504 }
3505 }
3506
3507 1 || has.add("dojo-moduleUrl",
3508 // include dojo.moduleUrl
3509 1
3510 );
3511 if( 1 ){
3512 dojo.moduleUrl = function(/*String*/module, /*String?*/url){
3513 // summary:
3514 // Returns a URL relative to a module.
3515 // example:
3516 // | var pngPath = dojo.moduleUrl("acme","images/small.png");
3517 // | console.dir(pngPath); // list the object properties
3518 // | // create an image and set it's source to pngPath's value:
3519 // | var img = document.createElement("img");
3520 // | img.src = pngPath;
3521 // | // add our image to the document
3522 // | dojo.body().appendChild(img);
3523 // example:
3524 // you may de-reference as far as you like down the package
3525 // hierarchy. This is sometimes handy to avoid lenghty relative
3526 // urls or for building portable sub-packages. In this example,
3527 // the `acme.widget` and `acme.util` directories may be located
3528 // under different roots (see `dojo.registerModulePath`) but the
3529 // the modules which reference them can be unaware of their
3530 // relative locations on the filesystem:
3531 // | // somewhere in a configuration block
3532 // | dojo.registerModulePath("acme.widget", "../../acme/widget");
3533 // | dojo.registerModulePath("acme.util", "../../util");
3534 // |
3535 // | // ...
3536 // |
3537 // | // code in a module using acme resources
3538 // | var tmpltPath = dojo.moduleUrl("acme.widget","templates/template.html");
3539 // | var dataPath = dojo.moduleUrl("acme.util","resources/data.json");
3540
3541 dojo.deprecated("dojo.moduleUrl()", "use require.toUrl", "2.0");
3542
3543 // require.toUrl requires a filetype; therefore, just append the suffix "/*.*" to guarantee a filetype, then
3544 // remove the suffix from the result. This way clients can request a url w/out a filetype. This should be
3545 // rare, but it maintains backcompat for the v1.x line (note: dojo.moduleUrl will be removed in v2.0).
3546 // Notice * is an illegal filename so it won't conflict with any real path map that may exist the paths config.
3547 var result = null;
3548 if(module){
3549 result = require.toUrl(module.replace(/\./g, "/") + (url ? ("/" + url) : "") + "/*.*").replace(/\/\*\.\*/, "") + (url ? "" : "/");
3550 }
3551 return result;
3552 };
3553 }
3554
3555 dojo._hasResource = {}; // for backward compatibility with layers built with 1.6 tooling
3556
3557 return dojo;
3558 });
3559
3560 },
3561 'dojo/io-query':function(){
3562 define(["./_base/lang"], function(lang){
3563
3564 // module:
3565 // dojo/io-query
3566
3567 var backstop = {};
3568
3569 return {
3570 // summary:
3571 // This module defines query string processing functions.
3572
3573 objectToQuery: function objectToQuery(/*Object*/ map){
3574 // summary:
3575 // takes a name/value mapping object and returns a string representing
3576 // a URL-encoded version of that object.
3577 // example:
3578 // this object:
3579 //
3580 // | {
3581 // | blah: "blah",
3582 // | multi: [
3583 // | "thud",
3584 // | "thonk"
3585 // | ]
3586 // | };
3587 //
3588 // yields the following query string:
3589 //
3590 // | "blah=blah&multi=thud&multi=thonk"
3591
3592 // FIXME: need to implement encodeAscii!!
3593 var enc = encodeURIComponent, pairs = [];
3594 for(var name in map){
3595 var value = map[name];
3596 if(value != backstop[name]){
3597 var assign = enc(name) + "=";
3598 if(lang.isArray(value)){
3599 for(var i = 0, l = value.length; i < l; ++i){
3600 pairs.push(assign + enc(value[i]));
3601 }
3602 }else{
3603 pairs.push(assign + enc(value));
3604 }
3605 }
3606 }
3607 return pairs.join("&"); // String
3608 },
3609
3610 queryToObject: function queryToObject(/*String*/ str){
3611 // summary:
3612 // Create an object representing a de-serialized query section of a
3613 // URL. Query keys with multiple values are returned in an array.
3614 //
3615 // example:
3616 // This string:
3617 //
3618 // | "foo=bar&foo=baz&thinger=%20spaces%20=blah&zonk=blarg&"
3619 //
3620 // results in this object structure:
3621 //
3622 // | {
3623 // | foo: [ "bar", "baz" ],
3624 // | thinger: " spaces =blah",
3625 // | zonk: "blarg"
3626 // | }
3627 //
3628 // Note that spaces and other urlencoded entities are correctly
3629 // handled.
3630
3631 // FIXME: should we grab the URL string if we're not passed one?
3632 var dec = decodeURIComponent, qp = str.split("&"), ret = {}, name, val;
3633 for(var i = 0, l = qp.length, item; i < l; ++i){
3634 item = qp[i];
3635 if(item.length){
3636 var s = item.indexOf("=");
3637 if(s < 0){
3638 name = dec(item);
3639 val = "";
3640 }else{
3641 name = dec(item.slice(0, s));
3642 val = dec(item.slice(s + 1));
3643 }
3644 if(typeof ret[name] == "string"){ // inline'd type check
3645 ret[name] = [ret[name]];
3646 }
3647
3648 if(lang.isArray(ret[name])){
3649 ret[name].push(val);
3650 }else{
3651 ret[name] = val;
3652 }
3653 }
3654 }
3655 return ret; // Object
3656 }
3657 };
3658 });
3659 },
3660 'dojo/_base/Deferred':function(){
3661 define([
3662 "./kernel",
3663 "../Deferred",
3664 "../promise/Promise",
3665 "../errors/CancelError",
3666 "../has",
3667 "./lang",
3668 "../when"
3669 ], function(dojo, NewDeferred, Promise, CancelError, has, lang, when){
3670 // module:
3671 // dojo/_base/Deferred
3672
3673 var mutator = function(){};
3674 var freeze = Object.freeze || function(){};
3675 // A deferred provides an API for creating and resolving a promise.
3676 var Deferred = dojo.Deferred = function(/*Function?*/ canceller){
3677 // summary:
3678 // Deprecated. This module defines the legacy dojo/_base/Deferred API.
3679 // New code should use dojo/Deferred instead.
3680 // description:
3681 // The Deferred API is based on the concept of promises that provide a
3682 // generic interface into the eventual completion of an asynchronous action.
3683 // The motivation for promises fundamentally is about creating a
3684 // separation of concerns that allows one to achieve the same type of
3685 // call patterns and logical data flow in asynchronous code as can be
3686 // achieved in synchronous code. Promises allows one
3687 // to be able to call a function purely with arguments needed for
3688 // execution, without conflating the call with concerns of whether it is
3689 // sync or async. One shouldn't need to alter a call's arguments if the
3690 // implementation switches from sync to async (or vice versa). By having
3691 // async functions return promises, the concerns of making the call are
3692 // separated from the concerns of asynchronous interaction (which are
3693 // handled by the promise).
3694 //
3695 // The Deferred is a type of promise that provides methods for fulfilling the
3696 // promise with a successful result or an error. The most important method for
3697 // working with Dojo's promises is the then() method, which follows the
3698 // CommonJS proposed promise API. An example of using a Dojo promise:
3699 //
3700 // | var resultingPromise = someAsyncOperation.then(function(result){
3701 // | ... handle result ...
3702 // | },
3703 // | function(error){
3704 // | ... handle error ...
3705 // | });
3706 //
3707 // The .then() call returns a new promise that represents the result of the
3708 // execution of the callback. The callbacks will never affect the original promises value.
3709 //
3710 // The Deferred instances also provide the following functions for backwards compatibility:
3711 //
3712 // - addCallback(handler)
3713 // - addErrback(handler)
3714 // - callback(result)
3715 // - errback(result)
3716 //
3717 // Callbacks are allowed to return promises themselves, so
3718 // you can build complicated sequences of events with ease.
3719 //
3720 // The creator of the Deferred may specify a canceller. The canceller
3721 // is a function that will be called if Deferred.cancel is called
3722 // before the Deferred fires. You can use this to implement clean
3723 // aborting of an XMLHttpRequest, etc. Note that cancel will fire the
3724 // deferred with a CancelledError (unless your canceller returns
3725 // another kind of error), so the errbacks should be prepared to
3726 // handle that error for cancellable Deferreds.
3727 // example:
3728 // | var deferred = new Deferred();
3729 // | setTimeout(function(){ deferred.callback({success: true}); }, 1000);
3730 // | return deferred;
3731 // example:
3732 // Deferred objects are often used when making code asynchronous. It
3733 // may be easiest to write functions in a synchronous manner and then
3734 // split code using a deferred to trigger a response to a long-lived
3735 // operation. For example, instead of register a callback function to
3736 // denote when a rendering operation completes, the function can
3737 // simply return a deferred:
3738 //
3739 // | // callback style:
3740 // | function renderLotsOfData(data, callback){
3741 // | var success = false
3742 // | try{
3743 // | for(var x in data){
3744 // | renderDataitem(data[x]);
3745 // | }
3746 // | success = true;
3747 // | }catch(e){ }
3748 // | if(callback){
3749 // | callback(success);
3750 // | }
3751 // | }
3752 //
3753 // | // using callback style
3754 // | renderLotsOfData(someDataObj, function(success){
3755 // | // handles success or failure
3756 // | if(!success){
3757 // | promptUserToRecover();
3758 // | }
3759 // | });
3760 // | // NOTE: no way to add another callback here!!
3761 // example:
3762 // Using a Deferred doesn't simplify the sending code any, but it
3763 // provides a standard interface for callers and senders alike,
3764 // providing both with a simple way to service multiple callbacks for
3765 // an operation and freeing both sides from worrying about details
3766 // such as "did this get called already?". With Deferreds, new
3767 // callbacks can be added at any time.
3768 //
3769 // | // Deferred style:
3770 // | function renderLotsOfData(data){
3771 // | var d = new Deferred();
3772 // | try{
3773 // | for(var x in data){
3774 // | renderDataitem(data[x]);
3775 // | }
3776 // | d.callback(true);
3777 // | }catch(e){
3778 // | d.errback(new Error("rendering failed"));
3779 // | }
3780 // | return d;
3781 // | }
3782 //
3783 // | // using Deferred style
3784 // | renderLotsOfData(someDataObj).then(null, function(){
3785 // | promptUserToRecover();
3786 // | });
3787 // | // NOTE: addErrback and addCallback both return the Deferred
3788 // | // again, so we could chain adding callbacks or save the
3789 // | // deferred for later should we need to be notified again.
3790 // example:
3791 // In this example, renderLotsOfData is synchronous and so both
3792 // versions are pretty artificial. Putting the data display on a
3793 // timeout helps show why Deferreds rock:
3794 //
3795 // | // Deferred style and async func
3796 // | function renderLotsOfData(data){
3797 // | var d = new Deferred();
3798 // | setTimeout(function(){
3799 // | try{
3800 // | for(var x in data){
3801 // | renderDataitem(data[x]);
3802 // | }
3803 // | d.callback(true);
3804 // | }catch(e){
3805 // | d.errback(new Error("rendering failed"));
3806 // | }
3807 // | }, 100);
3808 // | return d;
3809 // | }
3810 //
3811 // | // using Deferred style
3812 // | renderLotsOfData(someDataObj).then(null, function(){
3813 // | promptUserToRecover();
3814 // | });
3815 //
3816 // Note that the caller doesn't have to change his code at all to
3817 // handle the asynchronous case.
3818
3819 var result, finished, isError, head, nextListener;
3820 var promise = (this.promise = new Promise());
3821
3822 function complete(value){
3823 if(finished){
3824 throw new Error("This deferred has already been resolved");
3825 }
3826 result = value;
3827 finished = true;
3828 notify();
3829 }
3830 function notify(){
3831 var mutated;
3832 while(!mutated && nextListener){
3833 var listener = nextListener;
3834 nextListener = nextListener.next;
3835 if((mutated = (listener.progress == mutator))){ // assignment and check
3836 finished = false;
3837 }
3838
3839 var func = (isError ? listener.error : listener.resolved);
3840 if(has("config-useDeferredInstrumentation")){
3841 if(isError && NewDeferred.instrumentRejected){
3842 NewDeferred.instrumentRejected(result, !!func);
3843 }
3844 }
3845 if(func){
3846 try{
3847 var newResult = func(result);
3848 if (newResult && typeof newResult.then === "function"){
3849 newResult.then(lang.hitch(listener.deferred, "resolve"), lang.hitch(listener.deferred, "reject"), lang.hitch(listener.deferred, "progress"));
3850 continue;
3851 }
3852 var unchanged = mutated && newResult === undefined;
3853 if(mutated && !unchanged){
3854 isError = newResult instanceof Error;
3855 }
3856 listener.deferred[unchanged && isError ? "reject" : "resolve"](unchanged ? result : newResult);
3857 }catch(e){
3858 listener.deferred.reject(e);
3859 }
3860 }else{
3861 if(isError){
3862 listener.deferred.reject(result);
3863 }else{
3864 listener.deferred.resolve(result);
3865 }
3866 }
3867 }
3868 }
3869 // calling resolve will resolve the promise
3870 this.resolve = this.callback = function(value){
3871 // summary:
3872 // Fulfills the Deferred instance successfully with the provide value
3873 this.fired = 0;
3874 this.results = [value, null];
3875 complete(value);
3876 };
3877
3878
3879 // calling error will indicate that the promise failed
3880 this.reject = this.errback = function(error){
3881 // summary:
3882 // Fulfills the Deferred instance as an error with the provided error
3883 isError = true;
3884 this.fired = 1;
3885 if(has("config-useDeferredInstrumentation")){
3886 if(NewDeferred.instrumentRejected){
3887 NewDeferred.instrumentRejected(error, !!nextListener);
3888 }
3889 }
3890 complete(error);
3891 this.results = [null, error];
3892 };
3893 // call progress to provide updates on the progress on the completion of the promise
3894 this.progress = function(update){
3895 // summary:
3896 // Send progress events to all listeners
3897 var listener = nextListener;
3898 while(listener){
3899 var progress = listener.progress;
3900 progress && progress(update);
3901 listener = listener.next;
3902 }
3903 };
3904 this.addCallbacks = function(callback, errback){
3905 // summary:
3906 // Adds callback and error callback for this deferred instance.
3907 // callback: Function?
3908 // The callback attached to this deferred object.
3909 // errback: Function?
3910 // The error callback attached to this deferred object.
3911 // returns:
3912 // Returns this deferred object.
3913 this.then(callback, errback, mutator);
3914 return this; // Deferred
3915 };
3916 // provide the implementation of the promise
3917 promise.then = this.then = function(/*Function?*/resolvedCallback, /*Function?*/errorCallback, /*Function?*/progressCallback){
3918 // summary:
3919 // Adds a fulfilledHandler, errorHandler, and progressHandler to be called for
3920 // completion of a promise. The fulfilledHandler is called when the promise
3921 // is fulfilled. The errorHandler is called when a promise fails. The
3922 // progressHandler is called for progress events. All arguments are optional
3923 // and non-function values are ignored. The progressHandler is not only an
3924 // optional argument, but progress events are purely optional. Promise
3925 // providers are not required to ever create progress events.
3926 //
3927 // This function will return a new promise that is fulfilled when the given
3928 // fulfilledHandler or errorHandler callback is finished. This allows promise
3929 // operations to be chained together. The value returned from the callback
3930 // handler is the fulfillment value for the returned promise. If the callback
3931 // throws an error, the returned promise will be moved to failed state.
3932 //
3933 // returns:
3934 // Returns a new promise that represents the result of the
3935 // execution of the callback. The callbacks will never affect the original promises value.
3936 // example:
3937 // An example of using a CommonJS compliant promise:
3938 // | asyncComputeTheAnswerToEverything().
3939 // | then(addTwo).
3940 // | then(printResult, onError);
3941 // | >44
3942 //
3943 var returnDeferred = progressCallback == mutator ? this : new Deferred(promise.cancel);
3944 var listener = {
3945 resolved: resolvedCallback,
3946 error: errorCallback,
3947 progress: progressCallback,
3948 deferred: returnDeferred
3949 };
3950 if(nextListener){
3951 head = head.next = listener;
3952 }
3953 else{
3954 nextListener = head = listener;
3955 }
3956 if(finished){
3957 notify();
3958 }
3959 return returnDeferred.promise; // Promise
3960 };
3961 var deferred = this;
3962 promise.cancel = this.cancel = function(){
3963 // summary:
3964 // Cancels the asynchronous operation
3965 if(!finished){
3966 var error = canceller && canceller(deferred);
3967 if(!finished){
3968 if (!(error instanceof Error)){
3969 error = new CancelError(error);
3970 }
3971 error.log = false;
3972 deferred.reject(error);
3973 }
3974 }
3975 };
3976 freeze(promise);
3977 };
3978 lang.extend(Deferred, {
3979 addCallback: function(/*Function*/ callback){
3980 // summary:
3981 // Adds successful callback for this deferred instance.
3982 // returns:
3983 // Returns this deferred object.
3984 return this.addCallbacks(lang.hitch.apply(dojo, arguments)); // Deferred
3985 },
3986
3987 addErrback: function(/*Function*/ errback){
3988 // summary:
3989 // Adds error callback for this deferred instance.
3990 // returns:
3991 // Returns this deferred object.
3992 return this.addCallbacks(null, lang.hitch.apply(dojo, arguments)); // Deferred
3993 },
3994
3995 addBoth: function(/*Function*/ callback){
3996 // summary:
3997 // Add handler as both successful callback and error callback for this deferred instance.
3998 // returns:
3999 // Returns this deferred object.
4000 var enclosed = lang.hitch.apply(dojo, arguments);
4001 return this.addCallbacks(enclosed, enclosed); // Deferred
4002 },
4003 fired: -1
4004 });
4005
4006 Deferred.when = dojo.when = when;
4007
4008 return Deferred;
4009 });
4010
4011 },
4012 'dojo/NodeList-dom':function(){
4013 define(["./_base/kernel", "./query", "./_base/array", "./_base/lang", "./dom-class", "./dom-construct", "./dom-geometry", "./dom-attr", "./dom-style"], function(dojo, query, array, lang, domCls, domCtr, domGeom, domAttr, domStyle){
4014
4015 // module:
4016 // dojo/NodeList-dom.js
4017
4018 /*=====
4019 return function(){
4020 // summary:
4021 // Adds DOM related methods to NodeList, and returns NodeList constructor.
4022 };
4023 =====*/
4024
4025 var magicGuard = function(a){
4026 // summary:
4027 // the guard function for dojo.attr() and dojo.style()
4028 return a.length == 1 && (typeof a[0] == "string"); // inline'd type check
4029 };
4030
4031 var orphan = function(node){
4032 // summary:
4033 // function to orphan nodes
4034 var p = node.parentNode;
4035 if(p){
4036 p.removeChild(node);
4037 }
4038 };
4039 // FIXME: should we move orphan() to dojo.html?
4040
4041 var NodeList = query.NodeList,
4042 awc = NodeList._adaptWithCondition,
4043 aafe = NodeList._adaptAsForEach,
4044 aam = NodeList._adaptAsMap;
4045
4046 function getSet(module){
4047 return function(node, name, value){
4048 if(arguments.length == 2){
4049 return module[typeof name == "string" ? "get" : "set"](node, name);
4050 }
4051 // setter
4052 return module.set(node, name, value);
4053 };
4054 }
4055
4056 lang.extend(NodeList, {
4057 _normalize: function(/*String||Element||Object||NodeList*/content, /*DOMNode?*/refNode){
4058 // summary:
4059 // normalizes data to an array of items to insert.
4060 // description:
4061 // If content is an object, it can have special properties "template" and
4062 // "parse". If "template" is defined, then the template value is run through
4063 // dojo.string.substitute (if dojo/string.substitute() has been dojo.required elsewhere),
4064 // or if templateFunc is a function on the content, that function will be used to
4065 // transform the template into a final string to be used for for passing to dojo/dom-construct.toDom().
4066 // If content.parse is true, then it is remembered for later, for when the content
4067 // nodes are inserted into the DOM. At that point, the nodes will be parsed for widgets
4068 // (if dojo.parser has been dojo.required elsewhere).
4069
4070 //Wanted to just use a DocumentFragment, but for the array/NodeList
4071 //case that meant using cloneNode, but we may not want that.
4072 //Cloning should only happen if the node operations span
4073 //multiple refNodes. Also, need a real array, not a NodeList from the
4074 //DOM since the node movements could change those NodeLists.
4075
4076 var parse = content.parse === true;
4077
4078 //Do we have an object that needs to be run through a template?
4079 if(typeof content.template == "string"){
4080 var templateFunc = content.templateFunc || (dojo.string && dojo.string.substitute);
4081 content = templateFunc ? templateFunc(content.template, content) : content;
4082 }
4083
4084 var type = (typeof content);
4085 if(type == "string" || type == "number"){
4086 content = domCtr.toDom(content, (refNode && refNode.ownerDocument));
4087 if(content.nodeType == 11){
4088 //DocumentFragment. It cannot handle cloneNode calls, so pull out the children.
4089 content = lang._toArray(content.childNodes);
4090 }else{
4091 content = [content];
4092 }
4093 }else if(!lang.isArrayLike(content)){
4094 content = [content];
4095 }else if(!lang.isArray(content)){
4096 //To get to this point, content is array-like, but
4097 //not an array, which likely means a DOM NodeList. Convert it now.
4098 content = lang._toArray(content);
4099 }
4100
4101 //Pass around the parse info
4102 if(parse){
4103 content._runParse = true;
4104 }
4105 return content; //Array
4106 },
4107
4108 _cloneNode: function(/*DOMNode*/ node){
4109 // summary:
4110 // private utility to clone a node. Not very interesting in the vanilla
4111 // dojo/NodeList case, but delegates could do interesting things like
4112 // clone event handlers if that is derivable from the node.
4113 return node.cloneNode(true);
4114 },
4115
4116 _place: function(/*Array*/ary, /*DOMNode*/refNode, /*String*/position, /*Boolean*/useClone){
4117 // summary:
4118 // private utility to handle placing an array of nodes relative to another node.
4119 // description:
4120 // Allows for cloning the nodes in the array, and for
4121 // optionally parsing widgets, if ary._runParse is true.
4122
4123 //Avoid a disallowed operation if trying to do an innerHTML on a non-element node.
4124 if(refNode.nodeType != 1 && position == "only"){
4125 return;
4126 }
4127 var rNode = refNode, tempNode;
4128
4129 //Always cycle backwards in case the array is really a
4130 //DOM NodeList and the DOM operations take it out of the live collection.
4131 var length = ary.length;
4132 for(var i = length - 1; i >= 0; i--){
4133 var node = (useClone ? this._cloneNode(ary[i]) : ary[i]);
4134
4135 //If need widget parsing, use a temp node, instead of waiting after inserting into
4136 //real DOM because we need to start widget parsing at one node up from current node,
4137 //which could cause some already parsed widgets to be parsed again.
4138 if(ary._runParse && dojo.parser && dojo.parser.parse){
4139 if(!tempNode){
4140 tempNode = rNode.ownerDocument.createElement("div");
4141 }
4142 tempNode.appendChild(node);
4143 dojo.parser.parse(tempNode);
4144 node = tempNode.firstChild;
4145 while(tempNode.firstChild){
4146 tempNode.removeChild(tempNode.firstChild);
4147 }
4148 }
4149
4150 if(i == length - 1){
4151 domCtr.place(node, rNode, position);
4152 }else{
4153 rNode.parentNode.insertBefore(node, rNode);
4154 }
4155 rNode = node;
4156 }
4157 },
4158
4159
4160 position: aam(domGeom.position),
4161 /*=====
4162 position: function(){
4163 // summary:
4164 // Returns border-box objects (x/y/w/h) of all elements in a node list
4165 // as an Array (*not* a NodeList). Acts like `dojo.position`, though
4166 // assumes the node passed is each node in this list.
4167
4168 return dojo.map(this, dojo.position); // Array
4169 },
4170 =====*/
4171
4172 attr: awc(getSet(domAttr), magicGuard),
4173 /*=====
4174 attr: function(property, value){
4175 // summary:
4176 // gets or sets the DOM attribute for every element in the
4177 // NodeList. See also `dojo.attr`
4178 // property: String
4179 // the attribute to get/set
4180 // value: String?
4181 // optional. The value to set the property to
4182 // returns:
4183 // if no value is passed, the result is an array of attribute values
4184 // If a value is passed, the return is this NodeList
4185 // example:
4186 // Make all nodes with a particular class focusable:
4187 // | dojo.query(".focusable").attr("tabIndex", -1);
4188 // example:
4189 // Disable a group of buttons:
4190 // | dojo.query("button.group").attr("disabled", true);
4191 // example:
4192 // innerHTML can be assigned or retrieved as well:
4193 // | // get the innerHTML (as an array) for each list item
4194 // | var ih = dojo.query("li.replaceable").attr("innerHTML");
4195 return; // dojo/NodeList|Array
4196 },
4197 =====*/
4198
4199 style: awc(getSet(domStyle), magicGuard),
4200 /*=====
4201 style: function(property, value){
4202 // summary:
4203 // gets or sets the CSS property for every element in the NodeList
4204 // property: String
4205 // the CSS property to get/set, in JavaScript notation
4206 // ("lineHieght" instead of "line-height")
4207 // value: String?
4208 // optional. The value to set the property to
4209 // returns:
4210 // if no value is passed, the result is an array of strings.
4211 // If a value is passed, the return is this NodeList
4212 return; // dojo/NodeList
4213 return; // Array
4214 },
4215 =====*/
4216
4217 addClass: aafe(domCls.add),
4218 /*=====
4219 addClass: function(className){
4220 // summary:
4221 // adds the specified class to every node in the list
4222 // className: String|Array
4223 // A String class name to add, or several space-separated class names,
4224 // or an array of class names.
4225 return; // dojo/NodeList
4226 },
4227 =====*/
4228
4229 removeClass: aafe(domCls.remove),
4230 /*=====
4231 removeClass: function(className){
4232 // summary:
4233 // removes the specified class from every node in the list
4234 // className: String|Array?
4235 // An optional String class name to remove, or several space-separated
4236 // class names, or an array of class names. If omitted, all class names
4237 // will be deleted.
4238 // returns:
4239 // this list
4240 return; // dojo/NodeList
4241 },
4242 =====*/
4243
4244 toggleClass: aafe(domCls.toggle),
4245 /*=====
4246 toggleClass: function(className, condition){
4247 // summary:
4248 // Adds a class to node if not present, or removes if present.
4249 // Pass a boolean condition if you want to explicitly add or remove.
4250 // condition: Boolean?
4251 // If passed, true means to add the class, false means to remove.
4252 // className: String
4253 // the CSS class to add
4254 return; // dojo/NodeList
4255 },
4256 =====*/
4257
4258 replaceClass: aafe(domCls.replace),
4259 /*=====
4260 replaceClass: function(addClassStr, removeClassStr){
4261 // summary:
4262 // Replaces one or more classes on a node if not present.
4263 // Operates more quickly than calling `removeClass()` and `addClass()`
4264 // addClassStr: String|Array
4265 // A String class name to add, or several space-separated class names,
4266 // or an array of class names.
4267 // removeClassStr: String|Array?
4268 // A String class name to remove, or several space-separated class names,
4269 // or an array of class names.
4270 return; // dojo/NodeList
4271 },
4272 =====*/
4273
4274 empty: aafe(domCtr.empty),
4275 /*=====
4276 empty: function(){
4277 // summary:
4278 // clears all content from each node in the list. Effectively
4279 // equivalent to removing all child nodes from every item in
4280 // the list.
4281 return this.forEach("item.innerHTML='';"); // dojo/NodeList
4282 // FIXME: should we be checking for and/or disposing of widgets below these nodes?
4283 },
4284 =====*/
4285
4286 removeAttr: aafe(domAttr.remove),
4287 /*=====
4288 removeAttr: function(name){
4289 // summary:
4290 // Removes an attribute from each node in the list.
4291 // name: String
4292 // the name of the attribute to remove
4293 return; // dojo/NodeList
4294 },
4295 =====*/
4296
4297 marginBox: aam(domGeom.getMarginBox),
4298 /*=====
4299 marginBox: function(){
4300 // summary:
4301 // Returns margin-box size of nodes
4302 return; // dojo/NodeList
4303 },
4304 =====*/
4305
4306 // FIXME: connectPublisher()? connectRunOnce()?
4307
4308 /*
4309 destroy: function(){
4310 // summary:
4311 // destroys every item in the list.
4312 this.forEach(d.destroy);
4313 // FIXME: should we be checking for and/or disposing of widgets below these nodes?
4314 },
4315 */
4316
4317 place: function(/*String||Node*/ queryOrNode, /*String*/ position){
4318 // summary:
4319 // places elements of this node list relative to the first element matched
4320 // by queryOrNode. Returns the original NodeList. See: `dojo.place`
4321 // queryOrNode:
4322 // may be a string representing any valid CSS3 selector or a DOM node.
4323 // In the selector case, only the first matching element will be used
4324 // for relative positioning.
4325 // position:
4326 // can be one of:
4327 //
4328 // - "last" (default)
4329 // - "first"
4330 // - "before"
4331 // - "after"
4332 // - "only"
4333 // - "replace"
4334 //
4335 // or an offset in the childNodes property
4336 var item = query(queryOrNode)[0];
4337 return this.forEach(function(node){ domCtr.place(node, item, position); }); // dojo/NodeList
4338 },
4339
4340 orphan: function(/*String?*/ filter){
4341 // summary:
4342 // removes elements in this list that match the filter
4343 // from their parents and returns them as a new NodeList.
4344 // filter:
4345 // CSS selector like ".foo" or "div > span"
4346 // returns:
4347 // NodeList containing the orphaned elements
4348 return (filter ? query._filterResult(this, filter) : this).forEach(orphan); // dojo/NodeList
4349 },
4350
4351 adopt: function(/*String||Array||DomNode*/ queryOrListOrNode, /*String?*/ position){
4352 // summary:
4353 // places any/all elements in queryOrListOrNode at a
4354 // position relative to the first element in this list.
4355 // Returns a dojo/NodeList of the adopted elements.
4356 // queryOrListOrNode:
4357 // a DOM node or a query string or a query result.
4358 // Represents the nodes to be adopted relative to the
4359 // first element of this NodeList.
4360 // position:
4361 // can be one of:
4362 //
4363 // - "last" (default)
4364 // - "first"
4365 // - "before"
4366 // - "after"
4367 // - "only"
4368 // - "replace"
4369 //
4370 // or an offset in the childNodes property
4371 return query(queryOrListOrNode).place(this[0], position)._stash(this); // dojo/NodeList
4372 },
4373
4374 // FIXME: do we need this?
4375 query: function(/*String*/ queryStr){
4376 // summary:
4377 // Returns a new list whose members match the passed query,
4378 // assuming elements of the current NodeList as the root for
4379 // each search.
4380 // example:
4381 // assume a DOM created by this markup:
4382 // | <div id="foo">
4383 // | <p>
4384 // | bacon is tasty, <span>dontcha think?</span>
4385 // | </p>
4386 // | </div>
4387 // | <div id="bar">
4388 // | <p>great comedians may not be funny <span>in person</span></p>
4389 // | </div>
4390 // If we are presented with the following definition for a NodeList:
4391 // | var l = new NodeList(dojo.byId("foo"), dojo.byId("bar"));
4392 // it's possible to find all span elements under paragraphs
4393 // contained by these elements with this sub-query:
4394 // | var spans = l.query("p span");
4395
4396 // FIXME: probably slow
4397 if(!queryStr){ return this; }
4398 var ret = new NodeList;
4399 this.map(function(node){
4400 // FIXME: why would we ever get undefined here?
4401 query(queryStr, node).forEach(function(subNode){
4402 if(subNode !== undefined){
4403 ret.push(subNode);
4404 }
4405 });
4406 });
4407 return ret._stash(this); // dojo/NodeList
4408 },
4409
4410 filter: function(/*String|Function*/ filter){
4411 // summary:
4412 // "masks" the built-in javascript filter() method (supported
4413 // in Dojo via `dojo.filter`) to support passing a simple
4414 // string filter in addition to supporting filtering function
4415 // objects.
4416 // filter:
4417 // If a string, a CSS rule like ".thinger" or "div > span".
4418 // example:
4419 // "regular" JS filter syntax as exposed in dojo.filter:
4420 // | dojo.query("*").filter(function(item){
4421 // | // highlight every paragraph
4422 // | return (item.nodeName == "p");
4423 // | }).style("backgroundColor", "yellow");
4424 // example:
4425 // the same filtering using a CSS selector
4426 // | dojo.query("*").filter("p").styles("backgroundColor", "yellow");
4427
4428 var a = arguments, items = this, start = 0;
4429 if(typeof filter == "string"){ // inline'd type check
4430 items = query._filterResult(this, a[0]);
4431 if(a.length == 1){
4432 // if we only got a string query, pass back the filtered results
4433 return items._stash(this); // dojo/NodeList
4434 }
4435 // if we got a callback, run it over the filtered items
4436 start = 1;
4437 }
4438 return this._wrap(array.filter(items, a[start], a[start + 1]), this); // dojo/NodeList
4439 },
4440
4441 /*
4442 // FIXME: should this be "copyTo" and include parenting info?
4443 clone: function(){
4444 // summary:
4445 // creates node clones of each element of this list
4446 // and returns a new list containing the clones
4447 },
4448 */
4449
4450 addContent: function(/*String||DomNode||Object||dojo/NodeList*/ content, /*String||Integer?*/ position){
4451 // summary:
4452 // add a node, NodeList or some HTML as a string to every item in the
4453 // list. Returns the original list.
4454 // description:
4455 // a copy of the HTML content is added to each item in the
4456 // list, with an optional position argument. If no position
4457 // argument is provided, the content is appended to the end of
4458 // each item.
4459 // content:
4460 // DOM node, HTML in string format, a NodeList or an Object. If a DOM node or
4461 // NodeList, the content will be cloned if the current NodeList has more than one
4462 // element. Only the DOM nodes are cloned, no event handlers. If it is an Object,
4463 // it should be an object with at "template" String property that has the HTML string
4464 // to insert. If dojo.string has already been dojo.required, then dojo.string.substitute
4465 // will be used on the "template" to generate the final HTML string. Other allowed
4466 // properties on the object are: "parse" if the HTML
4467 // string should be parsed for widgets (dojo.require("dojo.parser") to get that
4468 // option to work), and "templateFunc" if a template function besides dojo.string.substitute
4469 // should be used to transform the "template".
4470 // position:
4471 // can be one of:
4472 //
4473 // - "last"||"end" (default)
4474 // - "first||"start"
4475 // - "before"
4476 // - "after"
4477 // - "replace" (replaces nodes in this NodeList with new content)
4478 // - "only" (removes other children of the nodes so new content is the only child)
4479 //
4480 // or an offset in the childNodes property
4481 // example:
4482 // appends content to the end if the position is omitted
4483 // | dojo.query("h3 > p").addContent("hey there!");
4484 // example:
4485 // add something to the front of each element that has a
4486 // "thinger" property:
4487 // | dojo.query("[thinger]").addContent("...", "first");
4488 // example:
4489 // adds a header before each element of the list
4490 // | dojo.query(".note").addContent("<h4>NOTE:</h4>", "before");
4491 // example:
4492 // add a clone of a DOM node to the end of every element in
4493 // the list, removing it from its existing parent.
4494 // | dojo.query(".note").addContent(dojo.byId("foo"));
4495 // example:
4496 // Append nodes from a templatized string.
4497 // | dojo.require("dojo.string");
4498 // | dojo.query(".note").addContent({
4499 // | template: '<b>${id}: </b><span>${name}</span>',
4500 // | id: "user332",
4501 // | name: "Mr. Anderson"
4502 // | });
4503 // example:
4504 // Append nodes from a templatized string that also has widgets parsed.
4505 // | dojo.require("dojo.string");
4506 // | dojo.require("dojo.parser");
4507 // | var notes = dojo.query(".note").addContent({
4508 // | template: '<button dojoType="dijit/form/Button">${text}</button>',
4509 // | parse: true,
4510 // | text: "Send"
4511 // | });
4512 content = this._normalize(content, this[0]);
4513 for(var i = 0, node; (node = this[i]); i++){
4514 this._place(content, node, position, i > 0);
4515 }
4516 return this; // dojo/NodeList
4517 }
4518 });
4519
4520 return NodeList;
4521 });
4522
4523 },
4524 'dojo/query':function(){
4525 define(["./_base/kernel", "./has", "./dom", "./on", "./_base/array", "./_base/lang", "./selector/_loader", "./selector/_loader!default"],
4526 function(dojo, has, dom, on, array, lang, loader, defaultEngine){
4527
4528 "use strict";
4529
4530 has.add("array-extensible", function(){
4531 // test to see if we can extend an array (not supported in old IE)
4532 return lang.delegate([], {length: 1}).length == 1 && !has("bug-for-in-skips-shadowed");
4533 });
4534
4535 var ap = Array.prototype, aps = ap.slice, apc = ap.concat, forEach = array.forEach;
4536
4537 var tnl = function(/*Array*/ a, /*dojo/NodeList?*/ parent, /*Function?*/ NodeListCtor){
4538 // summary:
4539 // decorate an array to make it look like a `dojo/NodeList`.
4540 // a:
4541 // Array of nodes to decorate.
4542 // parent:
4543 // An optional parent NodeList that generated the current
4544 // list of nodes. Used to call _stash() so the parent NodeList
4545 // can be accessed via end() later.
4546 // NodeListCtor:
4547 // An optional constructor function to use for any
4548 // new NodeList calls. This allows a certain chain of
4549 // NodeList calls to use a different object than dojo/NodeList.
4550 var nodeList = new (NodeListCtor || this._NodeListCtor || nl)(a);
4551 return parent ? nodeList._stash(parent) : nodeList;
4552 };
4553
4554 var loopBody = function(f, a, o){
4555 a = [0].concat(aps.call(a, 0));
4556 o = o || dojo.global;
4557 return function(node){
4558 a[0] = node;
4559 return f.apply(o, a);
4560 };
4561 };
4562
4563 // adapters
4564
4565 var adaptAsForEach = function(f, o){
4566 // summary:
4567 // adapts a single node function to be used in the forEach-type
4568 // actions. The initial object is returned from the specialized
4569 // function.
4570 // f: Function
4571 // a function to adapt
4572 // o: Object?
4573 // an optional context for f
4574 return function(){
4575 this.forEach(loopBody(f, arguments, o));
4576 return this; // Object
4577 };
4578 };
4579
4580 var adaptAsMap = function(f, o){
4581 // summary:
4582 // adapts a single node function to be used in the map-type
4583 // actions. The return is a new array of values, as via `dojo.map`
4584 // f: Function
4585 // a function to adapt
4586 // o: Object?
4587 // an optional context for f
4588 return function(){
4589 return this.map(loopBody(f, arguments, o));
4590 };
4591 };
4592
4593 var adaptAsFilter = function(f, o){
4594 // summary:
4595 // adapts a single node function to be used in the filter-type actions
4596 // f: Function
4597 // a function to adapt
4598 // o: Object?
4599 // an optional context for f
4600 return function(){
4601 return this.filter(loopBody(f, arguments, o));
4602 };
4603 };
4604
4605 var adaptWithCondition = function(f, g, o){
4606 // summary:
4607 // adapts a single node function to be used in the map-type
4608 // actions, behaves like forEach() or map() depending on arguments
4609 // f: Function
4610 // a function to adapt
4611 // g: Function
4612 // a condition function, if true runs as map(), otherwise runs as forEach()
4613 // o: Object?
4614 // an optional context for f and g
4615 return function(){
4616 var a = arguments, body = loopBody(f, a, o);
4617 if(g.call(o || dojo.global, a)){
4618 return this.map(body); // self
4619 }
4620 this.forEach(body);
4621 return this; // self
4622 };
4623 };
4624
4625 var NodeList = function(array){
4626 // summary:
4627 // Array-like object which adds syntactic
4628 // sugar for chaining, common iteration operations, animation, and
4629 // node manipulation. NodeLists are most often returned as the
4630 // result of dojo.query() calls.
4631 // description:
4632 // NodeList instances provide many utilities that reflect
4633 // core Dojo APIs for Array iteration and manipulation, DOM
4634 // manipulation, and event handling. Instead of needing to dig up
4635 // functions in the dojo.* namespace, NodeLists generally make the
4636 // full power of Dojo available for DOM manipulation tasks in a
4637 // simple, chainable way.
4638 // example:
4639 // create a node list from a node
4640 // | new query.NodeList(dojo.byId("foo"));
4641 // example:
4642 // get a NodeList from a CSS query and iterate on it
4643 // | var l = dojo.query(".thinger");
4644 // | l.forEach(function(node, index, nodeList){
4645 // | console.log(index, node.innerHTML);
4646 // | });
4647 // example:
4648 // use native and Dojo-provided array methods to manipulate a
4649 // NodeList without needing to use dojo.* functions explicitly:
4650 // | var l = dojo.query(".thinger");
4651 // | // since NodeLists are real arrays, they have a length
4652 // | // property that is both readable and writable and
4653 // | // push/pop/shift/unshift methods
4654 // | console.log(l.length);
4655 // | l.push(dojo.create("span"));
4656 // |
4657 // | // dojo's normalized array methods work too:
4658 // | console.log( l.indexOf(dojo.byId("foo")) );
4659 // | // ...including the special "function as string" shorthand
4660 // | console.log( l.every("item.nodeType == 1") );
4661 // |
4662 // | // NodeLists can be [..] indexed, or you can use the at()
4663 // | // function to get specific items wrapped in a new NodeList:
4664 // | var node = l[3]; // the 4th element
4665 // | var newList = l.at(1, 3); // the 2nd and 4th elements
4666 // example:
4667 // the style functions you expect are all there too:
4668 // | // style() as a getter...
4669 // | var borders = dojo.query(".thinger").style("border");
4670 // | // ...and as a setter:
4671 // | dojo.query(".thinger").style("border", "1px solid black");
4672 // | // class manipulation
4673 // | dojo.query("li:nth-child(even)").addClass("even");
4674 // | // even getting the coordinates of all the items
4675 // | var coords = dojo.query(".thinger").coords();
4676 // example:
4677 // DOM manipulation functions from the dojo.* namespace area also available:
4678 // | // remove all of the elements in the list from their
4679 // | // parents (akin to "deleting" them from the document)
4680 // | dojo.query(".thinger").orphan();
4681 // | // place all elements in the list at the front of #foo
4682 // | dojo.query(".thinger").place("foo", "first");
4683 // example:
4684 // Event handling couldn't be easier. `dojo.connect` is mapped in,
4685 // and shortcut handlers are provided for most DOM events:
4686 // | // like dojo.connect(), but with implicit scope
4687 // | dojo.query("li").connect("onclick", console, "log");
4688 // |
4689 // | // many common event handlers are already available directly:
4690 // | dojo.query("li").onclick(console, "log");
4691 // | var toggleHovered = dojo.hitch(dojo, "toggleClass", "hovered");
4692 // | dojo.query("p")
4693 // | .onmouseenter(toggleHovered)
4694 // | .onmouseleave(toggleHovered);
4695 // example:
4696 // chainability is a key advantage of NodeLists:
4697 // | dojo.query(".thinger")
4698 // | .onclick(function(e){ /* ... */ })
4699 // | .at(1, 3, 8) // get a subset
4700 // | .style("padding", "5px")
4701 // | .forEach(console.log);
4702 var isNew = this instanceof nl && has("array-extensible");
4703 if(typeof array == "number"){
4704 array = Array(array);
4705 }
4706 var nodeArray = (array && "length" in array) ? array : arguments;
4707 if(isNew || !nodeArray.sort){
4708 // make sure it's a real array before we pass it on to be wrapped
4709 var target = isNew ? this : [],
4710 l = target.length = nodeArray.length;
4711 for(var i = 0; i < l; i++){
4712 target[i] = nodeArray[i];
4713 }
4714 if(isNew){
4715 // called with new operator, this means we are going to use this instance and push
4716 // the nodes on to it. This is usually much faster since the NodeList properties
4717 // don't need to be copied (unless the list of nodes is extremely large).
4718 return target;
4719 }
4720 nodeArray = target;
4721 }
4722 // called without new operator, use a real array and copy prototype properties,
4723 // this is slower and exists for back-compat. Should be removed in 2.0.
4724 lang._mixin(nodeArray, nlp);
4725 nodeArray._NodeListCtor = function(array){
4726 // call without new operator to preserve back-compat behavior
4727 return nl(array);
4728 };
4729 return nodeArray;
4730 };
4731
4732 var nl = NodeList, nlp = nl.prototype =
4733 has("array-extensible") ? [] : {};// extend an array if it is extensible
4734
4735 // expose adapters and the wrapper as private functions
4736
4737 nl._wrap = nlp._wrap = tnl;
4738 nl._adaptAsMap = adaptAsMap;
4739 nl._adaptAsForEach = adaptAsForEach;
4740 nl._adaptAsFilter = adaptAsFilter;
4741 nl._adaptWithCondition = adaptWithCondition;
4742
4743 // mass assignment
4744
4745 // add array redirectors
4746 forEach(["slice", "splice"], function(name){
4747 var f = ap[name];
4748 //Use a copy of the this array via this.slice() to allow .end() to work right in the splice case.
4749 // CANNOT apply ._stash()/end() to splice since it currently modifies
4750 // the existing this array -- it would break backward compatibility if we copy the array before
4751 // the splice so that we can use .end(). So only doing the stash option to this._wrap for slice.
4752 nlp[name] = function(){ return this._wrap(f.apply(this, arguments), name == "slice" ? this : null); };
4753 });
4754 // concat should be here but some browsers with native NodeList have problems with it
4755
4756 // add array.js redirectors
4757 forEach(["indexOf", "lastIndexOf", "every", "some"], function(name){
4758 var f = array[name];
4759 nlp[name] = function(){ return f.apply(dojo, [this].concat(aps.call(arguments, 0))); };
4760 });
4761
4762 lang.extend(NodeList, {
4763 // copy the constructors
4764 constructor: nl,
4765 _NodeListCtor: nl,
4766 toString: function(){
4767 // Array.prototype.toString can't be applied to objects, so we use join
4768 return this.join(",");
4769 },
4770 _stash: function(parent){
4771 // summary:
4772 // private function to hold to a parent NodeList. end() to return the parent NodeList.
4773 //
4774 // example:
4775 // How to make a `dojo/NodeList` method that only returns the third node in
4776 // the dojo/NodeList but allows access to the original NodeList by using this._stash:
4777 // | dojo.extend(NodeList, {
4778 // | third: function(){
4779 // | var newNodeList = NodeList(this[2]);
4780 // | return newNodeList._stash(this);
4781 // | }
4782 // | });
4783 // | // then see how _stash applies a sub-list, to be .end()'ed out of
4784 // | dojo.query(".foo")
4785 // | .third()
4786 // | .addClass("thirdFoo")
4787 // | .end()
4788 // | // access to the orig .foo list
4789 // | .removeClass("foo")
4790 // |
4791 //
4792 this._parent = parent;
4793 return this; // dojo/NodeList
4794 },
4795
4796 on: function(eventName, listener){
4797 // summary:
4798 // Listen for events on the nodes in the NodeList. Basic usage is:
4799 // | query(".my-class").on("click", listener);
4800 // This supports event delegation by using selectors as the first argument with the event names as
4801 // pseudo selectors. For example:
4802 // | dojo.query("#my-list").on("li:click", listener);
4803 // This will listen for click events within `<li>` elements that are inside the `#my-list` element.
4804 // Because on supports CSS selector syntax, we can use comma-delimited events as well:
4805 // | dojo.query("#my-list").on("li button:mouseover, li:click", listener);
4806 var handles = this.map(function(node){
4807 return on(node, eventName, listener); // TODO: apply to the NodeList so the same selector engine is used for matches
4808 });
4809 handles.remove = function(){
4810 for(var i = 0; i < handles.length; i++){
4811 handles[i].remove();
4812 }
4813 };
4814 return handles;
4815 },
4816
4817 end: function(){
4818 // summary:
4819 // Ends use of the current `NodeList` by returning the previous NodeList
4820 // that generated the current NodeList.
4821 // description:
4822 // Returns the `NodeList` that generated the current `NodeList`. If there
4823 // is no parent NodeList, an empty NodeList is returned.
4824 // example:
4825 // | dojo.query("a")
4826 // | .filter(".disabled")
4827 // | // operate on the anchors that only have a disabled class
4828 // | .style("color", "grey")
4829 // | .end()
4830 // | // jump back to the list of anchors
4831 // | .style(...)
4832 //
4833 if(this._parent){
4834 return this._parent;
4835 }else{
4836 //Just return empty list.
4837 return new this._NodeListCtor(0);
4838 }
4839 },
4840
4841 // http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array#Methods
4842
4843 // FIXME: handle return values for #3244
4844 // http://trac.dojotoolkit.org/ticket/3244
4845
4846 // FIXME:
4847 // need to wrap or implement:
4848 // join (perhaps w/ innerHTML/outerHTML overload for toString() of items?)
4849 // reduce
4850 // reduceRight
4851
4852 /*=====
4853 slice: function(begin, end){
4854 // summary:
4855 // Returns a new NodeList, maintaining this one in place
4856 // description:
4857 // This method behaves exactly like the Array.slice method
4858 // with the caveat that it returns a dojo/NodeList and not a
4859 // raw Array. For more details, see Mozilla's [slice
4860 // documentation](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/slice)
4861 // begin: Integer
4862 // Can be a positive or negative integer, with positive
4863 // integers noting the offset to begin at, and negative
4864 // integers denoting an offset from the end (i.e., to the left
4865 // of the end)
4866 // end: Integer?
4867 // Optional parameter to describe what position relative to
4868 // the NodeList's zero index to end the slice at. Like begin,
4869 // can be positive or negative.
4870 return this._wrap(a.slice.apply(this, arguments));
4871 },
4872
4873 splice: function(index, howmany, item){
4874 // summary:
4875 // Returns a new NodeList, manipulating this NodeList based on
4876 // the arguments passed, potentially splicing in new elements
4877 // at an offset, optionally deleting elements
4878 // description:
4879 // This method behaves exactly like the Array.splice method
4880 // with the caveat that it returns a dojo/NodeList and not a
4881 // raw Array. For more details, see Mozilla's [splice
4882 // documentation](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/splice)
4883 // For backwards compatibility, calling .end() on the spliced NodeList
4884 // does not return the original NodeList -- splice alters the NodeList in place.
4885 // index: Integer
4886 // begin can be a positive or negative integer, with positive
4887 // integers noting the offset to begin at, and negative
4888 // integers denoting an offset from the end (i.e., to the left
4889 // of the end)
4890 // howmany: Integer?
4891 // Optional parameter to describe what position relative to
4892 // the NodeList's zero index to end the slice at. Like begin,
4893 // can be positive or negative.
4894 // item: Object...?
4895 // Any number of optional parameters may be passed in to be
4896 // spliced into the NodeList
4897 return this._wrap(a.splice.apply(this, arguments)); // dojo/NodeList
4898 },
4899
4900 indexOf: function(value, fromIndex){
4901 // summary:
4902 // see dojo.indexOf(). The primary difference is that the acted-on
4903 // array is implicitly this NodeList
4904 // value: Object
4905 // The value to search for.
4906 // fromIndex: Integer?
4907 // The location to start searching from. Optional. Defaults to 0.
4908 // description:
4909 // For more details on the behavior of indexOf, see Mozilla's
4910 // [indexOf
4911 // docs](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf)
4912 // returns:
4913 // Positive Integer or 0 for a match, -1 of not found.
4914 return d.indexOf(this, value, fromIndex); // Integer
4915 },
4916
4917 lastIndexOf: function(value, fromIndex){
4918 // summary:
4919 // see dojo.lastIndexOf(). The primary difference is that the
4920 // acted-on array is implicitly this NodeList
4921 // description:
4922 // For more details on the behavior of lastIndexOf, see
4923 // Mozilla's [lastIndexOf
4924 // docs](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/lastIndexOf)
4925 // value: Object
4926 // The value to search for.
4927 // fromIndex: Integer?
4928 // The location to start searching from. Optional. Defaults to 0.
4929 // returns:
4930 // Positive Integer or 0 for a match, -1 of not found.
4931 return d.lastIndexOf(this, value, fromIndex); // Integer
4932 },
4933
4934 every: function(callback, thisObject){
4935 // summary:
4936 // see `dojo.every()` and the [Array.every
4937 // docs](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/every).
4938 // Takes the same structure of arguments and returns as
4939 // dojo.every() with the caveat that the passed array is
4940 // implicitly this NodeList
4941 // callback: Function
4942 // the callback
4943 // thisObject: Object?
4944 // the context
4945 return d.every(this, callback, thisObject); // Boolean
4946 },
4947
4948 some: function(callback, thisObject){
4949 // summary:
4950 // Takes the same structure of arguments and returns as
4951 // `dojo.some()` with the caveat that the passed array is
4952 // implicitly this NodeList. See `dojo.some()` and Mozilla's
4953 // [Array.some
4954 // documentation](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/some).
4955 // callback: Function
4956 // the callback
4957 // thisObject: Object?
4958 // the context
4959 return d.some(this, callback, thisObject); // Boolean
4960 },
4961 =====*/
4962
4963 concat: function(item){
4964 // summary:
4965 // Returns a new NodeList comprised of items in this NodeList
4966 // as well as items passed in as parameters
4967 // description:
4968 // This method behaves exactly like the Array.concat method
4969 // with the caveat that it returns a `NodeList` and not a
4970 // raw Array. For more details, see the [Array.concat
4971 // docs](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/concat)
4972 // item: Object?
4973 // Any number of optional parameters may be passed in to be
4974 // spliced into the NodeList
4975
4976 //return this._wrap(apc.apply(this, arguments));
4977 // the line above won't work for the native NodeList, or for Dojo NodeLists either :-(
4978
4979 // implementation notes:
4980 // Array.concat() doesn't recognize native NodeLists or Dojo NodeLists
4981 // as arrays, and so does not inline them into a unioned array, but
4982 // appends them as single entities. Both the original NodeList and the
4983 // items passed in as parameters must be converted to raw Arrays
4984 // and then the concatenation result may be re-_wrap()ed as a Dojo NodeList.
4985
4986 var t = aps.call(this, 0),
4987 m = array.map(arguments, function(a){
4988 return aps.call(a, 0);
4989 });
4990 return this._wrap(apc.apply(t, m), this); // dojo/NodeList
4991 },
4992
4993 map: function(/*Function*/ func, /*Function?*/ obj){
4994 // summary:
4995 // see dojo.map(). The primary difference is that the acted-on
4996 // array is implicitly this NodeList and the return is a
4997 // NodeList (a subclass of Array)
4998 return this._wrap(array.map(this, func, obj), this); // dojo/NodeList
4999 },
5000
5001 forEach: function(callback, thisObj){
5002 // summary:
5003 // see `dojo.forEach()`. The primary difference is that the acted-on
5004 // array is implicitly this NodeList. If you want the option to break out
5005 // of the forEach loop, use every() or some() instead.
5006 forEach(this, callback, thisObj);
5007 // non-standard return to allow easier chaining
5008 return this; // dojo/NodeList
5009 },
5010 filter: function(/*String|Function*/ filter){
5011 // summary:
5012 // "masks" the built-in javascript filter() method (supported
5013 // in Dojo via `dojo.filter`) to support passing a simple
5014 // string filter in addition to supporting filtering function
5015 // objects.
5016 // filter:
5017 // If a string, a CSS rule like ".thinger" or "div > span".
5018 // example:
5019 // "regular" JS filter syntax as exposed in dojo.filter:
5020 // | dojo.query("*").filter(function(item){
5021 // | // highlight every paragraph
5022 // | return (item.nodeName == "p");
5023 // | }).style("backgroundColor", "yellow");
5024 // example:
5025 // the same filtering using a CSS selector
5026 // | dojo.query("*").filter("p").styles("backgroundColor", "yellow");
5027
5028 var a = arguments, items = this, start = 0;
5029 if(typeof filter == "string"){ // inline'd type check
5030 items = query._filterResult(this, a[0]);
5031 if(a.length == 1){
5032 // if we only got a string query, pass back the filtered results
5033 return items._stash(this); // dojo/NodeList
5034 }
5035 // if we got a callback, run it over the filtered items
5036 start = 1;
5037 }
5038 return this._wrap(array.filter(items, a[start], a[start + 1]), this); // dojo/NodeList
5039 },
5040 instantiate: function(/*String|Object*/ declaredClass, /*Object?*/ properties){
5041 // summary:
5042 // Create a new instance of a specified class, using the
5043 // specified properties and each node in the NodeList as a
5044 // srcNodeRef.
5045 // example:
5046 // Grabs all buttons in the page and converts them to dijit/form/Button's.
5047 // | var buttons = query("button").instantiate(Button, {showLabel: true});
5048 var c = lang.isFunction(declaredClass) ? declaredClass : lang.getObject(declaredClass);
5049 properties = properties || {};
5050 return this.forEach(function(node){
5051 new c(properties, node);
5052 }); // dojo/NodeList
5053 },
5054 at: function(/*===== index =====*/){
5055 // summary:
5056 // Returns a new NodeList comprised of items in this NodeList
5057 // at the given index or indices.
5058 //
5059 // index: Integer...
5060 // One or more 0-based indices of items in the current
5061 // NodeList. A negative index will start at the end of the
5062 // list and go backwards.
5063 //
5064 // example:
5065 // Shorten the list to the first, second, and third elements
5066 // | query("a").at(0, 1, 2).forEach(fn);
5067 //
5068 // example:
5069 // Retrieve the first and last elements of a unordered list:
5070 // | query("ul > li").at(0, -1).forEach(cb);
5071 //
5072 // example:
5073 // Do something for the first element only, but end() out back to
5074 // the original list and continue chaining:
5075 // | query("a").at(0).onclick(fn).end().forEach(function(n){
5076 // | console.log(n); // all anchors on the page.
5077 // | })
5078
5079 var t = new this._NodeListCtor(0);
5080 forEach(arguments, function(i){
5081 if(i < 0){ i = this.length + i; }
5082 if(this[i]){ t.push(this[i]); }
5083 }, this);
5084 return t._stash(this); // dojo/NodeList
5085 }
5086 });
5087
5088 function queryForEngine(engine, NodeList){
5089 var query = function(/*String*/ query, /*String|DOMNode?*/ root){
5090 // summary:
5091 // Returns nodes which match the given CSS selector, searching the
5092 // entire document by default but optionally taking a node to scope
5093 // the search by. Returns an instance of NodeList.
5094 if(typeof root == "string"){
5095 root = dom.byId(root);
5096 if(!root){
5097 return new NodeList([]);
5098 }
5099 }
5100 var results = typeof query == "string" ? engine(query, root) : query ? query.orphan ? query : [query] : [];
5101 if(results.orphan){
5102 // already wrapped
5103 return results;
5104 }
5105 return new NodeList(results);
5106 };
5107 query.matches = engine.match || function(node, selector, root){
5108 // summary:
5109 // Test to see if a node matches a selector
5110 return query.filter([node], selector, root).length > 0;
5111 };
5112 // the engine provides a filtering function, use it to for matching
5113 query.filter = engine.filter || function(nodes, selector, root){
5114 // summary:
5115 // Filters an array of nodes. Note that this does not guarantee to return a NodeList, just an array.
5116 return query(selector, root).filter(function(node){
5117 return array.indexOf(nodes, node) > -1;
5118 });
5119 };
5120 if(typeof engine != "function"){
5121 var search = engine.search;
5122 engine = function(selector, root){
5123 // Slick does it backwards (or everyone else does it backwards, probably the latter)
5124 return search(root || document, selector);
5125 };
5126 }
5127 return query;
5128 }
5129 var query = queryForEngine(defaultEngine, NodeList);
5130 /*=====
5131 query = function(selector, context){
5132 // summary:
5133 // This modules provides DOM querying functionality. The module export is a function
5134 // that can be used to query for DOM nodes by CSS selector and returns a NodeList
5135 // representing the matching nodes.
5136 // selector: String
5137 // A CSS selector to search for.
5138 // context: String|DomNode?
5139 // An optional context to limit the searching scope. Only nodes under `context` will be
5140 // scanned.
5141 // example:
5142 // add an onclick handler to every submit button in the document
5143 // which causes the form to be sent via Ajax instead:
5144 // | require(["dojo/query"], function(query){
5145 // | query("input[type='submit']").on("click", function(e){
5146 // | dojo.stopEvent(e); // prevent sending the form
5147 // | var btn = e.target;
5148 // | dojo.xhrPost({
5149 // | form: btn.form,
5150 // | load: function(data){
5151 // | // replace the form with the response
5152 // | var div = dojo.doc.createElement("div");
5153 // | dojo.place(div, btn.form, "after");
5154 // | div.innerHTML = data;
5155 // | dojo.style(btn.form, "display", "none");
5156 // | }
5157 // | });
5158 // | });
5159 // | });
5160 //
5161 // description:
5162 // dojo/query is responsible for loading the appropriate query engine and wrapping
5163 // its results with a `NodeList`. You can use dojo/query with a specific selector engine
5164 // by using it as a plugin. For example, if you installed the sizzle package, you could
5165 // use it as the selector engine with:
5166 // | require(["dojo/query!sizzle"], function(query){
5167 // | query("div")...
5168 //
5169 // The id after the ! can be a module id of the selector engine or one of the following values:
5170 //
5171 // - acme: This is the default engine used by Dojo base, and will ensure that the full
5172 // Acme engine is always loaded.
5173 //
5174 // - css2: If the browser has a native selector engine, this will be used, otherwise a
5175 // very minimal lightweight selector engine will be loaded that can do simple CSS2 selectors
5176 // (by #id, .class, tag, and [name=value] attributes, with standard child or descendant (>)
5177 // operators) and nothing more.
5178 //
5179 // - css2.1: If the browser has a native selector engine, this will be used, otherwise the
5180 // full Acme engine will be loaded.
5181 //
5182 // - css3: If the browser has a native selector engine with support for CSS3 pseudo
5183 // selectors (most modern browsers except IE8), this will be used, otherwise the
5184 // full Acme engine will be loaded.
5185 //
5186 // - Or the module id of a selector engine can be used to explicitly choose the selector engine
5187 //
5188 // For example, if you are using CSS3 pseudo selectors in module, you can specify that
5189 // you will need support them with:
5190 // | require(["dojo/query!css3"], function(query){
5191 // | query('#t > h3:nth-child(odd)')...
5192 //
5193 // You can also choose the selector engine/load configuration by setting the query-selector:
5194 // For example:
5195 // | <script data-dojo-config="query-selector:'css3'" src="dojo.js"></script>
5196 //
5197 return new NodeList(); // dojo/NodeList
5198 };
5199 =====*/
5200
5201 // the query that is returned from this module is slightly different than dojo.query,
5202 // because dojo.query has to maintain backwards compatibility with returning a
5203 // true array which has performance problems. The query returned from the module
5204 // does not use true arrays, but rather inherits from Array, making it much faster to
5205 // instantiate.
5206 dojo.query = queryForEngine(defaultEngine, function(array){
5207 // call it without the new operator to invoke the back-compat behavior that returns a true array
5208 return NodeList(array); // dojo/NodeList
5209 });
5210
5211 query.load = function(id, parentRequire, loaded){
5212 // summary:
5213 // can be used as AMD plugin to conditionally load new query engine
5214 // example:
5215 // | require(["dojo/query!custom"], function(qsa){
5216 // | // loaded selector/custom.js as engine
5217 // | qsa("#foobar").forEach(...);
5218 // | });
5219 loader.load(id, parentRequire, function(engine){
5220 loaded(queryForEngine(engine, NodeList));
5221 });
5222 };
5223
5224 dojo._filterQueryResult = query._filterResult = function(nodes, selector, root){
5225 return new NodeList(query.filter(nodes, selector, root));
5226 };
5227 dojo.NodeList = query.NodeList = NodeList;
5228 return query;
5229 });
5230
5231 },
5232 'dojo/has':function(){
5233 define(["require", "module"], function(require, module){
5234 // module:
5235 // dojo/has
5236 // summary:
5237 // Defines the has.js API and several feature tests used by dojo.
5238 // description:
5239 // This module defines the has API as described by the project has.js with the following additional features:
5240 //
5241 // - the has test cache is exposed at has.cache.
5242 // - the method has.add includes a forth parameter that controls whether or not existing tests are replaced
5243 // - the loader's has cache may be optionally copied into this module's has cahce.
5244 //
5245 // This module adopted from https://github.com/phiggins42/has.js; thanks has.js team!
5246
5247 // try to pull the has implementation from the loader; both the dojo loader and bdLoad provide one
5248 // if using a foreign loader, then the has cache may be initialized via the config object for this module
5249 // WARNING: if a foreign loader defines require.has to be something other than the has.js API, then this implementation fail
5250 var has = require.has || function(){};
5251 if(! 1 ){
5252 var
5253 isBrowser =
5254 // the most fundamental decision: are we in the browser?
5255 typeof window != "undefined" &&
5256 typeof location != "undefined" &&
5257 typeof document != "undefined" &&
5258 window.location == location && window.document == document,
5259
5260 // has API variables
5261 global = this,
5262 doc = isBrowser && document,
5263 element = doc && doc.createElement("DiV"),
5264 cache = (module.config && module.config()) || {};
5265
5266 has = function(name){
5267 // summary:
5268 // Return the current value of the named feature.
5269 //
5270 // name: String|Integer
5271 // The name (if a string) or identifier (if an integer) of the feature to test.
5272 //
5273 // description:
5274 // Returns the value of the feature named by name. The feature must have been
5275 // previously added to the cache by has.add.
5276
5277 return typeof cache[name] == "function" ? (cache[name] = cache[name](global, doc, element)) : cache[name]; // Boolean
5278 };
5279
5280 has.cache = cache;
5281
5282 has.add = function(name, test, now, force){
5283 // summary:
5284 // Register a new feature test for some named feature.
5285 // name: String|Integer
5286 // The name (if a string) or identifier (if an integer) of the feature to test.
5287 // test: Function
5288 // A test function to register. If a function, queued for testing until actually
5289 // needed. The test function should return a boolean indicating
5290 // the presence of a feature or bug.
5291 // now: Boolean?
5292 // Optional. Omit if `test` is not a function. Provides a way to immediately
5293 // run the test and cache the result.
5294 // force: Boolean?
5295 // Optional. If the test already exists and force is truthy, then the existing
5296 // test will be replaced; otherwise, add does not replace an existing test (that
5297 // is, by default, the first test advice wins).
5298 // example:
5299 // A redundant test, testFn with immediate execution:
5300 // | has.add("javascript", function(){ return true; }, true);
5301 //
5302 // example:
5303 // Again with the redundantness. You can do this in your tests, but we should
5304 // not be doing this in any internal has.js tests
5305 // | has.add("javascript", true);
5306 //
5307 // example:
5308 // Three things are passed to the testFunction. `global`, `document`, and a generic element
5309 // from which to work your test should the need arise.
5310 // | has.add("bug-byid", function(g, d, el){
5311 // | // g == global, typically window, yadda yadda
5312 // | // d == document object
5313 // | // el == the generic element. a `has` element.
5314 // | return false; // fake test, byid-when-form-has-name-matching-an-id is slightly longer
5315 // | });
5316
5317 (typeof cache[name]=="undefined" || force) && (cache[name]= test);
5318 return now && has(name);
5319 };
5320
5321 // since we're operating under a loader that doesn't provide a has API, we must explicitly initialize
5322 // has as it would have otherwise been initialized by the dojo loader; use has.add to the builder
5323 // can optimize these away iff desired
5324 1 || has.add("host-browser", isBrowser);
5325 1 || has.add("dom", isBrowser);
5326 1 || has.add("dojo-dom-ready-api", 1);
5327 1 || has.add("dojo-sniff", 1);
5328 }
5329
5330 if( 1 ){
5331 // Common application level tests
5332 has.add("dom-addeventlistener", !!document.addEventListener);
5333 has.add("touch", "ontouchstart" in document);
5334 // I don't know if any of these tests are really correct, just a rough guess
5335 has.add("device-width", screen.availWidth || innerWidth);
5336
5337 // Tests for DOMNode.attributes[] behavior:
5338 // - dom-attributes-explicit - attributes[] only lists explicitly user specified attributes
5339 // - dom-attributes-specified-flag (IE8) - need to check attr.specified flag to skip attributes user didn't specify
5340 // - Otherwise, in IE6-7. attributes[] will list hundreds of values, so need to do outerHTML to get attrs instead.
5341 var form = document.createElement("form");
5342 has.add("dom-attributes-explicit", form.attributes.length == 0); // W3C
5343 has.add("dom-attributes-specified-flag", form.attributes.length > 0 && form.attributes.length < 40); // IE8
5344 }
5345
5346 has.clearElement = function(element){
5347 // summary:
5348 // Deletes the contents of the element passed to test functions.
5349 element.innerHTML= "";
5350 return element;
5351 };
5352
5353 has.normalize = function(id, toAbsMid){
5354 // summary:
5355 // Resolves id into a module id based on possibly-nested tenary expression that branches on has feature test value(s).
5356 //
5357 // toAbsMid: Function
5358 // Resolves a relative module id into an absolute module id
5359 var
5360 tokens = id.match(/[\?:]|[^:\?]*/g), i = 0,
5361 get = function(skip){
5362 var term = tokens[i++];
5363 if(term == ":"){
5364 // empty string module name, resolves to 0
5365 return 0;
5366 }else{
5367 // postfixed with a ? means it is a feature to branch on, the term is the name of the feature
5368 if(tokens[i++] == "?"){
5369 if(!skip && has(term)){
5370 // matched the feature, get the first value from the options
5371 return get();
5372 }else{
5373 // did not match, get the second value, passing over the first
5374 get(true);
5375 return get(skip);
5376 }
5377 }
5378 // a module
5379 return term || 0;
5380 }
5381 };
5382 id = get();
5383 return id && toAbsMid(id);
5384 };
5385
5386 has.load = function(id, parentRequire, loaded){
5387 // summary:
5388 // Conditional loading of AMD modules based on a has feature test value.
5389 // id: String
5390 // Gives the resolved module id to load.
5391 // parentRequire: Function
5392 // The loader require function with respect to the module that contained the plugin resource in it's
5393 // dependency list.
5394 // loaded: Function
5395 // Callback to loader that consumes result of plugin demand.
5396
5397 if(id){
5398 parentRequire([id], loaded);
5399 }else{
5400 loaded();
5401 }
5402 };
5403
5404 return has;
5405 });
5406
5407 },
5408 'dojo/_base/loader':function(){
5409 define(["./kernel", "../has", "require", "module", "./json", "./lang", "./array"], function(dojo, has, require, thisModule, json, lang, array) {
5410 // module:
5411 // dojo/_base/loader
5412
5413 // This module defines the v1.x synchronous loader API.
5414
5415 // signal the loader in sync mode...
5416 //>>pure-amd
5417
5418 if (! 1 ){
5419 console.error("cannot load the Dojo v1.x loader with a foreign loader");
5420 return 0;
5421 }
5422
5423 1 || has.add("dojo-fast-sync-require", 1);
5424
5425
5426 var makeErrorToken = function(id){
5427 return {src:thisModule.id, id:id};
5428 },
5429
5430 slashName = function(name){
5431 return name.replace(/\./g, "/");
5432 },
5433
5434 buildDetectRe = /\/\/>>built/,
5435
5436 dojoRequireCallbacks = [],
5437 dojoRequireModuleStack = [],
5438
5439 dojoRequirePlugin = function(mid, require, loaded){
5440 dojoRequireCallbacks.push(loaded);
5441 array.forEach(mid.split(","), function(mid){
5442 var module = getModule(mid, require.module);
5443 dojoRequireModuleStack.push(module);
5444 injectModule(module);
5445 });
5446 checkDojoRequirePlugin();
5447 },
5448
5449 checkDojoRequirePlugin = ( 1 ?
5450 // This version of checkDojoRequirePlugin makes the observation that all dojoRequireCallbacks can be released
5451 // when all *non-dojo/require!, dojo/loadInit!* modules are either executed, not requested, or arrived. This is
5452 // the case since there are no more modules the loader is waiting for, therefore, dojo/require! must have
5453 // everything it needs on board.
5454 //
5455 // The potential weakness of this algorithm is that dojo/require will not execute callbacks until *all* dependency
5456 // trees are ready. It is possible that some trees may be ready earlier than others, and this extra wait is non-optimal.
5457 // Still, for big projects, this seems better than the original algorithm below that proved slow in some cases.
5458 // Note, however, the original algorithm had the potential to execute partial trees, but that potential was never enabled.
5459 // There are also other optimization available with the original algorithm that have not been explored.
5460 function(){
5461 var module, mid;
5462 for(mid in modules){
5463 module = modules[mid];
5464 if(module.noReqPluginCheck===undefined){
5465 // tag the module as either a loadInit or require plugin or not for future reference
5466 module.noReqPluginCheck = /loadInit\!/.test(mid) || /require\!/.test(mid) ? 1 : 0;
5467 }
5468 if(!module.executed && !module.noReqPluginCheck && module.injected==requested){
5469 return;
5470 }
5471 }
5472
5473 guardCheckComplete(function(){
5474 var oldCallbacks = dojoRequireCallbacks;
5475 dojoRequireCallbacks = [];
5476 array.forEach(oldCallbacks, function(cb){cb(1);});
5477 });
5478 } : (function(){
5479 // Note: this is the original checkDojoRequirePlugin that is much slower than the algorithm above. However, we know it
5480 // works, so we leave it here in case the algorithm above fails in some corner case.
5481 //
5482 // checkDojoRequirePlugin inspects all of the modules demanded by a dojo/require!<module-list> dependency
5483 // to see if they have arrived. The loader does not release *any* of these modules to be instantiated
5484 // until *all* of these modules are on board, thereby preventing the evaluation of a module with dojo.require's
5485 // that reference modules that are not available.
5486 //
5487 // The algorithm works by traversing the dependency graphs (remember, there can be cycles so they are not trees)
5488 // of each module in the dojoRequireModuleStack array (which contains the list of modules demanded by dojo/require!).
5489 // The moment a single module is discovered that is missing, the algorithm gives up and indicates that not all
5490 // modules are on board. dojo/loadInit! and dojo/require! are ignored because there dependencies are inserted
5491 // directly in dojoRequireModuleStack. For example, if "your/module" module depends on "dojo/require!my/module", then
5492 // *both* "dojo/require!my/module" and "my/module" will be in dojoRequireModuleStack. Obviously, if "my/module"
5493 // is on board, then "dojo/require!my/module" is also satisfied, so the algorithm doesn't check for "dojo/require!my/module".
5494 //
5495 // Note: inserting a dojo/require!<some-module-list> dependency in the dojoRequireModuleStack achieves nothing
5496 // with the current algorithm; however, having such modules present makes it possible to optimize the algorithm
5497 //
5498 // Note: prior versions of this algorithm had an optimization that signaled loaded on dojo/require! dependencies
5499 // individually (rather than waiting for them all to be resolved). The implementation proved problematic with cycles
5500 // and plugins. However, it is possible to reattach that strategy in the future.
5501
5502 // a set from module-id to {undefined | 1 | 0}, where...
5503 // undefined => the module has not been inspected
5504 // 0 => the module or at least one of its dependencies has not arrived
5505 // 1 => the module is a loadInit! or require! plugin resource, or is currently being traversed (therefore, assume
5506 // OK until proven otherwise), or has been completely traversed and all dependencies have arrived
5507
5508 var touched,
5509 traverse = function(m){
5510 touched[m.mid] = 1;
5511 for(var t, module, deps = m.deps || [], i= 0; i<deps.length; i++){
5512 module = deps[i];
5513 if(!(t = touched[module.mid])){
5514 if(t===0 || !traverse(module)){
5515 touched[m.mid] = 0;
5516 return false;
5517 }
5518 }
5519 }
5520 return true;
5521 };
5522
5523 return function(){
5524 // initialize the touched hash with easy-to-compute values that help short circuit recursive algorithm;
5525 // recall loadInit/require plugin modules are dependencies of modules in dojoRequireModuleStack...
5526 // which would cause a circular dependency chain that would never be resolved if checked here
5527 // notice all dependencies of any particular loadInit/require plugin module will already
5528 // be checked since those are pushed into dojoRequireModuleStack explicitly by the
5529 // plugin...so if a particular loadInitPlugin module's dependencies are not really
5530 // on board, that *will* be detected elsewhere in the traversal.
5531 var module, mid;
5532 touched = {};
5533 for(mid in modules){
5534 module = modules[mid];
5535 if(module.executed || module.noReqPluginCheck){
5536 touched[mid] = 1;
5537 }else{
5538 if(module.noReqPluginCheck!==0){
5539 // tag the module as either a loadInit or require plugin or not for future reference
5540 module.noReqPluginCheck = /loadInit\!/.test(mid) || /require\!/.test(mid) ? 1 : 0;
5541 }
5542 if(module.noReqPluginCheck){
5543 touched[mid] = 1;
5544 }else if(module.injected!==arrived){
5545 // not executed, has not arrived, and is not a loadInit or require plugin resource
5546 touched[mid] = 0;
5547 }// else, leave undefined and we'll traverse the dependencies
5548 }
5549 }
5550 for(var t, i = 0, end = dojoRequireModuleStack.length; i<end; i++){
5551 module = dojoRequireModuleStack[i];
5552 if(!(t = touched[module.mid])){
5553 if(t===0 || !traverse(module)){
5554 return;
5555 }
5556 }
5557 }
5558 guardCheckComplete(function(){
5559 var oldCallbacks = dojoRequireCallbacks;
5560 dojoRequireCallbacks = [];
5561 array.forEach(oldCallbacks, function(cb){cb(1);});
5562 });
5563 };
5564 })()),
5565
5566 dojoLoadInitPlugin = function(mid, require, loaded){
5567 // mid names a module that defines a "dojo load init" bundle, an object with two properties:
5568 //
5569 // * names: a vector of module ids that give top-level names to define in the lexical scope of def
5570 // * def: a function that contains some some legacy loader API applications
5571 //
5572 // The point of def is to possibly cause some modules to be loaded (but not executed) by dojo/require! where the module
5573 // ids are possibly-determined at runtime. For example, here is dojox.gfx from v1.6 expressed as an AMD module using the dojo/loadInit
5574 // and dojo/require plugins.
5575 //
5576 // // dojox/gfx:
5577 //
5578 // define("*loadInit_12, {
5579 // names:["dojo", "dijit", "dojox"],
5580 // def: function(){
5581 // dojo.loadInit(function(){
5582 // var gfx = lang.getObject("dojox.gfx", true);
5583 //
5584 // //
5585 // // code required to set gfx properties ommitted...
5586 // //
5587 //
5588 // // now use the calculations to include the runtime-dependent module
5589 // dojo.require("dojox.gfx." + gfx.renderer);
5590 // });
5591 // }
5592 // });
5593 //
5594 // define(["dojo", "dojo/loadInit!" + id].concat("dojo/require!dojox/gfx/matric,dojox/gfx/_base"), function(dojo){
5595 // // when this AMD factory function is executed, the following modules are guaranteed downloaded but not executed:
5596 // // "dojox.gfx." + gfx.renderer
5597 // // dojox.gfx.matrix
5598 // // dojox.gfx._base
5599 // dojo.provide("dojo.gfx");
5600 // dojo.require("dojox.gfx.matrix");
5601 // dojo.require("dojox.gfx._base");
5602 // dojo.require("dojox.gfx." + gfx.renderer);
5603 // return lang.getObject("dojo.gfx");
5604 // });
5605 // })();
5606 //
5607 // The idea is to run the legacy loader API with global variables shadowed, which allows these variables to
5608 // be relocated. For example, dojox and dojo could be relocated to different names by giving a map and the code above will
5609 // execute properly (because the plugin below resolves the load init bundle.names module with respect to the module that demanded
5610 // the plugin resource).
5611 //
5612 // Note that the relocation is specified in the runtime configuration; relocated names need not be set at build-time.
5613 //
5614 // Warning: this is not the best way to express dojox.gfx as and AMD module. In fact, the module has been properly converted in
5615 // v1.7. However, this technique allows the builder to convert legacy modules into AMD modules and guarantee the codepath is the
5616 // same in the converted AMD module.
5617 require([mid], function(bundle){
5618 // notice how names is resolved with respect to the module that demanded the plugin resource
5619 require(bundle.names, function(){
5620 // bring the bundle names into scope
5621 for(var scopeText = "", args= [], i = 0; i<arguments.length; i++){
5622 scopeText+= "var " + bundle.names[i] + "= arguments[" + i + "]; ";
5623 args.push(arguments[i]);
5624 }
5625 eval(scopeText);
5626
5627 var callingModule = require.module,
5628 // the list of modules that need to be downloaded but not executed before the callingModule can be executed
5629 requireList = [],
5630
5631 // the list of i18n bundles that are xdomain; undefined if none
5632 i18nDeps,
5633
5634 syncLoaderApi = {
5635 provide:function(moduleName){
5636 // mark modules that arrive consequent to multiple provides in this module as arrived since they can't be injected
5637 moduleName = slashName(moduleName);
5638 var providedModule = getModule(moduleName, callingModule);
5639 if(providedModule!==callingModule){
5640 setArrived(providedModule);
5641 }
5642 },
5643 require:function(moduleName, omitModuleCheck){
5644 moduleName = slashName(moduleName);
5645 omitModuleCheck && (getModule(moduleName, callingModule).result = nonmodule);
5646 requireList.push(moduleName);
5647 },
5648 requireLocalization:function(moduleName, bundleName, locale){
5649 // since we're going to need dojo/i8n, add it to i18nDeps if not already there
5650 if(!i18nDeps){
5651 // don't have to map since that will occur when the dependency is resolved
5652 i18nDeps = ["dojo/i18n"];
5653 }
5654
5655 // figure out if the bundle is xdomain; if so, add it to the i18nDepsSet
5656 locale = (locale || dojo.locale).toLowerCase();
5657 moduleName = slashName(moduleName) + "/nls/" + (/root/i.test(locale) ? "" : locale + "/") + slashName(bundleName);
5658 if(getModule(moduleName, callingModule).isXd){
5659 // don't have to map since that will occur when the dependency is resolved
5660 i18nDeps.push("dojo/i18n!" + moduleName);
5661 }// else the bundle will be loaded synchronously when the module is evaluated
5662 },
5663 loadInit:function(f){
5664 f();
5665 }
5666 },
5667
5668 hold = {},
5669 p;
5670
5671 // hijack the correct dojo and apply bundle.def
5672 try{
5673 for(p in syncLoaderApi){
5674 hold[p] = dojo[p];
5675 dojo[p] = syncLoaderApi[p];
5676 }
5677 bundle.def.apply(null, args);
5678 }catch(e){
5679 signal("error", [makeErrorToken("failedDojoLoadInit"), e]);
5680 }finally{
5681 for(p in syncLoaderApi){
5682 dojo[p] = hold[p];
5683 }
5684 }
5685
5686 if(i18nDeps){
5687 requireList = requireList.concat(i18nDeps);
5688 }
5689
5690 if(requireList.length){
5691 dojoRequirePlugin(requireList.join(","), require, loaded);
5692 }else{
5693 loaded();
5694 }
5695 });
5696 });
5697 },
5698
5699 extractApplication = function(
5700 text, // the text to search
5701 startSearch, // the position in text to start looking for the closing paren
5702 startApplication // the position in text where the function application expression starts
5703 ){
5704 // find end of the call by finding the matching end paren
5705 // Warning: as usual, this will fail in the presense of unmatched right parans contained in strings, regexs, or unremoved comments
5706 var parenRe = /\(|\)/g,
5707 matchCount = 1,
5708 match;
5709 parenRe.lastIndex = startSearch;
5710 while((match = parenRe.exec(text))){
5711 if(match[0] == ")"){
5712 matchCount -= 1;
5713 }else{
5714 matchCount += 1;
5715 }
5716 if(matchCount == 0){
5717 break;
5718 }
5719 }
5720
5721 if(matchCount != 0){
5722 throw "unmatched paren around character " + parenRe.lastIndex + " in: " + text;
5723 }
5724
5725 //Put the master matching string in the results.
5726 return [dojo.trim(text.substring(startApplication, parenRe.lastIndex))+";\n", parenRe.lastIndex];
5727 },
5728
5729 // the following regex is taken from 1.6. It is a very poor technique to remove comments and
5730 // will fail in some cases; for example, consider the code...
5731 //
5732 // var message = "Category-1 */* Category-2";
5733 //
5734 // The regex that follows will see a /* comment and trash the code accordingly. In fact, there are all
5735 // kinds of cases like this with strings and regexs that will cause this design to fail miserably.
5736 //
5737 // Alternative regex designs exist that will result in less-likely failures, but will still fail in many cases.
5738 // The only solution guaranteed 100% correct is to parse the code and that seems overkill for this
5739 // backcompat/unbuilt-xdomain layer. In the end, since it's been this way for a while, we won't change it.
5740 // See the opening paragraphs of Chapter 7 or ECME-262 which describes the lexical abiguity further.
5741 removeCommentRe = /(\/\*([\s\S]*?)\*\/|\/\/(.*)$)/mg,
5742
5743 syncLoaderApiRe = /(^|\s)dojo\.(loadInit|require|provide|requireLocalization|requireIf|requireAfterIf|platformRequire)\s*\(/mg,
5744
5745 amdLoaderApiRe = /(^|\s)(require|define)\s*\(/m,
5746
5747 extractLegacyApiApplications = function(text, noCommentText){
5748 // scan the noCommentText for any legacy loader API applications. Copy such applications into result (this is
5749 // used by the builder). Move dojo.loadInit applications to loadInitApplications string. Copy all other applications
5750 // to otherApplications string. If no applications were found, return 0, signalling an AMD module. Otherwise, return
5751 // loadInitApplications + otherApplications. Fixup text by replacing
5752 //
5753 // dojo.loadInit(// etc...
5754 //
5755 // with
5756 //
5757 // \n 0 && dojo.loadInit(// etc...
5758 //
5759 // Which results in the dojo.loadInit from *not* being applied. This design goes a long way towards protecting the
5760 // code from an over-agressive removeCommentRe. However...
5761 //
5762 // WARNING: the removeCommentRe will cause an error if a detected comment removes all or part of a legacy-loader application
5763 // that is not in a comment.
5764
5765 var match, startSearch, startApplication, application,
5766 loadInitApplications = [],
5767 otherApplications = [],
5768 allApplications = [];
5769
5770 // noCommentText may be provided by a build app with comments extracted by a better method than regex (hopefully)
5771 noCommentText = noCommentText || text.replace(removeCommentRe, function(match){
5772 // remove iff the detected comment has text that looks like a sync loader API application; this helps by
5773 // removing as little as possible, minimizing the changes the janky regex will kill the module
5774 syncLoaderApiRe.lastIndex = amdLoaderApiRe.lastIndex = 0;
5775 return (syncLoaderApiRe.test(match) || amdLoaderApiRe.test(match)) ? "" : match;
5776 });
5777
5778 // find and extract all dojo.loadInit applications
5779 while((match = syncLoaderApiRe.exec(noCommentText))){
5780 startSearch = syncLoaderApiRe.lastIndex;
5781 startApplication = startSearch - match[0].length;
5782 application = extractApplication(noCommentText, startSearch, startApplication);
5783 if(match[2]=="loadInit"){
5784 loadInitApplications.push(application[0]);
5785 }else{
5786 otherApplications.push(application[0]);
5787 }
5788 syncLoaderApiRe.lastIndex = application[1];
5789 }
5790 allApplications = loadInitApplications.concat(otherApplications);
5791 if(allApplications.length || !amdLoaderApiRe.test(noCommentText)){
5792 // either there were some legacy loader API applications or there were no AMD API applications
5793 return [text.replace(/(^|\s)dojo\.loadInit\s*\(/g, "\n0 && dojo.loadInit("), allApplications.join(""), allApplications];
5794 }else{
5795 // legacy loader API *was not* detected and AMD API *was* detected; therefore, assume it's an AMD module
5796 return 0;
5797 }
5798 },
5799
5800 transformToAmd = function(module, text){
5801 // This is roughly the equivalent of dojo._xdCreateResource in 1.6-; however, it expresses a v1.6- dojo
5802 // module in terms of AMD define instead of creating the dojo proprietary xdomain module expression.
5803 // The module could have originated from several sources:
5804 //
5805 // * amd require() a module, e.g., require(["my/module"])
5806 // * amd require() a nonmodule, e.g., require(["my/resource.js"')
5807 // * amd define() deps vector (always a module)
5808 // * dojo.require() a module, e.g. dojo.require("my.module")
5809 // * dojo.require() a nonmodule, e.g., dojo.require("my.module", true)
5810 // * dojo.requireIf/requireAfterIf/platformRequire a module
5811 //
5812 // The module is scanned for legacy loader API applications; if none are found, then assume the module is an
5813 // AMD module and return 0. Otherwise, a synthetic dojo/loadInit plugin resource is created and the module text
5814 // is rewritten as an AMD module with the single dependency of this synthetic resource. When the dojo/loadInit
5815 // plugin loaded the synthetic resource, it will cause all dojo.loadInit's to be executed, find all dojo.require's
5816 // (either directly consequent to dojo.require or indirectly consequent to dojo.require[After]If or
5817 // dojo.platformRequire, and finally cause loading of all dojo.required modules with the dojo/require plugin. Thus,
5818 // when the dojo/loadInit plugin reports it has been loaded, all modules required by the given module are guaranteed
5819 // loaded (but not executed). This then allows the module to execute it's code path without interupts, thereby
5820 // following the synchronous code path.
5821 //
5822 // Notice that this function behaves the same whether or not it happens to be in a mapped dojo/loader module.
5823
5824 var extractResult, id, names = [], namesAsStrings = [];
5825 if(buildDetectRe.test(text) || !(extractResult = extractLegacyApiApplications(text))){
5826 // buildDetectRe.test(text) => a built module, always AMD
5827 // extractResult==0 => no sync API
5828 return 0;
5829 }
5830
5831 // manufacture a synthetic module id that can never be a real mdule id (just like require does)
5832 id = module.mid + "-*loadInit";
5833
5834 // construct the dojo/loadInit names vector which causes any relocated names to be defined as lexical variables under their not-relocated name
5835 // the dojo/loadInit plugin assumes the first name in names is "dojo"
5836
5837 for(var p in getModule("dojo", module).result.scopeMap){
5838 names.push(p);
5839 namesAsStrings.push('"' + p + '"');
5840 }
5841
5842 // rewrite the module as a synthetic dojo/loadInit plugin resource + the module expressed as an AMD module that depends on this synthetic resource
5843 // don't have to map dojo/init since that will occur when the dependency is resolved
5844 return "// xdomain rewrite of " + module.mid + "\n" +
5845 "define('" + id + "',{\n" +
5846 "\tnames:" + dojo.toJson(names) + ",\n" +
5847 "\tdef:function(" + names.join(",") + "){" + extractResult[1] + "}" +
5848 "});\n\n" +
5849 "define(" + dojo.toJson(names.concat(["dojo/loadInit!"+id])) + ", function(" + names.join(",") + "){\n" + extractResult[0] + "});";
5850 },
5851
5852 loaderVars = require.initSyncLoader(dojoRequirePlugin, checkDojoRequirePlugin, transformToAmd),
5853
5854 sync =
5855 loaderVars.sync,
5856
5857 requested =
5858 loaderVars.requested,
5859
5860 arrived =
5861 loaderVars.arrived,
5862
5863 nonmodule =
5864 loaderVars.nonmodule,
5865
5866 executing =
5867 loaderVars.executing,
5868
5869 executed =
5870 loaderVars.executed,
5871
5872 syncExecStack =
5873 loaderVars.syncExecStack,
5874
5875 modules =
5876 loaderVars.modules,
5877
5878 execQ =
5879 loaderVars.execQ,
5880
5881 getModule =
5882 loaderVars.getModule,
5883
5884 injectModule =
5885 loaderVars.injectModule,
5886
5887 setArrived =
5888 loaderVars.setArrived,
5889
5890 signal =
5891 loaderVars.signal,
5892
5893 finishExec =
5894 loaderVars.finishExec,
5895
5896 execModule =
5897 loaderVars.execModule,
5898
5899 getLegacyMode =
5900 loaderVars.getLegacyMode,
5901
5902 guardCheckComplete =
5903 loaderVars.guardCheckComplete;
5904
5905 // there is exactly one dojoRequirePlugin among possibly-many dojo/_base/loader's (owing to mapping)
5906 dojoRequirePlugin = loaderVars.dojoRequirePlugin;
5907
5908 dojo.provide = function(mid){
5909 var executingModule = syncExecStack[0],
5910 module = lang.mixin(getModule(slashName(mid), require.module), {
5911 executed:executing,
5912 result:lang.getObject(mid, true)
5913 });
5914 setArrived(module);
5915 if(executingModule){
5916 (executingModule.provides || (executingModule.provides = [])).push(function(){
5917 module.result = lang.getObject(mid);
5918 delete module.provides;
5919 module.executed!==executed && finishExec(module);
5920 });
5921 }// else dojo.provide called not consequent to loading; therefore, give up trying to publish module value to loader namespace
5922 return module.result;
5923 };
5924
5925 has.add("config-publishRequireResult", 1, 0, 0);
5926
5927 dojo.require = function(moduleName, omitModuleCheck) {
5928 // summary:
5929 // loads a Javascript module from the appropriate URI
5930 //
5931 // moduleName: String
5932 // module name to load, using periods for separators,
5933 // e.g. "dojo.date.locale". Module paths are de-referenced by dojo's
5934 // internal mapping of locations to names and are disambiguated by
5935 // longest prefix. See `dojo.registerModulePath()` for details on
5936 // registering new modules.
5937 //
5938 // omitModuleCheck: Boolean?
5939 // if `true`, omitModuleCheck skips the step of ensuring that the
5940 // loaded file actually defines the symbol it is referenced by.
5941 // For example if it called as `dojo.require("a.b.c")` and the
5942 // file located at `a/b/c.js` does not define an object `a.b.c`,
5943 // and exception will be throws whereas no exception is raised
5944 // when called as `dojo.require("a.b.c", true)`
5945 //
5946 // description:
5947 // Modules are loaded via dojo.require by using one of two loaders: the normal loader
5948 // and the xdomain loader. The xdomain loader is used when dojo was built with a
5949 // custom build that specified loader=xdomain and the module lives on a modulePath
5950 // that is a whole URL, with protocol and a domain. The versions of Dojo that are on
5951 // the Google and AOL CDNs use the xdomain loader.
5952 //
5953 // If the module is loaded via the xdomain loader, it is an asynchronous load, since
5954 // the module is added via a dynamically created script tag. This
5955 // means that dojo.require() can return before the module has loaded. However, this
5956 // should only happen in the case where you do dojo.require calls in the top-level
5957 // HTML page, or if you purposely avoid the loader checking for dojo.require
5958 // dependencies in your module by using a syntax like dojo["require"] to load the module.
5959 //
5960 // Sometimes it is useful to not have the loader detect the dojo.require calls in the
5961 // module so that you can dynamically load the modules as a result of an action on the
5962 // page, instead of right at module load time.
5963 //
5964 // Also, for script blocks in an HTML page, the loader does not pre-process them, so
5965 // it does not know to download the modules before the dojo.require calls occur.
5966 //
5967 // So, in those two cases, when you want on-the-fly module loading or for script blocks
5968 // in the HTML page, special care must be taken if the dojo.required code is loaded
5969 // asynchronously. To make sure you can execute code that depends on the dojo.required
5970 // modules, be sure to add the code that depends on the modules in a dojo.addOnLoad()
5971 // callback. dojo.addOnLoad waits for all outstanding modules to finish loading before
5972 // executing.
5973 //
5974 // This type of syntax works with both xdomain and normal loaders, so it is good
5975 // practice to always use this idiom for on-the-fly code loading and in HTML script
5976 // blocks. If at some point you change loaders and where the code is loaded from,
5977 // it will all still work.
5978 //
5979 // More on how dojo.require
5980 // `dojo.require("A.B")` first checks to see if symbol A.B is
5981 // defined. If it is, it is simply returned (nothing to do).
5982 //
5983 // If it is not defined, it will look for `A/B.js` in the script root
5984 // directory.
5985 //
5986 // `dojo.require` throws an exception if it cannot find a file
5987 // to load, or if the symbol `A.B` is not defined after loading.
5988 //
5989 // It returns the object `A.B`, but note the caveats above about on-the-fly loading and
5990 // HTML script blocks when the xdomain loader is loading a module.
5991 //
5992 // `dojo.require()` does nothing about importing symbols into
5993 // the current namespace. It is presumed that the caller will
5994 // take care of that.
5995 //
5996 // example:
5997 // To use dojo.require in conjunction with dojo.ready:
5998 //
5999 // | dojo.require("foo");
6000 // | dojo.require("bar");
6001 // | dojo.addOnLoad(function(){
6002 // | //you can now safely do something with foo and bar
6003 // | });
6004 //
6005 // example:
6006 // For example, to import all symbols into a local block, you might write:
6007 //
6008 // | with (dojo.require("A.B")) {
6009 // | ...
6010 // | }
6011 //
6012 // And to import just the leaf symbol to a local variable:
6013 //
6014 // | var B = dojo.require("A.B");
6015 // | ...
6016 //
6017 // returns:
6018 // the required namespace object
6019 function doRequire(mid, omitModuleCheck){
6020 var module = getModule(slashName(mid), require.module);
6021 if(syncExecStack.length && syncExecStack[0].finish){
6022 // switched to async loading in the middle of evaluating a legacy module; stop
6023 // applying dojo.require so the remaining dojo.requires are applied in order
6024 syncExecStack[0].finish.push(mid);
6025 return undefined;
6026 }
6027
6028 // recall module.executed has values {0, executing, executed}; therefore, truthy indicates executing or executed
6029 if(module.executed){
6030 return module.result;
6031 }
6032 omitModuleCheck && (module.result = nonmodule);
6033
6034 // rcg...why here and in two lines??
6035 var currentMode = getLegacyMode();
6036
6037 // recall, in sync mode to inject is to *eval* the module text
6038 // if the module is a legacy module, this is the same as executing
6039 // but if the module is an AMD module, this means defining, not executing
6040 injectModule(module);
6041 // the inject may have changed the mode
6042 currentMode = getLegacyMode();
6043
6044 // in sync mode to dojo.require is to execute
6045 if(module.executed!==executed && module.injected===arrived){
6046 // the module was already here before injectModule was called probably finishing up a xdomain
6047 // load, but maybe a module given to the loader directly rather than having the loader retrieve it
6048
6049 loaderVars.guardCheckComplete(function(){
6050 execModule(module);
6051 });
6052 }
6053 if(module.executed){
6054 return module.result;
6055 }
6056
6057 if(currentMode==sync){
6058 // the only way to get here is in sync mode and dojo.required a module that
6059 // * was loaded async in the injectModule application a few lines up
6060 // * was an AMD module that had deps that are being loaded async and therefore couldn't execute
6061 if(module.cjs){
6062 // the module was an AMD module; unshift, not push, which causes the current traversal to be reattempted from the top
6063 execQ.unshift(module);
6064 }else{
6065 // the module was a legacy module
6066 syncExecStack.length && (syncExecStack[0].finish= [mid]);
6067 }
6068 }else{
6069 // the loader wasn't in sync mode on entry; probably async mode; therefore, no expectation of getting
6070 // the module value synchronously; make sure it gets executed though
6071 execQ.push(module);
6072 }
6073
6074 return undefined;
6075 }
6076
6077 var result = doRequire(moduleName, omitModuleCheck);
6078 if(has("config-publishRequireResult") && !lang.exists(moduleName) && result!==undefined){
6079 lang.setObject(moduleName, result);
6080 }
6081 return result;
6082 };
6083
6084 dojo.loadInit = function(f) {
6085 f();
6086 };
6087
6088 dojo.registerModulePath = function(/*String*/moduleName, /*String*/prefix){
6089 // summary:
6090 // Maps a module name to a path
6091 // description:
6092 // An unregistered module is given the default path of ../[module],
6093 // relative to Dojo root. For example, module acme is mapped to
6094 // ../acme. If you want to use a different module name, use
6095 // dojo.registerModulePath.
6096 // example:
6097 // If your dojo.js is located at this location in the web root:
6098 // | /myapp/js/dojo/dojo/dojo.js
6099 // and your modules are located at:
6100 // | /myapp/js/foo/bar.js
6101 // | /myapp/js/foo/baz.js
6102 // | /myapp/js/foo/thud/xyzzy.js
6103 // Your application can tell Dojo to locate the "foo" namespace by calling:
6104 // | dojo.registerModulePath("foo", "../../foo");
6105 // At which point you can then use dojo.require() to load the
6106 // modules (assuming they provide() the same things which are
6107 // required). The full code might be:
6108 // | <script type="text/javascript"
6109 // | src="/myapp/js/dojo/dojo/dojo.js"></script>
6110 // | <script type="text/javascript">
6111 // | dojo.registerModulePath("foo", "../../foo");
6112 // | dojo.require("foo.bar");
6113 // | dojo.require("foo.baz");
6114 // | dojo.require("foo.thud.xyzzy");
6115 // | </script>
6116
6117 var paths = {};
6118 paths[moduleName.replace(/\./g, "/")] = prefix;
6119 require({paths:paths});
6120 };
6121
6122 dojo.platformRequire = function(/*Object*/modMap){
6123 // summary:
6124 // require one or more modules based on which host environment
6125 // Dojo is currently operating in
6126 // description:
6127 // This method takes a "map" of arrays which one can use to
6128 // optionally load dojo modules. The map is indexed by the
6129 // possible dojo.name_ values, with two additional values:
6130 // "default" and "common". The items in the "default" array will
6131 // be loaded if none of the other items have been choosen based on
6132 // dojo.name_, set by your host environment. The items in the
6133 // "common" array will *always* be loaded, regardless of which
6134 // list is chosen.
6135 // example:
6136 // | dojo.platformRequire({
6137 // | browser: [
6138 // | "foo.sample", // simple module
6139 // | "foo.test",
6140 // | ["foo.bar.baz", true] // skip object check in _loadModule (dojo.require)
6141 // | ],
6142 // | default: [ "foo.sample._base" ],
6143 // | common: [ "important.module.common" ]
6144 // | });
6145
6146 var result = (modMap.common || []).concat(modMap[dojo._name] || modMap["default"] || []),
6147 temp;
6148 while(result.length){
6149 if(lang.isArray(temp = result.shift())){
6150 dojo.require.apply(dojo, temp);
6151 }else{
6152 dojo.require(temp);
6153 }
6154 }
6155 };
6156
6157 dojo.requireIf = dojo.requireAfterIf = function(/*Boolean*/ condition, /*String*/ moduleName, /*Boolean?*/omitModuleCheck){
6158 // summary:
6159 // If the condition is true then call `dojo.require()` for the specified
6160 // resource
6161 //
6162 // example:
6163 // | dojo.requireIf(dojo.isBrowser, "my.special.Module");
6164
6165 if(condition){
6166 dojo.require(moduleName, omitModuleCheck);
6167 }
6168 };
6169
6170 dojo.requireLocalization = function(/*String*/moduleName, /*String*/bundleName, /*String?*/locale){
6171 require(["../i18n"], function(i18n){
6172 i18n.getLocalization(moduleName, bundleName, locale);
6173 });
6174 };
6175
6176 return {
6177 // summary:
6178 // This module defines the v1.x synchronous loader API.
6179
6180 extractLegacyApiApplications:extractLegacyApiApplications,
6181 require:dojoRequirePlugin,
6182 loadInit:dojoLoadInitPlugin
6183 };
6184 });
6185
6186 },
6187 'dojo/json':function(){
6188 define(["./has"], function(has){
6189 "use strict";
6190 var hasJSON = typeof JSON != "undefined";
6191 has.add("json-parse", hasJSON); // all the parsers work fine
6192 // Firefox 3.5/Gecko 1.9 fails to use replacer in stringify properly https://bugzilla.mozilla.org/show_bug.cgi?id=509184
6193 has.add("json-stringify", hasJSON && JSON.stringify({a:0}, function(k,v){return v||1;}) == '{"a":1}');
6194
6195 /*=====
6196 return {
6197 // summary:
6198 // Functions to parse and serialize JSON
6199
6200 parse: function(str, strict){
6201 // summary:
6202 // Parses a [JSON](http://json.org) string to return a JavaScript object.
6203 // description:
6204 // This function follows [native JSON API](https://developer.mozilla.org/en/JSON)
6205 // Throws for invalid JSON strings. This delegates to eval() if native JSON
6206 // support is not available. By default this will evaluate any valid JS expression.
6207 // With the strict parameter set to true, the parser will ensure that only
6208 // valid JSON strings are parsed (otherwise throwing an error). Without the strict
6209 // parameter, the content passed to this method must come
6210 // from a trusted source.
6211 // str:
6212 // a string literal of a JSON item, for instance:
6213 // `'{ "foo": [ "bar", 1, { "baz": "thud" } ] }'`
6214 // strict:
6215 // When set to true, this will ensure that only valid, secure JSON is ever parsed.
6216 // Make sure this is set to true for untrusted content. Note that on browsers/engines
6217 // without native JSON support, setting this to true will run slower.
6218 },
6219 stringify: function(value, replacer, spacer){
6220 // summary:
6221 // Returns a [JSON](http://json.org) serialization of an object.
6222 // description:
6223 // Returns a [JSON](http://json.org) serialization of an object.
6224 // This function follows [native JSON API](https://developer.mozilla.org/en/JSON)
6225 // Note that this doesn't check for infinite recursion, so don't do that!
6226 // value:
6227 // A value to be serialized.
6228 // replacer:
6229 // A replacer function that is called for each value and can return a replacement
6230 // spacer:
6231 // A spacer string to be used for pretty printing of JSON
6232 // example:
6233 // simple serialization of a trivial object
6234 // | define(["dojo/json"], function(JSON){
6235 // | var jsonStr = JSON.stringify({ howdy: "stranger!", isStrange: true });
6236 // | doh.is('{"howdy":"stranger!","isStrange":true}', jsonStr);
6237 }
6238 };
6239 =====*/
6240
6241 if(has("json-stringify")){
6242 return JSON;
6243 }else{
6244 var escapeString = function(/*String*/str){
6245 // summary:
6246 // Adds escape sequences for non-visual characters, double quote and
6247 // backslash and surrounds with double quotes to form a valid string
6248 // literal.
6249 return ('"' + str.replace(/(["\\])/g, '\\$1') + '"').
6250 replace(/[\f]/g, "\\f").replace(/[\b]/g, "\\b").replace(/[\n]/g, "\\n").
6251 replace(/[\t]/g, "\\t").replace(/[\r]/g, "\\r"); // string
6252 };
6253 return {
6254 parse: has("json-parse") ? JSON.parse : function(str, strict){
6255 if(strict && !/^([\s\[\{]*(?:"(?:\\.|[^"])+"|-?\d[\d\.]*(?:[Ee][+-]?\d+)?|null|true|false|)[\s\]\}]*(?:,|:|$))+$/.test(str)){
6256 throw new SyntaxError("Invalid characters in JSON");
6257 }
6258 return eval('(' + str + ')');
6259 },
6260 stringify: function(value, replacer, spacer){
6261 var undef;
6262 if(typeof replacer == "string"){
6263 spacer = replacer;
6264 replacer = null;
6265 }
6266 function stringify(it, indent, key){
6267 if(replacer){
6268 it = replacer(key, it);
6269 }
6270 var val, objtype = typeof it;
6271 if(objtype == "number"){
6272 return isFinite(it) ? it + "" : "null";
6273 }
6274 if(objtype == "boolean"){
6275 return it + "";
6276 }
6277 if(it === null){
6278 return "null";
6279 }
6280 if(typeof it == "string"){
6281 return escapeString(it);
6282 }
6283 if(objtype == "function" || objtype == "undefined"){
6284 return undef; // undefined
6285 }
6286 // short-circuit for objects that support "json" serialization
6287 // if they return "self" then just pass-through...
6288 if(typeof it.toJSON == "function"){
6289 return stringify(it.toJSON(key), indent, key);
6290 }
6291 if(it instanceof Date){
6292 return '"{FullYear}-{Month+}-{Date}T{Hours}:{Minutes}:{Seconds}Z"'.replace(/\{(\w+)(\+)?\}/g, function(t, prop, plus){
6293 var num = it["getUTC" + prop]() + (plus ? 1 : 0);
6294 return num < 10 ? "0" + num : num;
6295 });
6296 }
6297 if(it.valueOf() !== it){
6298 // primitive wrapper, try again unwrapped:
6299 return stringify(it.valueOf(), indent, key);
6300 }
6301 var nextIndent= spacer ? (indent + spacer) : "";
6302 /* we used to test for DOM nodes and throw, but FF serializes them as {}, so cross-browser consistency is probably not efficiently attainable */
6303
6304 var sep = spacer ? " " : "";
6305 var newLine = spacer ? "\n" : "";
6306
6307 // array
6308 if(it instanceof Array){
6309 var itl = it.length, res = [];
6310 for(key = 0; key < itl; key++){
6311 var obj = it[key];
6312 val = stringify(obj, nextIndent, key);
6313 if(typeof val != "string"){
6314 val = "null";
6315 }
6316 res.push(newLine + nextIndent + val);
6317 }
6318 return "[" + res.join(",") + newLine + indent + "]";
6319 }
6320 // generic object code path
6321 var output = [];
6322 for(key in it){
6323 var keyStr;
6324 if(it.hasOwnProperty(key)){
6325 if(typeof key == "number"){
6326 keyStr = '"' + key + '"';
6327 }else if(typeof key == "string"){
6328 keyStr = escapeString(key);
6329 }else{
6330 // skip non-string or number keys
6331 continue;
6332 }
6333 val = stringify(it[key], nextIndent, key);
6334 if(typeof val != "string"){
6335 // skip non-serializable values
6336 continue;
6337 }
6338 // At this point, the most non-IE browsers don't get in this branch
6339 // (they have native JSON), so push is definitely the way to
6340 output.push(newLine + nextIndent + keyStr + ":" + sep + val);
6341 }
6342 }
6343 return "{" + output.join(",") + newLine + indent + "}"; // String
6344 }
6345 return stringify(value, "", "");
6346 }
6347 };
6348 }
6349 });
6350
6351 },
6352 'dojo/_base/declare':function(){
6353 define(["./kernel", "../has", "./lang"], function(dojo, has, lang){
6354 // module:
6355 // dojo/_base/declare
6356
6357 var mix = lang.mixin, op = Object.prototype, opts = op.toString,
6358 xtor = new Function, counter = 0, cname = "constructor";
6359
6360 function err(msg, cls){ throw new Error("declare" + (cls ? " " + cls : "") + ": " + msg); }
6361
6362 // C3 Method Resolution Order (see http://www.python.org/download/releases/2.3/mro/)
6363 function c3mro(bases, className){
6364 var result = [], roots = [{cls: 0, refs: []}], nameMap = {}, clsCount = 1,
6365 l = bases.length, i = 0, j, lin, base, top, proto, rec, name, refs;
6366
6367 // build a list of bases naming them if needed
6368 for(; i < l; ++i){
6369 base = bases[i];
6370 if(!base){
6371 err("mixin #" + i + " is unknown. Did you use dojo.require to pull it in?", className);
6372 }else if(opts.call(base) != "[object Function]"){
6373 err("mixin #" + i + " is not a callable constructor.", className);
6374 }
6375 lin = base._meta ? base._meta.bases : [base];
6376 top = 0;
6377 // add bases to the name map
6378 for(j = lin.length - 1; j >= 0; --j){
6379 proto = lin[j].prototype;
6380 if(!proto.hasOwnProperty("declaredClass")){
6381 proto.declaredClass = "uniqName_" + (counter++);
6382 }
6383 name = proto.declaredClass;
6384 if(!nameMap.hasOwnProperty(name)){
6385 nameMap[name] = {count: 0, refs: [], cls: lin[j]};
6386 ++clsCount;
6387 }
6388 rec = nameMap[name];
6389 if(top && top !== rec){
6390 rec.refs.push(top);
6391 ++top.count;
6392 }
6393 top = rec;
6394 }
6395 ++top.count;
6396 roots[0].refs.push(top);
6397 }
6398
6399 // remove classes without external references recursively
6400 while(roots.length){
6401 top = roots.pop();
6402 result.push(top.cls);
6403 --clsCount;
6404 // optimization: follow a single-linked chain
6405 while(refs = top.refs, refs.length == 1){
6406 top = refs[0];
6407 if(!top || --top.count){
6408 // branch or end of chain => do not end to roots
6409 top = 0;
6410 break;
6411 }
6412 result.push(top.cls);
6413 --clsCount;
6414 }
6415 if(top){
6416 // branch
6417 for(i = 0, l = refs.length; i < l; ++i){
6418 top = refs[i];
6419 if(!--top.count){
6420 roots.push(top);
6421 }
6422 }
6423 }
6424 }
6425 if(clsCount){
6426 err("can't build consistent linearization", className);
6427 }
6428
6429 // calculate the superclass offset
6430 base = bases[0];
6431 result[0] = base ?
6432 base._meta && base === result[result.length - base._meta.bases.length] ?
6433 base._meta.bases.length : 1 : 0;
6434
6435 return result;
6436 }
6437
6438 function inherited(args, a, f){
6439 var name, chains, bases, caller, meta, base, proto, opf, pos,
6440 cache = this._inherited = this._inherited || {};
6441
6442 // crack arguments
6443 if(typeof args == "string"){
6444 name = args;
6445 args = a;
6446 a = f;
6447 }
6448 f = 0;
6449
6450 caller = args.callee;
6451 name = name || caller.nom;
6452 if(!name){
6453 err("can't deduce a name to call inherited()", this.declaredClass);
6454 }
6455
6456 meta = this.constructor._meta;
6457 bases = meta.bases;
6458
6459 pos = cache.p;
6460 if(name != cname){
6461 // method
6462 if(cache.c !== caller){
6463 // cache bust
6464 pos = 0;
6465 base = bases[0];
6466 meta = base._meta;
6467 if(meta.hidden[name] !== caller){
6468 // error detection
6469 chains = meta.chains;
6470 if(chains && typeof chains[name] == "string"){
6471 err("calling chained method with inherited: " + name, this.declaredClass);
6472 }
6473 // find caller
6474 do{
6475 meta = base._meta;
6476 proto = base.prototype;
6477 if(meta && (proto[name] === caller && proto.hasOwnProperty(name) || meta.hidden[name] === caller)){
6478 break;
6479 }
6480 }while(base = bases[++pos]); // intentional assignment
6481 pos = base ? pos : -1;
6482 }
6483 }
6484 // find next
6485 base = bases[++pos];
6486 if(base){
6487 proto = base.prototype;
6488 if(base._meta && proto.hasOwnProperty(name)){
6489 f = proto[name];
6490 }else{
6491 opf = op[name];
6492 do{
6493 proto = base.prototype;
6494 f = proto[name];
6495 if(f && (base._meta ? proto.hasOwnProperty(name) : f !== opf)){
6496 break;
6497 }
6498 }while(base = bases[++pos]); // intentional assignment
6499 }
6500 }
6501 f = base && f || op[name];
6502 }else{
6503 // constructor
6504 if(cache.c !== caller){
6505 // cache bust
6506 pos = 0;
6507 meta = bases[0]._meta;
6508 if(meta && meta.ctor !== caller){
6509 // error detection
6510 chains = meta.chains;
6511 if(!chains || chains.constructor !== "manual"){
6512 err("calling chained constructor with inherited", this.declaredClass);
6513 }
6514 // find caller
6515 while(base = bases[++pos]){ // intentional assignment
6516 meta = base._meta;
6517 if(meta && meta.ctor === caller){
6518 break;
6519 }
6520 }
6521 pos = base ? pos : -1;
6522 }
6523 }
6524 // find next
6525 while(base = bases[++pos]){ // intentional assignment
6526 meta = base._meta;
6527 f = meta ? meta.ctor : base;
6528 if(f){
6529 break;
6530 }
6531 }
6532 f = base && f;
6533 }
6534
6535 // cache the found super method
6536 cache.c = f;
6537 cache.p = pos;
6538
6539 // now we have the result
6540 if(f){
6541 return a === true ? f : f.apply(this, a || args);
6542 }
6543 // intentionally no return if a super method was not found
6544 }
6545
6546 function getInherited(name, args){
6547 if(typeof name == "string"){
6548 return this.__inherited(name, args, true);
6549 }
6550 return this.__inherited(name, true);
6551 }
6552
6553 function inherited__debug(args, a1, a2){
6554 var f = this.getInherited(args, a1);
6555 if(f){ return f.apply(this, a2 || a1 || args); }
6556 // intentionally no return if a super method was not found
6557 }
6558
6559 var inheritedImpl = dojo.config.isDebug ? inherited__debug : inherited;
6560
6561 // emulation of "instanceof"
6562 function isInstanceOf(cls){
6563 var bases = this.constructor._meta.bases;
6564 for(var i = 0, l = bases.length; i < l; ++i){
6565 if(bases[i] === cls){
6566 return true;
6567 }
6568 }
6569 return this instanceof cls;
6570 }
6571
6572 function mixOwn(target, source){
6573 // add props adding metadata for incoming functions skipping a constructor
6574 for(var name in source){
6575 if(name != cname && source.hasOwnProperty(name)){
6576 target[name] = source[name];
6577 }
6578 }
6579 if(has("bug-for-in-skips-shadowed")){
6580 for(var extraNames= lang._extraNames, i= extraNames.length; i;){
6581 name = extraNames[--i];
6582 if(name != cname && source.hasOwnProperty(name)){
6583 target[name] = source[name];
6584 }
6585 }
6586 }
6587 }
6588
6589 // implementation of safe mixin function
6590 function safeMixin(target, source){
6591 // summary:
6592 // Mix in properties skipping a constructor and decorating functions
6593 // like it is done by declare().
6594 // target: Object
6595 // Target object to accept new properties.
6596 // source: Object
6597 // Source object for new properties.
6598 // description:
6599 // This function is used to mix in properties like lang.mixin does,
6600 // but it skips a constructor property and decorates functions like
6601 // declare() does.
6602 //
6603 // It is meant to be used with classes and objects produced with
6604 // declare. Functions mixed in with dojo.safeMixin can use
6605 // this.inherited() like normal methods.
6606 //
6607 // This function is used to implement extend() method of a constructor
6608 // produced with declare().
6609 //
6610 // example:
6611 // | var A = declare(null, {
6612 // | m1: function(){
6613 // | console.log("A.m1");
6614 // | },
6615 // | m2: function(){
6616 // | console.log("A.m2");
6617 // | }
6618 // | });
6619 // | var B = declare(A, {
6620 // | m1: function(){
6621 // | this.inherited(arguments);
6622 // | console.log("B.m1");
6623 // | }
6624 // | });
6625 // | B.extend({
6626 // | m2: function(){
6627 // | this.inherited(arguments);
6628 // | console.log("B.m2");
6629 // | }
6630 // | });
6631 // | var x = new B();
6632 // | dojo.safeMixin(x, {
6633 // | m1: function(){
6634 // | this.inherited(arguments);
6635 // | console.log("X.m1");
6636 // | },
6637 // | m2: function(){
6638 // | this.inherited(arguments);
6639 // | console.log("X.m2");
6640 // | }
6641 // | });
6642 // | x.m2();
6643 // | // prints:
6644 // | // A.m1
6645 // | // B.m1
6646 // | // X.m1
6647
6648 var name, t;
6649 // add props adding metadata for incoming functions skipping a constructor
6650 for(name in source){
6651 t = source[name];
6652 if((t !== op[name] || !(name in op)) && name != cname){
6653 if(opts.call(t) == "[object Function]"){
6654 // non-trivial function method => attach its name
6655 t.nom = name;
6656 }
6657 target[name] = t;
6658 }
6659 }
6660 if(has("bug-for-in-skips-shadowed")){
6661 for(var extraNames= lang._extraNames, i= extraNames.length; i;){
6662 name = extraNames[--i];
6663 t = source[name];
6664 if((t !== op[name] || !(name in op)) && name != cname){
6665 if(opts.call(t) == "[object Function]"){
6666 // non-trivial function method => attach its name
6667 t.nom = name;
6668 }
6669 target[name] = t;
6670 }
6671 }
6672 }
6673 return target;
6674 }
6675
6676 function extend(source){
6677 declare.safeMixin(this.prototype, source);
6678 return this;
6679 }
6680
6681 function createSubclass(mixins){
6682 return declare([this].concat(mixins));
6683 }
6684
6685 // chained constructor compatible with the legacy declare()
6686 function chainedConstructor(bases, ctorSpecial){
6687 return function(){
6688 var a = arguments, args = a, a0 = a[0], f, i, m,
6689 l = bases.length, preArgs;
6690
6691 if(!(this instanceof a.callee)){
6692 // not called via new, so force it
6693 return applyNew(a);
6694 }
6695
6696 //this._inherited = {};
6697 // perform the shaman's rituals of the original declare()
6698 // 1) call two types of the preamble
6699 if(ctorSpecial && (a0 && a0.preamble || this.preamble)){
6700 // full blown ritual
6701 preArgs = new Array(bases.length);
6702 // prepare parameters
6703 preArgs[0] = a;
6704 for(i = 0;;){
6705 // process the preamble of the 1st argument
6706 a0 = a[0];
6707 if(a0){
6708 f = a0.preamble;
6709 if(f){
6710 a = f.apply(this, a) || a;
6711 }
6712 }
6713 // process the preamble of this class
6714 f = bases[i].prototype;
6715 f = f.hasOwnProperty("preamble") && f.preamble;
6716 if(f){
6717 a = f.apply(this, a) || a;
6718 }
6719 // one peculiarity of the preamble:
6720 // it is called if it is not needed,
6721 // e.g., there is no constructor to call
6722 // let's watch for the last constructor
6723 // (see ticket #9795)
6724 if(++i == l){
6725 break;
6726 }
6727 preArgs[i] = a;
6728 }
6729 }
6730 // 2) call all non-trivial constructors using prepared arguments
6731 for(i = l - 1; i >= 0; --i){
6732 f = bases[i];
6733 m = f._meta;
6734 f = m ? m.ctor : f;
6735 if(f){
6736 f.apply(this, preArgs ? preArgs[i] : a);
6737 }
6738 }
6739 // 3) continue the original ritual: call the postscript
6740 f = this.postscript;
6741 if(f){
6742 f.apply(this, args);
6743 }
6744 };
6745 }
6746
6747
6748 // chained constructor compatible with the legacy declare()
6749 function singleConstructor(ctor, ctorSpecial){
6750 return function(){
6751 var a = arguments, t = a, a0 = a[0], f;
6752
6753 if(!(this instanceof a.callee)){
6754 // not called via new, so force it
6755 return applyNew(a);
6756 }
6757
6758 //this._inherited = {};
6759 // perform the shaman's rituals of the original declare()
6760 // 1) call two types of the preamble
6761 if(ctorSpecial){
6762 // full blown ritual
6763 if(a0){
6764 // process the preamble of the 1st argument
6765 f = a0.preamble;
6766 if(f){
6767 t = f.apply(this, t) || t;
6768 }
6769 }
6770 f = this.preamble;
6771 if(f){
6772 // process the preamble of this class
6773 f.apply(this, t);
6774 // one peculiarity of the preamble:
6775 // it is called even if it is not needed,
6776 // e.g., there is no constructor to call
6777 // let's watch for the last constructor
6778 // (see ticket #9795)
6779 }
6780 }
6781 // 2) call a constructor
6782 if(ctor){
6783 ctor.apply(this, a);
6784 }
6785 // 3) continue the original ritual: call the postscript
6786 f = this.postscript;
6787 if(f){
6788 f.apply(this, a);
6789 }
6790 };
6791 }
6792
6793 // plain vanilla constructor (can use inherited() to call its base constructor)
6794 function simpleConstructor(bases){
6795 return function(){
6796 var a = arguments, i = 0, f, m;
6797
6798 if(!(this instanceof a.callee)){
6799 // not called via new, so force it
6800 return applyNew(a);
6801 }
6802
6803 //this._inherited = {};
6804 // perform the shaman's rituals of the original declare()
6805 // 1) do not call the preamble
6806 // 2) call the top constructor (it can use this.inherited())
6807 for(; f = bases[i]; ++i){ // intentional assignment
6808 m = f._meta;
6809 f = m ? m.ctor : f;
6810 if(f){
6811 f.apply(this, a);
6812 break;
6813 }
6814 }
6815 // 3) call the postscript
6816 f = this.postscript;
6817 if(f){
6818 f.apply(this, a);
6819 }
6820 };
6821 }
6822
6823 function chain(name, bases, reversed){
6824 return function(){
6825 var b, m, f, i = 0, step = 1;
6826 if(reversed){
6827 i = bases.length - 1;
6828 step = -1;
6829 }
6830 for(; b = bases[i]; i += step){ // intentional assignment
6831 m = b._meta;
6832 f = (m ? m.hidden : b.prototype)[name];
6833 if(f){
6834 f.apply(this, arguments);
6835 }
6836 }
6837 };
6838 }
6839
6840 // forceNew(ctor)
6841 // return a new object that inherits from ctor.prototype but
6842 // without actually running ctor on the object.
6843 function forceNew(ctor){
6844 // create object with correct prototype using a do-nothing
6845 // constructor
6846 xtor.prototype = ctor.prototype;
6847 var t = new xtor;
6848 xtor.prototype = null; // clean up
6849 return t;
6850 }
6851
6852 // applyNew(args)
6853 // just like 'new ctor()' except that the constructor and its arguments come
6854 // from args, which must be an array or an arguments object
6855 function applyNew(args){
6856 // create an object with ctor's prototype but without
6857 // calling ctor on it.
6858 var ctor = args.callee, t = forceNew(ctor);
6859 // execute the real constructor on the new object
6860 ctor.apply(t, args);
6861 return t;
6862 }
6863
6864 function declare(className, superclass, props){
6865 // summary:
6866 // Create a feature-rich constructor from compact notation.
6867 // className: String?
6868 // The optional name of the constructor (loosely, a "class")
6869 // stored in the "declaredClass" property in the created prototype.
6870 // It will be used as a global name for a created constructor.
6871 // superclass: Function|Function[]
6872 // May be null, a Function, or an Array of Functions. This argument
6873 // specifies a list of bases (the left-most one is the most deepest
6874 // base).
6875 // props: Object
6876 // An object whose properties are copied to the created prototype.
6877 // Add an instance-initialization function by making it a property
6878 // named "constructor".
6879 // returns: dojo/_base/declare.__DeclareCreatedObject
6880 // New constructor function.
6881 // description:
6882 // Create a constructor using a compact notation for inheritance and
6883 // prototype extension.
6884 //
6885 // Mixin ancestors provide a type of multiple inheritance.
6886 // Prototypes of mixin ancestors are copied to the new class:
6887 // changes to mixin prototypes will not affect classes to which
6888 // they have been mixed in.
6889 //
6890 // Ancestors can be compound classes created by this version of
6891 // declare(). In complex cases all base classes are going to be
6892 // linearized according to C3 MRO algorithm
6893 // (see http://www.python.org/download/releases/2.3/mro/ for more
6894 // details).
6895 //
6896 // "className" is cached in "declaredClass" property of the new class,
6897 // if it was supplied. The immediate super class will be cached in
6898 // "superclass" property of the new class.
6899 //
6900 // Methods in "props" will be copied and modified: "nom" property
6901 // (the declared name of the method) will be added to all copied
6902 // functions to help identify them for the internal machinery. Be
6903 // very careful, while reusing methods: if you use the same
6904 // function under different names, it can produce errors in some
6905 // cases.
6906 //
6907 // It is possible to use constructors created "manually" (without
6908 // declare()) as bases. They will be called as usual during the
6909 // creation of an instance, their methods will be chained, and even
6910 // called by "this.inherited()".
6911 //
6912 // Special property "-chains-" governs how to chain methods. It is
6913 // a dictionary, which uses method names as keys, and hint strings
6914 // as values. If a hint string is "after", this method will be
6915 // called after methods of its base classes. If a hint string is
6916 // "before", this method will be called before methods of its base
6917 // classes.
6918 //
6919 // If "constructor" is not mentioned in "-chains-" property, it will
6920 // be chained using the legacy mode: using "after" chaining,
6921 // calling preamble() method before each constructor, if available,
6922 // and calling postscript() after all constructors were executed.
6923 // If the hint is "after", it is chained as a regular method, but
6924 // postscript() will be called after the chain of constructors.
6925 // "constructor" cannot be chained "before", but it allows
6926 // a special hint string: "manual", which means that constructors
6927 // are not going to be chained in any way, and programmer will call
6928 // them manually using this.inherited(). In the latter case
6929 // postscript() will be called after the construction.
6930 //
6931 // All chaining hints are "inherited" from base classes and
6932 // potentially can be overridden. Be very careful when overriding
6933 // hints! Make sure that all chained methods can work in a proposed
6934 // manner of chaining.
6935 //
6936 // Once a method was chained, it is impossible to unchain it. The
6937 // only exception is "constructor". You don't need to define a
6938 // method in order to supply a chaining hint.
6939 //
6940 // If a method is chained, it cannot use this.inherited() because
6941 // all other methods in the hierarchy will be called automatically.
6942 //
6943 // Usually constructors and initializers of any kind are chained
6944 // using "after" and destructors of any kind are chained as
6945 // "before". Note that chaining assumes that chained methods do not
6946 // return any value: any returned value will be discarded.
6947 //
6948 // example:
6949 // | declare("my.classes.bar", my.classes.foo, {
6950 // | // properties to be added to the class prototype
6951 // | someValue: 2,
6952 // | // initialization function
6953 // | constructor: function(){
6954 // | this.myComplicatedObject = new ReallyComplicatedObject();
6955 // | },
6956 // | // other functions
6957 // | someMethod: function(){
6958 // | doStuff();
6959 // | }
6960 // | });
6961 //
6962 // example:
6963 // | var MyBase = declare(null, {
6964 // | // constructor, properties, and methods go here
6965 // | // ...
6966 // | });
6967 // | var MyClass1 = declare(MyBase, {
6968 // | // constructor, properties, and methods go here
6969 // | // ...
6970 // | });
6971 // | var MyClass2 = declare(MyBase, {
6972 // | // constructor, properties, and methods go here
6973 // | // ...
6974 // | });
6975 // | var MyDiamond = declare([MyClass1, MyClass2], {
6976 // | // constructor, properties, and methods go here
6977 // | // ...
6978 // | });
6979 //
6980 // example:
6981 // | var F = function(){ console.log("raw constructor"); };
6982 // | F.prototype.method = function(){
6983 // | console.log("raw method");
6984 // | };
6985 // | var A = declare(F, {
6986 // | constructor: function(){
6987 // | console.log("A.constructor");
6988 // | },
6989 // | method: function(){
6990 // | console.log("before calling F.method...");
6991 // | this.inherited(arguments);
6992 // | console.log("...back in A");
6993 // | }
6994 // | });
6995 // | new A().method();
6996 // | // will print:
6997 // | // raw constructor
6998 // | // A.constructor
6999 // | // before calling F.method...
7000 // | // raw method
7001 // | // ...back in A
7002 //
7003 // example:
7004 // | var A = declare(null, {
7005 // | "-chains-": {
7006 // | destroy: "before"
7007 // | }
7008 // | });
7009 // | var B = declare(A, {
7010 // | constructor: function(){
7011 // | console.log("B.constructor");
7012 // | },
7013 // | destroy: function(){
7014 // | console.log("B.destroy");
7015 // | }
7016 // | });
7017 // | var C = declare(B, {
7018 // | constructor: function(){
7019 // | console.log("C.constructor");
7020 // | },
7021 // | destroy: function(){
7022 // | console.log("C.destroy");
7023 // | }
7024 // | });
7025 // | new C().destroy();
7026 // | // prints:
7027 // | // B.constructor
7028 // | // C.constructor
7029 // | // C.destroy
7030 // | // B.destroy
7031 //
7032 // example:
7033 // | var A = declare(null, {
7034 // | "-chains-": {
7035 // | constructor: "manual"
7036 // | }
7037 // | });
7038 // | var B = declare(A, {
7039 // | constructor: function(){
7040 // | // ...
7041 // | // call the base constructor with new parameters
7042 // | this.inherited(arguments, [1, 2, 3]);
7043 // | // ...
7044 // | }
7045 // | });
7046 //
7047 // example:
7048 // | var A = declare(null, {
7049 // | "-chains-": {
7050 // | m1: "before"
7051 // | },
7052 // | m1: function(){
7053 // | console.log("A.m1");
7054 // | },
7055 // | m2: function(){
7056 // | console.log("A.m2");
7057 // | }
7058 // | });
7059 // | var B = declare(A, {
7060 // | "-chains-": {
7061 // | m2: "after"
7062 // | },
7063 // | m1: function(){
7064 // | console.log("B.m1");
7065 // | },
7066 // | m2: function(){
7067 // | console.log("B.m2");
7068 // | }
7069 // | });
7070 // | var x = new B();
7071 // | x.m1();
7072 // | // prints:
7073 // | // B.m1
7074 // | // A.m1
7075 // | x.m2();
7076 // | // prints:
7077 // | // A.m2
7078 // | // B.m2
7079
7080 // crack parameters
7081 if(typeof className != "string"){
7082 props = superclass;
7083 superclass = className;
7084 className = "";
7085 }
7086 props = props || {};
7087
7088 var proto, i, t, ctor, name, bases, chains, mixins = 1, parents = superclass;
7089
7090 // build a prototype
7091 if(opts.call(superclass) == "[object Array]"){
7092 // C3 MRO
7093 bases = c3mro(superclass, className);
7094 t = bases[0];
7095 mixins = bases.length - t;
7096 superclass = bases[mixins];
7097 }else{
7098 bases = [0];
7099 if(superclass){
7100 if(opts.call(superclass) == "[object Function]"){
7101 t = superclass._meta;
7102 bases = bases.concat(t ? t.bases : superclass);
7103 }else{
7104 err("base class is not a callable constructor.", className);
7105 }
7106 }else if(superclass !== null){
7107 err("unknown base class. Did you use dojo.require to pull it in?", className);
7108 }
7109 }
7110 if(superclass){
7111 for(i = mixins - 1;; --i){
7112 proto = forceNew(superclass);
7113 if(!i){
7114 // stop if nothing to add (the last base)
7115 break;
7116 }
7117 // mix in properties
7118 t = bases[i];
7119 (t._meta ? mixOwn : mix)(proto, t.prototype);
7120 // chain in new constructor
7121 ctor = new Function;
7122 ctor.superclass = superclass;
7123 ctor.prototype = proto;
7124 superclass = proto.constructor = ctor;
7125 }
7126 }else{
7127 proto = {};
7128 }
7129 // add all properties
7130 declare.safeMixin(proto, props);
7131 // add constructor
7132 t = props.constructor;
7133 if(t !== op.constructor){
7134 t.nom = cname;
7135 proto.constructor = t;
7136 }
7137
7138 // collect chains and flags
7139 for(i = mixins - 1; i; --i){ // intentional assignment
7140 t = bases[i]._meta;
7141 if(t && t.chains){
7142 chains = mix(chains || {}, t.chains);
7143 }
7144 }
7145 if(proto["-chains-"]){
7146 chains = mix(chains || {}, proto["-chains-"]);
7147 }
7148
7149 // build ctor
7150 t = !chains || !chains.hasOwnProperty(cname);
7151 bases[0] = ctor = (chains && chains.constructor === "manual") ? simpleConstructor(bases) :
7152 (bases.length == 1 ? singleConstructor(props.constructor, t) : chainedConstructor(bases, t));
7153
7154 // add meta information to the constructor
7155 ctor._meta = {bases: bases, hidden: props, chains: chains,
7156 parents: parents, ctor: props.constructor};
7157 ctor.superclass = superclass && superclass.prototype;
7158 ctor.extend = extend;
7159 ctor.createSubclass = createSubclass;
7160 ctor.prototype = proto;
7161 proto.constructor = ctor;
7162
7163 // add "standard" methods to the prototype
7164 proto.getInherited = getInherited;
7165 proto.isInstanceOf = isInstanceOf;
7166 proto.inherited = inheritedImpl;
7167 proto.__inherited = inherited;
7168
7169 // add name if specified
7170 if(className){
7171 proto.declaredClass = className;
7172 lang.setObject(className, ctor);
7173 }
7174
7175 // build chains and add them to the prototype
7176 if(chains){
7177 for(name in chains){
7178 if(proto[name] && typeof chains[name] == "string" && name != cname){
7179 t = proto[name] = chain(name, bases, chains[name] === "after");
7180 t.nom = name;
7181 }
7182 }
7183 }
7184 // chained methods do not return values
7185 // no need to chain "invisible" functions
7186
7187 return ctor; // Function
7188 }
7189
7190 /*=====
7191 declare.__DeclareCreatedObject = {
7192 // summary:
7193 // dojo/_base/declare() returns a constructor `C`. `new C()` returns an Object with the following
7194 // methods, in addition to the methods and properties specified via the arguments passed to declare().
7195
7196 inherited: function(name, args, newArgs){
7197 // summary:
7198 // Calls a super method.
7199 // name: String?
7200 // The optional method name. Should be the same as the caller's
7201 // name. Usually "name" is specified in complex dynamic cases, when
7202 // the calling method was dynamically added, undecorated by
7203 // declare(), and it cannot be determined.
7204 // args: Arguments
7205 // The caller supply this argument, which should be the original
7206 // "arguments".
7207 // newArgs: Object?
7208 // If "true", the found function will be returned without
7209 // executing it.
7210 // If Array, it will be used to call a super method. Otherwise
7211 // "args" will be used.
7212 // returns:
7213 // Whatever is returned by a super method, or a super method itself,
7214 // if "true" was specified as newArgs.
7215 // description:
7216 // This method is used inside method of classes produced with
7217 // declare() to call a super method (next in the chain). It is
7218 // used for manually controlled chaining. Consider using the regular
7219 // chaining, because it is faster. Use "this.inherited()" only in
7220 // complex cases.
7221 //
7222 // This method cannot me called from automatically chained
7223 // constructors including the case of a special (legacy)
7224 // constructor chaining. It cannot be called from chained methods.
7225 //
7226 // If "this.inherited()" cannot find the next-in-chain method, it
7227 // does nothing and returns "undefined". The last method in chain
7228 // can be a default method implemented in Object, which will be
7229 // called last.
7230 //
7231 // If "name" is specified, it is assumed that the method that
7232 // received "args" is the parent method for this call. It is looked
7233 // up in the chain list and if it is found the next-in-chain method
7234 // is called. If it is not found, the first-in-chain method is
7235 // called.
7236 //
7237 // If "name" is not specified, it will be derived from the calling
7238 // method (using a methoid property "nom").
7239 //
7240 // example:
7241 // | var B = declare(A, {
7242 // | method1: function(a, b, c){
7243 // | this.inherited(arguments);
7244 // | },
7245 // | method2: function(a, b){
7246 // | return this.inherited(arguments, [a + b]);
7247 // | }
7248 // | });
7249 // | // next method is not in the chain list because it is added
7250 // | // manually after the class was created.
7251 // | B.prototype.method3 = function(){
7252 // | console.log("This is a dynamically-added method.");
7253 // | this.inherited("method3", arguments);
7254 // | };
7255 // example:
7256 // | var B = declare(A, {
7257 // | method: function(a, b){
7258 // | var super = this.inherited(arguments, true);
7259 // | // ...
7260 // | if(!super){
7261 // | console.log("there is no super method");
7262 // | return 0;
7263 // | }
7264 // | return super.apply(this, arguments);
7265 // | }
7266 // | });
7267 return {}; // Object
7268 },
7269
7270 getInherited: function(name, args){
7271 // summary:
7272 // Returns a super method.
7273 // name: String?
7274 // The optional method name. Should be the same as the caller's
7275 // name. Usually "name" is specified in complex dynamic cases, when
7276 // the calling method was dynamically added, undecorated by
7277 // declare(), and it cannot be determined.
7278 // args: Arguments
7279 // The caller supply this argument, which should be the original
7280 // "arguments".
7281 // returns:
7282 // Returns a super method (Function) or "undefined".
7283 // description:
7284 // This method is a convenience method for "this.inherited()".
7285 // It uses the same algorithm but instead of executing a super
7286 // method, it returns it, or "undefined" if not found.
7287 //
7288 // example:
7289 // | var B = declare(A, {
7290 // | method: function(a, b){
7291 // | var super = this.getInherited(arguments);
7292 // | // ...
7293 // | if(!super){
7294 // | console.log("there is no super method");
7295 // | return 0;
7296 // | }
7297 // | return super.apply(this, arguments);
7298 // | }
7299 // | });
7300 return {}; // Object
7301 },
7302
7303 isInstanceOf: function(cls){
7304 // summary:
7305 // Checks the inheritance chain to see if it is inherited from this
7306 // class.
7307 // cls: Function
7308 // Class constructor.
7309 // returns:
7310 // "true", if this object is inherited from this class, "false"
7311 // otherwise.
7312 // description:
7313 // This method is used with instances of classes produced with
7314 // declare() to determine of they support a certain interface or
7315 // not. It models "instanceof" operator.
7316 //
7317 // example:
7318 // | var A = declare(null, {
7319 // | // constructor, properties, and methods go here
7320 // | // ...
7321 // | });
7322 // | var B = declare(null, {
7323 // | // constructor, properties, and methods go here
7324 // | // ...
7325 // | });
7326 // | var C = declare([A, B], {
7327 // | // constructor, properties, and methods go here
7328 // | // ...
7329 // | });
7330 // | var D = declare(A, {
7331 // | // constructor, properties, and methods go here
7332 // | // ...
7333 // | });
7334 // |
7335 // | var a = new A(), b = new B(), c = new C(), d = new D();
7336 // |
7337 // | console.log(a.isInstanceOf(A)); // true
7338 // | console.log(b.isInstanceOf(A)); // false
7339 // | console.log(c.isInstanceOf(A)); // true
7340 // | console.log(d.isInstanceOf(A)); // true
7341 // |
7342 // | console.log(a.isInstanceOf(B)); // false
7343 // | console.log(b.isInstanceOf(B)); // true
7344 // | console.log(c.isInstanceOf(B)); // true
7345 // | console.log(d.isInstanceOf(B)); // false
7346 // |
7347 // | console.log(a.isInstanceOf(C)); // false
7348 // | console.log(b.isInstanceOf(C)); // false
7349 // | console.log(c.isInstanceOf(C)); // true
7350 // | console.log(d.isInstanceOf(C)); // false
7351 // |
7352 // | console.log(a.isInstanceOf(D)); // false
7353 // | console.log(b.isInstanceOf(D)); // false
7354 // | console.log(c.isInstanceOf(D)); // false
7355 // | console.log(d.isInstanceOf(D)); // true
7356 return {}; // Object
7357 },
7358
7359 extend: function(source){
7360 // summary:
7361 // Adds all properties and methods of source to constructor's
7362 // prototype, making them available to all instances created with
7363 // constructor. This method is specific to constructors created with
7364 // declare().
7365 // source: Object
7366 // Source object which properties are going to be copied to the
7367 // constructor's prototype.
7368 // description:
7369 // Adds source properties to the constructor's prototype. It can
7370 // override existing properties.
7371 //
7372 // This method is similar to dojo.extend function, but it is specific
7373 // to constructors produced by declare(). It is implemented
7374 // using dojo.safeMixin, and it skips a constructor property,
7375 // and properly decorates copied functions.
7376 //
7377 // example:
7378 // | var A = declare(null, {
7379 // | m1: function(){},
7380 // | s1: "Popokatepetl"
7381 // | });
7382 // | A.extend({
7383 // | m1: function(){},
7384 // | m2: function(){},
7385 // | f1: true,
7386 // | d1: 42
7387 // | });
7388 }
7389 };
7390 =====*/
7391
7392 // For back-compat, remove for 2.0
7393 dojo.safeMixin = declare.safeMixin = safeMixin;
7394 dojo.declare = declare;
7395
7396 return declare;
7397 });
7398
7399 },
7400 'dojo/dom':function(){
7401 define(["./sniff", "./_base/window"],
7402 function(has, win){
7403 // module:
7404 // dojo/dom
7405
7406 // FIXME: need to add unit tests for all the semi-public methods
7407
7408 if(has("ie") <= 7){
7409 try{
7410 document.execCommand("BackgroundImageCache", false, true);
7411 }catch(e){
7412 // sane browsers don't have cache "issues"
7413 }
7414 }
7415
7416 // =============================
7417 // DOM Functions
7418 // =============================
7419
7420 // the result object
7421 var dom = {
7422 // summary:
7423 // This module defines the core dojo DOM API.
7424 };
7425
7426 if(has("ie")){
7427 dom.byId = function(id, doc){
7428 if(typeof id != "string"){
7429 return id;
7430 }
7431 var _d = doc || win.doc, te = id && _d.getElementById(id);
7432 // attributes.id.value is better than just id in case the
7433 // user has a name=id inside a form
7434 if(te && (te.attributes.id.value == id || te.id == id)){
7435 return te;
7436 }else{
7437 var eles = _d.all[id];
7438 if(!eles || eles.nodeName){
7439 eles = [eles];
7440 }
7441 // if more than 1, choose first with the correct id
7442 var i = 0;
7443 while((te = eles[i++])){
7444 if((te.attributes && te.attributes.id && te.attributes.id.value == id) || te.id == id){
7445 return te;
7446 }
7447 }
7448 }
7449 };
7450 }else{
7451 dom.byId = function(id, doc){
7452 // inline'd type check.
7453 // be sure to return null per documentation, to match IE branch.
7454 return ((typeof id == "string") ? (doc || win.doc).getElementById(id) : id) || null; // DOMNode
7455 };
7456 }
7457 /*=====
7458 dom.byId = function(id, doc){
7459 // summary:
7460 // Returns DOM node with matching `id` attribute or falsy value (ex: null or undefined)
7461 // if not found. If `id` is a DomNode, this function is a no-op.
7462 //
7463 // id: String|DOMNode
7464 // A string to match an HTML id attribute or a reference to a DOM Node
7465 //
7466 // doc: Document?
7467 // Document to work in. Defaults to the current value of
7468 // dojo.doc. Can be used to retrieve
7469 // node references from other documents.
7470 //
7471 // example:
7472 // Look up a node by ID:
7473 // | var n = dojo.byId("foo");
7474 //
7475 // example:
7476 // Check if a node exists, and use it.
7477 // | var n = dojo.byId("bar");
7478 // | if(n){ doStuff() ... }
7479 //
7480 // example:
7481 // Allow string or DomNode references to be passed to a custom function:
7482 // | var foo = function(nodeOrId){
7483 // | nodeOrId = dojo.byId(nodeOrId);
7484 // | // ... more stuff
7485 // | }
7486 };
7487 =====*/
7488
7489 dom.isDescendant = function(/*DOMNode|String*/ node, /*DOMNode|String*/ ancestor){
7490 // summary:
7491 // Returns true if node is a descendant of ancestor
7492 // node: DOMNode|String
7493 // string id or node reference to test
7494 // ancestor: DOMNode|String
7495 // string id or node reference of potential parent to test against
7496 //
7497 // example:
7498 // Test is node id="bar" is a descendant of node id="foo"
7499 // | if(dojo.isDescendant("bar", "foo")){ ... }
7500
7501 try{
7502 node = dom.byId(node);
7503 ancestor = dom.byId(ancestor);
7504 while(node){
7505 if(node == ancestor){
7506 return true; // Boolean
7507 }
7508 node = node.parentNode;
7509 }
7510 }catch(e){ /* squelch, return false */ }
7511 return false; // Boolean
7512 };
7513
7514
7515 // TODO: do we need setSelectable in the base?
7516
7517 // Add feature test for user-select CSS property
7518 // (currently known to work in all but IE < 10 and Opera)
7519 has.add("css-user-select", function(global, doc, element){
7520 // Avoid exception when dom.js is loaded in non-browser environments
7521 if(!element){ return false; }
7522
7523 var style = element.style;
7524 var prefixes = ["Khtml", "O", "ms", "Moz", "Webkit"],
7525 i = prefixes.length,
7526 name = "userSelect",
7527 prefix;
7528
7529 // Iterate prefixes from most to least likely
7530 do{
7531 if(typeof style[name] !== "undefined"){
7532 // Supported; return property name
7533 return name;
7534 }
7535 }while(i-- && (name = prefixes[i] + "UserSelect"));
7536
7537 // Not supported if we didn't return before now
7538 return false;
7539 });
7540
7541 /*=====
7542 dom.setSelectable = function(node, selectable){
7543 // summary:
7544 // Enable or disable selection on a node
7545 // node: DOMNode|String
7546 // id or reference to node
7547 // selectable: Boolean
7548 // state to put the node in. false indicates unselectable, true
7549 // allows selection.
7550 // example:
7551 // Make the node id="bar" unselectable
7552 // | dojo.setSelectable("bar");
7553 // example:
7554 // Make the node id="bar" selectable
7555 // | dojo.setSelectable("bar", true);
7556 };
7557 =====*/
7558
7559 var cssUserSelect = has("css-user-select");
7560 dom.setSelectable = cssUserSelect ? function(node, selectable){
7561 // css-user-select returns a (possibly vendor-prefixed) CSS property name
7562 dom.byId(node).style[cssUserSelect] = selectable ? "" : "none";
7563 } : function(node, selectable){
7564 node = dom.byId(node);
7565
7566 // (IE < 10 / Opera) Fall back to setting/removing the
7567 // unselectable attribute on the element and all its children
7568 var nodes = node.getElementsByTagName("*"),
7569 i = nodes.length;
7570
7571 if(selectable){
7572 node.removeAttribute("unselectable");
7573 while(i--){
7574 nodes[i].removeAttribute("unselectable");
7575 }
7576 }else{
7577 node.setAttribute("unselectable", "on");
7578 while(i--){
7579 nodes[i].setAttribute("unselectable", "on");
7580 }
7581 }
7582 };
7583
7584 return dom;
7585 });
7586
7587 },
7588 'dojo/_base/browser':function(){
7589 if(require.has){
7590 require.has.add("config-selectorEngine", "acme");
7591 }
7592 define([
7593 "../ready",
7594 "./kernel",
7595 "./connect", // until we decide if connect is going back into non-browser environments
7596 "./unload",
7597 "./window",
7598 "./event",
7599 "./html",
7600 "./NodeList",
7601 "../query",
7602 "./xhr",
7603 "./fx"], function(dojo){
7604
7605 // module:
7606 // dojo/_base/browser
7607
7608 /*=====
7609 return {
7610 // summary:
7611 // This module causes the browser-only base modules to be loaded.
7612 };
7613 =====*/
7614
7615 return dojo;
7616 });
7617
7618 },
7619 'dojo/errors/RequestTimeoutError':function(){
7620 define("dojo/errors/RequestTimeoutError", ['./create', './RequestError'], function(create, RequestError){
7621 // module:
7622 // dojo/errors/RequestTimeoutError
7623
7624 /*=====
7625 return function(){
7626 // summary:
7627 // TODOC
7628 };
7629 =====*/
7630
7631 return create("RequestTimeoutError", null, RequestError, {
7632 dojoType: "timeout"
7633 });
7634 });
7635
7636 },
7637 'dojo/dom-style':function(){
7638 define("dojo/dom-style", ["./sniff", "./dom"], function(has, dom){
7639 // module:
7640 // dojo/dom-style
7641
7642 // =============================
7643 // Style Functions
7644 // =============================
7645
7646 // getComputedStyle drives most of the style code.
7647 // Wherever possible, reuse the returned object.
7648 //
7649 // API functions below that need to access computed styles accept an
7650 // optional computedStyle parameter.
7651 // If this parameter is omitted, the functions will call getComputedStyle themselves.
7652 // This way, calling code can access computedStyle once, and then pass the reference to
7653 // multiple API functions.
7654
7655 // Although we normally eschew argument validation at this
7656 // level, here we test argument 'node' for (duck)type,
7657 // by testing nodeType, ecause 'document' is the 'parentNode' of 'body'
7658 // it is frequently sent to this function even
7659 // though it is not Element.
7660 var getComputedStyle, style = {
7661 // summary:
7662 // This module defines the core dojo DOM style API.
7663 };
7664 if(has("webkit")){
7665 getComputedStyle = function(/*DomNode*/ node){
7666 var s;
7667 if(node.nodeType == 1){
7668 var dv = node.ownerDocument.defaultView;
7669 s = dv.getComputedStyle(node, null);
7670 if(!s && node.style){
7671 node.style.display = "";
7672 s = dv.getComputedStyle(node, null);
7673 }
7674 }
7675 return s || {};
7676 };
7677 }else if(has("ie") && (has("ie") < 9 || has("quirks"))){
7678 getComputedStyle = function(node){
7679 // IE (as of 7) doesn't expose Element like sane browsers
7680 // currentStyle can be null on IE8!
7681 return node.nodeType == 1 /* ELEMENT_NODE*/ && node.currentStyle ? node.currentStyle : {};
7682 };
7683 }else{
7684 getComputedStyle = function(node){
7685 return node.nodeType == 1 /* ELEMENT_NODE*/ ?
7686 node.ownerDocument.defaultView.getComputedStyle(node, null) : {};
7687 };
7688 }
7689 style.getComputedStyle = getComputedStyle;
7690 /*=====
7691 style.getComputedStyle = function(node){
7692 // summary:
7693 // Returns a "computed style" object.
7694 //
7695 // description:
7696 // Gets a "computed style" object which can be used to gather
7697 // information about the current state of the rendered node.
7698 //
7699 // Note that this may behave differently on different browsers.
7700 // Values may have different formats and value encodings across
7701 // browsers.
7702 //
7703 // Note also that this method is expensive. Wherever possible,
7704 // reuse the returned object.
7705 //
7706 // Use the dojo.style() method for more consistent (pixelized)
7707 // return values.
7708 //
7709 // node: DOMNode
7710 // A reference to a DOM node. Does NOT support taking an
7711 // ID string for speed reasons.
7712 // example:
7713 // | dojo.getComputedStyle(dojo.byId('foo')).borderWidth;
7714 //
7715 // example:
7716 // Reusing the returned object, avoiding multiple lookups:
7717 // | var cs = dojo.getComputedStyle(dojo.byId("someNode"));
7718 // | var w = cs.width, h = cs.height;
7719 return; // CSS2Properties
7720 };
7721 =====*/
7722
7723 var toPixel;
7724 if(!has("ie")){
7725 toPixel = function(element, value){
7726 // style values can be floats, client code may want
7727 // to round for integer pixels.
7728 return parseFloat(value) || 0;
7729 };
7730 }else{
7731 toPixel = function(element, avalue){
7732 if(!avalue){ return 0; }
7733 // on IE7, medium is usually 4 pixels
7734 if(avalue == "medium"){ return 4; }
7735 // style values can be floats, client code may
7736 // want to round this value for integer pixels.
7737 if(avalue.slice && avalue.slice(-2) == 'px'){ return parseFloat(avalue); }
7738 var s = element.style, rs = element.runtimeStyle, cs = element.currentStyle,
7739 sLeft = s.left, rsLeft = rs.left;
7740 rs.left = cs.left;
7741 try{
7742 // 'avalue' may be incompatible with style.left, which can cause IE to throw
7743 // this has been observed for border widths using "thin", "medium", "thick" constants
7744 // those particular constants could be trapped by a lookup
7745 // but perhaps there are more
7746 s.left = avalue;
7747 avalue = s.pixelLeft;
7748 }catch(e){
7749 avalue = 0;
7750 }
7751 s.left = sLeft;
7752 rs.left = rsLeft;
7753 return avalue;
7754 };
7755 }
7756 style.toPixelValue = toPixel;
7757 /*=====
7758 style.toPixelValue = function(node, value){
7759 // summary:
7760 // converts style value to pixels on IE or return a numeric value.
7761 // node: DOMNode
7762 // value: String
7763 // returns: Number
7764 };
7765 =====*/
7766
7767 // FIXME: there opacity quirks on FF that we haven't ported over. Hrm.
7768
7769 var astr = "DXImageTransform.Microsoft.Alpha";
7770 var af = function(n, f){
7771 try{
7772 return n.filters.item(astr);
7773 }catch(e){
7774 return f ? {} : null;
7775 }
7776 };
7777
7778 var _getOpacity =
7779 has("ie") < 9 || (has("ie") < 10 && has("quirks")) ? function(node){
7780 try{
7781 return af(node).Opacity / 100; // Number
7782 }catch(e){
7783 return 1; // Number
7784 }
7785 } :
7786 function(node){
7787 return getComputedStyle(node).opacity;
7788 };
7789
7790 var _setOpacity =
7791 has("ie") < 9 || (has("ie") < 10 && has("quirks")) ? function(/*DomNode*/ node, /*Number*/ opacity){
7792 var ov = opacity * 100, opaque = opacity == 1;
7793 node.style.zoom = opaque ? "" : 1;
7794
7795 if(!af(node)){
7796 if(opaque){
7797 return opacity;
7798 }
7799 node.style.filter += " progid:" + astr + "(Opacity=" + ov + ")";
7800 }else{
7801 af(node, 1).Opacity = ov;
7802 }
7803
7804 // on IE7 Alpha(Filter opacity=100) makes text look fuzzy so disable it altogether (bug #2661),
7805 //but still update the opacity value so we can get a correct reading if it is read later.
7806 af(node, 1).Enabled = !opaque;
7807
7808 if(node.tagName.toLowerCase() == "tr"){
7809 for(var td = node.firstChild; td; td = td.nextSibling){
7810 if(td.tagName.toLowerCase() == "td"){
7811 _setOpacity(td, opacity);
7812 }
7813 }
7814 }
7815 return opacity;
7816 } :
7817 function(node, opacity){
7818 return node.style.opacity = opacity;
7819 };
7820
7821 var _pixelNamesCache = {
7822 left: true, top: true
7823 };
7824 var _pixelRegExp = /margin|padding|width|height|max|min|offset/; // |border
7825 function _toStyleValue(node, type, value){
7826 //TODO: should we really be doing string case conversion here? Should we cache it? Need to profile!
7827 type = type.toLowerCase();
7828 if(has("ie")){
7829 if(value == "auto"){
7830 if(type == "height"){ return node.offsetHeight; }
7831 if(type == "width"){ return node.offsetWidth; }
7832 }
7833 if(type == "fontweight"){
7834 switch(value){
7835 case 700: return "bold";
7836 case 400:
7837 default: return "normal";
7838 }
7839 }
7840 }
7841 if(!(type in _pixelNamesCache)){
7842 _pixelNamesCache[type] = _pixelRegExp.test(type);
7843 }
7844 return _pixelNamesCache[type] ? toPixel(node, value) : value;
7845 }
7846
7847 var _floatStyle = has("ie") ? "styleFloat" : "cssFloat",
7848 _floatAliases = {"cssFloat": _floatStyle, "styleFloat": _floatStyle, "float": _floatStyle};
7849
7850 // public API
7851
7852 style.get = function getStyle(/*DOMNode|String*/ node, /*String?*/ name){
7853 // summary:
7854 // Accesses styles on a node.
7855 // description:
7856 // Getting the style value uses the computed style for the node, so the value
7857 // will be a calculated value, not just the immediate node.style value.
7858 // Also when getting values, use specific style names,
7859 // like "borderBottomWidth" instead of "border" since compound values like
7860 // "border" are not necessarily reflected as expected.
7861 // If you want to get node dimensions, use `dojo.marginBox()`,
7862 // `dojo.contentBox()` or `dojo.position()`.
7863 // node: DOMNode|String
7864 // id or reference to node to get style for
7865 // name: String?
7866 // the style property to get
7867 // example:
7868 // Passing only an ID or node returns the computed style object of
7869 // the node:
7870 // | dojo.getStyle("thinger");
7871 // example:
7872 // Passing a node and a style property returns the current
7873 // normalized, computed value for that property:
7874 // | dojo.getStyle("thinger", "opacity"); // 1 by default
7875
7876 var n = dom.byId(node), l = arguments.length, op = (name == "opacity");
7877 if(l == 2 && op){
7878 return _getOpacity(n);
7879 }
7880 name = _floatAliases[name] || name;
7881 var s = style.getComputedStyle(n);
7882 return (l == 1) ? s : _toStyleValue(n, name, s[name] || n.style[name]); /* CSS2Properties||String||Number */
7883 };
7884
7885 style.set = function setStyle(/*DOMNode|String*/ node, /*String|Object*/ name, /*String?*/ value){
7886 // summary:
7887 // Sets styles on a node.
7888 // node: DOMNode|String
7889 // id or reference to node to set style for
7890 // name: String|Object
7891 // the style property to set in DOM-accessor format
7892 // ("borderWidth", not "border-width") or an object with key/value
7893 // pairs suitable for setting each property.
7894 // value: String?
7895 // If passed, sets value on the node for style, handling
7896 // cross-browser concerns. When setting a pixel value,
7897 // be sure to include "px" in the value. For instance, top: "200px".
7898 // Otherwise, in some cases, some browsers will not apply the style.
7899 //
7900 // example:
7901 // Passing a node, a style property, and a value changes the
7902 // current display of the node and returns the new computed value
7903 // | dojo.setStyle("thinger", "opacity", 0.5); // == 0.5
7904 //
7905 // example:
7906 // Passing a node, an object-style style property sets each of the values in turn and returns the computed style object of the node:
7907 // | dojo.setStyle("thinger", {
7908 // | "opacity": 0.5,
7909 // | "border": "3px solid black",
7910 // | "height": "300px"
7911 // | });
7912 //
7913 // example:
7914 // When the CSS style property is hyphenated, the JavaScript property is camelCased.
7915 // font-size becomes fontSize, and so on.
7916 // | dojo.setStyle("thinger",{
7917 // | fontSize:"14pt",
7918 // | letterSpacing:"1.2em"
7919 // | });
7920 //
7921 // example:
7922 // dojo/NodeList implements .style() using the same syntax, omitting the "node" parameter, calling
7923 // dojo.style() on every element of the list. See: `dojo.query()` and `dojo/NodeList`
7924 // | dojo.query(".someClassName").style("visibility","hidden");
7925 // | // or
7926 // | dojo.query("#baz > div").style({
7927 // | opacity:0.75,
7928 // | fontSize:"13pt"
7929 // | });
7930
7931 var n = dom.byId(node), l = arguments.length, op = (name == "opacity");
7932 name = _floatAliases[name] || name;
7933 if(l == 3){
7934 return op ? _setOpacity(n, value) : n.style[name] = value; // Number
7935 }
7936 for(var x in name){
7937 style.set(node, x, name[x]);
7938 }
7939 return style.getComputedStyle(n);
7940 };
7941
7942 return style;
7943 });
7944
7945 },
7946 'dojo/dom-geometry':function(){
7947 define(["./sniff", "./_base/window","./dom", "./dom-style"],
7948 function(has, win, dom, style){
7949 // module:
7950 // dojo/dom-geometry
7951
7952 // the result object
7953 var geom = {
7954 // summary:
7955 // This module defines the core dojo DOM geometry API.
7956 };
7957
7958 // Box functions will assume this model.
7959 // On IE/Opera, BORDER_BOX will be set if the primary document is in quirks mode.
7960 // Can be set to change behavior of box setters.
7961
7962 // can be either:
7963 // "border-box"
7964 // "content-box" (default)
7965 geom.boxModel = "content-box";
7966
7967 // We punt per-node box mode testing completely.
7968 // If anybody cares, we can provide an additional (optional) unit
7969 // that overrides existing code to include per-node box sensitivity.
7970
7971 // Opera documentation claims that Opera 9 uses border-box in BackCompat mode.
7972 // but experiments (Opera 9.10.8679 on Windows Vista) indicate that it actually continues to use content-box.
7973 // IIRC, earlier versions of Opera did in fact use border-box.
7974 // Opera guys, this is really confusing. Opera being broken in quirks mode is not our fault.
7975
7976 if(has("ie") /*|| has("opera")*/){
7977 // client code may have to adjust if compatMode varies across iframes
7978 geom.boxModel = document.compatMode == "BackCompat" ? "border-box" : "content-box";
7979 }
7980
7981 geom.getPadExtents = function getPadExtents(/*DomNode*/ node, /*Object*/ computedStyle){
7982 // summary:
7983 // Returns object with special values specifically useful for node
7984 // fitting.
7985 // description:
7986 // Returns an object with `w`, `h`, `l`, `t` properties:
7987 // | l/t/r/b = left/top/right/bottom padding (respectively)
7988 // | w = the total of the left and right padding
7989 // | h = the total of the top and bottom padding
7990 // If 'node' has position, l/t forms the origin for child nodes.
7991 // The w/h are used for calculating boxes.
7992 // Normally application code will not need to invoke this
7993 // directly, and will use the ...box... functions instead.
7994 // node: DOMNode
7995 // computedStyle: Object?
7996 // This parameter accepts computed styles object.
7997 // If this parameter is omitted, the functions will call
7998 // dojo.getComputedStyle to get one. It is a better way, calling
7999 // dojo.computedStyle once, and then pass the reference to this
8000 // computedStyle parameter. Wherever possible, reuse the returned
8001 // object of dojo/dom-style.getComputedStyle().
8002
8003 node = dom.byId(node);
8004 var s = computedStyle || style.getComputedStyle(node), px = style.toPixelValue,
8005 l = px(node, s.paddingLeft), t = px(node, s.paddingTop), r = px(node, s.paddingRight), b = px(node, s.paddingBottom);
8006 return {l: l, t: t, r: r, b: b, w: l + r, h: t + b};
8007 };
8008
8009 var none = "none";
8010
8011 geom.getBorderExtents = function getBorderExtents(/*DomNode*/ node, /*Object*/ computedStyle){
8012 // summary:
8013 // returns an object with properties useful for noting the border
8014 // dimensions.
8015 // description:
8016 // - l/t/r/b = the sum of left/top/right/bottom border (respectively)
8017 // - w = the sum of the left and right border
8018 // - h = the sum of the top and bottom border
8019 //
8020 // The w/h are used for calculating boxes.
8021 // Normally application code will not need to invoke this
8022 // directly, and will use the ...box... functions instead.
8023 // node: DOMNode
8024 // computedStyle: Object?
8025 // This parameter accepts computed styles object.
8026 // If this parameter is omitted, the functions will call
8027 // dojo.getComputedStyle to get one. It is a better way, calling
8028 // dojo.computedStyle once, and then pass the reference to this
8029 // computedStyle parameter. Wherever possible, reuse the returned
8030 // object of dojo/dom-style.getComputedStyle().
8031
8032 node = dom.byId(node);
8033 var px = style.toPixelValue, s = computedStyle || style.getComputedStyle(node),
8034 l = s.borderLeftStyle != none ? px(node, s.borderLeftWidth) : 0,
8035 t = s.borderTopStyle != none ? px(node, s.borderTopWidth) : 0,
8036 r = s.borderRightStyle != none ? px(node, s.borderRightWidth) : 0,
8037 b = s.borderBottomStyle != none ? px(node, s.borderBottomWidth) : 0;
8038 return {l: l, t: t, r: r, b: b, w: l + r, h: t + b};
8039 };
8040
8041 geom.getPadBorderExtents = function getPadBorderExtents(/*DomNode*/ node, /*Object*/ computedStyle){
8042 // summary:
8043 // Returns object with properties useful for box fitting with
8044 // regards to padding.
8045 // description:
8046 // - l/t/r/b = the sum of left/top/right/bottom padding and left/top/right/bottom border (respectively)
8047 // - w = the sum of the left and right padding and border
8048 // - h = the sum of the top and bottom padding and border
8049 //
8050 // The w/h are used for calculating boxes.
8051 // Normally application code will not need to invoke this
8052 // directly, and will use the ...box... functions instead.
8053 // node: DOMNode
8054 // computedStyle: Object?
8055 // This parameter accepts computed styles object.
8056 // If this parameter is omitted, the functions will call
8057 // dojo.getComputedStyle to get one. It is a better way, calling
8058 // dojo.computedStyle once, and then pass the reference to this
8059 // computedStyle parameter. Wherever possible, reuse the returned
8060 // object of dojo/dom-style.getComputedStyle().
8061
8062 node = dom.byId(node);
8063 var s = computedStyle || style.getComputedStyle(node),
8064 p = geom.getPadExtents(node, s),
8065 b = geom.getBorderExtents(node, s);
8066 return {
8067 l: p.l + b.l,
8068 t: p.t + b.t,
8069 r: p.r + b.r,
8070 b: p.b + b.b,
8071 w: p.w + b.w,
8072 h: p.h + b.h
8073 };
8074 };
8075
8076 geom.getMarginExtents = function getMarginExtents(node, computedStyle){
8077 // summary:
8078 // returns object with properties useful for box fitting with
8079 // regards to box margins (i.e., the outer-box).
8080 //
8081 // - l/t = marginLeft, marginTop, respectively
8082 // - w = total width, margin inclusive
8083 // - h = total height, margin inclusive
8084 //
8085 // The w/h are used for calculating boxes.
8086 // Normally application code will not need to invoke this
8087 // directly, and will use the ...box... functions instead.
8088 // node: DOMNode
8089 // computedStyle: Object?
8090 // This parameter accepts computed styles object.
8091 // If this parameter is omitted, the functions will call
8092 // dojo.getComputedStyle to get one. It is a better way, calling
8093 // dojo.computedStyle once, and then pass the reference to this
8094 // computedStyle parameter. Wherever possible, reuse the returned
8095 // object of dojo/dom-style.getComputedStyle().
8096
8097 node = dom.byId(node);
8098 var s = computedStyle || style.getComputedStyle(node), px = style.toPixelValue,
8099 l = px(node, s.marginLeft), t = px(node, s.marginTop), r = px(node, s.marginRight), b = px(node, s.marginBottom);
8100 return {l: l, t: t, r: r, b: b, w: l + r, h: t + b};
8101 };
8102
8103 // Box getters work in any box context because offsetWidth/clientWidth
8104 // are invariant wrt box context
8105 //
8106 // They do *not* work for display: inline objects that have padding styles
8107 // because the user agent ignores padding (it's bogus styling in any case)
8108 //
8109 // Be careful with IMGs because they are inline or block depending on
8110 // browser and browser mode.
8111
8112 // Although it would be easier to read, there are not separate versions of
8113 // _getMarginBox for each browser because:
8114 // 1. the branching is not expensive
8115 // 2. factoring the shared code wastes cycles (function call overhead)
8116 // 3. duplicating the shared code wastes bytes
8117
8118 geom.getMarginBox = function getMarginBox(/*DomNode*/ node, /*Object*/ computedStyle){
8119 // summary:
8120 // returns an object that encodes the width, height, left and top
8121 // positions of the node's margin box.
8122 // node: DOMNode
8123 // computedStyle: Object?
8124 // This parameter accepts computed styles object.
8125 // If this parameter is omitted, the functions will call
8126 // dojo.getComputedStyle to get one. It is a better way, calling
8127 // dojo.computedStyle once, and then pass the reference to this
8128 // computedStyle parameter. Wherever possible, reuse the returned
8129 // object of dojo/dom-style.getComputedStyle().
8130
8131 node = dom.byId(node);
8132 var s = computedStyle || style.getComputedStyle(node), me = geom.getMarginExtents(node, s),
8133 l = node.offsetLeft - me.l, t = node.offsetTop - me.t, p = node.parentNode, px = style.toPixelValue, pcs;
8134 if(has("mozilla")){
8135 // Mozilla:
8136 // If offsetParent has a computed overflow != visible, the offsetLeft is decreased
8137 // by the parent's border.
8138 // We don't want to compute the parent's style, so instead we examine node's
8139 // computed left/top which is more stable.
8140 var sl = parseFloat(s.left), st = parseFloat(s.top);
8141 if(!isNaN(sl) && !isNaN(st)){
8142 l = sl;
8143 t = st;
8144 }else{
8145 // If child's computed left/top are not parseable as a number (e.g. "auto"), we
8146 // have no choice but to examine the parent's computed style.
8147 if(p && p.style){
8148 pcs = style.getComputedStyle(p);
8149 if(pcs.overflow != "visible"){
8150 l += pcs.borderLeftStyle != none ? px(node, pcs.borderLeftWidth) : 0;
8151 t += pcs.borderTopStyle != none ? px(node, pcs.borderTopWidth) : 0;
8152 }
8153 }
8154 }
8155 }else if(has("opera") || (has("ie") == 8 && !has("quirks"))){
8156 // On Opera and IE 8, offsetLeft/Top includes the parent's border
8157 if(p){
8158 pcs = style.getComputedStyle(p);
8159 l -= pcs.borderLeftStyle != none ? px(node, pcs.borderLeftWidth) : 0;
8160 t -= pcs.borderTopStyle != none ? px(node, pcs.borderTopWidth) : 0;
8161 }
8162 }
8163 return {l: l, t: t, w: node.offsetWidth + me.w, h: node.offsetHeight + me.h};
8164 };
8165
8166 geom.getContentBox = function getContentBox(node, computedStyle){
8167 // summary:
8168 // Returns an object that encodes the width, height, left and top
8169 // positions of the node's content box, irrespective of the
8170 // current box model.
8171 // node: DOMNode
8172 // computedStyle: Object?
8173 // This parameter accepts computed styles object.
8174 // If this parameter is omitted, the functions will call
8175 // dojo.getComputedStyle to get one. It is a better way, calling
8176 // dojo.computedStyle once, and then pass the reference to this
8177 // computedStyle parameter. Wherever possible, reuse the returned
8178 // object of dojo/dom-style.getComputedStyle().
8179
8180 // clientWidth/Height are important since the automatically account for scrollbars
8181 // fallback to offsetWidth/Height for special cases (see #3378)
8182 node = dom.byId(node);
8183 var s = computedStyle || style.getComputedStyle(node), w = node.clientWidth, h,
8184 pe = geom.getPadExtents(node, s), be = geom.getBorderExtents(node, s);
8185 if(!w){
8186 w = node.offsetWidth;
8187 h = node.offsetHeight;
8188 }else{
8189 h = node.clientHeight;
8190 be.w = be.h = 0;
8191 }
8192 // On Opera, offsetLeft includes the parent's border
8193 if(has("opera")){
8194 pe.l += be.l;
8195 pe.t += be.t;
8196 }
8197 return {l: pe.l, t: pe.t, w: w - pe.w - be.w, h: h - pe.h - be.h};
8198 };
8199
8200 // Box setters depend on box context because interpretation of width/height styles
8201 // vary wrt box context.
8202 //
8203 // The value of boxModel is used to determine box context.
8204 // boxModel can be set directly to change behavior.
8205 //
8206 // Beware of display: inline objects that have padding styles
8207 // because the user agent ignores padding (it's a bogus setup anyway)
8208 //
8209 // Be careful with IMGs because they are inline or block depending on
8210 // browser and browser mode.
8211 //
8212 // Elements other than DIV may have special quirks, like built-in
8213 // margins or padding, or values not detectable via computedStyle.
8214 // In particular, margins on TABLE do not seems to appear
8215 // at all in computedStyle on Mozilla.
8216
8217 function setBox(/*DomNode*/ node, /*Number?*/ l, /*Number?*/ t, /*Number?*/ w, /*Number?*/ h, /*String?*/ u){
8218 // summary:
8219 // sets width/height/left/top in the current (native) box-model
8220 // dimensions. Uses the unit passed in u.
8221 // node:
8222 // DOM Node reference. Id string not supported for performance
8223 // reasons.
8224 // l:
8225 // left offset from parent.
8226 // t:
8227 // top offset from parent.
8228 // w:
8229 // width in current box model.
8230 // h:
8231 // width in current box model.
8232 // u:
8233 // unit measure to use for other measures. Defaults to "px".
8234 u = u || "px";
8235 var s = node.style;
8236 if(!isNaN(l)){
8237 s.left = l + u;
8238 }
8239 if(!isNaN(t)){
8240 s.top = t + u;
8241 }
8242 if(w >= 0){
8243 s.width = w + u;
8244 }
8245 if(h >= 0){
8246 s.height = h + u;
8247 }
8248 }
8249
8250 function isButtonTag(/*DomNode*/ node){
8251 // summary:
8252 // True if the node is BUTTON or INPUT.type="button".
8253 return node.tagName.toLowerCase() == "button" ||
8254 node.tagName.toLowerCase() == "input" && (node.getAttribute("type") || "").toLowerCase() == "button"; // boolean
8255 }
8256
8257 function usesBorderBox(/*DomNode*/ node){
8258 // summary:
8259 // True if the node uses border-box layout.
8260
8261 // We could test the computed style of node to see if a particular box
8262 // has been specified, but there are details and we choose not to bother.
8263
8264 // TABLE and BUTTON (and INPUT type=button) are always border-box by default.
8265 // If you have assigned a different box to either one via CSS then
8266 // box functions will break.
8267
8268 return geom.boxModel == "border-box" || node.tagName.toLowerCase() == "table" || isButtonTag(node); // boolean
8269 }
8270
8271 geom.setContentSize = function setContentSize(/*DomNode*/ node, /*Object*/ box, /*Object*/ computedStyle){
8272 // summary:
8273 // Sets the size of the node's contents, irrespective of margins,
8274 // padding, or borders.
8275 // node: DOMNode
8276 // box: Object
8277 // hash with optional "w", and "h" properties for "width", and "height"
8278 // respectively. All specified properties should have numeric values in whole pixels.
8279 // computedStyle: Object?
8280 // This parameter accepts computed styles object.
8281 // If this parameter is omitted, the functions will call
8282 // dojo.getComputedStyle to get one. It is a better way, calling
8283 // dojo.computedStyle once, and then pass the reference to this
8284 // computedStyle parameter. Wherever possible, reuse the returned
8285 // object of dojo/dom-style.getComputedStyle().
8286
8287 node = dom.byId(node);
8288 var w = box.w, h = box.h;
8289 if(usesBorderBox(node)){
8290 var pb = geom.getPadBorderExtents(node, computedStyle);
8291 if(w >= 0){
8292 w += pb.w;
8293 }
8294 if(h >= 0){
8295 h += pb.h;
8296 }
8297 }
8298 setBox(node, NaN, NaN, w, h);
8299 };
8300
8301 var nilExtents = {l: 0, t: 0, w: 0, h: 0};
8302
8303 geom.setMarginBox = function setMarginBox(/*DomNode*/ node, /*Object*/ box, /*Object*/ computedStyle){
8304 // summary:
8305 // sets the size of the node's margin box and placement
8306 // (left/top), irrespective of box model. Think of it as a
8307 // passthrough to setBox that handles box-model vagaries for
8308 // you.
8309 // node: DOMNode
8310 // box: Object
8311 // hash with optional "l", "t", "w", and "h" properties for "left", "right", "width", and "height"
8312 // respectively. All specified properties should have numeric values in whole pixels.
8313 // computedStyle: Object?
8314 // This parameter accepts computed styles object.
8315 // If this parameter is omitted, the functions will call
8316 // dojo.getComputedStyle to get one. It is a better way, calling
8317 // dojo.computedStyle once, and then pass the reference to this
8318 // computedStyle parameter. Wherever possible, reuse the returned
8319 // object of dojo/dom-style.getComputedStyle().
8320
8321 node = dom.byId(node);
8322 var s = computedStyle || style.getComputedStyle(node), w = box.w, h = box.h,
8323 // Some elements have special padding, margin, and box-model settings.
8324 // To use box functions you may need to set padding, margin explicitly.
8325 // Controlling box-model is harder, in a pinch you might set dojo/dom-geometry.boxModel.
8326 pb = usesBorderBox(node) ? nilExtents : geom.getPadBorderExtents(node, s),
8327 mb = geom.getMarginExtents(node, s);
8328 if(has("webkit")){
8329 // on Safari (3.1.2), button nodes with no explicit size have a default margin
8330 // setting an explicit size eliminates the margin.
8331 // We have to swizzle the width to get correct margin reading.
8332 if(isButtonTag(node)){
8333 var ns = node.style;
8334 if(w >= 0 && !ns.width){
8335 ns.width = "4px";
8336 }
8337 if(h >= 0 && !ns.height){
8338 ns.height = "4px";
8339 }
8340 }
8341 }
8342 if(w >= 0){
8343 w = Math.max(w - pb.w - mb.w, 0);
8344 }
8345 if(h >= 0){
8346 h = Math.max(h - pb.h - mb.h, 0);
8347 }
8348 setBox(node, box.l, box.t, w, h);
8349 };
8350
8351 // =============================
8352 // Positioning
8353 // =============================
8354
8355 geom.isBodyLtr = function isBodyLtr(/*Document?*/ doc){
8356 // summary:
8357 // Returns true if the current language is left-to-right, and false otherwise.
8358 // doc: Document?
8359 // Optional document to query. If unspecified, use win.doc.
8360 // returns: Boolean
8361
8362 doc = doc || win.doc;
8363 return (win.body(doc).dir || doc.documentElement.dir || "ltr").toLowerCase() == "ltr"; // Boolean
8364 };
8365
8366 geom.docScroll = function docScroll(/*Document?*/ doc){
8367 // summary:
8368 // Returns an object with {node, x, y} with corresponding offsets.
8369 // doc: Document?
8370 // Optional document to query. If unspecified, use win.doc.
8371 // returns: Object
8372
8373 doc = doc || win.doc;
8374 var node = win.doc.parentWindow || win.doc.defaultView; // use UI window, not dojo.global window. TODO: use dojo/window::get() except for circular dependency problem
8375 return "pageXOffset" in node ? {x: node.pageXOffset, y: node.pageYOffset } :
8376 (node = has("quirks") ? win.body(doc) : doc.documentElement) &&
8377 {x: geom.fixIeBiDiScrollLeft(node.scrollLeft || 0, doc), y: node.scrollTop || 0 };
8378 };
8379
8380 if(has("ie")){
8381 geom.getIeDocumentElementOffset = function getIeDocumentElementOffset(/*Document?*/ doc){
8382 // summary:
8383 // returns the offset in x and y from the document body to the
8384 // visual edge of the page for IE
8385 // doc: Document?
8386 // Optional document to query. If unspecified, use win.doc.
8387 // description:
8388 // The following values in IE contain an offset:
8389 // | event.clientX
8390 // | event.clientY
8391 // | node.getBoundingClientRect().left
8392 // | node.getBoundingClientRect().top
8393 // But other position related values do not contain this offset,
8394 // such as node.offsetLeft, node.offsetTop, node.style.left and
8395 // node.style.top. The offset is always (2, 2) in LTR direction.
8396 // When the body is in RTL direction, the offset counts the width
8397 // of left scroll bar's width. This function computes the actual
8398 // offset.
8399
8400 //NOTE: assumes we're being called in an IE browser
8401
8402 doc = doc || win.doc;
8403 var de = doc.documentElement; // only deal with HTML element here, position() handles body/quirks
8404
8405 if(has("ie") < 8){
8406 var r = de.getBoundingClientRect(), // works well for IE6+
8407 l = r.left, t = r.top;
8408 if(has("ie") < 7){
8409 l += de.clientLeft; // scrollbar size in strict/RTL, or,
8410 t += de.clientTop; // HTML border size in strict
8411 }
8412 return {
8413 x: l < 0 ? 0 : l, // FRAME element border size can lead to inaccurate negative values
8414 y: t < 0 ? 0 : t
8415 };
8416 }else{
8417 return {
8418 x: 0,
8419 y: 0
8420 };
8421 }
8422 };
8423 }
8424
8425 geom.fixIeBiDiScrollLeft = function fixIeBiDiScrollLeft(/*Integer*/ scrollLeft, /*Document?*/ doc){
8426 // summary:
8427 // In RTL direction, scrollLeft should be a negative value, but IE
8428 // returns a positive one. All codes using documentElement.scrollLeft
8429 // must call this function to fix this error, otherwise the position
8430 // will offset to right when there is a horizontal scrollbar.
8431 // scrollLeft: Number
8432 // doc: Document?
8433 // Optional document to query. If unspecified, use win.doc.
8434 // returns: Number
8435
8436 // In RTL direction, scrollLeft should be a negative value, but IE
8437 // returns a positive one. All codes using documentElement.scrollLeft
8438 // must call this function to fix this error, otherwise the position
8439 // will offset to right when there is a horizontal scrollbar.
8440
8441 doc = doc || win.doc;
8442 var ie = has("ie");
8443 if(ie && !geom.isBodyLtr(doc)){
8444 var qk = has("quirks"),
8445 de = qk ? win.body(doc) : doc.documentElement,
8446 pwin = win.global; // TODO: use winUtils.get(doc) after resolving circular dependency b/w dom-geometry.js and dojo/window.js
8447 if(ie == 6 && !qk && pwin.frameElement && de.scrollHeight > de.clientHeight){
8448 scrollLeft += de.clientLeft; // workaround ie6+strict+rtl+iframe+vertical-scrollbar bug where clientWidth is too small by clientLeft pixels
8449 }
8450 return (ie < 8 || qk) ? (scrollLeft + de.clientWidth - de.scrollWidth) : -scrollLeft; // Integer
8451 }
8452 return scrollLeft; // Integer
8453 };
8454
8455 geom.position = function(/*DomNode*/ node, /*Boolean?*/ includeScroll){
8456 // summary:
8457 // Gets the position and size of the passed element relative to
8458 // the viewport (if includeScroll==false), or relative to the
8459 // document root (if includeScroll==true).
8460 //
8461 // description:
8462 // Returns an object of the form:
8463 // `{ x: 100, y: 300, w: 20, h: 15 }`.
8464 // If includeScroll==true, the x and y values will include any
8465 // document offsets that may affect the position relative to the
8466 // viewport.
8467 // Uses the border-box model (inclusive of border and padding but
8468 // not margin). Does not act as a setter.
8469 // node: DOMNode|String
8470 // includeScroll: Boolean?
8471 // returns: Object
8472
8473 node = dom.byId(node);
8474 var db = win.body(node.ownerDocument),
8475 ret = node.getBoundingClientRect();
8476 ret = {x: ret.left, y: ret.top, w: ret.right - ret.left, h: ret.bottom - ret.top};
8477
8478 if(has("ie") < 9){
8479 // On IE<9 there's a 2px offset that we need to adjust for, see dojo.getIeDocumentElementOffset()
8480 var offset = geom.getIeDocumentElementOffset(node.ownerDocument);
8481
8482 // fixes the position in IE, quirks mode
8483 ret.x -= offset.x + (has("quirks") ? db.clientLeft + db.offsetLeft : 0);
8484 ret.y -= offset.y + (has("quirks") ? db.clientTop + db.offsetTop : 0);
8485 }
8486
8487 // account for document scrolling
8488 // if offsetParent is used, ret value already includes scroll position
8489 // so we may have to actually remove that value if !includeScroll
8490 if(includeScroll){
8491 var scroll = geom.docScroll(node.ownerDocument);
8492 ret.x += scroll.x;
8493 ret.y += scroll.y;
8494 }
8495
8496 return ret; // Object
8497 };
8498
8499 // random "private" functions wildly used throughout the toolkit
8500
8501 geom.getMarginSize = function getMarginSize(/*DomNode*/ node, /*Object*/ computedStyle){
8502 // summary:
8503 // returns an object that encodes the width and height of
8504 // the node's margin box
8505 // node: DOMNode|String
8506 // computedStyle: Object?
8507 // This parameter accepts computed styles object.
8508 // If this parameter is omitted, the functions will call
8509 // dojo.getComputedStyle to get one. It is a better way, calling
8510 // dojo.computedStyle once, and then pass the reference to this
8511 // computedStyle parameter. Wherever possible, reuse the returned
8512 // object of dojo/dom-style.getComputedStyle().
8513
8514 node = dom.byId(node);
8515 var me = geom.getMarginExtents(node, computedStyle || style.getComputedStyle(node));
8516 var size = node.getBoundingClientRect();
8517 return {
8518 w: (size.right - size.left) + me.w,
8519 h: (size.bottom - size.top) + me.h
8520 };
8521 };
8522
8523 geom.normalizeEvent = function(event){
8524 // summary:
8525 // Normalizes the geometry of a DOM event, normalizing the pageX, pageY,
8526 // offsetX, offsetY, layerX, and layerX properties
8527 // event: Object
8528 if(!("layerX" in event)){
8529 event.layerX = event.offsetX;
8530 event.layerY = event.offsetY;
8531 }
8532 if(!has("dom-addeventlistener")){
8533 // old IE version
8534 // FIXME: scroll position query is duped from dojo.html to
8535 // avoid dependency on that entire module. Now that HTML is in
8536 // Base, we should convert back to something similar there.
8537 var se = event.target;
8538 var doc = (se && se.ownerDocument) || document;
8539 // DO NOT replace the following to use dojo.body(), in IE, document.documentElement should be used
8540 // here rather than document.body
8541 var docBody = has("quirks") ? doc.body : doc.documentElement;
8542 var offset = geom.getIeDocumentElementOffset(doc);
8543 event.pageX = event.clientX + geom.fixIeBiDiScrollLeft(docBody.scrollLeft || 0, doc) - offset.x;
8544 event.pageY = event.clientY + (docBody.scrollTop || 0) - offset.y;
8545 }
8546 };
8547
8548 // TODO: evaluate separate getters/setters for position and sizes?
8549
8550 return geom;
8551 });
8552
8553 },
8554 'dojo/dom-prop':function(){
8555 define(["exports", "./_base/kernel", "./sniff", "./_base/lang", "./dom", "./dom-style", "./dom-construct", "./_base/connect"],
8556 function(exports, dojo, has, lang, dom, style, ctr, conn){
8557 // module:
8558 // dojo/dom-prop
8559 // summary:
8560 // This module defines the core dojo DOM properties API.
8561 // Indirectly depends on dojo.empty() and dojo.toDom().
8562
8563 // TODOC: summary not showing up in output, see https://github.com/csnover/js-doc-parse/issues/42
8564
8565 // =============================
8566 // Element properties Functions
8567 // =============================
8568
8569 // helper to connect events
8570 var _evtHdlrMap = {}, _ctr = 0, _attrId = dojo._scopeName + "attrid";
8571
8572 exports.names = {
8573 // properties renamed to avoid clashes with reserved words
8574 "class": "className",
8575 "for": "htmlFor",
8576 // properties written as camelCase
8577 tabindex: "tabIndex",
8578 readonly: "readOnly",
8579 colspan: "colSpan",
8580 frameborder: "frameBorder",
8581 rowspan: "rowSpan",
8582 valuetype: "valueType"
8583 };
8584
8585 exports.get = function getProp(/*DOMNode|String*/ node, /*String*/ name){
8586 // summary:
8587 // Gets a property on an HTML element.
8588 // description:
8589 // Handles normalized getting of properties on DOM nodes.
8590 //
8591 // node: DOMNode|String
8592 // id or reference to the element to get the property on
8593 // name: String
8594 // the name of the property to get.
8595 // returns:
8596 // the value of the requested property or its default value
8597 //
8598 // example:
8599 // | // get the current value of the "foo" property on a node
8600 // | dojo.getProp(dojo.byId("nodeId"), "foo");
8601 // | // or we can just pass the id:
8602 // | dojo.getProp("nodeId", "foo");
8603
8604 node = dom.byId(node);
8605 var lc = name.toLowerCase(), propName = exports.names[lc] || name;
8606 return node[propName]; // Anything
8607 };
8608
8609 exports.set = function setProp(/*DOMNode|String*/ node, /*String|Object*/ name, /*String?*/ value){
8610 // summary:
8611 // Sets a property on an HTML element.
8612 // description:
8613 // Handles normalized setting of properties on DOM nodes.
8614 //
8615 // When passing functions as values, note that they will not be
8616 // directly assigned to slots on the node, but rather the default
8617 // behavior will be removed and the new behavior will be added
8618 // using `dojo.connect()`, meaning that event handler properties
8619 // will be normalized and that some caveats with regards to
8620 // non-standard behaviors for onsubmit apply. Namely that you
8621 // should cancel form submission using `dojo.stopEvent()` on the
8622 // passed event object instead of returning a boolean value from
8623 // the handler itself.
8624 // node: DOMNode|String
8625 // id or reference to the element to set the property on
8626 // name: String|Object
8627 // the name of the property to set, or a hash object to set
8628 // multiple properties at once.
8629 // value: String?
8630 // The value to set for the property
8631 // returns:
8632 // the DOM node
8633 //
8634 // example:
8635 // | // use prop() to set the tab index
8636 // | dojo.setProp("nodeId", "tabIndex", 3);
8637 // |
8638 //
8639 // example:
8640 // Set multiple values at once, including event handlers:
8641 // | dojo.setProp("formId", {
8642 // | "foo": "bar",
8643 // | "tabIndex": -1,
8644 // | "method": "POST",
8645 // | "onsubmit": function(e){
8646 // | // stop submitting the form. Note that the IE behavior
8647 // | // of returning true or false will have no effect here
8648 // | // since our handler is connect()ed to the built-in
8649 // | // onsubmit behavior and so we need to use
8650 // | // dojo.stopEvent() to ensure that the submission
8651 // | // doesn't proceed.
8652 // | dojo.stopEvent(e);
8653 // |
8654 // | // submit the form with Ajax
8655 // | dojo.xhrPost({ form: "formId" });
8656 // | }
8657 // | });
8658 //
8659 // example:
8660 // Style is s special case: Only set with an object hash of styles
8661 // | dojo.setProp("someNode",{
8662 // | id:"bar",
8663 // | style:{
8664 // | width:"200px", height:"100px", color:"#000"
8665 // | }
8666 // | });
8667 //
8668 // example:
8669 // Again, only set style as an object hash of styles:
8670 // | var obj = { color:"#fff", backgroundColor:"#000" };
8671 // | dojo.setProp("someNode", "style", obj);
8672 // |
8673 // | // though shorter to use `dojo.style()` in this case:
8674 // | dojo.style("someNode", obj);
8675
8676 node = dom.byId(node);
8677 var l = arguments.length;
8678 if(l == 2 && typeof name != "string"){ // inline'd type check
8679 // the object form of setter: the 2nd argument is a dictionary
8680 for(var x in name){
8681 exports.set(node, x, name[x]);
8682 }
8683 return node; // DomNode
8684 }
8685 var lc = name.toLowerCase(), propName = exports.names[lc] || name;
8686 if(propName == "style" && typeof value != "string"){ // inline'd type check
8687 // special case: setting a style
8688 style.set(node, value);
8689 return node; // DomNode
8690 }
8691 if(propName == "innerHTML"){
8692 // special case: assigning HTML
8693 // the hash lists elements with read-only innerHTML on IE
8694 if(has("ie") && node.tagName.toLowerCase() in {col: 1, colgroup: 1,
8695 table: 1, tbody: 1, tfoot: 1, thead: 1, tr: 1, title: 1}){
8696 ctr.empty(node);
8697 node.appendChild(ctr.toDom(value, node.ownerDocument));
8698 }else{
8699 node[propName] = value;
8700 }
8701 return node; // DomNode
8702 }
8703 if(lang.isFunction(value)){
8704 // special case: assigning an event handler
8705 // clobber if we can
8706 var attrId = node[_attrId];
8707 if(!attrId){
8708 attrId = _ctr++;
8709 node[_attrId] = attrId;
8710 }
8711 if(!_evtHdlrMap[attrId]){
8712 _evtHdlrMap[attrId] = {};
8713 }
8714 var h = _evtHdlrMap[attrId][propName];
8715 if(h){
8716 //h.remove();
8717 conn.disconnect(h);
8718 }else{
8719 try{
8720 delete node[propName];
8721 }catch(e){}
8722 }
8723 // ensure that event objects are normalized, etc.
8724 if(value){
8725 //_evtHdlrMap[attrId][propName] = on(node, propName, value);
8726 _evtHdlrMap[attrId][propName] = conn.connect(node, propName, value);
8727 }else{
8728 node[propName] = null;
8729 }
8730 return node; // DomNode
8731 }
8732 node[propName] = value;
8733 return node; // DomNode
8734 };
8735 });
8736
8737 },
8738 'dojo/when':function(){
8739 define([
8740 "./Deferred",
8741 "./promise/Promise"
8742 ], function(Deferred, Promise){
8743 "use strict";
8744
8745 // module:
8746 // dojo/when
8747
8748 return function when(valueOrPromise, callback, errback, progback){
8749 // summary:
8750 // Transparently applies callbacks to values and/or promises.
8751 // description:
8752 // Accepts promises but also transparently handles non-promises. If no
8753 // callbacks are provided returns a promise, regardless of the initial
8754 // value. Foreign promises are converted.
8755 //
8756 // If callbacks are provided and the initial value is not a promise,
8757 // the callback is executed immediately with no error handling. Returns
8758 // a promise if the initial value is a promise, or the result of the
8759 // callback otherwise.
8760 // valueOrPromise:
8761 // Either a regular value or an object with a `then()` method that
8762 // follows the Promises/A specification.
8763 // callback: Function?
8764 // Callback to be invoked when the promise is resolved, or a non-promise
8765 // is received.
8766 // errback: Function?
8767 // Callback to be invoked when the promise is rejected.
8768 // progback: Function?
8769 // Callback to be invoked when the promise emits a progress update.
8770 // returns: dojo/promise/Promise
8771 // Promise, or if a callback is provided, the result of the callback.
8772
8773 var receivedPromise = valueOrPromise && typeof valueOrPromise.then === "function";
8774 var nativePromise = receivedPromise && valueOrPromise instanceof Promise;
8775
8776 if(!receivedPromise){
8777 if(callback){
8778 return callback(valueOrPromise);
8779 }else{
8780 return new Deferred().resolve(valueOrPromise);
8781 }
8782 }else if(!nativePromise){
8783 var deferred = new Deferred(valueOrPromise.cancel);
8784 valueOrPromise.then(deferred.resolve, deferred.reject, deferred.progress);
8785 valueOrPromise = deferred.promise;
8786 }
8787
8788 if(callback || errback || progback){
8789 return valueOrPromise.then(callback, errback, progback);
8790 }
8791 return valueOrPromise;
8792 };
8793 });
8794
8795 },
8796 'dojo/dom-attr':function(){
8797 define(["exports", "./sniff", "./_base/lang", "./dom", "./dom-style", "./dom-prop"],
8798 function(exports, has, lang, dom, style, prop){
8799 // module:
8800 // dojo/dom-attr
8801 // summary:
8802 // This module defines the core dojo DOM attributes API.
8803
8804 // TODOC: summary not showing up in output see https://github.com/csnover/js-doc-parse/issues/42
8805
8806 // =============================
8807 // Element attribute Functions
8808 // =============================
8809
8810 // This module will be obsolete soon. Use dojo/prop instead.
8811
8812 // dojo.attr() should conform to http://www.w3.org/TR/DOM-Level-2-Core/
8813
8814 // attribute-related functions (to be obsolete soon)
8815
8816 var forcePropNames = {
8817 innerHTML: 1,
8818 className: 1,
8819 htmlFor: has("ie"),
8820 value: 1
8821 },
8822 attrNames = {
8823 // original attribute names
8824 classname: "class",
8825 htmlfor: "for",
8826 // for IE
8827 tabindex: "tabIndex",
8828 readonly: "readOnly"
8829 };
8830
8831 function _hasAttr(node, name){
8832 var attr = node.getAttributeNode && node.getAttributeNode(name);
8833 return attr && attr.specified; // Boolean
8834 }
8835
8836 // There is a difference in the presence of certain properties and their default values
8837 // between browsers. For example, on IE "disabled" is present on all elements,
8838 // but it is value is "false"; "tabIndex" of <div> returns 0 by default on IE, yet other browsers
8839 // can return -1.
8840
8841 exports.has = function hasAttr(/*DOMNode|String*/ node, /*String*/ name){
8842 // summary:
8843 // Returns true if the requested attribute is specified on the
8844 // given element, and false otherwise.
8845 // node: DOMNode|String
8846 // id or reference to the element to check
8847 // name: String
8848 // the name of the attribute
8849 // returns: Boolean
8850 // true if the requested attribute is specified on the
8851 // given element, and false otherwise
8852
8853 var lc = name.toLowerCase();
8854 return forcePropNames[prop.names[lc] || name] || _hasAttr(dom.byId(node), attrNames[lc] || name); // Boolean
8855 };
8856
8857 exports.get = function getAttr(/*DOMNode|String*/ node, /*String*/ name){
8858 // summary:
8859 // Gets an attribute on an HTML element.
8860 // description:
8861 // Handles normalized getting of attributes on DOM Nodes.
8862 // node: DOMNode|String
8863 // id or reference to the element to get the attribute on
8864 // name: String
8865 // the name of the attribute to get.
8866 // returns:
8867 // the value of the requested attribute or null if that attribute does not have a specified or
8868 // default value;
8869 //
8870 // example:
8871 // | // get the current value of the "foo" attribute on a node
8872 // | dojo.getAttr(dojo.byId("nodeId"), "foo");
8873 // | // or we can just pass the id:
8874 // | dojo.getAttr("nodeId", "foo");
8875
8876 node = dom.byId(node);
8877 var lc = name.toLowerCase(),
8878 propName = prop.names[lc] || name,
8879 forceProp = forcePropNames[propName],
8880 value = node[propName]; // should we access this attribute via a property or via getAttribute()?
8881
8882 if(forceProp && typeof value != "undefined"){
8883 // node's property
8884 return value; // Anything
8885 }
8886 if(propName != "href" && (typeof value == "boolean" || lang.isFunction(value))){
8887 // node's property
8888 return value; // Anything
8889 }
8890 // node's attribute
8891 // we need _hasAttr() here to guard against IE returning a default value
8892 var attrName = attrNames[lc] || name;
8893 return _hasAttr(node, attrName) ? node.getAttribute(attrName) : null; // Anything
8894 };
8895
8896 exports.set = function setAttr(/*DOMNode|String*/ node, /*String|Object*/ name, /*String?*/ value){
8897 // summary:
8898 // Sets an attribute on an HTML element.
8899 // description:
8900 // Handles normalized setting of attributes on DOM Nodes.
8901 //
8902 // When passing functions as values, note that they will not be
8903 // directly assigned to slots on the node, but rather the default
8904 // behavior will be removed and the new behavior will be added
8905 // using `dojo.connect()`, meaning that event handler properties
8906 // will be normalized and that some caveats with regards to
8907 // non-standard behaviors for onsubmit apply. Namely that you
8908 // should cancel form submission using `dojo.stopEvent()` on the
8909 // passed event object instead of returning a boolean value from
8910 // the handler itself.
8911 // node: DOMNode|String
8912 // id or reference to the element to set the attribute on
8913 // name: String|Object
8914 // the name of the attribute to set, or a hash of key-value pairs to set.
8915 // value: String?
8916 // the value to set for the attribute, if the name is a string.
8917 // returns:
8918 // the DOM node
8919 //
8920 // example:
8921 // | // use attr() to set the tab index
8922 // | dojo.setAttr("nodeId", "tabIndex", 3);
8923 //
8924 // example:
8925 // Set multiple values at once, including event handlers:
8926 // | dojo.setAttr("formId", {
8927 // | "foo": "bar",
8928 // | "tabIndex": -1,
8929 // | "method": "POST",
8930 // | "onsubmit": function(e){
8931 // | // stop submitting the form. Note that the IE behavior
8932 // | // of returning true or false will have no effect here
8933 // | // since our handler is connect()ed to the built-in
8934 // | // onsubmit behavior and so we need to use
8935 // | // dojo.stopEvent() to ensure that the submission
8936 // | // doesn't proceed.
8937 // | dojo.stopEvent(e);
8938 // |
8939 // | // submit the form with Ajax
8940 // | dojo.xhrPost({ form: "formId" });
8941 // | }
8942 // | });
8943 //
8944 // example:
8945 // Style is s special case: Only set with an object hash of styles
8946 // | dojo.setAttr("someNode",{
8947 // | id:"bar",
8948 // | style:{
8949 // | width:"200px", height:"100px", color:"#000"
8950 // | }
8951 // | });
8952 //
8953 // example:
8954 // Again, only set style as an object hash of styles:
8955 // | var obj = { color:"#fff", backgroundColor:"#000" };
8956 // | dojo.setAttr("someNode", "style", obj);
8957 // |
8958 // | // though shorter to use `dojo.style()` in this case:
8959 // | dojo.setStyle("someNode", obj);
8960
8961 node = dom.byId(node);
8962 if(arguments.length == 2){ // inline'd type check
8963 // the object form of setter: the 2nd argument is a dictionary
8964 for(var x in name){
8965 exports.set(node, x, name[x]);
8966 }
8967 return node; // DomNode
8968 }
8969 var lc = name.toLowerCase(),
8970 propName = prop.names[lc] || name,
8971 forceProp = forcePropNames[propName];
8972 if(propName == "style" && typeof value != "string"){ // inline'd type check
8973 // special case: setting a style
8974 style.set(node, value);
8975 return node; // DomNode
8976 }
8977 if(forceProp || typeof value == "boolean" || lang.isFunction(value)){
8978 return prop.set(node, name, value);
8979 }
8980 // node's attribute
8981 node.setAttribute(attrNames[lc] || name, value);
8982 return node; // DomNode
8983 };
8984
8985 exports.remove = function removeAttr(/*DOMNode|String*/ node, /*String*/ name){
8986 // summary:
8987 // Removes an attribute from an HTML element.
8988 // node: DOMNode|String
8989 // id or reference to the element to remove the attribute from
8990 // name: String
8991 // the name of the attribute to remove
8992
8993 dom.byId(node).removeAttribute(attrNames[name.toLowerCase()] || name);
8994 };
8995
8996 exports.getNodeProp = function getNodeProp(/*DomNode|String*/ node, /*String*/ name){
8997 // summary:
8998 // Returns an effective value of a property or an attribute.
8999 // node: DOMNode|String
9000 // id or reference to the element to remove the attribute from
9001 // name: String
9002 // the name of the attribute
9003 // returns:
9004 // the value of the attribute
9005
9006 node = dom.byId(node);
9007 var lc = name.toLowerCase(), propName = prop.names[lc] || name;
9008 if((propName in node) && propName != "href"){
9009 // node's property
9010 return node[propName]; // Anything
9011 }
9012 // node's attribute
9013 var attrName = attrNames[lc] || name;
9014 return _hasAttr(node, attrName) ? node.getAttribute(attrName) : null; // Anything
9015 };
9016 });
9017
9018 },
9019 'dojo/dom-construct':function(){
9020 define(["exports", "./_base/kernel", "./sniff", "./_base/window", "./dom", "./dom-attr", "./on"],
9021 function(exports, dojo, has, win, dom, attr, on){
9022 // module:
9023 // dojo/dom-construct
9024 // summary:
9025 // This module defines the core dojo DOM construction API.
9026
9027 // TODOC: summary not showing up in output, see https://github.com/csnover/js-doc-parse/issues/42
9028
9029 // support stuff for toDom()
9030 var tagWrap = {
9031 option: ["select"],
9032 tbody: ["table"],
9033 thead: ["table"],
9034 tfoot: ["table"],
9035 tr: ["table", "tbody"],
9036 td: ["table", "tbody", "tr"],
9037 th: ["table", "thead", "tr"],
9038 legend: ["fieldset"],
9039 caption: ["table"],
9040 colgroup: ["table"],
9041 col: ["table", "colgroup"],
9042 li: ["ul"]
9043 },
9044 reTag = /<\s*([\w\:]+)/,
9045 masterNode = {}, masterNum = 0,
9046 masterName = "__" + dojo._scopeName + "ToDomId";
9047
9048 // generate start/end tag strings to use
9049 // for the injection for each special tag wrap case.
9050 for(var param in tagWrap){
9051 if(tagWrap.hasOwnProperty(param)){
9052 var tw = tagWrap[param];
9053 tw.pre = param == "option" ? '<select multiple="multiple">' : "<" + tw.join("><") + ">";
9054 tw.post = "</" + tw.reverse().join("></") + ">";
9055 // the last line is destructive: it reverses the array,
9056 // but we don't care at this point
9057 }
9058 }
9059
9060 function _insertBefore(/*DomNode*/ node, /*DomNode*/ ref){
9061 var parent = ref.parentNode;
9062 if(parent){
9063 parent.insertBefore(node, ref);
9064 }
9065 }
9066
9067 function _insertAfter(/*DomNode*/ node, /*DomNode*/ ref){
9068 // summary:
9069 // Try to insert node after ref
9070 var parent = ref.parentNode;
9071 if(parent){
9072 if(parent.lastChild == ref){
9073 parent.appendChild(node);
9074 }else{
9075 parent.insertBefore(node, ref.nextSibling);
9076 }
9077 }
9078 }
9079
9080 exports.toDom = function toDom(frag, doc){
9081 // summary:
9082 // instantiates an HTML fragment returning the corresponding DOM.
9083 // frag: String
9084 // the HTML fragment
9085 // doc: DocumentNode?
9086 // optional document to use when creating DOM nodes, defaults to
9087 // dojo.doc if not specified.
9088 // returns:
9089 // Document fragment, unless it's a single node in which case it returns the node itself
9090 // example:
9091 // Create a table row:
9092 // | var tr = dojo.toDom("<tr><td>First!</td></tr>");
9093
9094 doc = doc || win.doc;
9095 var masterId = doc[masterName];
9096 if(!masterId){
9097 doc[masterName] = masterId = ++masterNum + "";
9098 masterNode[masterId] = doc.createElement("div");
9099 }
9100
9101 // make sure the frag is a string.
9102 frag += "";
9103
9104 // find the starting tag, and get node wrapper
9105 var match = frag.match(reTag),
9106 tag = match ? match[1].toLowerCase() : "",
9107 master = masterNode[masterId],
9108 wrap, i, fc, df;
9109 if(match && tagWrap[tag]){
9110 wrap = tagWrap[tag];
9111 master.innerHTML = wrap.pre + frag + wrap.post;
9112 for(i = wrap.length; i; --i){
9113 master = master.firstChild;
9114 }
9115 }else{
9116 master.innerHTML = frag;
9117 }
9118
9119 // one node shortcut => return the node itself
9120 if(master.childNodes.length == 1){
9121 return master.removeChild(master.firstChild); // DOMNode
9122 }
9123
9124 // return multiple nodes as a document fragment
9125 df = doc.createDocumentFragment();
9126 while((fc = master.firstChild)){ // intentional assignment
9127 df.appendChild(fc);
9128 }
9129 return df; // DocumentFragment
9130 };
9131
9132 exports.place = function place(/*DOMNode|String*/ node, /*DOMNode|String*/ refNode, /*String|Number?*/ position){
9133 // summary:
9134 // Attempt to insert node into the DOM, choosing from various positioning options.
9135 // Returns the first argument resolved to a DOM node.
9136 // node: DOMNode|String
9137 // id or node reference, or HTML fragment starting with "<" to place relative to refNode
9138 // refNode: DOMNode|String
9139 // id or node reference to use as basis for placement
9140 // position: String|Number?
9141 // string noting the position of node relative to refNode or a
9142 // number indicating the location in the childNodes collection of refNode.
9143 // Accepted string values are:
9144 //
9145 // - before
9146 // - after
9147 // - replace
9148 // - only
9149 // - first
9150 // - last
9151 //
9152 // "first" and "last" indicate positions as children of refNode, "replace" replaces refNode,
9153 // "only" replaces all children. position defaults to "last" if not specified
9154 // returns: DOMNode
9155 // Returned values is the first argument resolved to a DOM node.
9156 //
9157 // .place() is also a method of `dojo/NodeList`, allowing `dojo.query` node lookups.
9158 // example:
9159 // Place a node by string id as the last child of another node by string id:
9160 // | dojo.place("someNode", "anotherNode");
9161 // example:
9162 // Place a node by string id before another node by string id
9163 // | dojo.place("someNode", "anotherNode", "before");
9164 // example:
9165 // Create a Node, and place it in the body element (last child):
9166 // | dojo.place("<div></div>", dojo.body());
9167 // example:
9168 // Put a new LI as the first child of a list by id:
9169 // | dojo.place("<li></li>", "someUl", "first");
9170
9171 refNode = dom.byId(refNode);
9172 if(typeof node == "string"){ // inline'd type check
9173 node = /^\s*</.test(node) ? exports.toDom(node, refNode.ownerDocument) : dom.byId(node);
9174 }
9175 if(typeof position == "number"){ // inline'd type check
9176 var cn = refNode.childNodes;
9177 if(!cn.length || cn.length <= position){
9178 refNode.appendChild(node);
9179 }else{
9180 _insertBefore(node, cn[position < 0 ? 0 : position]);
9181 }
9182 }else{
9183 switch(position){
9184 case "before":
9185 _insertBefore(node, refNode);
9186 break;
9187 case "after":
9188 _insertAfter(node, refNode);
9189 break;
9190 case "replace":
9191 refNode.parentNode.replaceChild(node, refNode);
9192 break;
9193 case "only":
9194 exports.empty(refNode);
9195 refNode.appendChild(node);
9196 break;
9197 case "first":
9198 if(refNode.firstChild){
9199 _insertBefore(node, refNode.firstChild);
9200 break;
9201 }
9202 // else fallthrough...
9203 default: // aka: last
9204 refNode.appendChild(node);
9205 }
9206 }
9207 return node; // DomNode
9208 };
9209
9210 exports.create = function create(/*DOMNode|String*/ tag, /*Object*/ attrs, /*DOMNode|String?*/ refNode, /*String?*/ pos){
9211 // summary:
9212 // Create an element, allowing for optional attribute decoration
9213 // and placement.
9214 // description:
9215 // A DOM Element creation function. A shorthand method for creating a node or
9216 // a fragment, and allowing for a convenient optional attribute setting step,
9217 // as well as an optional DOM placement reference.
9218 //
9219 // Attributes are set by passing the optional object through `dojo.setAttr`.
9220 // See `dojo.setAttr` for noted caveats and nuances, and API if applicable.
9221 //
9222 // Placement is done via `dojo.place`, assuming the new node to be the action
9223 // node, passing along the optional reference node and position.
9224 // tag: DOMNode|String
9225 // A string of the element to create (eg: "div", "a", "p", "li", "script", "br"),
9226 // or an existing DOM node to process.
9227 // attrs: Object
9228 // An object-hash of attributes to set on the newly created node.
9229 // Can be null, if you don't want to set any attributes/styles.
9230 // See: `dojo.setAttr` for a description of available attributes.
9231 // refNode: DOMNode|String?
9232 // Optional reference node. Used by `dojo.place` to place the newly created
9233 // node somewhere in the dom relative to refNode. Can be a DomNode reference
9234 // or String ID of a node.
9235 // pos: String?
9236 // Optional positional reference. Defaults to "last" by way of `dojo.place`,
9237 // though can be set to "first","after","before","last", "replace" or "only"
9238 // to further control the placement of the new node relative to the refNode.
9239 // 'refNode' is required if a 'pos' is specified.
9240 // example:
9241 // Create a DIV:
9242 // | var n = dojo.create("div");
9243 //
9244 // example:
9245 // Create a DIV with content:
9246 // | var n = dojo.create("div", { innerHTML:"<p>hi</p>" });
9247 //
9248 // example:
9249 // Place a new DIV in the BODY, with no attributes set
9250 // | var n = dojo.create("div", null, dojo.body());
9251 //
9252 // example:
9253 // Create an UL, and populate it with LI's. Place the list as the first-child of a
9254 // node with id="someId":
9255 // | var ul = dojo.create("ul", null, "someId", "first");
9256 // | var items = ["one", "two", "three", "four"];
9257 // | dojo.forEach(items, function(data){
9258 // | dojo.create("li", { innerHTML: data }, ul);
9259 // | });
9260 //
9261 // example:
9262 // Create an anchor, with an href. Place in BODY:
9263 // | dojo.create("a", { href:"foo.html", title:"Goto FOO!" }, dojo.body());
9264 //
9265 // example:
9266 // Create a `dojo/NodeList()` from a new element (for syntactic sugar):
9267 // | dojo.query(dojo.create('div'))
9268 // | .addClass("newDiv")
9269 // | .onclick(function(e){ console.log('clicked', e.target) })
9270 // | .place("#someNode"); // redundant, but cleaner.
9271
9272 var doc = win.doc;
9273 if(refNode){
9274 refNode = dom.byId(refNode);
9275 doc = refNode.ownerDocument;
9276 }
9277 if(typeof tag == "string"){ // inline'd type check
9278 tag = doc.createElement(tag);
9279 }
9280 if(attrs){ attr.set(tag, attrs); }
9281 if(refNode){ exports.place(tag, refNode, pos); }
9282 return tag; // DomNode
9283 };
9284
9285 var _empty = has("ie") ?
9286 function(/*DomNode*/ node){
9287 try{
9288 node.innerHTML = ""; // really fast when it works
9289 }catch(e){ // IE can generate Unknown Error
9290 for(var c; c = node.lastChild;){ // intentional assignment
9291 _destroy(c, node); // destroy is better than removeChild so TABLE elements are removed in proper order
9292 }
9293 }
9294 } :
9295 function(/*DomNode*/ node){
9296 node.innerHTML = "";
9297 };
9298
9299 exports.empty = function empty(/*DOMNode|String*/ node){
9300 // summary:
9301 // safely removes all children of the node.
9302 // node: DOMNode|String
9303 // a reference to a DOM node or an id.
9304 // example:
9305 // Destroy node's children byId:
9306 // | dojo.empty("someId");
9307 //
9308 // example:
9309 // Destroy all nodes' children in a list by reference:
9310 // | dojo.query(".someNode").forEach(dojo.empty);
9311
9312 _empty(dom.byId(node));
9313 };
9314
9315
9316 function _destroy(/*DomNode*/ node, /*DomNode*/ parent){
9317 if(node.firstChild){
9318 _empty(node);
9319 }
9320 if(parent){
9321 parent.removeChild(node);
9322 }
9323 }
9324 exports.destroy = function destroy(/*DOMNode|String*/ node){
9325 // summary:
9326 // Removes a node from its parent, clobbering it and all of its
9327 // children.
9328 //
9329 // description:
9330 // Removes a node from its parent, clobbering it and all of its
9331 // children. Function only works with DomNodes, and returns nothing.
9332 //
9333 // node: DOMNode|String
9334 // A String ID or DomNode reference of the element to be destroyed
9335 //
9336 // example:
9337 // Destroy a node byId:
9338 // | dojo.destroy("someId");
9339 //
9340 // example:
9341 // Destroy all nodes in a list by reference:
9342 // | dojo.query(".someNode").forEach(dojo.destroy);
9343
9344 node = dom.byId(node);
9345 if(!node){ return; }
9346 _destroy(node, node.parentNode);
9347 };
9348 });
9349
9350 },
9351 'dojo/request/xhr':function(){
9352 define("dojo/request/xhr", [
9353 '../errors/RequestError',
9354 './watch',
9355 './handlers',
9356 './util',
9357 '../has'/*=====,
9358 '../request',
9359 '../_base/declare' =====*/
9360 ], function(RequestError, watch, handlers, util, has/*=====, request, declare =====*/){
9361 has.add('native-xhr', function(){
9362 // if true, the environment has a native XHR implementation
9363 return typeof XMLHttpRequest !== 'undefined';
9364 });
9365 has.add('dojo-force-activex-xhr', function(){
9366 return has('activex') && !document.addEventListener && window.location.protocol === 'file:';
9367 });
9368
9369 has.add('native-xhr2', function(){
9370 if(!has('native-xhr')){ return; }
9371 var x = new XMLHttpRequest();
9372 return typeof x['addEventListener'] !== 'undefined' &&
9373 (typeof opera === 'undefined' || typeof x['upload'] !== 'undefined');
9374 });
9375
9376 has.add('native-formdata', function(){
9377 // if true, the environment has a native FormData implementation
9378 return typeof FormData === 'function';
9379 });
9380
9381 function handleResponse(response, error){
9382 var _xhr = response.xhr;
9383 response.status = response.xhr.status;
9384 response.text = _xhr.responseText;
9385
9386 if(response.options.handleAs === 'xml'){
9387 response.data = _xhr.responseXML;
9388 }
9389
9390 if(!error){
9391 try{
9392 handlers(response);
9393 }catch(e){
9394 error = e;
9395 }
9396 }
9397
9398 if(error){
9399 this.reject(error);
9400 }else if(util.checkStatus(_xhr.status)){
9401 this.resolve(response);
9402 }else{
9403 error = new RequestError('Unable to load ' + response.url + ' status: ' + _xhr.status, response);
9404
9405 this.reject(error);
9406 }
9407 }
9408
9409 var isValid, isReady, addListeners, cancel;
9410 if(has('native-xhr2')){
9411 // Any platform with XHR2 will only use the watch mechanism for timeout.
9412
9413 isValid = function(response){
9414 // summary:
9415 // Check to see if the request should be taken out of the watch queue
9416 return !this.isFulfilled();
9417 };
9418 cancel = function(dfd, response){
9419 // summary:
9420 // Canceler for deferred
9421 response.xhr.abort();
9422 };
9423 addListeners = function(_xhr, dfd, response){
9424 // summary:
9425 // Adds event listeners to the XMLHttpRequest object
9426 function onLoad(evt){
9427 dfd.handleResponse(response);
9428 }
9429 function onError(evt){
9430 var _xhr = evt.target;
9431 var error = new RequestError('Unable to load ' + response.url + ' status: ' + _xhr.status, response);
9432 dfd.handleResponse(response, error);
9433 }
9434
9435 function onProgress(evt){
9436 if(evt.lengthComputable){
9437 response.loaded = evt.loaded;
9438 response.total = evt.total;
9439 dfd.progress(response);
9440 }
9441 }
9442
9443 _xhr.addEventListener('load', onLoad, false);
9444 _xhr.addEventListener('error', onError, false);
9445 _xhr.addEventListener('progress', onProgress, false);
9446
9447 return function(){
9448 _xhr.removeEventListener('load', onLoad, false);
9449 _xhr.removeEventListener('error', onError, false);
9450 _xhr.removeEventListener('progress', onProgress, false);
9451 };
9452 };
9453 }else{
9454 isValid = function(response){
9455 return response.xhr.readyState; //boolean
9456 };
9457 isReady = function(response){
9458 return 4 === response.xhr.readyState; //boolean
9459 };
9460 cancel = function(dfd, response){
9461 // summary:
9462 // canceller function for util.deferred call.
9463 var xhr = response.xhr;
9464 var _at = typeof xhr.abort;
9465 if(_at === 'function' || _at === 'object' || _at === 'unknown'){
9466 xhr.abort();
9467 }
9468 };
9469 }
9470
9471 var undefined,
9472 defaultOptions = {
9473 data: null,
9474 query: null,
9475 sync: false,
9476 method: 'GET',
9477 headers: {
9478 'Content-Type': 'application/x-www-form-urlencoded'
9479 }
9480 };
9481 function xhr(url, options, returnDeferred){
9482 var response = util.parseArgs(
9483 url,
9484 util.deepCreate(defaultOptions, options),
9485 has('native-formdata') && options && options.data && options.data instanceof FormData
9486 );
9487 url = response.url;
9488 options = response.options;
9489
9490 var remover,
9491 last = function(){
9492 remover && remover();
9493 };
9494
9495 //Make the Deferred object for this xhr request.
9496 var dfd = util.deferred(
9497 response,
9498 cancel,
9499 isValid,
9500 isReady,
9501 handleResponse,
9502 last
9503 );
9504 var _xhr = response.xhr = xhr._create();
9505
9506 if(!_xhr){
9507 // If XHR factory somehow returns nothings,
9508 // cancel the deferred.
9509 dfd.cancel(new RequestError('XHR was not created'));
9510 return returnDeferred ? dfd : dfd.promise;
9511 }
9512
9513 response.getHeader = function(headerName){
9514 return this.xhr.getResponseHeader(headerName);
9515 };
9516
9517 if(addListeners){
9518 remover = addListeners(_xhr, dfd, response);
9519 }
9520
9521 var data = options.data,
9522 async = !options.sync,
9523 method = options.method;
9524
9525 try{
9526 // IE6 won't let you call apply() on the native function.
9527 _xhr.open(method, url, async, options.user || undefined, options.password || undefined);
9528
9529 if(options.withCredentials){
9530 _xhr.withCredentials = options.withCredentials;
9531 }
9532
9533 var headers = options.headers,
9534 contentType;
9535 if(headers){
9536 for(var hdr in headers){
9537 if(hdr.toLowerCase() === 'content-type'){
9538 contentType = headers[hdr];
9539 }else if(headers[hdr]){
9540 //Only add header if it has a value. This allows for instance, skipping
9541 //insertion of X-Requested-With by specifying empty value.
9542 _xhr.setRequestHeader(hdr, headers[hdr]);
9543 }
9544 }
9545 }
9546
9547 if(contentType && contentType !== false){
9548 _xhr.setRequestHeader('Content-Type', contentType);
9549 }
9550 if(!headers || !('X-Requested-With' in headers)){
9551 _xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
9552 }
9553
9554 if(util.notify){
9555 util.notify.emit('send', response, dfd.promise.cancel);
9556 }
9557 _xhr.send(data);
9558 }catch(e){
9559 dfd.reject(e);
9560 }
9561
9562 watch(dfd);
9563 _xhr = null;
9564
9565 return returnDeferred ? dfd : dfd.promise;
9566 }
9567
9568 /*=====
9569 xhr = function(url, options){
9570 // summary:
9571 // Sends a request using XMLHttpRequest with the given URL and options.
9572 // url: String
9573 // URL to request
9574 // options: dojo/request/xhr.__Options?
9575 // Options for the request.
9576 // returns: dojo/request.__Promise
9577 };
9578 xhr.__BaseOptions = declare(request.__BaseOptions, {
9579 // sync: Boolean?
9580 // Whether to make a synchronous request or not. Default
9581 // is `false` (asynchronous).
9582 // data: String|Object|FormData?
9583 // Data to transfer. This is ignored for GET and DELETE
9584 // requests.
9585 // headers: Object?
9586 // Headers to use for the request.
9587 // user: String?
9588 // Username to use during the request.
9589 // password: String?
9590 // Password to use during the request.
9591 // withCredentials: Boolean?
9592 // For cross-site requests, whether to send credentials
9593 // or not.
9594 });
9595 xhr.__MethodOptions = declare(null, {
9596 // method: String?
9597 // The HTTP method to use to make the request. Must be
9598 // uppercase. Default is `"GET"`.
9599 });
9600 xhr.__Options = declare([xhr.__BaseOptions, xhr.__MethodOptions]);
9601
9602 xhr.get = function(url, options){
9603 // summary:
9604 // Send an HTTP GET request using XMLHttpRequest with the given URL and options.
9605 // url: String
9606 // URL to request
9607 // options: dojo/request/xhr.__BaseOptions?
9608 // Options for the request.
9609 // returns: dojo/request.__Promise
9610 };
9611 xhr.post = function(url, options){
9612 // summary:
9613 // Send an HTTP POST request using XMLHttpRequest with the given URL and options.
9614 // url: String
9615 // URL to request
9616 // options: dojo/request/xhr.__BaseOptions?
9617 // Options for the request.
9618 // returns: dojo/request.__Promise
9619 };
9620 xhr.put = function(url, options){
9621 // summary:
9622 // Send an HTTP PUT request using XMLHttpRequest with the given URL and options.
9623 // url: String
9624 // URL to request
9625 // options: dojo/request/xhr.__BaseOptions?
9626 // Options for the request.
9627 // returns: dojo/request.__Promise
9628 };
9629 xhr.del = function(url, options){
9630 // summary:
9631 // Send an HTTP DELETE request using XMLHttpRequest with the given URL and options.
9632 // url: String
9633 // URL to request
9634 // options: dojo/request/xhr.__BaseOptions?
9635 // Options for the request.
9636 // returns: dojo/request.__Promise
9637 };
9638 =====*/
9639 xhr._create = function(){
9640 // summary:
9641 // does the work of portably generating a new XMLHTTPRequest object.
9642 throw new Error('XMLHTTP not available');
9643 };
9644 if(has('native-xhr') && !has('dojo-force-activex-xhr')){
9645 xhr._create = function(){
9646 return new XMLHttpRequest();
9647 };
9648 }else if(has('activex')){
9649 try{
9650 new ActiveXObject('Msxml2.XMLHTTP');
9651 xhr._create = function(){
9652 return new ActiveXObject('Msxml2.XMLHTTP');
9653 };
9654 }catch(e){
9655 try{
9656 new ActiveXObject('Microsoft.XMLHTTP');
9657 xhr._create = function(){
9658 return new ActiveXObject('Microsoft.XMLHTTP');
9659 };
9660 }catch(e){}
9661 }
9662 }
9663
9664 util.addCommonMethods(xhr);
9665
9666 return xhr;
9667 });
9668
9669 },
9670 'dojo/keys':function(){
9671 define("dojo/keys", ["./_base/kernel", "./sniff"], function(dojo, has){
9672
9673 // module:
9674 // dojo/keys
9675
9676 return dojo.keys = {
9677 // summary:
9678 // Definitions for common key values. Client code should test keyCode against these named constants,
9679 // as the actual codes can vary by browser.
9680
9681 BACKSPACE: 8,
9682 TAB: 9,
9683 CLEAR: 12,
9684 ENTER: 13,
9685 SHIFT: 16,
9686 CTRL: 17,
9687 ALT: 18,
9688 META: has("webkit") ? 91 : 224, // the apple key on macs
9689 PAUSE: 19,
9690 CAPS_LOCK: 20,
9691 ESCAPE: 27,
9692 SPACE: 32,
9693 PAGE_UP: 33,
9694 PAGE_DOWN: 34,
9695 END: 35,
9696 HOME: 36,
9697 LEFT_ARROW: 37,
9698 UP_ARROW: 38,
9699 RIGHT_ARROW: 39,
9700 DOWN_ARROW: 40,
9701 INSERT: 45,
9702 DELETE: 46,
9703 HELP: 47,
9704 LEFT_WINDOW: 91,
9705 RIGHT_WINDOW: 92,
9706 SELECT: 93,
9707 NUMPAD_0: 96,
9708 NUMPAD_1: 97,
9709 NUMPAD_2: 98,
9710 NUMPAD_3: 99,
9711 NUMPAD_4: 100,
9712 NUMPAD_5: 101,
9713 NUMPAD_6: 102,
9714 NUMPAD_7: 103,
9715 NUMPAD_8: 104,
9716 NUMPAD_9: 105,
9717 NUMPAD_MULTIPLY: 106,
9718 NUMPAD_PLUS: 107,
9719 NUMPAD_ENTER: 108,
9720 NUMPAD_MINUS: 109,
9721 NUMPAD_PERIOD: 110,
9722 NUMPAD_DIVIDE: 111,
9723 F1: 112,
9724 F2: 113,
9725 F3: 114,
9726 F4: 115,
9727 F5: 116,
9728 F6: 117,
9729 F7: 118,
9730 F8: 119,
9731 F9: 120,
9732 F10: 121,
9733 F11: 122,
9734 F12: 123,
9735 F13: 124,
9736 F14: 125,
9737 F15: 126,
9738 NUM_LOCK: 144,
9739 SCROLL_LOCK: 145,
9740 UP_DPAD: 175,
9741 DOWN_DPAD: 176,
9742 LEFT_DPAD: 177,
9743 RIGHT_DPAD: 178,
9744 // virtual key mapping
9745 copyKey: has("mac") && !has("air") ? (has("safari") ? 91 : 224 ) : 17
9746 };
9747 });
9748
9749 },
9750 'dojo/domReady':function(){
9751 define(['./has'], function(has){
9752 var global = this,
9753 doc = document,
9754 readyStates = { 'loaded': 1, 'complete': 1 },
9755 fixReadyState = typeof doc.readyState != "string",
9756 ready = !!readyStates[doc.readyState];
9757
9758 // For FF <= 3.5
9759 if(fixReadyState){ doc.readyState = "loading"; }
9760
9761 if(!ready){
9762 var readyQ = [], tests = [],
9763 detectReady = function(evt){
9764 evt = evt || global.event;
9765 if(ready || (evt.type == "readystatechange" && !readyStates[doc.readyState])){ return; }
9766 ready = 1;
9767
9768 // For FF <= 3.5
9769 if(fixReadyState){ doc.readyState = "complete"; }
9770
9771 while(readyQ.length){
9772 (readyQ.shift())(doc);
9773 }
9774 },
9775 on = function(node, event){
9776 node.addEventListener(event, detectReady, false);
9777 readyQ.push(function(){ node.removeEventListener(event, detectReady, false); });
9778 };
9779
9780 if(!has("dom-addeventlistener")){
9781 on = function(node, event){
9782 event = "on" + event;
9783 node.attachEvent(event, detectReady);
9784 readyQ.push(function(){ node.detachEvent(event, detectReady); });
9785 };
9786
9787 var div = doc.createElement("div");
9788 try{
9789 if(div.doScroll && global.frameElement === null){
9790 // the doScroll test is only useful if we're in the top-most frame
9791 tests.push(function(){
9792 // Derived with permission from Diego Perini's IEContentLoaded
9793 // http://javascript.nwbox.com/IEContentLoaded/
9794 try{
9795 div.doScroll("left");
9796 return 1;
9797 }catch(e){}
9798 });
9799 }
9800 }catch(e){}
9801 }
9802
9803 on(doc, "DOMContentLoaded");
9804 on(global, "load");
9805
9806 if("onreadystatechange" in doc){
9807 on(doc, "readystatechange");
9808 }else if(!fixReadyState){
9809 // if the ready state property exists and there's
9810 // no readystatechange event, poll for the state
9811 // to change
9812 tests.push(function(){
9813 return readyStates[doc.readyState];
9814 });
9815 }
9816
9817 if(tests.length){
9818 var poller = function(){
9819 if(ready){ return; }
9820 var i = tests.length;
9821 while(i--){
9822 if(tests[i]()){
9823 detectReady("poller");
9824 return;
9825 }
9826 }
9827 setTimeout(poller, 30);
9828 };
9829 poller();
9830 }
9831 }
9832
9833 function domReady(callback){
9834 // summary:
9835 // Plugin to delay require()/define() callback from firing until the DOM has finished loading.
9836 if(ready){
9837 callback(doc);
9838 }else{
9839 readyQ.push(callback);
9840 }
9841 }
9842 domReady.load = function(id, req, load){
9843 domReady(load);
9844 };
9845
9846 return domReady;
9847 });
9848
9849 },
9850 'dojo/_base/lang':function(){
9851 define("dojo/_base/lang", ["./kernel", "../has", "../sniff"], function(dojo, has){
9852 // module:
9853 // dojo/_base/lang
9854
9855 has.add("bug-for-in-skips-shadowed", function(){
9856 // if true, the for-in iterator skips object properties that exist in Object's prototype (IE 6 - ?)
9857 for(var i in {toString: 1}){
9858 return 0;
9859 }
9860 return 1;
9861 });
9862
9863 // Helper methods
9864 var _extraNames =
9865 has("bug-for-in-skips-shadowed") ?
9866 "hasOwnProperty.valueOf.isPrototypeOf.propertyIsEnumerable.toLocaleString.toString.constructor".split(".") : [],
9867
9868 _extraLen = _extraNames.length,
9869
9870 getProp = function(/*Array*/parts, /*Boolean*/create, /*Object*/context){
9871 var p, i = 0, dojoGlobal = dojo.global;
9872 if(!context){
9873 if(!parts.length){
9874 return dojoGlobal;
9875 }else{
9876 p = parts[i++];
9877 try{
9878 context = dojo.scopeMap[p] && dojo.scopeMap[p][1];
9879 }catch(e){}
9880 context = context || (p in dojoGlobal ? dojoGlobal[p] : (create ? dojoGlobal[p] = {} : undefined));
9881 }
9882 }
9883 while(context && (p = parts[i++])){
9884 context = (p in context ? context[p] : (create ? context[p] = {} : undefined));
9885 }
9886 return context; // mixed
9887 },
9888
9889 opts = Object.prototype.toString,
9890
9891 efficient = function(obj, offset, startWith){
9892 return (startWith||[]).concat(Array.prototype.slice.call(obj, offset||0));
9893 },
9894
9895 _pattern = /\{([^\}]+)\}/g;
9896
9897 // Module export
9898 var lang = {
9899 // summary:
9900 // This module defines Javascript language extensions.
9901
9902 // _extraNames: String[]
9903 // Lists property names that must be explicitly processed during for-in iteration
9904 // in environments that have has("bug-for-in-skips-shadowed") true.
9905 _extraNames:_extraNames,
9906
9907 _mixin: function(dest, source, copyFunc){
9908 // summary:
9909 // Copies/adds all properties of source to dest; returns dest.
9910 // dest: Object
9911 // The object to which to copy/add all properties contained in source.
9912 // source: Object
9913 // The object from which to draw all properties to copy into dest.
9914 // copyFunc: Function?
9915 // The process used to copy/add a property in source; defaults to the Javascript assignment operator.
9916 // returns:
9917 // dest, as modified
9918 // description:
9919 // All properties, including functions (sometimes termed "methods"), excluding any non-standard extensions
9920 // found in Object.prototype, are copied/added to dest. Copying/adding each particular property is
9921 // delegated to copyFunc (if any); copyFunc defaults to the Javascript assignment operator if not provided.
9922 // Notice that by default, _mixin executes a so-called "shallow copy" and aggregate types are copied/added by reference.
9923 var name, s, i, empty = {};
9924 for(name in source){
9925 // the (!(name in empty) || empty[name] !== s) condition avoids copying properties in "source"
9926 // inherited from Object.prototype. For example, if dest has a custom toString() method,
9927 // don't overwrite it with the toString() method that source inherited from Object.prototype
9928 s = source[name];
9929 if(!(name in dest) || (dest[name] !== s && (!(name in empty) || empty[name] !== s))){
9930 dest[name] = copyFunc ? copyFunc(s) : s;
9931 }
9932 }
9933
9934 if(has("bug-for-in-skips-shadowed")){
9935 if(source){
9936 for(i = 0; i < _extraLen; ++i){
9937 name = _extraNames[i];
9938 s = source[name];
9939 if(!(name in dest) || (dest[name] !== s && (!(name in empty) || empty[name] !== s))){
9940 dest[name] = copyFunc ? copyFunc(s) : s;
9941 }
9942 }
9943 }
9944 }
9945
9946 return dest; // Object
9947 },
9948
9949 mixin: function(dest, sources){
9950 // summary:
9951 // Copies/adds all properties of one or more sources to dest; returns dest.
9952 // dest: Object
9953 // The object to which to copy/add all properties contained in source. If dest is falsy, then
9954 // a new object is manufactured before copying/adding properties begins.
9955 // sources: Object...
9956 // One of more objects from which to draw all properties to copy into dest. sources are processed
9957 // left-to-right and if more than one of these objects contain the same property name, the right-most
9958 // value "wins".
9959 // returns: Object
9960 // dest, as modified
9961 // description:
9962 // All properties, including functions (sometimes termed "methods"), excluding any non-standard extensions
9963 // found in Object.prototype, are copied/added from sources to dest. sources are processed left to right.
9964 // The Javascript assignment operator is used to copy/add each property; therefore, by default, mixin
9965 // executes a so-called "shallow copy" and aggregate types are copied/added by reference.
9966 // example:
9967 // make a shallow copy of an object
9968 // | var copy = lang.mixin({}, source);
9969 // example:
9970 // many class constructors often take an object which specifies
9971 // values to be configured on the object. In this case, it is
9972 // often simplest to call `lang.mixin` on the `this` object:
9973 // | declare("acme.Base", null, {
9974 // | constructor: function(properties){
9975 // | // property configuration:
9976 // | lang.mixin(this, properties);
9977 // |
9978 // | console.log(this.quip);
9979 // | // ...
9980 // | },
9981 // | quip: "I wasn't born yesterday, you know - I've seen movies.",
9982 // | // ...
9983 // | });
9984 // |
9985 // | // create an instance of the class and configure it
9986 // | var b = new acme.Base({quip: "That's what it does!" });
9987 // example:
9988 // copy in properties from multiple objects
9989 // | var flattened = lang.mixin(
9990 // | {
9991 // | name: "Frylock",
9992 // | braces: true
9993 // | },
9994 // | {
9995 // | name: "Carl Brutanananadilewski"
9996 // | }
9997 // | );
9998 // |
9999 // | // will print "Carl Brutanananadilewski"
10000 // | console.log(flattened.name);
10001 // | // will print "true"
10002 // | console.log(flattened.braces);
10003
10004 if(!dest){ dest = {}; }
10005 for(var i = 1, l = arguments.length; i < l; i++){
10006 lang._mixin(dest, arguments[i]);
10007 }
10008 return dest; // Object
10009 },
10010
10011 setObject: function(name, value, context){
10012 // summary:
10013 // Set a property from a dot-separated string, such as "A.B.C"
10014 // description:
10015 // Useful for longer api chains where you have to test each object in
10016 // the chain, or when you have an object reference in string format.
10017 // Objects are created as needed along `path`. Returns the passed
10018 // value if setting is successful or `undefined` if not.
10019 // name: String
10020 // Path to a property, in the form "A.B.C".
10021 // value: anything
10022 // value or object to place at location given by name
10023 // context: Object?
10024 // Optional. Object to use as root of path. Defaults to
10025 // `dojo.global`.
10026 // example:
10027 // set the value of `foo.bar.baz`, regardless of whether
10028 // intermediate objects already exist:
10029 // | lang.setObject("foo.bar.baz", value);
10030 // example:
10031 // without `lang.setObject`, we often see code like this:
10032 // | // ensure that intermediate objects are available
10033 // | if(!obj["parent"]){ obj.parent = {}; }
10034 // | if(!obj.parent["child"]){ obj.parent.child = {}; }
10035 // | // now we can safely set the property
10036 // | obj.parent.child.prop = "some value";
10037 // whereas with `lang.setObject`, we can shorten that to:
10038 // | lang.setObject("parent.child.prop", "some value", obj);
10039
10040 var parts = name.split("."), p = parts.pop(), obj = getProp(parts, true, context);
10041 return obj && p ? (obj[p] = value) : undefined; // Object
10042 },
10043
10044 getObject: function(name, create, context){
10045 // summary:
10046 // Get a property from a dot-separated string, such as "A.B.C"
10047 // description:
10048 // Useful for longer api chains where you have to test each object in
10049 // the chain, or when you have an object reference in string format.
10050 // name: String
10051 // Path to an property, in the form "A.B.C".
10052 // create: Boolean?
10053 // Optional. Defaults to `false`. If `true`, Objects will be
10054 // created at any point along the 'path' that is undefined.
10055 // context: Object?
10056 // Optional. Object to use as root of path. Defaults to
10057 // 'dojo.global'. Null may be passed.
10058 return getProp(name.split("."), create, context); // Object
10059 },
10060
10061 exists: function(name, obj){
10062 // summary:
10063 // determine if an object supports a given method
10064 // description:
10065 // useful for longer api chains where you have to test each object in
10066 // the chain. Useful for object and method detection.
10067 // name: String
10068 // Path to an object, in the form "A.B.C".
10069 // obj: Object?
10070 // Object to use as root of path. Defaults to
10071 // 'dojo.global'. Null may be passed.
10072 // example:
10073 // | // define an object
10074 // | var foo = {
10075 // | bar: { }
10076 // | };
10077 // |
10078 // | // search the global scope
10079 // | lang.exists("foo.bar"); // true
10080 // | lang.exists("foo.bar.baz"); // false
10081 // |
10082 // | // search from a particular scope
10083 // | lang.exists("bar", foo); // true
10084 // | lang.exists("bar.baz", foo); // false
10085 return lang.getObject(name, false, obj) !== undefined; // Boolean
10086 },
10087
10088 // Crockford (ish) functions
10089
10090 isString: function(it){
10091 // summary:
10092 // Return true if it is a String
10093 // it: anything
10094 // Item to test.
10095 return (typeof it == "string" || it instanceof String); // Boolean
10096 },
10097
10098 isArray: function(it){
10099 // summary:
10100 // Return true if it is an Array.
10101 // Does not work on Arrays created in other windows.
10102 // it: anything
10103 // Item to test.
10104 return it && (it instanceof Array || typeof it == "array"); // Boolean
10105 },
10106
10107 isFunction: function(it){
10108 // summary:
10109 // Return true if it is a Function
10110 // it: anything
10111 // Item to test.
10112 return opts.call(it) === "[object Function]";
10113 },
10114
10115 isObject: function(it){
10116 // summary:
10117 // Returns true if it is a JavaScript object (or an Array, a Function
10118 // or null)
10119 // it: anything
10120 // Item to test.
10121 return it !== undefined &&
10122 (it === null || typeof it == "object" || lang.isArray(it) || lang.isFunction(it)); // Boolean
10123 },
10124
10125 isArrayLike: function(it){
10126 // summary:
10127 // similar to isArray() but more permissive
10128 // it: anything
10129 // Item to test.
10130 // returns:
10131 // If it walks like a duck and quacks like a duck, return `true`
10132 // description:
10133 // Doesn't strongly test for "arrayness". Instead, settles for "isn't
10134 // a string or number and has a length property". Arguments objects
10135 // and DOM collections will return true when passed to
10136 // isArrayLike(), but will return false when passed to
10137 // isArray().
10138 return it && it !== undefined && // Boolean
10139 // keep out built-in constructors (Number, String, ...) which have length
10140 // properties
10141 !lang.isString(it) && !lang.isFunction(it) &&
10142 !(it.tagName && it.tagName.toLowerCase() == 'form') &&
10143 (lang.isArray(it) || isFinite(it.length));
10144 },
10145
10146 isAlien: function(it){
10147 // summary:
10148 // Returns true if it is a built-in function or some other kind of
10149 // oddball that *should* report as a function but doesn't
10150 return it && !lang.isFunction(it) && /\{\s*\[native code\]\s*\}/.test(String(it)); // Boolean
10151 },
10152
10153 extend: function(ctor, props){
10154 // summary:
10155 // Adds all properties and methods of props to constructor's
10156 // prototype, making them available to all instances created with
10157 // constructor.
10158 // ctor: Object
10159 // Target constructor to extend.
10160 // props: Object
10161 // One or more objects to mix into ctor.prototype
10162 for(var i=1, l=arguments.length; i<l; i++){
10163 lang._mixin(ctor.prototype, arguments[i]);
10164 }
10165 return ctor; // Object
10166 },
10167
10168 _hitchArgs: function(scope, method){
10169 var pre = lang._toArray(arguments, 2);
10170 var named = lang.isString(method);
10171 return function(){
10172 // arrayify arguments
10173 var args = lang._toArray(arguments);
10174 // locate our method
10175 var f = named ? (scope||dojo.global)[method] : method;
10176 // invoke with collected args
10177 return f && f.apply(scope || this, pre.concat(args)); // mixed
10178 }; // Function
10179 },
10180
10181 hitch: function(scope, method){
10182 // summary:
10183 // Returns a function that will only ever execute in the a given scope.
10184 // This allows for easy use of object member functions
10185 // in callbacks and other places in which the "this" keyword may
10186 // otherwise not reference the expected scope.
10187 // Any number of default positional arguments may be passed as parameters
10188 // beyond "method".
10189 // Each of these values will be used to "placehold" (similar to curry)
10190 // for the hitched function.
10191 // scope: Object
10192 // The scope to use when method executes. If method is a string,
10193 // scope is also the object containing method.
10194 // method: Function|String...
10195 // A function to be hitched to scope, or the name of the method in
10196 // scope to be hitched.
10197 // example:
10198 // | lang.hitch(foo, "bar")();
10199 // runs foo.bar() in the scope of foo
10200 // example:
10201 // | lang.hitch(foo, myFunction);
10202 // returns a function that runs myFunction in the scope of foo
10203 // example:
10204 // Expansion on the default positional arguments passed along from
10205 // hitch. Passed args are mixed first, additional args after.
10206 // | var foo = { bar: function(a, b, c){ console.log(a, b, c); } };
10207 // | var fn = lang.hitch(foo, "bar", 1, 2);
10208 // | fn(3); // logs "1, 2, 3"
10209 // example:
10210 // | var foo = { bar: 2 };
10211 // | lang.hitch(foo, function(){ this.bar = 10; })();
10212 // execute an anonymous function in scope of foo
10213 if(arguments.length > 2){
10214 return lang._hitchArgs.apply(dojo, arguments); // Function
10215 }
10216 if(!method){
10217 method = scope;
10218 scope = null;
10219 }
10220 if(lang.isString(method)){
10221 scope = scope || dojo.global;
10222 if(!scope[method]){ throw(['lang.hitch: scope["', method, '"] is null (scope="', scope, '")'].join('')); }
10223 return function(){ return scope[method].apply(scope, arguments || []); }; // Function
10224 }
10225 return !scope ? method : function(){ return method.apply(scope, arguments || []); }; // Function
10226 },
10227
10228 delegate: (function(){
10229 // boodman/crockford delegation w/ cornford optimization
10230 function TMP(){}
10231 return function(obj, props){
10232 TMP.prototype = obj;
10233 var tmp = new TMP();
10234 TMP.prototype = null;
10235 if(props){
10236 lang._mixin(tmp, props);
10237 }
10238 return tmp; // Object
10239 };
10240 })(),
10241 /*=====
10242 delegate: function(obj, props){
10243 // summary:
10244 // Returns a new object which "looks" to obj for properties which it
10245 // does not have a value for. Optionally takes a bag of properties to
10246 // seed the returned object with initially.
10247 // description:
10248 // This is a small implementation of the Boodman/Crockford delegation
10249 // pattern in JavaScript. An intermediate object constructor mediates
10250 // the prototype chain for the returned object, using it to delegate
10251 // down to obj for property lookup when object-local lookup fails.
10252 // This can be thought of similarly to ES4's "wrap", save that it does
10253 // not act on types but rather on pure objects.
10254 // obj: Object
10255 // The object to delegate to for properties not found directly on the
10256 // return object or in props.
10257 // props: Object...
10258 // an object containing properties to assign to the returned object
10259 // returns:
10260 // an Object of anonymous type
10261 // example:
10262 // | var foo = { bar: "baz" };
10263 // | var thinger = lang.delegate(foo, { thud: "xyzzy"});
10264 // | thinger.bar == "baz"; // delegated to foo
10265 // | foo.thud == undefined; // by definition
10266 // | thinger.thud == "xyzzy"; // mixed in from props
10267 // | foo.bar = "thonk";
10268 // | thinger.bar == "thonk"; // still delegated to foo's bar
10269 },
10270 =====*/
10271
10272 _toArray: has("ie") ?
10273 (function(){
10274 function slow(obj, offset, startWith){
10275 var arr = startWith||[];
10276 for(var x = offset || 0; x < obj.length; x++){
10277 arr.push(obj[x]);
10278 }
10279 return arr;
10280 }
10281 return function(obj){
10282 return ((obj.item) ? slow : efficient).apply(this, arguments);
10283 };
10284 })() : efficient,
10285 /*=====
10286 _toArray: function(obj, offset, startWith){
10287 // summary:
10288 // Converts an array-like object (i.e. arguments, DOMCollection) to an
10289 // array. Returns a new Array with the elements of obj.
10290 // obj: Object
10291 // the object to "arrayify". We expect the object to have, at a
10292 // minimum, a length property which corresponds to integer-indexed
10293 // properties.
10294 // offset: Number?
10295 // the location in obj to start iterating from. Defaults to 0.
10296 // Optional.
10297 // startWith: Array?
10298 // An array to pack with the properties of obj. If provided,
10299 // properties in obj are appended at the end of startWith and
10300 // startWith is the returned array.
10301 },
10302 =====*/
10303
10304 partial: function(/*Function|String*/ method /*, ...*/){
10305 // summary:
10306 // similar to hitch() except that the scope object is left to be
10307 // whatever the execution context eventually becomes.
10308 // description:
10309 // Calling lang.partial is the functional equivalent of calling:
10310 // | lang.hitch(null, funcName, ...);
10311 // method:
10312 // The function to "wrap"
10313 var arr = [ null ];
10314 return lang.hitch.apply(dojo, arr.concat(lang._toArray(arguments))); // Function
10315 },
10316
10317 clone: function(/*anything*/ src){
10318 // summary:
10319 // Clones objects (including DOM nodes) and all children.
10320 // Warning: do not clone cyclic structures.
10321 // src:
10322 // The object to clone
10323 if(!src || typeof src != "object" || lang.isFunction(src)){
10324 // null, undefined, any non-object, or function
10325 return src; // anything
10326 }
10327 if(src.nodeType && "cloneNode" in src){
10328 // DOM Node
10329 return src.cloneNode(true); // Node
10330 }
10331 if(src instanceof Date){
10332 // Date
10333 return new Date(src.getTime()); // Date
10334 }
10335 if(src instanceof RegExp){
10336 // RegExp
10337 return new RegExp(src); // RegExp
10338 }
10339 var r, i, l;
10340 if(lang.isArray(src)){
10341 // array
10342 r = [];
10343 for(i = 0, l = src.length; i < l; ++i){
10344 if(i in src){
10345 r.push(lang.clone(src[i]));
10346 }
10347 }
10348 // we don't clone functions for performance reasons
10349 // }else if(d.isFunction(src)){
10350 // // function
10351 // r = function(){ return src.apply(this, arguments); };
10352 }else{
10353 // generic objects
10354 r = src.constructor ? new src.constructor() : {};
10355 }
10356 return lang._mixin(r, src, lang.clone);
10357 },
10358
10359
10360 trim: String.prototype.trim ?
10361 function(str){ return str.trim(); } :
10362 function(str){ return str.replace(/^\s\s*/, '').replace(/\s\s*$/, ''); },
10363 /*=====
10364 trim: function(str){
10365 // summary:
10366 // Trims whitespace from both sides of the string
10367 // str: String
10368 // String to be trimmed
10369 // returns: String
10370 // Returns the trimmed string
10371 // description:
10372 // This version of trim() was selected for inclusion into the base due
10373 // to its compact size and relatively good performance
10374 // (see [Steven Levithan's blog](http://blog.stevenlevithan.com/archives/faster-trim-javascript)
10375 // Uses String.prototype.trim instead, if available.
10376 // The fastest but longest version of this function is located at
10377 // lang.string.trim()
10378 },
10379 =====*/
10380
10381 replace: function(tmpl, map, pattern){
10382 // summary:
10383 // Performs parameterized substitutions on a string. Throws an
10384 // exception if any parameter is unmatched.
10385 // tmpl: String
10386 // String to be used as a template.
10387 // map: Object|Function
10388 // If an object, it is used as a dictionary to look up substitutions.
10389 // If a function, it is called for every substitution with following parameters:
10390 // a whole match, a name, an offset, and the whole template
10391 // string (see https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/String/replace
10392 // for more details).
10393 // pattern: RegEx?
10394 // Optional regular expression objects that overrides the default pattern.
10395 // Must be global and match one item. The default is: /\{([^\}]+)\}/g,
10396 // which matches patterns like that: "{xxx}", where "xxx" is any sequence
10397 // of characters, which doesn't include "}".
10398 // returns: String
10399 // Returns the substituted string.
10400 // example:
10401 // | // uses a dictionary for substitutions:
10402 // | lang.replace("Hello, {name.first} {name.last} AKA {nick}!",
10403 // | {
10404 // | nick: "Bob",
10405 // | name: {
10406 // | first: "Robert",
10407 // | middle: "X",
10408 // | last: "Cringely"
10409 // | }
10410 // | });
10411 // | // returns: Hello, Robert Cringely AKA Bob!
10412 // example:
10413 // | // uses an array for substitutions:
10414 // | lang.replace("Hello, {0} {2}!",
10415 // | ["Robert", "X", "Cringely"]);
10416 // | // returns: Hello, Robert Cringely!
10417 // example:
10418 // | // uses a function for substitutions:
10419 // | function sum(a){
10420 // | var t = 0;
10421 // | arrayforEach(a, function(x){ t += x; });
10422 // | return t;
10423 // | }
10424 // | lang.replace(
10425 // | "{count} payments averaging {avg} USD per payment.",
10426 // | lang.hitch(
10427 // | { payments: [11, 16, 12] },
10428 // | function(_, key){
10429 // | switch(key){
10430 // | case "count": return this.payments.length;
10431 // | case "min": return Math.min.apply(Math, this.payments);
10432 // | case "max": return Math.max.apply(Math, this.payments);
10433 // | case "sum": return sum(this.payments);
10434 // | case "avg": return sum(this.payments) / this.payments.length;
10435 // | }
10436 // | }
10437 // | )
10438 // | );
10439 // | // prints: 3 payments averaging 13 USD per payment.
10440 // example:
10441 // | // uses an alternative PHP-like pattern for substitutions:
10442 // | lang.replace("Hello, ${0} ${2}!",
10443 // | ["Robert", "X", "Cringely"], /\$\{([^\}]+)\}/g);
10444 // | // returns: Hello, Robert Cringely!
10445
10446 return tmpl.replace(pattern || _pattern, lang.isFunction(map) ?
10447 map : function(_, k){ return lang.getObject(k, false, map); });
10448 }
10449 };
10450
10451 1 && lang.mixin(dojo, lang);
10452
10453 return lang;
10454 });
10455
10456
10457 },
10458 'dojo/request/util':function(){
10459 define("dojo/request/util", [
10460 'exports',
10461 '../errors/RequestError',
10462 '../errors/CancelError',
10463 '../Deferred',
10464 '../io-query',
10465 '../_base/array',
10466 '../_base/lang'
10467 ], function(exports, RequestError, CancelError, Deferred, ioQuery, array, lang){
10468 exports.deepCopy = function deepCopy(target, source){
10469 for(var name in source){
10470 var tval = target[name],
10471 sval = source[name];
10472 if(tval !== sval){
10473 if(tval && typeof tval === 'object' && sval && typeof sval === 'object'){
10474 exports.deepCopy(tval, sval);
10475 }else{
10476 target[name] = sval;
10477 }
10478 }
10479 }
10480 return target;
10481 };
10482
10483 exports.deepCreate = function deepCreate(source, properties){
10484 properties = properties || {};
10485 var target = lang.delegate(source),
10486 name, value;
10487
10488 for(name in source){
10489 value = source[name];
10490
10491 if(value && typeof value === 'object'){
10492 target[name] = exports.deepCreate(value, properties[name]);
10493 }
10494 }
10495 return exports.deepCopy(target, properties);
10496 };
10497
10498 var freeze = Object.freeze || function(obj){ return obj; };
10499 function okHandler(response){
10500 return freeze(response);
10501 }
10502
10503 exports.deferred = function deferred(response, cancel, isValid, isReady, handleResponse, last){
10504 var def = new Deferred(function(reason){
10505 cancel && cancel(def, response);
10506
10507 if(!reason || !(reason instanceof RequestError) && !(reason instanceof CancelError)){
10508 return new CancelError('Request canceled', response);
10509 }
10510 return reason;
10511 });
10512
10513 def.response = response;
10514 def.isValid = isValid;
10515 def.isReady = isReady;
10516 def.handleResponse = handleResponse;
10517
10518 function errHandler(error){
10519 error.response = response;
10520 throw error;
10521 }
10522 var responsePromise = def.then(okHandler).otherwise(errHandler);
10523
10524 if(exports.notify){
10525 responsePromise.then(
10526 lang.hitch(exports.notify, 'emit', 'load'),
10527 lang.hitch(exports.notify, 'emit', 'error')
10528 );
10529 }
10530
10531 var dataPromise = responsePromise.then(function(response){
10532 return response.data || response.text;
10533 });
10534
10535 var promise = freeze(lang.delegate(dataPromise, {
10536 response: responsePromise
10537 }));
10538
10539
10540 if(last){
10541 def.then(function(response){
10542 last.call(def, response);
10543 }, function(error){
10544 last.call(def, response, error);
10545 });
10546 }
10547
10548 def.promise = promise;
10549 def.then = promise.then;
10550
10551 return def;
10552 };
10553
10554 exports.addCommonMethods = function addCommonMethods(provider, methods){
10555 array.forEach(methods||['GET', 'POST', 'PUT', 'DELETE'], function(method){
10556 provider[(method === 'DELETE' ? 'DEL' : method).toLowerCase()] = function(url, options){
10557 options = lang.delegate(options||{});
10558 options.method = method;
10559 return provider(url, options);
10560 };
10561 });
10562 };
10563
10564 exports.parseArgs = function parseArgs(url, options, skipData){
10565 var data = options.data,
10566 query = options.query;
10567
10568 if(data && !skipData){
10569 if(typeof data === 'object'){
10570 options.data = ioQuery.objectToQuery(data);
10571 }
10572 }
10573
10574 if(query){
10575 if(typeof query === 'object'){
10576 query = ioQuery.objectToQuery(query);
10577 }
10578 if(options.preventCache){
10579 query += (query ? '&' : '') + 'request.preventCache=' + (+(new Date));
10580 }
10581 }else if(options.preventCache){
10582 query = 'request.preventCache=' + (+(new Date));
10583 }
10584
10585 if(url && query){
10586 url += (~url.indexOf('?') ? '&' : '?') + query;
10587 }
10588
10589 return {
10590 url: url,
10591 options: options,
10592 getHeader: function(headerName){ return null; }
10593 };
10594 };
10595
10596 exports.checkStatus = function(stat){
10597 stat = stat || 0;
10598 return (stat >= 200 && stat < 300) || // allow any 2XX response code
10599 stat === 304 || // or, get it out of the cache
10600 stat === 1223 || // or, Internet Explorer mangled the status code
10601 !stat; // or, we're Titanium/browser chrome/chrome extension requesting a local file
10602 };
10603 });
10604
10605 },
10606 'dojo/Evented':function(){
10607 define("dojo/Evented", ["./aspect", "./on"], function(aspect, on){
10608 // module:
10609 // dojo/Evented
10610
10611 "use strict";
10612 var after = aspect.after;
10613 function Evented(){
10614 // summary:
10615 // A class that can be used as a mixin or base class,
10616 // to add on() and emit() methods to a class
10617 // for listening for events and emitting events:
10618 //
10619 // | define(["dojo/Evented"], function(Evented){
10620 // | var EventedWidget = dojo.declare([Evented, dijit._Widget], {...});
10621 // | widget = new EventedWidget();
10622 // | widget.on("open", function(event){
10623 // | ... do something with event
10624 // | });
10625 // |
10626 // | widget.emit("open", {name:"some event", ...});
10627 }
10628 Evented.prototype = {
10629 on: function(type, listener){
10630 return on.parse(this, type, listener, function(target, type){
10631 return after(target, 'on' + type, listener, true);
10632 });
10633 },
10634 emit: function(type, event){
10635 var args = [this];
10636 args.push.apply(args, arguments);
10637 return on.emit.apply(on, args);
10638 }
10639 };
10640 return Evented;
10641 });
10642
10643 },
10644 'dojo/mouse':function(){
10645 define("dojo/mouse", ["./_base/kernel", "./on", "./has", "./dom", "./_base/window"], function(dojo, on, has, dom, win){
10646
10647 // module:
10648 // dojo/mouse
10649
10650 has.add("dom-quirks", win.doc && win.doc.compatMode == "BackCompat");
10651 has.add("events-mouseenter", win.doc && "onmouseenter" in win.doc.createElement("div"));
10652 has.add("events-mousewheel", win.doc && 'onmousewheel' in win.doc);
10653
10654 var mouseButtons;
10655 if((has("dom-quirks") && has("ie")) || !has("dom-addeventlistener")){
10656 mouseButtons = {
10657 LEFT: 1,
10658 MIDDLE: 4,
10659 RIGHT: 2,
10660 // helper functions
10661 isButton: function(e, button){ return e.button & button; },
10662 isLeft: function(e){ return e.button & 1; },
10663 isMiddle: function(e){ return e.button & 4; },
10664 isRight: function(e){ return e.button & 2; }
10665 };
10666 }else{
10667 mouseButtons = {
10668 LEFT: 0,
10669 MIDDLE: 1,
10670 RIGHT: 2,
10671 // helper functions
10672 isButton: function(e, button){ return e.button == button; },
10673 isLeft: function(e){ return e.button == 0; },
10674 isMiddle: function(e){ return e.button == 1; },
10675 isRight: function(e){ return e.button == 2; }
10676 };
10677 }
10678 dojo.mouseButtons = mouseButtons;
10679
10680 /*=====
10681 dojo.mouseButtons = {
10682 // LEFT: Number
10683 // Numeric value of the left mouse button for the platform.
10684 LEFT: 0,
10685 // MIDDLE: Number
10686 // Numeric value of the middle mouse button for the platform.
10687 MIDDLE: 1,
10688 // RIGHT: Number
10689 // Numeric value of the right mouse button for the platform.
10690 RIGHT: 2,
10691
10692 isButton: function(e, button){
10693 // summary:
10694 // Checks an event object for a pressed button
10695 // e: Event
10696 // Event object to examine
10697 // button: Number
10698 // The button value (example: dojo.mouseButton.LEFT)
10699 return e.button == button; // Boolean
10700 },
10701 isLeft: function(e){
10702 // summary:
10703 // Checks an event object for the pressed left button
10704 // e: Event
10705 // Event object to examine
10706 return e.button == 0; // Boolean
10707 },
10708 isMiddle: function(e){
10709 // summary:
10710 // Checks an event object for the pressed middle button
10711 // e: Event
10712 // Event object to examine
10713 return e.button == 1; // Boolean
10714 },
10715 isRight: function(e){
10716 // summary:
10717 // Checks an event object for the pressed right button
10718 // e: Event
10719 // Event object to examine
10720 return e.button == 2; // Boolean
10721 }
10722 };
10723 =====*/
10724
10725 function eventHandler(type, selectHandler){
10726 // emulation of mouseenter/leave with mouseover/out using descendant checking
10727 var handler = function(node, listener){
10728 return on(node, type, function(evt){
10729 if(selectHandler){
10730 return selectHandler(evt, listener);
10731 }
10732 if(!dom.isDescendant(evt.relatedTarget, node)){
10733 return listener.call(this, evt);
10734 }
10735 });
10736 };
10737 handler.bubble = function(select){
10738 return eventHandler(type, function(evt, listener){
10739 // using a selector, use the select function to determine if the mouse moved inside the selector and was previously outside the selector
10740 var target = select(evt.target);
10741 var relatedTarget = evt.relatedTarget;
10742 if(target && (target != (relatedTarget && relatedTarget.nodeType == 1 && select(relatedTarget)))){
10743 return listener.call(target, evt);
10744 }
10745 });
10746 };
10747 return handler;
10748 }
10749 var wheel;
10750 if(has("events-mousewheel")){
10751 wheel = 'mousewheel';
10752 }else{ //firefox
10753 wheel = function(node, listener){
10754 return on(node, 'DOMMouseScroll', function(evt){
10755 evt.wheelDelta = -evt.detail;
10756 listener.call(this, evt);
10757 });
10758 };
10759 }
10760 return {
10761 // summary:
10762 // This module provide mouse event handling utility functions and exports
10763 // mouseenter and mouseleave event emulation.
10764 // example:
10765 // To use these events, you register a mouseenter like this:
10766 // | define(["dojo/on", dojo/mouse"], function(on, mouse){
10767 // | on(targetNode, mouse.enter, function(event){
10768 // | dojo.addClass(targetNode, "highlighted");
10769 // | });
10770 // | on(targetNode, mouse.leave, function(event){
10771 // | dojo.removeClass(targetNode, "highlighted");
10772 // | });
10773
10774 _eventHandler: eventHandler, // for dojo/touch
10775
10776 // enter: Synthetic Event
10777 // This is an extension event for the mouseenter that IE provides, emulating the
10778 // behavior on other browsers.
10779 enter: eventHandler("mouseover"),
10780
10781 // leave: Synthetic Event
10782 // This is an extension event for the mouseleave that IE provides, emulating the
10783 // behavior on other browsers.
10784 leave: eventHandler("mouseout"),
10785
10786 // wheel: Normalized Mouse Wheel Event
10787 // This is an extension event for the mousewheel that non-Mozilla browsers provide,
10788 // emulating the behavior on Mozilla based browsers.
10789 wheel: wheel,
10790
10791 isLeft: mouseButtons.isLeft,
10792 /*=====
10793 isLeft: function(){
10794 // summary:
10795 // Test an event object (from a mousedown event) to see if the left button was pressed.
10796 },
10797 =====*/
10798
10799 isMiddle: mouseButtons.isMiddle,
10800 /*=====
10801 isMiddle: function(){
10802 // summary:
10803 // Test an event object (from a mousedown event) to see if the middle button was pressed.
10804 },
10805 =====*/
10806
10807 isRight: mouseButtons.isRight
10808 /*=====
10809 , isRight: function(){
10810 // summary:
10811 // Test an event object (from a mousedown event) to see if the right button was pressed.
10812 }
10813 =====*/
10814 };
10815 });
10816
10817 },
10818 'dojo/topic':function(){
10819 define("dojo/topic", ["./Evented"], function(Evented){
10820
10821 // module:
10822 // dojo/topic
10823
10824 var hub = new Evented;
10825 return {
10826 // summary:
10827 // Pubsub hub.
10828 // example:
10829 // | topic.subscribe("some/topic", function(event){
10830 // | ... do something with event
10831 // | });
10832 // | topic.publish("some/topic", {name:"some event", ...});
10833
10834 publish: function(topic, event){
10835 // summary:
10836 // Publishes a message to a topic on the pub/sub hub. All arguments after
10837 // the first will be passed to the subscribers, so any number of arguments
10838 // can be provided (not just event).
10839 // topic: String
10840 // The name of the topic to publish to
10841 // event: Object
10842 // An event to distribute to the topic listeners
10843 return hub.emit.apply(hub, arguments);
10844 },
10845
10846 subscribe: function(topic, listener){
10847 // summary:
10848 // Subscribes to a topic on the pub/sub hub
10849 // topic: String
10850 // The topic to subscribe to
10851 // listener: Function
10852 // A function to call when a message is published to the given topic
10853 return hub.on.apply(hub, arguments);
10854 }
10855 };
10856 });
10857
10858 },
10859 'dojo/_base/xhr':function(){
10860 define("dojo/_base/xhr", [
10861 "./kernel",
10862 "./sniff",
10863 "require",
10864 "../io-query",
10865 /*===== "./declare", =====*/
10866 "../dom",
10867 "../dom-form",
10868 "./Deferred",
10869 "./config",
10870 "./json",
10871 "./lang",
10872 "./array",
10873 "../on",
10874 "../aspect",
10875 "../request/watch",
10876 "../request/xhr",
10877 "../request/util"
10878 ], function(dojo, has, require, ioq, /*===== declare, =====*/ dom, domForm, Deferred, config, json, lang, array, on, aspect, watch, _xhr, util){
10879 // module:
10880 // dojo/_base/xhr
10881
10882 /*=====
10883 dojo._xhrObj = function(){
10884 // summary:
10885 // does the work of portably generating a new XMLHTTPRequest object.
10886 };
10887 =====*/
10888 dojo._xhrObj = _xhr._create;
10889
10890 var cfg = dojo.config;
10891
10892 // mix in io-query and dom-form
10893 dojo.objectToQuery = ioq.objectToQuery;
10894 dojo.queryToObject = ioq.queryToObject;
10895 dojo.fieldToObject = domForm.fieldToObject;
10896 dojo.formToObject = domForm.toObject;
10897 dojo.formToQuery = domForm.toQuery;
10898 dojo.formToJson = domForm.toJson;
10899
10900 // need to block async callbacks from snatching this thread as the result
10901 // of an async callback might call another sync XHR, this hangs khtml forever
10902 // must checked by watchInFlight()
10903
10904 dojo._blockAsync = false;
10905
10906 // MOW: remove dojo._contentHandlers alias in 2.0
10907 var handlers = dojo._contentHandlers = dojo.contentHandlers = {
10908 // summary:
10909 // A map of available XHR transport handle types. Name matches the
10910 // `handleAs` attribute passed to XHR calls.
10911 // description:
10912 // A map of available XHR transport handle types. Name matches the
10913 // `handleAs` attribute passed to XHR calls. Each contentHandler is
10914 // called, passing the xhr object for manipulation. The return value
10915 // from the contentHandler will be passed to the `load` or `handle`
10916 // functions defined in the original xhr call.
10917 // example:
10918 // Creating a custom content-handler:
10919 // | xhr.contentHandlers.makeCaps = function(xhr){
10920 // | return xhr.responseText.toUpperCase();
10921 // | }
10922 // | // and later:
10923 // | dojo.xhrGet({
10924 // | url:"foo.txt",
10925 // | handleAs:"makeCaps",
10926 // | load: function(data){ /* data is a toUpper version of foo.txt */ }
10927 // | });
10928
10929 "text": function(xhr){
10930 // summary:
10931 // A contentHandler which simply returns the plaintext response data
10932 return xhr.responseText;
10933 },
10934 "json": function(xhr){
10935 // summary:
10936 // A contentHandler which returns a JavaScript object created from the response data
10937 return json.fromJson(xhr.responseText || null);
10938 },
10939 "json-comment-filtered": function(xhr){
10940 // summary:
10941 // A contentHandler which expects comment-filtered JSON.
10942 // description:
10943 // A contentHandler which expects comment-filtered JSON.
10944 // the json-comment-filtered option was implemented to prevent
10945 // "JavaScript Hijacking", but it is less secure than standard JSON. Use
10946 // standard JSON instead. JSON prefixing can be used to subvert hijacking.
10947 //
10948 // Will throw a notice suggesting to use application/json mimetype, as
10949 // json-commenting can introduce security issues. To decrease the chances of hijacking,
10950 // use the standard `json` contentHandler, and prefix your "JSON" with: {}&&
10951 //
10952 // use djConfig.useCommentedJson = true to turn off the notice
10953 if(!config.useCommentedJson){
10954 console.warn("Consider using the standard mimetype:application/json."
10955 + " json-commenting can introduce security issues. To"
10956 + " decrease the chances of hijacking, use the standard the 'json' handler and"
10957 + " prefix your json with: {}&&\n"
10958 + "Use djConfig.useCommentedJson=true to turn off this message.");
10959 }
10960
10961 var value = xhr.responseText;
10962 var cStartIdx = value.indexOf("\/*");
10963 var cEndIdx = value.lastIndexOf("*\/");
10964 if(cStartIdx == -1 || cEndIdx == -1){
10965 throw new Error("JSON was not comment filtered");
10966 }
10967 return json.fromJson(value.substring(cStartIdx+2, cEndIdx));
10968 },
10969 "javascript": function(xhr){
10970 // summary:
10971 // A contentHandler which evaluates the response data, expecting it to be valid JavaScript
10972
10973 // FIXME: try Moz and IE specific eval variants?
10974 return dojo.eval(xhr.responseText);
10975 },
10976 "xml": function(xhr){
10977 // summary:
10978 // A contentHandler returning an XML Document parsed from the response data
10979 var result = xhr.responseXML;
10980
10981 if(has("ie")){
10982 if((!result || !result.documentElement)){
10983 //WARNING: this branch used by the xml handling in dojo.io.iframe,
10984 //so be sure to test dojo.io.iframe if making changes below.
10985 var ms = function(n){ return "MSXML" + n + ".DOMDocument"; };
10986 var dp = ["Microsoft.XMLDOM", ms(6), ms(4), ms(3), ms(2)];
10987 array.some(dp, function(p){
10988 try{
10989 var dom = new ActiveXObject(p);
10990 dom.async = false;
10991 dom.loadXML(xhr.responseText);
10992 result = dom;
10993 }catch(e){ return false; }
10994 return true;
10995 });
10996 }
10997 }
10998 return result; // DOMDocument
10999 },
11000 "json-comment-optional": function(xhr){
11001 // summary:
11002 // A contentHandler which checks the presence of comment-filtered JSON and
11003 // alternates between the `json` and `json-comment-filtered` contentHandlers.
11004 if(xhr.responseText && /^[^{\[]*\/\*/.test(xhr.responseText)){
11005 return handlers["json-comment-filtered"](xhr);
11006 }else{
11007 return handlers["json"](xhr);
11008 }
11009 }
11010 };
11011
11012 /*=====
11013
11014 // kwargs function parameter definitions. Assigning to dojo namespace rather than making them local variables
11015 // because they are used by dojo/io modules too
11016
11017 dojo.__IoArgs = declare(null, {
11018 // url: String
11019 // URL to server endpoint.
11020 // content: Object?
11021 // Contains properties with string values. These
11022 // properties will be serialized as name1=value2 and
11023 // passed in the request.
11024 // timeout: Integer?
11025 // Milliseconds to wait for the response. If this time
11026 // passes, the then error callbacks are called.
11027 // form: DOMNode?
11028 // DOM node for a form. Used to extract the form values
11029 // and send to the server.
11030 // preventCache: Boolean?
11031 // Default is false. If true, then a
11032 // "dojo.preventCache" parameter is sent in the request
11033 // with a value that changes with each request
11034 // (timestamp). Useful only with GET-type requests.
11035 // handleAs: String?
11036 // Acceptable values depend on the type of IO
11037 // transport (see specific IO calls for more information).
11038 // rawBody: String?
11039 // Sets the raw body for an HTTP request. If this is used, then the content
11040 // property is ignored. This is mostly useful for HTTP methods that have
11041 // a body to their requests, like PUT or POST. This property can be used instead
11042 // of postData and putData for dojo/_base/xhr.rawXhrPost and dojo/_base/xhr.rawXhrPut respectively.
11043 // ioPublish: Boolean?
11044 // Set this explicitly to false to prevent publishing of topics related to
11045 // IO operations. Otherwise, if djConfig.ioPublish is set to true, topics
11046 // will be published via dojo/topic.publish() for different phases of an IO operation.
11047 // See dojo/main.__IoPublish for a list of topics that are published.
11048
11049 load: function(response, ioArgs){
11050 // summary:
11051 // This function will be
11052 // called on a successful HTTP response code.
11053 // ioArgs: dojo/main.__IoCallbackArgs
11054 // Provides additional information about the request.
11055 // response: Object
11056 // The response in the format as defined with handleAs.
11057 },
11058
11059 error: function(response, ioArgs){
11060 // summary:
11061 // This function will
11062 // be called when the request fails due to a network or server error, the url
11063 // is invalid, etc. It will also be called if the load or handle callback throws an
11064 // exception, unless djConfig.debugAtAllCosts is true. This allows deployed applications
11065 // to continue to run even when a logic error happens in the callback, while making
11066 // it easier to troubleshoot while in debug mode.
11067 // ioArgs: dojo/main.__IoCallbackArgs
11068 // Provides additional information about the request.
11069 // response: Object
11070 // The response in the format as defined with handleAs.
11071 },
11072
11073 handle: function(loadOrError, response, ioArgs){
11074 // summary:
11075 // This function will
11076 // be called at the end of every request, whether or not an error occurs.
11077 // loadOrError: String
11078 // Provides a string that tells you whether this function
11079 // was called because of success (load) or failure (error).
11080 // response: Object
11081 // The response in the format as defined with handleAs.
11082 // ioArgs: dojo/main.__IoCallbackArgs
11083 // Provides additional information about the request.
11084 }
11085 });
11086
11087 dojo.__IoCallbackArgs = declare(null, {
11088 // args: Object
11089 // the original object argument to the IO call.
11090 // xhr: XMLHttpRequest
11091 // For XMLHttpRequest calls only, the
11092 // XMLHttpRequest object that was used for the
11093 // request.
11094 // url: String
11095 // The final URL used for the call. Many times it
11096 // will be different than the original args.url
11097 // value.
11098 // query: String
11099 // For non-GET requests, the
11100 // name1=value1&name2=value2 parameters sent up in
11101 // the request.
11102 // handleAs: String
11103 // The final indicator on how the response will be
11104 // handled.
11105 // id: String
11106 // For dojo/io/script calls only, the internal
11107 // script ID used for the request.
11108 // canDelete: Boolean
11109 // For dojo/io/script calls only, indicates
11110 // whether the script tag that represents the
11111 // request can be deleted after callbacks have
11112 // been called. Used internally to know when
11113 // cleanup can happen on JSONP-type requests.
11114 // json: Object
11115 // For dojo/io/script calls only: holds the JSON
11116 // response for JSONP-type requests. Used
11117 // internally to hold on to the JSON responses.
11118 // You should not need to access it directly --
11119 // the same object should be passed to the success
11120 // callbacks directly.
11121 });
11122
11123 dojo.__IoPublish = declare(null, {
11124 // summary:
11125 // This is a list of IO topics that can be published
11126 // if djConfig.ioPublish is set to true. IO topics can be
11127 // published for any Input/Output, network operation. So,
11128 // dojo.xhr, dojo.io.script and dojo.io.iframe can all
11129 // trigger these topics to be published.
11130 // start: String
11131 // "/dojo/io/start" is sent when there are no outstanding IO
11132 // requests, and a new IO request is started. No arguments
11133 // are passed with this topic.
11134 // send: String
11135 // "/dojo/io/send" is sent whenever a new IO request is started.
11136 // It passes the dojo.Deferred for the request with the topic.
11137 // load: String
11138 // "/dojo/io/load" is sent whenever an IO request has loaded
11139 // successfully. It passes the response and the dojo.Deferred
11140 // for the request with the topic.
11141 // error: String
11142 // "/dojo/io/error" is sent whenever an IO request has errored.
11143 // It passes the error and the dojo.Deferred
11144 // for the request with the topic.
11145 // done: String
11146 // "/dojo/io/done" is sent whenever an IO request has completed,
11147 // either by loading or by erroring. It passes the error and
11148 // the dojo.Deferred for the request with the topic.
11149 // stop: String
11150 // "/dojo/io/stop" is sent when all outstanding IO requests have
11151 // finished. No arguments are passed with this topic.
11152 });
11153 =====*/
11154
11155
11156 dojo._ioSetArgs = function(/*dojo/main.__IoArgs*/args,
11157 /*Function*/canceller,
11158 /*Function*/okHandler,
11159 /*Function*/errHandler){
11160 // summary:
11161 // sets up the Deferred and ioArgs property on the Deferred so it
11162 // can be used in an io call.
11163 // args:
11164 // The args object passed into the public io call. Recognized properties on
11165 // the args object are:
11166 // canceller:
11167 // The canceller function used for the Deferred object. The function
11168 // will receive one argument, the Deferred object that is related to the
11169 // canceller.
11170 // okHandler:
11171 // The first OK callback to be registered with Deferred. It has the opportunity
11172 // to transform the OK response. It will receive one argument -- the Deferred
11173 // object returned from this function.
11174 // errHandler:
11175 // The first error callback to be registered with Deferred. It has the opportunity
11176 // to do cleanup on an error. It will receive two arguments: error (the
11177 // Error object) and dfd, the Deferred object returned from this function.
11178
11179 var ioArgs = {args: args, url: args.url};
11180
11181 //Get values from form if requested.
11182 var formObject = null;
11183 if(args.form){
11184 var form = dom.byId(args.form);
11185 //IE requires going through getAttributeNode instead of just getAttribute in some form cases,
11186 //so use it for all. See #2844
11187 var actnNode = form.getAttributeNode("action");
11188 ioArgs.url = ioArgs.url || (actnNode ? actnNode.value : null);
11189 formObject = domForm.toObject(form);
11190 }
11191
11192 // set up the query params
11193 var miArgs = [{}];
11194
11195 if(formObject){
11196 // potentially over-ride url-provided params w/ form values
11197 miArgs.push(formObject);
11198 }
11199 if(args.content){
11200 // stuff in content over-rides what's set by form
11201 miArgs.push(args.content);
11202 }
11203 if(args.preventCache){
11204 miArgs.push({"dojo.preventCache": new Date().valueOf()});
11205 }
11206 ioArgs.query = ioq.objectToQuery(lang.mixin.apply(null, miArgs));
11207
11208 // .. and the real work of getting the deferred in order, etc.
11209 ioArgs.handleAs = args.handleAs || "text";
11210 var d = new Deferred(function(dfd){
11211 dfd.canceled = true;
11212 canceller && canceller(dfd);
11213
11214 var err = dfd.ioArgs.error;
11215 if(!err){
11216 err = new Error("request cancelled");
11217 err.dojoType="cancel";
11218 dfd.ioArgs.error = err;
11219 }
11220 return err;
11221 });
11222 d.addCallback(okHandler);
11223
11224 //Support specifying load, error and handle callback functions from the args.
11225 //For those callbacks, the "this" object will be the args object.
11226 //The callbacks will get the deferred result value as the
11227 //first argument and the ioArgs object as the second argument.
11228 var ld = args.load;
11229 if(ld && lang.isFunction(ld)){
11230 d.addCallback(function(value){
11231 return ld.call(args, value, ioArgs);
11232 });
11233 }
11234 var err = args.error;
11235 if(err && lang.isFunction(err)){
11236 d.addErrback(function(value){
11237 return err.call(args, value, ioArgs);
11238 });
11239 }
11240 var handle = args.handle;
11241 if(handle && lang.isFunction(handle)){
11242 d.addBoth(function(value){
11243 return handle.call(args, value, ioArgs);
11244 });
11245 }
11246
11247 // Attach error handler last (not including topic publishing)
11248 // to catch any errors that may have been generated from load
11249 // or handle functions.
11250 d.addErrback(function(error){
11251 return errHandler(error, d);
11252 });
11253
11254 //Plug in topic publishing, if dojo.publish is loaded.
11255 if(cfg.ioPublish && dojo.publish && ioArgs.args.ioPublish !== false){
11256 d.addCallbacks(
11257 function(res){
11258 dojo.publish("/dojo/io/load", [d, res]);
11259 return res;
11260 },
11261 function(res){
11262 dojo.publish("/dojo/io/error", [d, res]);
11263 return res;
11264 }
11265 );
11266 d.addBoth(function(res){
11267 dojo.publish("/dojo/io/done", [d, res]);
11268 return res;
11269 });
11270 }
11271
11272 d.ioArgs = ioArgs;
11273
11274 // FIXME: need to wire up the xhr object's abort method to something
11275 // analogous in the Deferred
11276 return d;
11277 };
11278
11279 var _deferredOk = function(/*Deferred*/dfd){
11280 // summary:
11281 // okHandler function for dojo._ioSetArgs call.
11282
11283 var ret = handlers[dfd.ioArgs.handleAs](dfd.ioArgs.xhr);
11284 return ret === undefined ? null : ret;
11285 };
11286 var _deferError = function(/*Error*/error, /*Deferred*/dfd){
11287 // summary:
11288 // errHandler function for dojo._ioSetArgs call.
11289
11290 if(!dfd.ioArgs.args.failOk){
11291 console.error(error);
11292 }
11293 return error;
11294 };
11295
11296 //Use a separate count for knowing if we are starting/stopping io calls.
11297 var _checkPubCount = function(dfd){
11298 if(_pubCount <= 0){
11299 _pubCount = 0;
11300 if(cfg.ioPublish && dojo.publish && (!dfd || dfd && dfd.ioArgs.args.ioPublish !== false)){
11301 dojo.publish("/dojo/io/stop");
11302 }
11303 }
11304 };
11305
11306 var _pubCount = 0;
11307 aspect.after(watch, "_onAction", function(){
11308 _pubCount -= 1;
11309 });
11310 aspect.after(watch, "_onInFlight", _checkPubCount);
11311
11312 dojo._ioCancelAll = watch.cancelAll;
11313 /*=====
11314 dojo._ioCancelAll = function(){
11315 // summary:
11316 // Cancels all pending IO requests, regardless of IO type
11317 // (xhr, script, iframe).
11318 };
11319 =====*/
11320
11321 dojo._ioNotifyStart = function(/*Deferred*/dfd){
11322 // summary:
11323 // If dojo.publish is available, publish topics
11324 // about the start of a request queue and/or the
11325 // the beginning of request.
11326 //
11327 // Used by IO transports. An IO transport should
11328 // call this method before making the network connection.
11329 if(cfg.ioPublish && dojo.publish && dfd.ioArgs.args.ioPublish !== false){
11330 if(!_pubCount){
11331 dojo.publish("/dojo/io/start");
11332 }
11333 _pubCount += 1;
11334 dojo.publish("/dojo/io/send", [dfd]);
11335 }
11336 };
11337
11338 dojo._ioWatch = function(dfd, validCheck, ioCheck, resHandle){
11339 // summary:
11340 // Watches the io request represented by dfd to see if it completes.
11341 // dfd: Deferred
11342 // The Deferred object to watch.
11343 // validCheck: Function
11344 // Function used to check if the IO request is still valid. Gets the dfd
11345 // object as its only argument.
11346 // ioCheck: Function
11347 // Function used to check if basic IO call worked. Gets the dfd
11348 // object as its only argument.
11349 // resHandle: Function
11350 // Function used to process response. Gets the dfd
11351 // object as its only argument.
11352
11353 var args = dfd.ioArgs.options = dfd.ioArgs.args;
11354 lang.mixin(dfd, {
11355 response: dfd.ioArgs,
11356 isValid: function(response){
11357 return validCheck(dfd);
11358 },
11359 isReady: function(response){
11360 return ioCheck(dfd);
11361 },
11362 handleResponse: function(response){
11363 return resHandle(dfd);
11364 }
11365 });
11366 watch(dfd);
11367
11368 _checkPubCount(dfd);
11369 };
11370
11371 var _defaultContentType = "application/x-www-form-urlencoded";
11372
11373 dojo._ioAddQueryToUrl = function(/*dojo.__IoCallbackArgs*/ioArgs){
11374 // summary:
11375 // Adds query params discovered by the io deferred construction to the URL.
11376 // Only use this for operations which are fundamentally GET-type operations.
11377 if(ioArgs.query.length){
11378 ioArgs.url += (ioArgs.url.indexOf("?") == -1 ? "?" : "&") + ioArgs.query;
11379 ioArgs.query = null;
11380 }
11381 };
11382
11383 /*=====
11384 dojo.__XhrArgs = declare(dojo.__IoArgs, {
11385 // summary:
11386 // In addition to the properties listed for the dojo._IoArgs type,
11387 // the following properties are allowed for dojo.xhr* methods.
11388 // handleAs: String?
11389 // Acceptable values are: text (default), json, json-comment-optional,
11390 // json-comment-filtered, javascript, xml. See `dojo/_base/xhr.contentHandlers`
11391 // sync: Boolean?
11392 // false is default. Indicates whether the request should
11393 // be a synchronous (blocking) request.
11394 // headers: Object?
11395 // Additional HTTP headers to send in the request.
11396 // failOk: Boolean?
11397 // false is default. Indicates whether a request should be
11398 // allowed to fail (and therefore no console error message in
11399 // the event of a failure)
11400 // contentType: String|Boolean
11401 // "application/x-www-form-urlencoded" is default. Set to false to
11402 // prevent a Content-Type header from being sent, or to a string
11403 // to send a different Content-Type.
11404 });
11405 =====*/
11406
11407 dojo.xhr = function(/*String*/ method, /*dojo.__XhrArgs*/ args, /*Boolean?*/ hasBody){
11408 // summary:
11409 // Deprecated. Use dojo/request instead.
11410 // description:
11411 // Sends an HTTP request with the given method.
11412 // See also dojo.xhrGet(), xhrPost(), xhrPut() and dojo.xhrDelete() for shortcuts
11413 // for those HTTP methods. There are also methods for "raw" PUT and POST methods
11414 // via dojo.rawXhrPut() and dojo.rawXhrPost() respectively.
11415 // method:
11416 // HTTP method to be used, such as GET, POST, PUT, DELETE. Should be uppercase.
11417 // hasBody:
11418 // If the request has an HTTP body, then pass true for hasBody.
11419
11420 var rDfd;
11421 //Make the Deferred object for this xhr request.
11422 var dfd = dojo._ioSetArgs(args, function(dfd){
11423 rDfd && rDfd.cancel();
11424 }, _deferredOk, _deferError);
11425 var ioArgs = dfd.ioArgs;
11426
11427 //Allow for specifying the HTTP body completely.
11428 if("postData" in args){
11429 ioArgs.query = args.postData;
11430 }else if("putData" in args){
11431 ioArgs.query = args.putData;
11432 }else if("rawBody" in args){
11433 ioArgs.query = args.rawBody;
11434 }else if((arguments.length > 2 && !hasBody) || "POST|PUT".indexOf(method.toUpperCase()) === -1){
11435 //Check for hasBody being passed. If no hasBody,
11436 //then only append query string if not a POST or PUT request.
11437 dojo._ioAddQueryToUrl(ioArgs);
11438 }
11439
11440 var options = {
11441 method: method,
11442 handleAs: "text",
11443 timeout: args.timeout,
11444 withCredentials: args.withCredentials,
11445 ioArgs: ioArgs
11446 };
11447
11448 if(typeof args.headers !== 'undefined'){
11449 options.headers = args.headers;
11450 }
11451 if(typeof args.contentType !== 'undefined'){
11452 if(!options.headers){
11453 options.headers = {};
11454 }
11455 options.headers['Content-Type'] = args.contentType;
11456 }
11457 if(typeof ioArgs.query !== 'undefined'){
11458 options.data = ioArgs.query;
11459 }
11460 if(typeof args.sync !== 'undefined'){
11461 options.sync = args.sync;
11462 }
11463
11464 dojo._ioNotifyStart(dfd);
11465 try{
11466 rDfd = _xhr(ioArgs.url, options, true);
11467 }catch(e){
11468 // If XHR creation fails, dojo/request/xhr throws
11469 // When this happens, cancel the deferred
11470 dfd.cancel();
11471 return dfd;
11472 }
11473
11474 // sync ioArgs
11475 dfd.ioArgs.xhr = rDfd.response.xhr;
11476
11477 rDfd.then(function(){
11478 dfd.resolve(dfd);
11479 }).otherwise(function(error){
11480 ioArgs.error = error;
11481 if(error.response){
11482 error.status = error.response.status;
11483 error.responseText = error.response.text;
11484 error.xhr = error.response.xhr;
11485 }
11486 dfd.reject(error);
11487 });
11488 return dfd; // dojo/_base/Deferred
11489 };
11490
11491 dojo.xhrGet = function(/*dojo.__XhrArgs*/ args){
11492 // summary:
11493 // Sends an HTTP GET request to the server.
11494 return dojo.xhr("GET", args); // dojo/_base/Deferred
11495 };
11496
11497 dojo.rawXhrPost = dojo.xhrPost = function(/*dojo.__XhrArgs*/ args){
11498 // summary:
11499 // Sends an HTTP POST request to the server. In addition to the properties
11500 // listed for the dojo.__XhrArgs type, the following property is allowed:
11501 // postData:
11502 // String. Send raw data in the body of the POST request.
11503 return dojo.xhr("POST", args, true); // dojo/_base/Deferred
11504 };
11505
11506 dojo.rawXhrPut = dojo.xhrPut = function(/*dojo.__XhrArgs*/ args){
11507 // summary:
11508 // Sends an HTTP PUT request to the server. In addition to the properties
11509 // listed for the dojo.__XhrArgs type, the following property is allowed:
11510 // putData:
11511 // String. Send raw data in the body of the PUT request.
11512 return dojo.xhr("PUT", args, true); // dojo/_base/Deferred
11513 };
11514
11515 dojo.xhrDelete = function(/*dojo.__XhrArgs*/ args){
11516 // summary:
11517 // Sends an HTTP DELETE request to the server.
11518 return dojo.xhr("DELETE", args); // dojo/_base/Deferred
11519 };
11520
11521 /*
11522 dojo.wrapForm = function(formNode){
11523 // summary:
11524 // A replacement for FormBind, but not implemented yet.
11525
11526 // FIXME: need to think harder about what extensions to this we might
11527 // want. What should we allow folks to do w/ this? What events to
11528 // set/send?
11529 throw new Error("dojo.wrapForm not yet implemented");
11530 }
11531 */
11532
11533 dojo._isDocumentOk = function(x){
11534 return util.checkStatus(x.status);
11535 };
11536
11537 dojo._getText = function(url){
11538 var result;
11539 dojo.xhrGet({url:url, sync:true, load:function(text){
11540 result = text;
11541 }});
11542 return result;
11543 };
11544
11545 // Add aliases for static functions to dojo.xhr since dojo.xhr is what's returned from this module
11546 lang.mixin(dojo.xhr, {
11547 _xhrObj: dojo._xhrObj,
11548 fieldToObject: domForm.fieldToObject,
11549 formToObject: domForm.toObject,
11550 objectToQuery: ioq.objectToQuery,
11551 formToQuery: domForm.toQuery,
11552 formToJson: domForm.toJson,
11553 queryToObject: ioq.queryToObject,
11554 contentHandlers: handlers,
11555 _ioSetArgs: dojo._ioSetArgs,
11556 _ioCancelAll: dojo._ioCancelAll,
11557 _ioNotifyStart: dojo._ioNotifyStart,
11558 _ioWatch: dojo._ioWatch,
11559 _ioAddQueryToUrl: dojo._ioAddQueryToUrl,
11560 _isDocumentOk: dojo._isDocumentOk,
11561 _getText: dojo._getText,
11562 get: dojo.xhrGet,
11563 post: dojo.xhrPost,
11564 put: dojo.xhrPut,
11565 del: dojo.xhrDelete // because "delete" is a reserved word
11566 });
11567
11568 return dojo.xhr;
11569 });
11570
11571 },
11572 'dojo/_base/unload':function(){
11573 define(["./kernel", "./lang", "../on"], function(dojo, lang, on){
11574
11575 // module:
11576 // dojo/unload
11577
11578 var win = window;
11579
11580 var unload = {
11581 // summary:
11582 // This module contains the document and window unload detection API.
11583
11584 addOnWindowUnload: function(/*Object|Function?*/ obj, /*String|Function?*/ functionName){
11585 // summary:
11586 // registers a function to be triggered when window.onunload
11587 // fires.
11588 // description:
11589 // The first time that addOnWindowUnload is called Dojo
11590 // will register a page listener to trigger your unload
11591 // handler with. Note that registering these handlers may
11592 // destroy "fastback" page caching in browsers that support
11593 // it. Be careful trying to modify the DOM or access
11594 // JavaScript properties during this phase of page unloading:
11595 // they may not always be available. Consider
11596 // addOnUnload() if you need to modify the DOM or do
11597 // heavy JavaScript work since it fires at the equivalent of
11598 // the page's "onbeforeunload" event.
11599 // example:
11600 // | unload.addOnWindowUnload(functionPointer)
11601 // | unload.addOnWindowUnload(object, "functionName");
11602 // | unload.addOnWindowUnload(object, function(){ /* ... */});
11603
11604 if (!dojo.windowUnloaded){
11605 on(win, "unload", (dojo.windowUnloaded = function(){
11606 // summary:
11607 // signal fired by impending window destruction. You may use
11608 // dojo.addOnWindowUnload() to register a listener for this
11609 // event. NOTE: if you wish to dojo.connect() to this method
11610 // to perform page/application cleanup, be aware that this
11611 // event WILL NOT fire if no handler has been registered with
11612 // addOnWindowUnload(). This behavior started in Dojo 1.3.
11613 // Previous versions always triggered windowUnloaded(). See
11614 // addOnWindowUnload for more info.
11615 }));
11616 }
11617 on(win, "unload", lang.hitch(obj, functionName));
11618 },
11619
11620 addOnUnload: function(/*Object?|Function?*/ obj, /*String|Function?*/ functionName){
11621 // summary:
11622 // registers a function to be triggered when the page unloads.
11623 // description:
11624 // The first time that addOnUnload is called Dojo will
11625 // register a page listener to trigger your unload handler
11626 // with.
11627 //
11628 // In a browser environment, the functions will be triggered
11629 // during the window.onbeforeunload event. Be careful of doing
11630 // too much work in an unload handler. onbeforeunload can be
11631 // triggered if a link to download a file is clicked, or if
11632 // the link is a javascript: link. In these cases, the
11633 // onbeforeunload event fires, but the document is not
11634 // actually destroyed. So be careful about doing destructive
11635 // operations in a dojo.addOnUnload callback.
11636 //
11637 // Further note that calling dojo.addOnUnload will prevent
11638 // browsers from using a "fast back" cache to make page
11639 // loading via back button instantaneous.
11640 // example:
11641 // | dojo.addOnUnload(functionPointer)
11642 // | dojo.addOnUnload(object, "functionName")
11643 // | dojo.addOnUnload(object, function(){ /* ... */});
11644
11645 on(win, "beforeunload", lang.hitch(obj, functionName));
11646 }
11647 };
11648
11649 dojo.addOnWindowUnload = unload.addOnWindowUnload;
11650 dojo.addOnUnload = unload.addOnUnload;
11651
11652 return unload;
11653
11654 });
11655
11656 },
11657 'dojo/Deferred':function(){
11658 define([
11659 "./has",
11660 "./_base/lang",
11661 "./errors/CancelError",
11662 "./promise/Promise",
11663 "./promise/instrumentation"
11664 ], function(has, lang, CancelError, Promise, instrumentation){
11665 "use strict";
11666
11667 // module:
11668 // dojo/Deferred
11669
11670 var PROGRESS = 0,
11671 RESOLVED = 1,
11672 REJECTED = 2;
11673 var FULFILLED_ERROR_MESSAGE = "This deferred has already been fulfilled.";
11674
11675 var freezeObject = Object.freeze || function(){};
11676
11677 var signalWaiting = function(waiting, type, result, rejection, deferred){
11678 if( 1 ){
11679 if(type === REJECTED && Deferred.instrumentRejected && waiting.length === 0){
11680 Deferred.instrumentRejected(result, false, rejection, deferred);
11681 }
11682 }
11683
11684 for(var i = 0; i < waiting.length; i++){
11685 signalListener(waiting[i], type, result, rejection);
11686 }
11687 };
11688
11689 var signalListener = function(listener, type, result, rejection){
11690 var func = listener[type];
11691 var deferred = listener.deferred;
11692 if(func){
11693 try{
11694 var newResult = func(result);
11695 if(type === PROGRESS){
11696 if(typeof newResult !== "undefined"){
11697 signalDeferred(deferred, type, newResult);
11698 }
11699 }else{
11700 if(newResult && typeof newResult.then === "function"){
11701 listener.cancel = newResult.cancel;
11702 newResult.then(
11703 // Only make resolvers if they're actually going to be used
11704 makeDeferredSignaler(deferred, RESOLVED),
11705 makeDeferredSignaler(deferred, REJECTED),
11706 makeDeferredSignaler(deferred, PROGRESS));
11707 return;
11708 }
11709 signalDeferred(deferred, RESOLVED, newResult);
11710 }
11711 }catch(error){
11712 signalDeferred(deferred, REJECTED, error);
11713 }
11714 }else{
11715 signalDeferred(deferred, type, result);
11716 }
11717
11718 if( 1 ){
11719 if(type === REJECTED && Deferred.instrumentRejected){
11720 Deferred.instrumentRejected(result, !!func, rejection, deferred.promise);
11721 }
11722 }
11723 };
11724
11725 var makeDeferredSignaler = function(deferred, type){
11726 return function(value){
11727 signalDeferred(deferred, type, value);
11728 };
11729 };
11730
11731 var signalDeferred = function(deferred, type, result){
11732 if(!deferred.isCanceled()){
11733 switch(type){
11734 case PROGRESS:
11735 deferred.progress(result);
11736 break;
11737 case RESOLVED:
11738 deferred.resolve(result);
11739 break;
11740 case REJECTED:
11741 deferred.reject(result);
11742 break;
11743 }
11744 }
11745 };
11746
11747 var Deferred = function(canceler){
11748 // summary:
11749 // Creates a new deferred. This API is preferred over
11750 // `dojo/_base/Deferred`.
11751 // description:
11752 // Creates a new deferred, as an abstraction over (primarily)
11753 // asynchronous operations. The deferred is the private interface
11754 // that should not be returned to calling code. That's what the
11755 // `promise` is for. See `dojo/promise/Promise`.
11756 // canceler: Function?
11757 // Will be invoked if the deferred is canceled. The canceler
11758 // receives the reason the deferred was canceled as its argument.
11759 // The deferred is rejected with its return value, or a new
11760 // `dojo/errors/CancelError` instance.
11761
11762 // promise: dojo/promise/Promise
11763 // The public promise object that clients can add callbacks to.
11764 var promise = this.promise = new Promise();
11765
11766 var deferred = this;
11767 var fulfilled, result, rejection;
11768 var canceled = false;
11769 var waiting = [];
11770
11771 if( 1 && Error.captureStackTrace){
11772 Error.captureStackTrace(deferred, Deferred);
11773 Error.captureStackTrace(promise, Deferred);
11774 }
11775
11776 this.isResolved = promise.isResolved = function(){
11777 // summary:
11778 // Checks whether the deferred has been resolved.
11779 // returns: Boolean
11780
11781 return fulfilled === RESOLVED;
11782 };
11783
11784 this.isRejected = promise.isRejected = function(){
11785 // summary:
11786 // Checks whether the deferred has been rejected.
11787 // returns: Boolean
11788
11789 return fulfilled === REJECTED;
11790 };
11791
11792 this.isFulfilled = promise.isFulfilled = function(){
11793 // summary:
11794 // Checks whether the deferred has been resolved or rejected.
11795 // returns: Boolean
11796
11797 return !!fulfilled;
11798 };
11799
11800 this.isCanceled = promise.isCanceled = function(){
11801 // summary:
11802 // Checks whether the deferred has been canceled.
11803 // returns: Boolean
11804
11805 return canceled;
11806 };
11807
11808 this.progress = function(update, strict){
11809 // summary:
11810 // Emit a progress update on the deferred.
11811 // description:
11812 // Emit a progress update on the deferred. Progress updates
11813 // can be used to communicate updates about the asynchronous
11814 // operation before it has finished.
11815 // update: any
11816 // The progress update. Passed to progbacks.
11817 // strict: Boolean?
11818 // If strict, will throw an error if the deferred has already
11819 // been fulfilled and consequently no progress can be emitted.
11820 // returns: dojo/promise/Promise
11821 // Returns the original promise for the deferred.
11822
11823 if(!fulfilled){
11824 signalWaiting(waiting, PROGRESS, update, null, deferred);
11825 return promise;
11826 }else if(strict === true){
11827 throw new Error(FULFILLED_ERROR_MESSAGE);
11828 }else{
11829 return promise;
11830 }
11831 };
11832
11833 this.resolve = function(value, strict){
11834 // summary:
11835 // Resolve the deferred.
11836 // description:
11837 // Resolve the deferred, putting it in a success state.
11838 // value: any
11839 // The result of the deferred. Passed to callbacks.
11840 // strict: Boolean?
11841 // If strict, will throw an error if the deferred has already
11842 // been fulfilled and consequently cannot be resolved.
11843 // returns: dojo/promise/Promise
11844 // Returns the original promise for the deferred.
11845
11846 if(!fulfilled){
11847 // Set fulfilled, store value. After signaling waiting listeners unset
11848 // waiting.
11849 signalWaiting(waiting, fulfilled = RESOLVED, result = value, null, deferred);
11850 waiting = null;
11851 return promise;
11852 }else if(strict === true){
11853 throw new Error(FULFILLED_ERROR_MESSAGE);
11854 }else{
11855 return promise;
11856 }
11857 };
11858
11859 var reject = this.reject = function(error, strict){
11860 // summary:
11861 // Reject the deferred.
11862 // description:
11863 // Reject the deferred, putting it in an error state.
11864 // error: any
11865 // The error result of the deferred. Passed to errbacks.
11866 // strict: Boolean?
11867 // If strict, will throw an error if the deferred has already
11868 // been fulfilled and consequently cannot be rejected.
11869 // returns: dojo/promise/Promise
11870 // Returns the original promise for the deferred.
11871
11872 if(!fulfilled){
11873 if( 1 && Error.captureStackTrace){
11874 Error.captureStackTrace(rejection = {}, reject);
11875 }
11876 signalWaiting(waiting, fulfilled = REJECTED, result = error, rejection, deferred);
11877 waiting = null;
11878 return promise;
11879 }else if(strict === true){
11880 throw new Error(FULFILLED_ERROR_MESSAGE);
11881 }else{
11882 return promise;
11883 }
11884 };
11885
11886 this.then = promise.then = function(callback, errback, progback){
11887 // summary:
11888 // Add new callbacks to the deferred.
11889 // description:
11890 // Add new callbacks to the deferred. Callbacks can be added
11891 // before or after the deferred is fulfilled.
11892 // callback: Function?
11893 // Callback to be invoked when the promise is resolved.
11894 // Receives the resolution value.
11895 // errback: Function?
11896 // Callback to be invoked when the promise is rejected.
11897 // Receives the rejection error.
11898 // progback: Function?
11899 // Callback to be invoked when the promise emits a progress
11900 // update. Receives the progress update.
11901 // returns: dojo/promise/Promise
11902 // Returns a new promise for the result of the callback(s).
11903 // This can be used for chaining many asynchronous operations.
11904
11905 var listener = [progback, callback, errback];
11906 // Ensure we cancel the promise we're waiting for, or if callback/errback
11907 // have returned a promise, cancel that one.
11908 listener.cancel = promise.cancel;
11909 listener.deferred = new Deferred(function(reason){
11910 // Check whether cancel is really available, returned promises are not
11911 // required to expose `cancel`
11912 return listener.cancel && listener.cancel(reason);
11913 });
11914 if(fulfilled && !waiting){
11915 signalListener(listener, fulfilled, result, rejection);
11916 }else{
11917 waiting.push(listener);
11918 }
11919 return listener.deferred.promise;
11920 };
11921
11922 this.cancel = promise.cancel = function(reason, strict){
11923 // summary:
11924 // Inform the deferred it may cancel its asynchronous operation.
11925 // description:
11926 // Inform the deferred it may cancel its asynchronous operation.
11927 // The deferred's (optional) canceler is invoked and the
11928 // deferred will be left in a rejected state. Can affect other
11929 // promises that originate with the same deferred.
11930 // reason: any
11931 // A message that may be sent to the deferred's canceler,
11932 // explaining why it's being canceled.
11933 // strict: Boolean?
11934 // If strict, will throw an error if the deferred has already
11935 // been fulfilled and consequently cannot be canceled.
11936 // returns: any
11937 // Returns the rejection reason if the deferred was canceled
11938 // normally.
11939
11940 if(!fulfilled){
11941 // Cancel can be called even after the deferred is fulfilled
11942 if(canceler){
11943 var returnedReason = canceler(reason);
11944 reason = typeof returnedReason === "undefined" ? reason : returnedReason;
11945 }
11946 canceled = true;
11947 if(!fulfilled){
11948 // Allow canceler to provide its own reason, but fall back to a CancelError
11949 if(typeof reason === "undefined"){
11950 reason = new CancelError();
11951 }
11952 reject(reason);
11953 return reason;
11954 }else if(fulfilled === REJECTED && result === reason){
11955 return reason;
11956 }
11957 }else if(strict === true){
11958 throw new Error(FULFILLED_ERROR_MESSAGE);
11959 }
11960 };
11961
11962 freezeObject(promise);
11963 };
11964
11965 Deferred.prototype.toString = function(){
11966 // returns: String
11967 // Returns `[object Deferred]`.
11968
11969 return "[object Deferred]";
11970 };
11971
11972 if(instrumentation){
11973 instrumentation(Deferred);
11974 }
11975
11976 return Deferred;
11977 });
11978
11979 },
11980 'dojo/_base/NodeList':function(){
11981 define("dojo/_base/NodeList", ["./kernel", "../query", "./array", "./html", "../NodeList-dom"], function(dojo, query, array){
11982 // module:
11983 // dojo/_base/NodeList
11984
11985 /*=====
11986 return {
11987 // summary:
11988 // This module extends dojo/NodeList with the legacy connect(), coords(),
11989 // blur(), focus(), change(), click(), error(), keydown(), keypress(),
11990 // keyup(), load(), mousedown(), mouseenter(), mouseleave(), mousemove(),
11991 // mouseout(), mouseover(), mouseup(), and submit() methods.
11992 };
11993 =====*/
11994
11995 var NodeList = query.NodeList,
11996 nlp = NodeList.prototype;
11997
11998 nlp.connect = NodeList._adaptAsForEach(function(){
11999 // don't bind early to dojo.connect since we no longer explicitly depend on it
12000 return dojo.connect.apply(this, arguments);
12001 });
12002 /*=====
12003 nlp.connect = function(methodName, objOrFunc, funcName){
12004 // summary:
12005 // Attach event handlers to every item of the NodeList. Uses dojo.connect()
12006 // so event properties are normalized.
12007 //
12008 // Application must manually require() "dojo/_base/connect" before using this method.
12009 // methodName: String
12010 // the name of the method to attach to. For DOM events, this should be
12011 // the lower-case name of the event
12012 // objOrFunc: Object|Function|String
12013 // if 2 arguments are passed (methodName, objOrFunc), objOrFunc should
12014 // reference a function or be the name of the function in the global
12015 // namespace to attach. If 3 arguments are provided
12016 // (methodName, objOrFunc, funcName), objOrFunc must be the scope to
12017 // locate the bound function in
12018 // funcName: String?
12019 // optional. A string naming the function in objOrFunc to bind to the
12020 // event. May also be a function reference.
12021 // example:
12022 // add an onclick handler to every button on the page
12023 // | query("div:nth-child(odd)").connect("onclick", function(e){
12024 // | console.log("clicked!");
12025 // | });
12026 // example:
12027 // attach foo.bar() to every odd div's onmouseover
12028 // | query("div:nth-child(odd)").connect("onmouseover", foo, "bar");
12029
12030 return null; // NodeList
12031 };
12032 =====*/
12033
12034 nlp.coords = NodeList._adaptAsMap(dojo.coords);
12035 /*=====
12036 nlp.coords = function(){
12037 // summary:
12038 // Deprecated: Use position() for border-box x/y/w/h
12039 // or marginBox() for margin-box w/h/l/t.
12040 // Returns the box objects of all elements in a node list as
12041 // an Array (*not* a NodeList). Acts like `domGeom.coords`, though assumes
12042 // the node passed is each node in this list.
12043
12044 return []; // Array
12045 };
12046 =====*/
12047
12048 NodeList.events = [
12049 // summary:
12050 // list of all DOM events used in NodeList
12051 "blur", "focus", "change", "click", "error", "keydown", "keypress",
12052 "keyup", "load", "mousedown", "mouseenter", "mouseleave", "mousemove",
12053 "mouseout", "mouseover", "mouseup", "submit"
12054 ];
12055
12056 // FIXME: pseudo-doc the above automatically generated on-event functions
12057
12058 // syntactic sugar for DOM events
12059 array.forEach(NodeList.events, function(evt){
12060 var _oe = "on" + evt;
12061 nlp[_oe] = function(a, b){
12062 return this.connect(_oe, a, b);
12063 };
12064 // FIXME: should these events trigger publishes?
12065 /*
12066 return (a ? this.connect(_oe, a, b) :
12067 this.forEach(function(n){
12068 // FIXME:
12069 // listeners get buried by
12070 // addEventListener and can't be dug back
12071 // out to be triggered externally.
12072 // see:
12073 // http://developer.mozilla.org/en/docs/DOM:element
12074
12075 console.log(n, evt, _oe);
12076
12077 // FIXME: need synthetic event support!
12078 var _e = { target: n, faux: true, type: evt };
12079 // dojo._event_listener._synthesizeEvent({}, { target: n, faux: true, type: evt });
12080 try{ n[evt](_e); }catch(e){ console.log(e); }
12081 try{ n[_oe](_e); }catch(e){ console.log(e); }
12082 })
12083 );
12084 */
12085 }
12086 );
12087
12088 dojo.NodeList = NodeList;
12089 return NodeList;
12090 });
12091
12092 },
12093 'dojo/_base/Color':function(){
12094 define(["./kernel", "./lang", "./array", "./config"], function(dojo, lang, ArrayUtil, config){
12095
12096 var Color = dojo.Color = function(/*Array|String|Object*/ color){
12097 // summary:
12098 // Takes a named string, hex string, array of rgb or rgba values,
12099 // an object with r, g, b, and a properties, or another `Color` object
12100 // and creates a new Color instance to work from.
12101 //
12102 // example:
12103 // Work with a Color instance:
12104 // | var c = new Color();
12105 // | c.setColor([0,0,0]); // black
12106 // | var hex = c.toHex(); // #000000
12107 //
12108 // example:
12109 // Work with a node's color:
12110 // | var color = dojo.style("someNode", "backgroundColor");
12111 // | var n = new Color(color);
12112 // | // adjust the color some
12113 // | n.r *= .5;
12114 // | console.log(n.toString()); // rgb(128, 255, 255);
12115 if(color){ this.setColor(color); }
12116 };
12117
12118 // FIXME:
12119 // there's got to be a more space-efficient way to encode or discover
12120 // these!! Use hex?
12121 Color.named = {
12122 // summary:
12123 // Dictionary list of all CSS named colors, by name. Values are 3-item arrays with corresponding RG and B values.
12124 "black": [0,0,0],
12125 "silver": [192,192,192],
12126 "gray": [128,128,128],
12127 "white": [255,255,255],
12128 "maroon": [128,0,0],
12129 "red": [255,0,0],
12130 "purple": [128,0,128],
12131 "fuchsia":[255,0,255],
12132 "green": [0,128,0],
12133 "lime": [0,255,0],
12134 "olive": [128,128,0],
12135 "yellow": [255,255,0],
12136 "navy": [0,0,128],
12137 "blue": [0,0,255],
12138 "teal": [0,128,128],
12139 "aqua": [0,255,255],
12140 "transparent": config.transparentColor || [0,0,0,0]
12141 };
12142
12143 lang.extend(Color, {
12144 r: 255, g: 255, b: 255, a: 1,
12145 _set: function(r, g, b, a){
12146 var t = this; t.r = r; t.g = g; t.b = b; t.a = a;
12147 },
12148 setColor: function(/*Array|String|Object*/ color){
12149 // summary:
12150 // Takes a named string, hex string, array of rgb or rgba values,
12151 // an object with r, g, b, and a properties, or another `Color` object
12152 // and sets this color instance to that value.
12153 //
12154 // example:
12155 // | var c = new Color(); // no color
12156 // | c.setColor("#ededed"); // greyish
12157 if(lang.isString(color)){
12158 Color.fromString(color, this);
12159 }else if(lang.isArray(color)){
12160 Color.fromArray(color, this);
12161 }else{
12162 this._set(color.r, color.g, color.b, color.a);
12163 if(!(color instanceof Color)){ this.sanitize(); }
12164 }
12165 return this; // Color
12166 },
12167 sanitize: function(){
12168 // summary:
12169 // Ensures the object has correct attributes
12170 // description:
12171 // the default implementation does nothing, include dojo.colors to
12172 // augment it with real checks
12173 return this; // Color
12174 },
12175 toRgb: function(){
12176 // summary:
12177 // Returns 3 component array of rgb values
12178 // example:
12179 // | var c = new Color("#000000");
12180 // | console.log(c.toRgb()); // [0,0,0]
12181 var t = this;
12182 return [t.r, t.g, t.b]; // Array
12183 },
12184 toRgba: function(){
12185 // summary:
12186 // Returns a 4 component array of rgba values from the color
12187 // represented by this object.
12188 var t = this;
12189 return [t.r, t.g, t.b, t.a]; // Array
12190 },
12191 toHex: function(){
12192 // summary:
12193 // Returns a CSS color string in hexadecimal representation
12194 // example:
12195 // | console.log(new Color([0,0,0]).toHex()); // #000000
12196 var arr = ArrayUtil.map(["r", "g", "b"], function(x){
12197 var s = this[x].toString(16);
12198 return s.length < 2 ? "0" + s : s;
12199 }, this);
12200 return "#" + arr.join(""); // String
12201 },
12202 toCss: function(/*Boolean?*/ includeAlpha){
12203 // summary:
12204 // Returns a css color string in rgb(a) representation
12205 // example:
12206 // | var c = new Color("#FFF").toCss();
12207 // | console.log(c); // rgb('255','255','255')
12208 var t = this, rgb = t.r + ", " + t.g + ", " + t.b;
12209 return (includeAlpha ? "rgba(" + rgb + ", " + t.a : "rgb(" + rgb) + ")"; // String
12210 },
12211 toString: function(){
12212 // summary:
12213 // Returns a visual representation of the color
12214 return this.toCss(true); // String
12215 }
12216 });
12217
12218 Color.blendColors = dojo.blendColors = function(
12219 /*Color*/ start,
12220 /*Color*/ end,
12221 /*Number*/ weight,
12222 /*Color?*/ obj
12223 ){
12224 // summary:
12225 // Blend colors end and start with weight from 0 to 1, 0.5 being a 50/50 blend,
12226 // can reuse a previously allocated Color object for the result
12227 var t = obj || new Color();
12228 ArrayUtil.forEach(["r", "g", "b", "a"], function(x){
12229 t[x] = start[x] + (end[x] - start[x]) * weight;
12230 if(x != "a"){ t[x] = Math.round(t[x]); }
12231 });
12232 return t.sanitize(); // Color
12233 };
12234
12235 Color.fromRgb = dojo.colorFromRgb = function(/*String*/ color, /*Color?*/ obj){
12236 // summary:
12237 // Returns a `Color` instance from a string of the form
12238 // "rgb(...)" or "rgba(...)". Optionally accepts a `Color`
12239 // object to update with the parsed value and return instead of
12240 // creating a new object.
12241 // returns:
12242 // A Color object. If obj is passed, it will be the return value.
12243 var m = color.toLowerCase().match(/^rgba?\(([\s\.,0-9]+)\)/);
12244 return m && Color.fromArray(m[1].split(/\s*,\s*/), obj); // Color
12245 };
12246
12247 Color.fromHex = dojo.colorFromHex = function(/*String*/ color, /*Color?*/ obj){
12248 // summary:
12249 // Converts a hex string with a '#' prefix to a color object.
12250 // Supports 12-bit #rgb shorthand. Optionally accepts a
12251 // `Color` object to update with the parsed value.
12252 //
12253 // returns:
12254 // A Color object. If obj is passed, it will be the return value.
12255 //
12256 // example:
12257 // | var thing = dojo.colorFromHex("#ededed"); // grey, longhand
12258 //
12259 // example:
12260 // | var thing = dojo.colorFromHex("#000"); // black, shorthand
12261 var t = obj || new Color(),
12262 bits = (color.length == 4) ? 4 : 8,
12263 mask = (1 << bits) - 1;
12264 color = Number("0x" + color.substr(1));
12265 if(isNaN(color)){
12266 return null; // Color
12267 }
12268 ArrayUtil.forEach(["b", "g", "r"], function(x){
12269 var c = color & mask;
12270 color >>= bits;
12271 t[x] = bits == 4 ? 17 * c : c;
12272 });
12273 t.a = 1;
12274 return t; // Color
12275 };
12276
12277 Color.fromArray = dojo.colorFromArray = function(/*Array*/ a, /*Color?*/ obj){
12278 // summary:
12279 // Builds a `Color` from a 3 or 4 element array, mapping each
12280 // element in sequence to the rgb(a) values of the color.
12281 // example:
12282 // | var myColor = dojo.colorFromArray([237,237,237,0.5]); // grey, 50% alpha
12283 // returns:
12284 // A Color object. If obj is passed, it will be the return value.
12285 var t = obj || new Color();
12286 t._set(Number(a[0]), Number(a[1]), Number(a[2]), Number(a[3]));
12287 if(isNaN(t.a)){ t.a = 1; }
12288 return t.sanitize(); // Color
12289 };
12290
12291 Color.fromString = dojo.colorFromString = function(/*String*/ str, /*Color?*/ obj){
12292 // summary:
12293 // Parses `str` for a color value. Accepts hex, rgb, and rgba
12294 // style color values.
12295 // description:
12296 // Acceptable input values for str may include arrays of any form
12297 // accepted by dojo.colorFromArray, hex strings such as "#aaaaaa", or
12298 // rgb or rgba strings such as "rgb(133, 200, 16)" or "rgba(10, 10,
12299 // 10, 50)"
12300 // returns:
12301 // A Color object. If obj is passed, it will be the return value.
12302 var a = Color.named[str];
12303 return a && Color.fromArray(a, obj) || Color.fromRgb(str, obj) || Color.fromHex(str, obj); // Color
12304 };
12305
12306 return Color;
12307 });
12308
12309 },
12310 'dojo/promise/instrumentation':function(){
12311 define([
12312 "./tracer",
12313 "../has",
12314 "../_base/lang",
12315 "../_base/array"
12316 ], function(tracer, has, lang, arrayUtil){
12317 function logError(error, rejection, deferred){
12318 var stack = "";
12319 if(error && error.stack){
12320 stack += error.stack;
12321 }
12322 if(rejection && rejection.stack){
12323 stack += "\n ----------------------------------------\n rejected" + rejection.stack.split("\n").slice(1).join("\n").replace(/^\s+/, " ");
12324 }
12325 if(deferred && deferred.stack){
12326 stack += "\n ----------------------------------------\n" + deferred.stack;
12327 }
12328 console.error(error, stack);
12329 }
12330
12331 function reportRejections(error, handled, rejection, deferred){
12332 if(!handled){
12333 logError(error, rejection, deferred);
12334 }
12335 }
12336
12337 var errors = [];
12338 var activeTimeout = false;
12339 var unhandledWait = 1000;
12340 function trackUnhandledRejections(error, handled, rejection, deferred){
12341 if(handled){
12342 arrayUtil.some(errors, function(obj, ix){
12343 if(obj.error === error){
12344 errors.splice(ix, 1);
12345 return true;
12346 }
12347 });
12348 }else if(!arrayUtil.some(errors, function(obj){ return obj.error === error; })){
12349 errors.push({
12350 error: error,
12351 rejection: rejection,
12352 deferred: deferred,
12353 timestamp: new Date().getTime()
12354 });
12355 }
12356
12357 if(!activeTimeout){
12358 activeTimeout = setTimeout(logRejected, unhandledWait);
12359 }
12360 }
12361
12362 function logRejected(){
12363 var now = new Date().getTime();
12364 var reportBefore = now - unhandledWait;
12365 errors = arrayUtil.filter(errors, function(obj){
12366 if(obj.timestamp < reportBefore){
12367 logError(obj.error, obj.rejection, obj.deferred);
12368 return false;
12369 }
12370 return true;
12371 });
12372
12373 if(errors.length){
12374 activeTimeout = setTimeout(logRejected, errors[0].timestamp + unhandledWait - now);
12375 }else{
12376 activeTimeout = false;
12377 }
12378 }
12379
12380 return function(Deferred){
12381 // summary:
12382 // Initialize instrumentation for the Deferred class.
12383 // description:
12384 // Initialize instrumentation for the Deferred class.
12385 // Done automatically by `dojo/Deferred` if the
12386 // `deferredInstrumentation` and `useDeferredInstrumentation`
12387 // config options are set.
12388 //
12389 // Sets up `dojo/promise/tracer` to log to the console.
12390 //
12391 // Sets up instrumentation of rejected deferreds so unhandled
12392 // errors are logged to the console.
12393
12394 var usage = has("config-useDeferredInstrumentation");
12395 if(usage){
12396 tracer.on("resolved", lang.hitch(console, "log", "resolved"));
12397 tracer.on("rejected", lang.hitch(console, "log", "rejected"));
12398 tracer.on("progress", lang.hitch(console, "log", "progress"));
12399
12400 var args = [];
12401 if(typeof usage === "string"){
12402 args = usage.split(",");
12403 usage = args.shift();
12404 }
12405 if(usage === "report-rejections"){
12406 Deferred.instrumentRejected = reportRejections;
12407 }else if(usage === "report-unhandled-rejections" || usage === true || usage === 1){
12408 Deferred.instrumentRejected = trackUnhandledRejections;
12409 unhandledWait = parseInt(args[0], 10) || unhandledWait;
12410 }else{
12411 throw new Error("Unsupported instrumentation usage <" + usage + ">");
12412 }
12413 }
12414 };
12415 });
12416
12417 },
12418 'dojo/selector/_loader':function(){
12419 define(["../has", "require"],
12420 function(has, require){
12421
12422 "use strict";
12423 var testDiv = document.createElement("div");
12424 has.add("dom-qsa2.1", !!testDiv.querySelectorAll);
12425 has.add("dom-qsa3", function(){
12426 // test to see if we have a reasonable native selector engine available
12427 try{
12428 testDiv.innerHTML = "<p class='TEST'></p>"; // test kind of from sizzle
12429 // Safari can't handle uppercase or unicode characters when
12430 // in quirks mode, IE8 can't handle pseudos like :empty
12431 return testDiv.querySelectorAll(".TEST:empty").length == 1;
12432 }catch(e){}
12433 });
12434 var fullEngine;
12435 var acme = "./acme", lite = "./lite";
12436 return {
12437 // summary:
12438 // This module handles loading the appropriate selector engine for the given browser
12439
12440 load: function(id, parentRequire, loaded, config){
12441 var req = require;
12442 // here we implement the default logic for choosing a selector engine
12443 id = id == "default" ? has("config-selectorEngine") || "css3" : id;
12444 id = id == "css2" || id == "lite" ? lite :
12445 id == "css2.1" ? has("dom-qsa2.1") ? lite : acme :
12446 id == "css3" ? has("dom-qsa3") ? lite : acme :
12447 id == "acme" ? acme : (req = parentRequire) && id;
12448 if(id.charAt(id.length-1) == '?'){
12449 id = id.substring(0,id.length - 1);
12450 var optionalLoad = true;
12451 }
12452 // the query engine is optional, only load it if a native one is not available or existing one has not been loaded
12453 if(optionalLoad && (has("dom-compliant-qsa") || fullEngine)){
12454 return loaded(fullEngine);
12455 }
12456 // load the referenced selector engine
12457 req([id], function(engine){
12458 if(id != "./lite"){
12459 fullEngine = engine;
12460 }
12461 loaded(engine);
12462 });
12463 }
12464 };
12465 });
12466
12467 },
12468 'dojo/promise/Promise':function(){
12469 define([
12470 "../_base/lang"
12471 ], function(lang){
12472 "use strict";
12473
12474 // module:
12475 // dojo/promise/Promise
12476
12477 function throwAbstract(){
12478 throw new TypeError("abstract");
12479 }
12480
12481 return lang.extend(function Promise(){
12482 // summary:
12483 // The public interface to a deferred.
12484 // description:
12485 // The public interface to a deferred. All promises in Dojo are
12486 // instances of this class.
12487 }, {
12488 then: function(callback, errback, progback){
12489 // summary:
12490 // Add new callbacks to the promise.
12491 // description:
12492 // Add new callbacks to the deferred. Callbacks can be added
12493 // before or after the deferred is fulfilled.
12494 // callback: Function?
12495 // Callback to be invoked when the promise is resolved.
12496 // Receives the resolution value.
12497 // errback: Function?
12498 // Callback to be invoked when the promise is rejected.
12499 // Receives the rejection error.
12500 // progback: Function?
12501 // Callback to be invoked when the promise emits a progress
12502 // update. Receives the progress update.
12503 // returns: dojo/promise/Promise
12504 // Returns a new promise for the result of the callback(s).
12505 // This can be used for chaining many asynchronous operations.
12506
12507 throwAbstract();
12508 },
12509
12510 cancel: function(reason, strict){
12511 // summary:
12512 // Inform the deferred it may cancel its asynchronous operation.
12513 // description:
12514 // Inform the deferred it may cancel its asynchronous operation.
12515 // The deferred's (optional) canceler is invoked and the
12516 // deferred will be left in a rejected state. Can affect other
12517 // promises that originate with the same deferred.
12518 // reason: any
12519 // A message that may be sent to the deferred's canceler,
12520 // explaining why it's being canceled.
12521 // strict: Boolean?
12522 // If strict, will throw an error if the deferred has already
12523 // been fulfilled and consequently cannot be canceled.
12524 // returns: any
12525 // Returns the rejection reason if the deferred was canceled
12526 // normally.
12527
12528 throwAbstract();
12529 },
12530
12531 isResolved: function(){
12532 // summary:
12533 // Checks whether the promise has been resolved.
12534 // returns: Boolean
12535
12536 throwAbstract();
12537 },
12538
12539 isRejected: function(){
12540 // summary:
12541 // Checks whether the promise has been rejected.
12542 // returns: Boolean
12543
12544 throwAbstract();
12545 },
12546
12547 isFulfilled: function(){
12548 // summary:
12549 // Checks whether the promise has been resolved or rejected.
12550 // returns: Boolean
12551
12552 throwAbstract();
12553 },
12554
12555 isCanceled: function(){
12556 // summary:
12557 // Checks whether the promise has been canceled.
12558 // returns: Boolean
12559
12560 throwAbstract();
12561 },
12562
12563 always: function(callbackOrErrback){
12564 // summary:
12565 // Add a callback to be invoked when the promise is resolved
12566 // or rejected.
12567 // callbackOrErrback: Function?
12568 // A function that is used both as a callback and errback.
12569 // returns: dojo/promise/Promise
12570 // Returns a new promise for the result of the callback/errback.
12571
12572 return this.then(callbackOrErrback, callbackOrErrback);
12573 },
12574
12575 otherwise: function(errback){
12576 // summary:
12577 // Add new errbacks to the promise.
12578 // errback: Function?
12579 // Callback to be invoked when the promise is rejected.
12580 // returns: dojo/promise/Promise
12581 // Returns a new promise for the result of the errback.
12582
12583 return this.then(null, errback);
12584 },
12585
12586 trace: function(){
12587 return this;
12588 },
12589
12590 traceRejected: function(){
12591 return this;
12592 },
12593
12594 toString: function(){
12595 // returns: string
12596 // Returns `[object Promise]`.
12597
12598 return "[object Promise]";
12599 }
12600 });
12601 });
12602
12603 },
12604 'dojo/request/watch':function(){
12605 define([
12606 './util',
12607 '../errors/RequestTimeoutError',
12608 '../errors/CancelError',
12609 '../_base/array',
12610 '../_base/window',
12611 '../has!host-browser?dom-addeventlistener?:../on:'
12612 ], function(util, RequestTimeoutError, CancelError, array, win, on){
12613 // avoid setting a timer per request. It degrades performance on IE
12614 // something fierece if we don't use unified loops.
12615 var _inFlightIntvl = null,
12616 _inFlight = [];
12617
12618 function watchInFlight(){
12619 // summary:
12620 // internal method that checks each inflight XMLHttpRequest to see
12621 // if it has completed or if the timeout situation applies.
12622
12623 var now = +(new Date);
12624
12625 // we need manual loop because we often modify _inFlight (and therefore 'i') while iterating
12626 for(var i = 0, dfd; i < _inFlight.length && (dfd = _inFlight[i]); i++){
12627 var response = dfd.response,
12628 options = response.options;
12629 if((dfd.isCanceled && dfd.isCanceled()) || (dfd.isValid && !dfd.isValid(response))){
12630 _inFlight.splice(i--, 1);
12631 watch._onAction && watch._onAction();
12632 }else if(dfd.isReady && dfd.isReady(response)){
12633 _inFlight.splice(i--, 1);
12634 dfd.handleResponse(response);
12635 watch._onAction && watch._onAction();
12636 }else if(dfd.startTime){
12637 // did we timeout?
12638 if(dfd.startTime + (options.timeout || 0) < now){
12639 _inFlight.splice(i--, 1);
12640 // Cancel the request so the io module can do appropriate cleanup.
12641 dfd.cancel(new RequestTimeoutError('Timeout exceeded', response));
12642 watch._onAction && watch._onAction();
12643 }
12644 }
12645 }
12646
12647 watch._onInFlight && watch._onInFlight(dfd);
12648
12649 if(!_inFlight.length){
12650 clearInterval(_inFlightIntvl);
12651 _inFlightIntvl = null;
12652 }
12653 }
12654
12655 function watch(dfd){
12656 // summary:
12657 // Watches the io request represented by dfd to see if it completes.
12658 // dfd: Deferred
12659 // The Deferred object to watch.
12660 // response: Object
12661 // The object used as the value of the request promise.
12662 // validCheck: Function
12663 // Function used to check if the IO request is still valid. Gets the dfd
12664 // object as its only argument.
12665 // ioCheck: Function
12666 // Function used to check if basic IO call worked. Gets the dfd
12667 // object as its only argument.
12668 // resHandle: Function
12669 // Function used to process response. Gets the dfd
12670 // object as its only argument.
12671 if(dfd.response.options.timeout){
12672 dfd.startTime = +(new Date);
12673 }
12674
12675 if(dfd.isFulfilled()){
12676 // bail out if the deferred is already fulfilled
12677 return;
12678 }
12679
12680 _inFlight.push(dfd);
12681 if(!_inFlightIntvl){
12682 _inFlightIntvl = setInterval(watchInFlight, 50);
12683 }
12684
12685 // handle sync requests separately from async:
12686 // http://bugs.dojotoolkit.org/ticket/8467
12687 if(dfd.response.options.sync){
12688 watchInFlight();
12689 }
12690 }
12691
12692 watch.cancelAll = function cancelAll(){
12693 // summary:
12694 // Cancels all pending IO requests, regardless of IO type
12695 try{
12696 array.forEach(_inFlight, function(dfd){
12697 try{
12698 dfd.cancel(new CancelError('All requests canceled.'));
12699 }catch(e){}
12700 });
12701 }catch(e){}
12702 };
12703
12704 if(win && on && win.doc.attachEvent){
12705 // Automatically call cancel all io calls on unload in IE
12706 // http://bugs.dojotoolkit.org/ticket/2357
12707 on(win.global, 'unload', function(){
12708 watch.cancelAll();
12709 });
12710 }
12711
12712 return watch;
12713 });
12714
12715 },
12716 'dojo/on':function(){
12717 define(["./has!dom-addeventlistener?:./aspect", "./_base/kernel", "./has"], function(aspect, dojo, has){
12718
12719 "use strict";
12720 if( 1 ){ // check to make sure we are in a browser, this module should work anywhere
12721 var major = window.ScriptEngineMajorVersion;
12722 has.add("jscript", major && (major() + ScriptEngineMinorVersion() / 10));
12723 has.add("event-orientationchange", has("touch") && !has("android")); // TODO: how do we detect this?
12724 has.add("event-stopimmediatepropagation", window.Event && !!window.Event.prototype && !!window.Event.prototype.stopImmediatePropagation);
12725 }
12726 var on = function(target, type, listener, dontFix){
12727 // summary:
12728 // A function that provides core event listening functionality. With this function
12729 // you can provide a target, event type, and listener to be notified of
12730 // future matching events that are fired.
12731 // target: Element|Object
12732 // This is the target object or DOM element that to receive events from
12733 // type: String|Function
12734 // This is the name of the event to listen for or an extension event type.
12735 // listener: Function
12736 // This is the function that should be called when the event fires.
12737 // returns: Object
12738 // An object with a remove() method that can be used to stop listening for this
12739 // event.
12740 // description:
12741 // To listen for "click" events on a button node, we can do:
12742 // | define(["dojo/on"], function(listen){
12743 // | on(button, "click", clickHandler);
12744 // | ...
12745 // Evented JavaScript objects can also have their own events.
12746 // | var obj = new Evented;
12747 // | on(obj, "foo", fooHandler);
12748 // And then we could publish a "foo" event:
12749 // | on.emit(obj, "foo", {key: "value"});
12750 // We can use extension events as well. For example, you could listen for a tap gesture:
12751 // | define(["dojo/on", "dojo/gesture/tap", function(listen, tap){
12752 // | on(button, tap, tapHandler);
12753 // | ...
12754 // which would trigger fooHandler. Note that for a simple object this is equivalent to calling:
12755 // | obj.onfoo({key:"value"});
12756 // If you use on.emit on a DOM node, it will use native event dispatching when possible.
12757
12758 if(typeof target.on == "function" && typeof type != "function"){
12759 // delegate to the target's on() method, so it can handle it's own listening if it wants
12760 return target.on(type, listener);
12761 }
12762 // delegate to main listener code
12763 return on.parse(target, type, listener, addListener, dontFix, this);
12764 };
12765 on.pausable = function(target, type, listener, dontFix){
12766 // summary:
12767 // This function acts the same as on(), but with pausable functionality. The
12768 // returned signal object has pause() and resume() functions. Calling the
12769 // pause() method will cause the listener to not be called for future events. Calling the
12770 // resume() method will cause the listener to again be called for future events.
12771 var paused;
12772 var signal = on(target, type, function(){
12773 if(!paused){
12774 return listener.apply(this, arguments);
12775 }
12776 }, dontFix);
12777 signal.pause = function(){
12778 paused = true;
12779 };
12780 signal.resume = function(){
12781 paused = false;
12782 };
12783 return signal;
12784 };
12785 on.once = function(target, type, listener, dontFix){
12786 // summary:
12787 // This function acts the same as on(), but will only call the listener once. The
12788 // listener will be called for the first
12789 // event that takes place and then listener will automatically be removed.
12790 var signal = on(target, type, function(){
12791 // remove this listener
12792 signal.remove();
12793 // proceed to call the listener
12794 return listener.apply(this, arguments);
12795 });
12796 return signal;
12797 };
12798 on.parse = function(target, type, listener, addListener, dontFix, matchesTarget){
12799 if(type.call){
12800 // event handler function
12801 // on(node, touch.press, touchListener);
12802 return type.call(matchesTarget, target, listener);
12803 }
12804
12805 if(type.indexOf(",") > -1){
12806 // we allow comma delimited event names, so you can register for multiple events at once
12807 var events = type.split(/\s*,\s*/);
12808 var handles = [];
12809 var i = 0;
12810 var eventName;
12811 while(eventName = events[i++]){
12812 handles.push(addListener(target, eventName, listener, dontFix, matchesTarget));
12813 }
12814 handles.remove = function(){
12815 for(var i = 0; i < handles.length; i++){
12816 handles[i].remove();
12817 }
12818 };
12819 return handles;
12820 }
12821 return addListener(target, type, listener, dontFix, matchesTarget);
12822 };
12823 var touchEvents = /^touch/;
12824 function addListener(target, type, listener, dontFix, matchesTarget){
12825 // event delegation:
12826 var selector = type.match(/(.*):(.*)/);
12827 // if we have a selector:event, the last one is interpreted as an event, and we use event delegation
12828 if(selector){
12829 type = selector[2];
12830 selector = selector[1];
12831 // create the extension event for selectors and directly call it
12832 return on.selector(selector, type).call(matchesTarget, target, listener);
12833 }
12834 // test to see if it a touch event right now, so we don't have to do it every time it fires
12835 if(has("touch")){
12836 if(touchEvents.test(type)){
12837 // touch event, fix it
12838 listener = fixTouchListener(listener);
12839 }
12840 if(!has("event-orientationchange") && (type == "orientationchange")){
12841 //"orientationchange" not supported <= Android 2.1,
12842 //but works through "resize" on window
12843 type = "resize";
12844 target = window;
12845 listener = fixTouchListener(listener);
12846 }
12847 }
12848 if(addStopImmediate){
12849 // add stopImmediatePropagation if it doesn't exist
12850 listener = addStopImmediate(listener);
12851 }
12852 // normal path, the target is |this|
12853 if(target.addEventListener){
12854 // the target has addEventListener, which should be used if available (might or might not be a node, non-nodes can implement this method as well)
12855 // check for capture conversions
12856 var capture = type in captures,
12857 adjustedType = capture ? captures[type] : type;
12858 target.addEventListener(adjustedType, listener, capture);
12859 // create and return the signal
12860 return {
12861 remove: function(){
12862 target.removeEventListener(adjustedType, listener, capture);
12863 }
12864 };
12865 }
12866 type = "on" + type;
12867 if(fixAttach && target.attachEvent){
12868 return fixAttach(target, type, listener);
12869 }
12870 throw new Error("Target must be an event emitter");
12871 }
12872
12873 on.selector = function(selector, eventType, children){
12874 // summary:
12875 // Creates a new extension event with event delegation. This is based on
12876 // the provided event type (can be extension event) that
12877 // only calls the listener when the CSS selector matches the target of the event.
12878 //
12879 // The application must require() an appropriate level of dojo/query to handle the selector.
12880 // selector:
12881 // The CSS selector to use for filter events and determine the |this| of the event listener.
12882 // eventType:
12883 // The event to listen for
12884 // children:
12885 // Indicates if children elements of the selector should be allowed. This defaults to
12886 // true
12887 // example:
12888 // | require(["dojo/on", "dojo/mouse", "dojo/query!css2"], function(listen, mouse){
12889 // | on(node, on.selector(".my-class", mouse.enter), handlerForMyHover);
12890 return function(target, listener){
12891 // if the selector is function, use it to select the node, otherwise use the matches method
12892 var matchesTarget = typeof selector == "function" ? {matches: selector} : this,
12893 bubble = eventType.bubble;
12894 function select(eventTarget){
12895 // see if we have a valid matchesTarget or default to dojo.query
12896 matchesTarget = matchesTarget && matchesTarget.matches ? matchesTarget : dojo.query;
12897 // there is a selector, so make sure it matches
12898 while(!matchesTarget.matches(eventTarget, selector, target)){
12899 if(eventTarget == target || children === false || !(eventTarget = eventTarget.parentNode) || eventTarget.nodeType != 1){ // intentional assignment
12900 return;
12901 }
12902 }
12903 return eventTarget;
12904 }
12905 if(bubble){
12906 // the event type doesn't naturally bubble, but has a bubbling form, use that, and give it the selector so it can perform the select itself
12907 return on(target, bubble(select), listener);
12908 }
12909 // standard event delegation
12910 return on(target, eventType, function(event){
12911 // call select to see if we match
12912 var eventTarget = select(event.target);
12913 // if it matches we call the listener
12914 return eventTarget && listener.call(eventTarget, event);
12915 });
12916 };
12917 };
12918
12919 function syntheticPreventDefault(){
12920 this.cancelable = false;
12921 }
12922 function syntheticStopPropagation(){
12923 this.bubbles = false;
12924 }
12925 var slice = [].slice,
12926 syntheticDispatch = on.emit = function(target, type, event){
12927 // summary:
12928 // Fires an event on the target object.
12929 // target:
12930 // The target object to fire the event on. This can be a DOM element or a plain
12931 // JS object. If the target is a DOM element, native event emiting mechanisms
12932 // are used when possible.
12933 // type:
12934 // The event type name. You can emulate standard native events like "click" and
12935 // "mouseover" or create custom events like "open" or "finish".
12936 // event:
12937 // An object that provides the properties for the event. See https://developer.mozilla.org/en/DOM/event.initEvent
12938 // for some of the properties. These properties are copied to the event object.
12939 // Of particular importance are the cancelable and bubbles properties. The
12940 // cancelable property indicates whether or not the event has a default action
12941 // that can be cancelled. The event is cancelled by calling preventDefault() on
12942 // the event object. The bubbles property indicates whether or not the
12943 // event will bubble up the DOM tree. If bubbles is true, the event will be called
12944 // on the target and then each parent successively until the top of the tree
12945 // is reached or stopPropagation() is called. Both bubbles and cancelable
12946 // default to false.
12947 // returns:
12948 // If the event is cancelable and the event is not cancelled,
12949 // emit will return true. If the event is cancelable and the event is cancelled,
12950 // emit will return false.
12951 // details:
12952 // Note that this is designed to emit events for listeners registered through
12953 // dojo/on. It should actually work with any event listener except those
12954 // added through IE's attachEvent (IE8 and below's non-W3C event emiting
12955 // doesn't support custom event types). It should work with all events registered
12956 // through dojo/on. Also note that the emit method does do any default
12957 // action, it only returns a value to indicate if the default action should take
12958 // place. For example, emiting a keypress event would not cause a character
12959 // to appear in a textbox.
12960 // example:
12961 // To fire our own click event
12962 // | on.emit(dojo.byId("button"), "click", {
12963 // | cancelable: true,
12964 // | bubbles: true,
12965 // | screenX: 33,
12966 // | screenY: 44
12967 // | });
12968 // We can also fire our own custom events:
12969 // | on.emit(dojo.byId("slider"), "slide", {
12970 // | cancelable: true,
12971 // | bubbles: true,
12972 // | direction: "left-to-right"
12973 // | });
12974 var args = slice.call(arguments, 2);
12975 var method = "on" + type;
12976 if("parentNode" in target){
12977 // node (or node-like), create event controller methods
12978 var newEvent = args[0] = {};
12979 for(var i in event){
12980 newEvent[i] = event[i];
12981 }
12982 newEvent.preventDefault = syntheticPreventDefault;
12983 newEvent.stopPropagation = syntheticStopPropagation;
12984 newEvent.target = target;
12985 newEvent.type = type;
12986 event = newEvent;
12987 }
12988 do{
12989 // call any node which has a handler (note that ideally we would try/catch to simulate normal event propagation but that causes too much pain for debugging)
12990 target[method] && target[method].apply(target, args);
12991 // and then continue up the parent node chain if it is still bubbling (if started as bubbles and stopPropagation hasn't been called)
12992 }while(event && event.bubbles && (target = target.parentNode));
12993 return event && event.cancelable && event; // if it is still true (was cancelable and was cancelled), return the event to indicate default action should happen
12994 };
12995 var captures = {};
12996 if(!has("event-stopimmediatepropagation")){
12997 var stopImmediatePropagation =function(){
12998 this.immediatelyStopped = true;
12999 this.modified = true; // mark it as modified so the event will be cached in IE
13000 };
13001 var addStopImmediate = function(listener){
13002 return function(event){
13003 if(!event.immediatelyStopped){// check to make sure it hasn't been stopped immediately
13004 event.stopImmediatePropagation = stopImmediatePropagation;
13005 return listener.apply(this, arguments);
13006 }
13007 };
13008 }
13009 }
13010 if(has("dom-addeventlistener")){
13011 // normalize focusin and focusout
13012 captures = {
13013 focusin: "focus",
13014 focusout: "blur"
13015 };
13016
13017 // emiter that works with native event handling
13018 on.emit = function(target, type, event){
13019 if(target.dispatchEvent && document.createEvent){
13020 // use the native event emiting mechanism if it is available on the target object
13021 // create a generic event
13022 // we could create branch into the different types of event constructors, but
13023 // that would be a lot of extra code, with little benefit that I can see, seems
13024 // best to use the generic constructor and copy properties over, making it
13025 // easy to have events look like the ones created with specific initializers
13026 var nativeEvent = target.ownerDocument.createEvent("HTMLEvents");
13027 nativeEvent.initEvent(type, !!event.bubbles, !!event.cancelable);
13028 // and copy all our properties over
13029 for(var i in event){
13030 var value = event[i];
13031 if(!(i in nativeEvent)){
13032 nativeEvent[i] = event[i];
13033 }
13034 }
13035 return target.dispatchEvent(nativeEvent) && nativeEvent;
13036 }
13037 return syntheticDispatch.apply(on, arguments); // emit for a non-node
13038 };
13039 }else{
13040 // no addEventListener, basically old IE event normalization
13041 on._fixEvent = function(evt, sender){
13042 // summary:
13043 // normalizes properties on the event object including event
13044 // bubbling methods, keystroke normalization, and x/y positions
13045 // evt:
13046 // native event object
13047 // sender:
13048 // node to treat as "currentTarget"
13049 if(!evt){
13050 var w = sender && (sender.ownerDocument || sender.document || sender).parentWindow || window;
13051 evt = w.event;
13052 }
13053 if(!evt){return evt;}
13054 if(lastEvent && evt.type == lastEvent.type){
13055 // should be same event, reuse event object (so it can be augmented)
13056 evt = lastEvent;
13057 }
13058 if(!evt.target){ // check to see if it has been fixed yet
13059 evt.target = evt.srcElement;
13060 evt.currentTarget = (sender || evt.srcElement);
13061 if(evt.type == "mouseover"){
13062 evt.relatedTarget = evt.fromElement;
13063 }
13064 if(evt.type == "mouseout"){
13065 evt.relatedTarget = evt.toElement;
13066 }
13067 if(!evt.stopPropagation){
13068 evt.stopPropagation = stopPropagation;
13069 evt.preventDefault = preventDefault;
13070 }
13071 switch(evt.type){
13072 case "keypress":
13073 var c = ("charCode" in evt ? evt.charCode : evt.keyCode);
13074 if (c==10){
13075 // CTRL-ENTER is CTRL-ASCII(10) on IE, but CTRL-ENTER on Mozilla
13076 c=0;
13077 evt.keyCode = 13;
13078 }else if(c==13||c==27){
13079 c=0; // Mozilla considers ENTER and ESC non-printable
13080 }else if(c==3){
13081 c=99; // Mozilla maps CTRL-BREAK to CTRL-c
13082 }
13083 // Mozilla sets keyCode to 0 when there is a charCode
13084 // but that stops the event on IE.
13085 evt.charCode = c;
13086 _setKeyChar(evt);
13087 break;
13088 }
13089 }
13090 return evt;
13091 };
13092 var lastEvent, IESignal = function(handle){
13093 this.handle = handle;
13094 };
13095 IESignal.prototype.remove = function(){
13096 delete _dojoIEListeners_[this.handle];
13097 };
13098 var fixListener = function(listener){
13099 // this is a minimal function for closing on the previous listener with as few as variables as possible
13100 return function(evt){
13101 evt = on._fixEvent(evt, this);
13102 var result = listener.call(this, evt);
13103 if(evt.modified){
13104 // cache the last event and reuse it if we can
13105 if(!lastEvent){
13106 setTimeout(function(){
13107 lastEvent = null;
13108 });
13109 }
13110 lastEvent = evt;
13111 }
13112 return result;
13113 };
13114 };
13115 var fixAttach = function(target, type, listener){
13116 listener = fixListener(listener);
13117 if(((target.ownerDocument ? target.ownerDocument.parentWindow : target.parentWindow || target.window || window) != top ||
13118 has("jscript") < 5.8) &&
13119 !has("config-_allow_leaks")){
13120 // IE will leak memory on certain handlers in frames (IE8 and earlier) and in unattached DOM nodes for JScript 5.7 and below.
13121 // Here we use global redirection to solve the memory leaks
13122 if(typeof _dojoIEListeners_ == "undefined"){
13123 _dojoIEListeners_ = [];
13124 }
13125 var emiter = target[type];
13126 if(!emiter || !emiter.listeners){
13127 var oldListener = emiter;
13128 emiter = Function('event', 'var callee = arguments.callee; for(var i = 0; i<callee.listeners.length; i++){var listener = _dojoIEListeners_[callee.listeners[i]]; if(listener){listener.call(this,event);}}');
13129 emiter.listeners = [];
13130 target[type] = emiter;
13131 emiter.global = this;
13132 if(oldListener){
13133 emiter.listeners.push(_dojoIEListeners_.push(oldListener) - 1);
13134 }
13135 }
13136 var handle;
13137 emiter.listeners.push(handle = (emiter.global._dojoIEListeners_.push(listener) - 1));
13138 return new IESignal(handle);
13139 }
13140 return aspect.after(target, type, listener, true);
13141 };
13142
13143 var _setKeyChar = function(evt){
13144 evt.keyChar = evt.charCode ? String.fromCharCode(evt.charCode) : '';
13145 evt.charOrCode = evt.keyChar || evt.keyCode;
13146 };
13147 // Called in Event scope
13148 var stopPropagation = function(){
13149 this.cancelBubble = true;
13150 };
13151 var preventDefault = on._preventDefault = function(){
13152 // Setting keyCode to 0 is the only way to prevent certain keypresses (namely
13153 // ctrl-combinations that correspond to menu accelerator keys).
13154 // Otoh, it prevents upstream listeners from getting this information
13155 // Try to split the difference here by clobbering keyCode only for ctrl
13156 // combinations. If you still need to access the key upstream, bubbledKeyCode is
13157 // provided as a workaround.
13158 this.bubbledKeyCode = this.keyCode;
13159 if(this.ctrlKey){
13160 try{
13161 // squelch errors when keyCode is read-only
13162 // (e.g. if keyCode is ctrl or shift)
13163 this.keyCode = 0;
13164 }catch(e){
13165 }
13166 }
13167 this.defaultPrevented = true;
13168 this.returnValue = false;
13169 };
13170 }
13171 if(has("touch")){
13172 var Event = function(){};
13173 var windowOrientation = window.orientation;
13174 var fixTouchListener = function(listener){
13175 return function(originalEvent){
13176 //Event normalization(for ontouchxxx and resize):
13177 //1.incorrect e.pageX|pageY in iOS
13178 //2.there are no "e.rotation", "e.scale" and "onorientationchange" in Andriod
13179 //3.More TBD e.g. force | screenX | screenX | clientX | clientY | radiusX | radiusY
13180
13181 // see if it has already been corrected
13182 var event = originalEvent.corrected;
13183 if(!event){
13184 var type = originalEvent.type;
13185 try{
13186 delete originalEvent.type; // on some JS engines (android), deleting properties make them mutable
13187 }catch(e){}
13188 if(originalEvent.type){
13189 // deleting properties doesn't work (older iOS), have to use delegation
13190 Event.prototype = originalEvent;
13191 var event = new Event;
13192 // have to delegate methods to make them work
13193 event.preventDefault = function(){
13194 originalEvent.preventDefault();
13195 };
13196 event.stopPropagation = function(){
13197 originalEvent.stopPropagation();
13198 };
13199 }else{
13200 // deletion worked, use property as is
13201 event = originalEvent;
13202 event.type = type;
13203 }
13204 originalEvent.corrected = event;
13205 if(type == 'resize'){
13206 if(windowOrientation == window.orientation){
13207 return null;//double tap causes an unexpected 'resize' in Andriod
13208 }
13209 windowOrientation = window.orientation;
13210 event.type = "orientationchange";
13211 return listener.call(this, event);
13212 }
13213 // We use the original event and augment, rather than doing an expensive mixin operation
13214 if(!("rotation" in event)){ // test to see if it has rotation
13215 event.rotation = 0;
13216 event.scale = 1;
13217 }
13218 //use event.changedTouches[0].pageX|pageY|screenX|screenY|clientX|clientY|target
13219 var firstChangeTouch = event.changedTouches[0];
13220 for(var i in firstChangeTouch){ // use for-in, we don't need to have dependency on dojo/_base/lang here
13221 delete event[i]; // delete it first to make it mutable
13222 event[i] = firstChangeTouch[i];
13223 }
13224 }
13225 return listener.call(this, event);
13226 };
13227 };
13228 }
13229 return on;
13230 });
13231
13232 },
13233 'dojo/_base/sniff':function(){
13234 define(["./kernel", "./lang", "../sniff"], function(dojo, lang, has){
13235 // module:
13236 // dojo/_base/sniff
13237
13238 /*=====
13239 return {
13240 // summary:
13241 // Deprecated. New code should use dojo/sniff.
13242 // This module populates the dojo browser version sniffing properties like dojo.isIE.
13243 };
13244 =====*/
13245
13246 if(! 1 ){
13247 return has;
13248 }
13249
13250 // no idea what this is for, or if it's used
13251 dojo._name = "browser";
13252
13253 lang.mixin(dojo, {
13254 // isBrowser: Boolean
13255 // True if the client is a web-browser
13256 isBrowser: true,
13257
13258 // isFF: Number|undefined
13259 // Version as a Number if client is FireFox. undefined otherwise. Corresponds to
13260 // major detected FireFox version (1.5, 2, 3, etc.)
13261 isFF: has("ff"),
13262
13263 // isIE: Number|undefined
13264 // Version as a Number if client is MSIE(PC). undefined otherwise. Corresponds to
13265 // major detected IE version (6, 7, 8, etc.)
13266 isIE: has("ie"),
13267
13268 // isKhtml: Number|undefined
13269 // Version as a Number if client is a KHTML browser. undefined otherwise. Corresponds to major
13270 // detected version.
13271 isKhtml: has("khtml"),
13272
13273 // isWebKit: Number|undefined
13274 // Version as a Number if client is a WebKit-derived browser (Konqueror,
13275 // Safari, Chrome, etc.). undefined otherwise.
13276 isWebKit: has("webkit"),
13277
13278 // isMozilla: Number|undefined
13279 // Version as a Number if client is a Mozilla-based browser (Firefox,
13280 // SeaMonkey). undefined otherwise. Corresponds to major detected version.
13281 isMozilla: has("mozilla"),
13282 // isMoz: Number|undefined
13283 // Version as a Number if client is a Mozilla-based browser (Firefox,
13284 // SeaMonkey). undefined otherwise. Corresponds to major detected version.
13285 isMoz: has("mozilla"),
13286
13287 // isOpera: Number|undefined
13288 // Version as a Number if client is Opera. undefined otherwise. Corresponds to
13289 // major detected version.
13290 isOpera: has("opera"),
13291
13292 // isSafari: Number|undefined
13293 // Version as a Number if client is Safari or iPhone. undefined otherwise.
13294 isSafari: has("safari"),
13295
13296 // isChrome: Number|undefined
13297 // Version as a Number if client is Chrome browser. undefined otherwise.
13298 isChrome: has("chrome"),
13299
13300 // isMac: Boolean
13301 // True if the client runs on Mac
13302 isMac: has("mac"),
13303
13304 // isIos: Boolean
13305 // True if client is iPhone, iPod, or iPad
13306 isIos: has("ios"),
13307
13308 // isAndroid: Number|undefined
13309 // Version as a Number if client is android browser. undefined otherwise.
13310 isAndroid: has("android"),
13311
13312 // isWii: Boolean
13313 // True if client is Wii
13314 isWii: has("wii"),
13315
13316 // isQuirks: Boolean
13317 // Page is in quirks mode.
13318 isQuirks: has("quirks"),
13319
13320 // isAir: Boolean
13321 // True if client is Adobe Air
13322 isAir: has("air")
13323 });
13324
13325
13326 dojo.locale = dojo.locale || (has("ie") ? navigator.userLanguage : navigator.language).toLowerCase();
13327
13328 return has;
13329 });
13330
13331 },
13332 'dojo/errors/create':function(){
13333 define(["../_base/lang"], function(lang){
13334 return function(name, ctor, base, props){
13335 base = base || Error;
13336
13337 var ErrorCtor = function(message){
13338 if(base === Error){
13339 if(Error.captureStackTrace){
13340 Error.captureStackTrace(this, ErrorCtor);
13341 }
13342
13343 // Error.call() operates on the returned error
13344 // object rather than operating on |this|
13345 var err = Error.call(this, message),
13346 prop;
13347
13348 // Copy own properties from err to |this|
13349 for(prop in err){
13350 if(err.hasOwnProperty(prop)){
13351 this[prop] = err[prop];
13352 }
13353 }
13354
13355 // messsage is non-enumerable in ES5
13356 this.message = message;
13357 // stack is non-enumerable in at least Firefox
13358 this.stack = err.stack;
13359 }else{
13360 base.apply(this, arguments);
13361 }
13362 if(ctor){
13363 ctor.apply(this, arguments);
13364 }
13365 };
13366
13367 ErrorCtor.prototype = lang.delegate(base.prototype, props);
13368 ErrorCtor.prototype.name = name;
13369 ErrorCtor.prototype.constructor = ErrorCtor;
13370
13371 return ErrorCtor;
13372 };
13373 });
13374
13375 },
13376 'dojo/_base/array':function(){
13377 define(["./kernel", "../has", "./lang"], function(dojo, has, lang){
13378 // module:
13379 // dojo/_base/array
13380
13381 // our old simple function builder stuff
13382 var cache = {}, u;
13383
13384 function buildFn(fn){
13385 return cache[fn] = new Function("item", "index", "array", fn); // Function
13386 }
13387 // magic snippet: if(typeof fn == "string") fn = cache[fn] || buildFn(fn);
13388
13389 // every & some
13390
13391 function everyOrSome(some){
13392 var every = !some;
13393 return function(a, fn, o){
13394 var i = 0, l = a && a.length || 0, result;
13395 if(l && typeof a == "string") a = a.split("");
13396 if(typeof fn == "string") fn = cache[fn] || buildFn(fn);
13397 if(o){
13398 for(; i < l; ++i){
13399 result = !fn.call(o, a[i], i, a);
13400 if(some ^ result){
13401 return !result;
13402 }
13403 }
13404 }else{
13405 for(; i < l; ++i){
13406 result = !fn(a[i], i, a);
13407 if(some ^ result){
13408 return !result;
13409 }
13410 }
13411 }
13412 return every; // Boolean
13413 };
13414 }
13415
13416 // indexOf, lastIndexOf
13417
13418 function index(up){
13419 var delta = 1, lOver = 0, uOver = 0;
13420 if(!up){
13421 delta = lOver = uOver = -1;
13422 }
13423 return function(a, x, from, last){
13424 if(last && delta > 0){
13425 // TODO: why do we use a non-standard signature? why do we need "last"?
13426 return array.lastIndexOf(a, x, from);
13427 }
13428 var l = a && a.length || 0, end = up ? l + uOver : lOver, i;
13429 if(from === u){
13430 i = up ? lOver : l + uOver;
13431 }else{
13432 if(from < 0){
13433 i = l + from;
13434 if(i < 0){
13435 i = lOver;
13436 }
13437 }else{
13438 i = from >= l ? l + uOver : from;
13439 }
13440 }
13441 if(l && typeof a == "string") a = a.split("");
13442 for(; i != end; i += delta){
13443 if(a[i] == x){
13444 return i; // Number
13445 }
13446 }
13447 return -1; // Number
13448 };
13449 }
13450
13451 var array = {
13452 // summary:
13453 // The Javascript v1.6 array extensions.
13454
13455 every: everyOrSome(false),
13456 /*=====
13457 every: function(arr, callback, thisObject){
13458 // summary:
13459 // Determines whether or not every item in arr satisfies the
13460 // condition implemented by callback.
13461 // arr: Array|String
13462 // the array to iterate on. If a string, operates on individual characters.
13463 // callback: Function|String
13464 // a function is invoked with three arguments: item, index,
13465 // and array and returns true if the condition is met.
13466 // thisObject: Object?
13467 // may be used to scope the call to callback
13468 // returns: Boolean
13469 // description:
13470 // This function corresponds to the JavaScript 1.6 Array.every() method, with one difference: when
13471 // run over sparse arrays, this implementation passes the "holes" in the sparse array to
13472 // the callback function with a value of undefined. JavaScript 1.6's every skips the holes in the sparse array.
13473 // For more details, see:
13474 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/every
13475 // example:
13476 // | // returns false
13477 // | array.every([1, 2, 3, 4], function(item){ return item>1; });
13478 // example:
13479 // | // returns true
13480 // | array.every([1, 2, 3, 4], function(item){ return item>0; });
13481 },
13482 =====*/
13483
13484 some: everyOrSome(true),
13485 /*=====
13486 some: function(arr, callback, thisObject){
13487 // summary:
13488 // Determines whether or not any item in arr satisfies the
13489 // condition implemented by callback.
13490 // arr: Array|String
13491 // the array to iterate over. If a string, operates on individual characters.
13492 // callback: Function|String
13493 // a function is invoked with three arguments: item, index,
13494 // and array and returns true if the condition is met.
13495 // thisObject: Object?
13496 // may be used to scope the call to callback
13497 // returns: Boolean
13498 // description:
13499 // This function corresponds to the JavaScript 1.6 Array.some() method, with one difference: when
13500 // run over sparse arrays, this implementation passes the "holes" in the sparse array to
13501 // the callback function with a value of undefined. JavaScript 1.6's some skips the holes in the sparse array.
13502 // For more details, see:
13503 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/some
13504 // example:
13505 // | // is true
13506 // | array.some([1, 2, 3, 4], function(item){ return item>1; });
13507 // example:
13508 // | // is false
13509 // | array.some([1, 2, 3, 4], function(item){ return item<1; });
13510 },
13511 =====*/
13512
13513 indexOf: index(true),
13514 /*=====
13515 indexOf: function(arr, value, fromIndex, findLast){
13516 // summary:
13517 // locates the first index of the provided value in the
13518 // passed array. If the value is not found, -1 is returned.
13519 // description:
13520 // This method corresponds to the JavaScript 1.6 Array.indexOf method, with one difference: when
13521 // run over sparse arrays, the Dojo function invokes the callback for every index whereas JavaScript
13522 // 1.6's indexOf skips the holes in the sparse array.
13523 // For details on this method, see:
13524 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/indexOf
13525 // arr: Array
13526 // value: Object
13527 // fromIndex: Integer?
13528 // findLast: Boolean?
13529 // returns: Number
13530 },
13531 =====*/
13532
13533 lastIndexOf: index(false),
13534 /*=====
13535 lastIndexOf: function(arr, value, fromIndex){
13536 // summary:
13537 // locates the last index of the provided value in the passed
13538 // array. If the value is not found, -1 is returned.
13539 // description:
13540 // This method corresponds to the JavaScript 1.6 Array.lastIndexOf method, with one difference: when
13541 // run over sparse arrays, the Dojo function invokes the callback for every index whereas JavaScript
13542 // 1.6's lastIndexOf skips the holes in the sparse array.
13543 // For details on this method, see:
13544 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/lastIndexOf
13545 // arr: Array,
13546 // value: Object,
13547 // fromIndex: Integer?
13548 // returns: Number
13549 },
13550 =====*/
13551
13552 forEach: function(arr, callback, thisObject){
13553 // summary:
13554 // for every item in arr, callback is invoked. Return values are ignored.
13555 // If you want to break out of the loop, consider using array.every() or array.some().
13556 // forEach does not allow breaking out of the loop over the items in arr.
13557 // arr:
13558 // the array to iterate over. If a string, operates on individual characters.
13559 // callback:
13560 // a function is invoked with three arguments: item, index, and array
13561 // thisObject:
13562 // may be used to scope the call to callback
13563 // description:
13564 // This function corresponds to the JavaScript 1.6 Array.forEach() method, with one difference: when
13565 // run over sparse arrays, this implementation passes the "holes" in the sparse array to
13566 // the callback function with a value of undefined. JavaScript 1.6's forEach skips the holes in the sparse array.
13567 // For more details, see:
13568 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/forEach
13569 // example:
13570 // | // log out all members of the array:
13571 // | array.forEach(
13572 // | [ "thinger", "blah", "howdy", 10 ],
13573 // | function(item){
13574 // | console.log(item);
13575 // | }
13576 // | );
13577 // example:
13578 // | // log out the members and their indexes
13579 // | array.forEach(
13580 // | [ "thinger", "blah", "howdy", 10 ],
13581 // | function(item, idx, arr){
13582 // | console.log(item, "at index:", idx);
13583 // | }
13584 // | );
13585 // example:
13586 // | // use a scoped object member as the callback
13587 // |
13588 // | var obj = {
13589 // | prefix: "logged via obj.callback:",
13590 // | callback: function(item){
13591 // | console.log(this.prefix, item);
13592 // | }
13593 // | };
13594 // |
13595 // | // specifying the scope function executes the callback in that scope
13596 // | array.forEach(
13597 // | [ "thinger", "blah", "howdy", 10 ],
13598 // | obj.callback,
13599 // | obj
13600 // | );
13601 // |
13602 // | // alternately, we can accomplish the same thing with lang.hitch()
13603 // | array.forEach(
13604 // | [ "thinger", "blah", "howdy", 10 ],
13605 // | lang.hitch(obj, "callback")
13606 // | );
13607 // arr: Array|String
13608 // callback: Function|String
13609 // thisObject: Object?
13610
13611 var i = 0, l = arr && arr.length || 0;
13612 if(l && typeof arr == "string") arr = arr.split("");
13613 if(typeof callback == "string") callback = cache[callback] || buildFn(callback);
13614 if(thisObject){
13615 for(; i < l; ++i){
13616 callback.call(thisObject, arr[i], i, arr);
13617 }
13618 }else{
13619 for(; i < l; ++i){
13620 callback(arr[i], i, arr);
13621 }
13622 }
13623 },
13624
13625 map: function(arr, callback, thisObject, Ctr){
13626 // summary:
13627 // applies callback to each element of arr and returns
13628 // an Array with the results
13629 // arr: Array|String
13630 // the array to iterate on. If a string, operates on
13631 // individual characters.
13632 // callback: Function|String
13633 // a function is invoked with three arguments, (item, index,
13634 // array), and returns a value
13635 // thisObject: Object?
13636 // may be used to scope the call to callback
13637 // returns: Array
13638 // description:
13639 // This function corresponds to the JavaScript 1.6 Array.map() method, with one difference: when
13640 // run over sparse arrays, this implementation passes the "holes" in the sparse array to
13641 // the callback function with a value of undefined. JavaScript 1.6's map skips the holes in the sparse array.
13642 // For more details, see:
13643 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map
13644 // example:
13645 // | // returns [2, 3, 4, 5]
13646 // | array.map([1, 2, 3, 4], function(item){ return item+1 });
13647
13648 // TODO: why do we have a non-standard signature here? do we need "Ctr"?
13649 var i = 0, l = arr && arr.length || 0, out = new (Ctr || Array)(l);
13650 if(l && typeof arr == "string") arr = arr.split("");
13651 if(typeof callback == "string") callback = cache[callback] || buildFn(callback);
13652 if(thisObject){
13653 for(; i < l; ++i){
13654 out[i] = callback.call(thisObject, arr[i], i, arr);
13655 }
13656 }else{
13657 for(; i < l; ++i){
13658 out[i] = callback(arr[i], i, arr);
13659 }
13660 }
13661 return out; // Array
13662 },
13663
13664 filter: function(arr, callback, thisObject){
13665 // summary:
13666 // Returns a new Array with those items from arr that match the
13667 // condition implemented by callback.
13668 // arr: Array
13669 // the array to iterate over.
13670 // callback: Function|String
13671 // a function that is invoked with three arguments (item,
13672 // index, array). The return of this function is expected to
13673 // be a boolean which determines whether the passed-in item
13674 // will be included in the returned array.
13675 // thisObject: Object?
13676 // may be used to scope the call to callback
13677 // returns: Array
13678 // description:
13679 // This function corresponds to the JavaScript 1.6 Array.filter() method, with one difference: when
13680 // run over sparse arrays, this implementation passes the "holes" in the sparse array to
13681 // the callback function with a value of undefined. JavaScript 1.6's filter skips the holes in the sparse array.
13682 // For more details, see:
13683 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/filter
13684 // example:
13685 // | // returns [2, 3, 4]
13686 // | array.filter([1, 2, 3, 4], function(item){ return item>1; });
13687
13688 // TODO: do we need "Ctr" here like in map()?
13689 var i = 0, l = arr && arr.length || 0, out = [], value;
13690 if(l && typeof arr == "string") arr = arr.split("");
13691 if(typeof callback == "string") callback = cache[callback] || buildFn(callback);
13692 if(thisObject){
13693 for(; i < l; ++i){
13694 value = arr[i];
13695 if(callback.call(thisObject, value, i, arr)){
13696 out.push(value);
13697 }
13698 }
13699 }else{
13700 for(; i < l; ++i){
13701 value = arr[i];
13702 if(callback(value, i, arr)){
13703 out.push(value);
13704 }
13705 }
13706 }
13707 return out; // Array
13708 },
13709
13710 clearCache: function(){
13711 cache = {};
13712 }
13713 };
13714
13715
13716 1 && lang.mixin(dojo, array);
13717
13718 return array;
13719 });
13720
13721 },
13722 'dojo/_base/json':function(){
13723 define(["./kernel", "../json"], function(dojo, json){
13724
13725 // module:
13726 // dojo/_base/json
13727
13728 /*=====
13729 return {
13730 // summary:
13731 // This module defines the dojo JSON API.
13732 };
13733 =====*/
13734
13735 dojo.fromJson = function(/*String*/ js){
13736 // summary:
13737 // Parses a JavaScript expression and returns a JavaScript value.
13738 // description:
13739 // Throws for invalid JavaScript expressions. It does not use a strict JSON parser. It
13740 // always delegates to eval(). The content passed to this method must therefore come
13741 // from a trusted source.
13742 // It is recommend that you use dojo/json's parse function for an
13743 // implementation uses the (faster) native JSON parse when available.
13744 // js:
13745 // a string literal of a JavaScript expression, for instance:
13746 // `'{ "foo": [ "bar", 1, { "baz": "thud" } ] }'`
13747
13748 return eval("(" + js + ")"); // Object
13749 };
13750
13751 /*=====
13752 dojo._escapeString = function(){
13753 // summary:
13754 // Adds escape sequences for non-visual characters, double quote and
13755 // backslash and surrounds with double quotes to form a valid string
13756 // literal.
13757 };
13758 =====*/
13759 dojo._escapeString = json.stringify; // just delegate to json.stringify
13760
13761 dojo.toJsonIndentStr = "\t";
13762 dojo.toJson = function(/*Object*/ it, /*Boolean?*/ prettyPrint){
13763 // summary:
13764 // Returns a [JSON](http://json.org) serialization of an object.
13765 // description:
13766 // Returns a [JSON](http://json.org) serialization of an object.
13767 // Note that this doesn't check for infinite recursion, so don't do that!
13768 // It is recommend that you use dojo/json's stringify function for an lighter
13769 // and faster implementation that matches the native JSON API and uses the
13770 // native JSON serializer when available.
13771 // it:
13772 // an object to be serialized. Objects may define their own
13773 // serialization via a special "__json__" or "json" function
13774 // property. If a specialized serializer has been defined, it will
13775 // be used as a fallback.
13776 // Note that in 1.6, toJson would serialize undefined, but this no longer supported
13777 // since it is not supported by native JSON serializer.
13778 // prettyPrint:
13779 // if true, we indent objects and arrays to make the output prettier.
13780 // The variable `dojo.toJsonIndentStr` is used as the indent string --
13781 // to use something other than the default (tab), change that variable
13782 // before calling dojo.toJson().
13783 // Note that if native JSON support is available, it will be used for serialization,
13784 // and native implementations vary on the exact spacing used in pretty printing.
13785 // returns:
13786 // A JSON string serialization of the passed-in object.
13787 // example:
13788 // simple serialization of a trivial object
13789 // | var jsonStr = dojo.toJson({ howdy: "stranger!", isStrange: true });
13790 // | doh.is('{"howdy":"stranger!","isStrange":true}', jsonStr);
13791 // example:
13792 // a custom serializer for an objects of a particular class:
13793 // | dojo.declare("Furby", null, {
13794 // | furbies: "are strange",
13795 // | furbyCount: 10,
13796 // | __json__: function(){
13797 // | },
13798 // | });
13799
13800 // use dojo/json
13801 return json.stringify(it, function(key, value){
13802 if(value){
13803 var tf = value.__json__||value.json;
13804 if(typeof tf == "function"){
13805 return tf.call(value);
13806 }
13807 }
13808 return value;
13809 }, prettyPrint && dojo.toJsonIndentStr); // String
13810 };
13811
13812 return dojo;
13813 });
13814
13815 },
13816 'dojo/_base/window':function(){
13817 define("dojo/_base/window", ["./kernel", "./lang", "../sniff"], function(dojo, lang, has){
13818 // module:
13819 // dojo/_base/window
13820
13821 var ret = {
13822 // summary:
13823 // API to save/set/restore the global/document scope.
13824
13825 global: dojo.global,
13826 /*=====
13827 global: {
13828 // summary:
13829 // Alias for the current window. 'global' can be modified
13830 // for temporary context shifting. See also withGlobal().
13831 // description:
13832 // Use this rather than referring to 'window' to ensure your code runs
13833 // correctly in managed contexts.
13834 },
13835 =====*/
13836
13837 doc: this["document"] || null,
13838 /*=====
13839 doc: {
13840 // summary:
13841 // Alias for the current document. 'doc' can be modified
13842 // for temporary context shifting. See also withDoc().
13843 // description:
13844 // Use this rather than referring to 'window.document' to ensure your code runs
13845 // correctly in managed contexts.
13846 // example:
13847 // | n.appendChild(dojo.doc.createElement('div'));
13848 },
13849 =====*/
13850
13851 body: function(/*Document?*/ doc){
13852 // summary:
13853 // Return the body element of the specified document or of dojo/_base/window::doc.
13854 // example:
13855 // | win.body().appendChild(dojo.doc.createElement('div'));
13856
13857 // Note: document.body is not defined for a strict xhtml document
13858 // Would like to memoize this, but dojo.doc can change vi dojo.withDoc().
13859 doc = doc || dojo.doc;
13860 return doc.body || doc.getElementsByTagName("body")[0]; // Node
13861 },
13862
13863 setContext: function(/*Object*/ globalObject, /*DocumentElement*/ globalDocument){
13864 // summary:
13865 // changes the behavior of many core Dojo functions that deal with
13866 // namespace and DOM lookup, changing them to work in a new global
13867 // context (e.g., an iframe). The varibles dojo.global and dojo.doc
13868 // are modified as a result of calling this function and the result of
13869 // `dojo.body()` likewise differs.
13870 dojo.global = ret.global = globalObject;
13871 dojo.doc = ret.doc = globalDocument;
13872 },
13873
13874 withGlobal: function( /*Object*/ globalObject,
13875 /*Function*/ callback,
13876 /*Object?*/ thisObject,
13877 /*Array?*/ cbArguments){
13878 // summary:
13879 // Invoke callback with globalObject as dojo.global and
13880 // globalObject.document as dojo.doc.
13881 // description:
13882 // Invoke callback with globalObject as dojo.global and
13883 // globalObject.document as dojo.doc. If provided, globalObject
13884 // will be executed in the context of object thisObject
13885 // When callback() returns or throws an error, the dojo.global
13886 // and dojo.doc will be restored to its previous state.
13887
13888 var oldGlob = dojo.global;
13889 try{
13890 dojo.global = ret.global = globalObject;
13891 return ret.withDoc.call(null, globalObject.document, callback, thisObject, cbArguments);
13892 }finally{
13893 dojo.global = ret.global = oldGlob;
13894 }
13895 },
13896
13897 withDoc: function( /*DocumentElement*/ documentObject,
13898 /*Function*/ callback,
13899 /*Object?*/ thisObject,
13900 /*Array?*/ cbArguments){
13901 // summary:
13902 // Invoke callback with documentObject as dojo/_base/window::doc.
13903 // description:
13904 // Invoke callback with documentObject as dojo/_base/window::doc. If provided,
13905 // callback will be executed in the context of object thisObject
13906 // When callback() returns or throws an error, the dojo/_base/window::doc will
13907 // be restored to its previous state.
13908
13909 var oldDoc = ret.doc,
13910 oldQ = has("quirks"),
13911 oldIE = has("ie"), isIE, mode, pwin;
13912
13913 try{
13914 dojo.doc = ret.doc = documentObject;
13915 // update dojo.isQuirks and the value of the has feature "quirks".
13916 // remove setting dojo.isQuirks and dojo.isIE for 2.0
13917 dojo.isQuirks = has.add("quirks", dojo.doc.compatMode == "BackCompat", true, true); // no need to check for QuirksMode which was Opera 7 only
13918
13919 if(has("ie")){
13920 if((pwin = documentObject.parentWindow) && pwin.navigator){
13921 // re-run IE detection logic and update dojo.isIE / has("ie")
13922 // (the only time parentWindow/navigator wouldn't exist is if we were not
13923 // passed an actual legitimate document object)
13924 isIE = parseFloat(pwin.navigator.appVersion.split("MSIE ")[1]) || undefined;
13925 mode = documentObject.documentMode;
13926 if(mode && mode != 5 && Math.floor(isIE) != mode){
13927 isIE = mode;
13928 }
13929 dojo.isIE = has.add("ie", isIE, true, true);
13930 }
13931 }
13932
13933 if(thisObject && typeof callback == "string"){
13934 callback = thisObject[callback];
13935 }
13936
13937 return callback.apply(thisObject, cbArguments || []);
13938 }finally{
13939 dojo.doc = ret.doc = oldDoc;
13940 dojo.isQuirks = has.add("quirks", oldQ, true, true);
13941 dojo.isIE = has.add("ie", oldIE, true, true);
13942 }
13943 }
13944 };
13945
13946 1 && lang.mixin(dojo, ret);
13947
13948 return ret;
13949
13950 });
13951
13952 },
13953 'dojo/dom-class':function(){
13954 define(["./_base/lang", "./_base/array", "./dom"], function(lang, array, dom){
13955 // module:
13956 // dojo/dom-class
13957
13958 var className = "className";
13959
13960 /* Part I of classList-based implementation is preserved here for posterity
13961 var classList = "classList";
13962 has.add("dom-classList", function(){
13963 return classList in document.createElement("p");
13964 });
13965 */
13966
13967 // =============================
13968 // (CSS) Class Functions
13969 // =============================
13970
13971 var cls, // exports object
13972 spaces = /\s+/, a1 = [""];
13973
13974 function str2array(s){
13975 if(typeof s == "string" || s instanceof String){
13976 if(s && !spaces.test(s)){
13977 a1[0] = s;
13978 return a1;
13979 }
13980 var a = s.split(spaces);
13981 if(a.length && !a[0]){
13982 a.shift();
13983 }
13984 if(a.length && !a[a.length - 1]){
13985 a.pop();
13986 }
13987 return a;
13988 }
13989 // assumed to be an array
13990 if(!s){
13991 return [];
13992 }
13993 return array.filter(s, function(x){ return x; });
13994 }
13995
13996 /* Part II of classList-based implementation is preserved here for posterity
13997 if(has("dom-classList")){
13998 // new classList version
13999 cls = {
14000 contains: function containsClass(node, classStr){
14001 var clslst = classStr && dom.byId(node)[classList];
14002 return clslst && clslst.contains(classStr); // Boolean
14003 },
14004
14005 add: function addClass(node, classStr){
14006 node = dom.byId(node);
14007 classStr = str2array(classStr);
14008 for(var i = 0, len = classStr.length; i < len; ++i){
14009 node[classList].add(classStr[i]);
14010 }
14011 },
14012
14013 remove: function removeClass(node, classStr){
14014 node = dom.byId(node);
14015 if(classStr === undefined){
14016 node[className] = "";
14017 }else{
14018 classStr = str2array(classStr);
14019 for(var i = 0, len = classStr.length; i < len; ++i){
14020 node[classList].remove(classStr[i]);
14021 }
14022 }
14023 },
14024
14025 replace: function replaceClass(node, addClassStr, removeClassStr){
14026 node = dom.byId(node);
14027 if(removeClassStr === undefined){
14028 node[className] = "";
14029 }else{
14030 removeClassStr = str2array(removeClassStr);
14031 for(var i = 0, len = removeClassStr.length; i < len; ++i){
14032 node[classList].remove(removeClassStr[i]);
14033 }
14034 }
14035 addClassStr = str2array(addClassStr);
14036 for(i = 0, len = addClassStr.length; i < len; ++i){
14037 node[classList].add(addClassStr[i]);
14038 }
14039 },
14040
14041 toggle: function toggleClass(node, classStr, condition){
14042 node = dom.byId(node);
14043 if(condition === undefined){
14044 classStr = str2array(classStr);
14045 for(var i = 0, len = classStr.length; i < len; ++i){
14046 node[classList].toggle(classStr[i]);
14047 }
14048 }else{
14049 cls[condition ? "add" : "remove"](node, classStr);
14050 }
14051 return condition; // Boolean
14052 }
14053 }
14054 }
14055 */
14056
14057 // regular DOM version
14058 var fakeNode = {}; // for effective replacement
14059 cls = {
14060 // summary:
14061 // This module defines the core dojo DOM class API.
14062
14063 contains: function containsClass(/*DomNode|String*/ node, /*String*/ classStr){
14064 // summary:
14065 // Returns whether or not the specified classes are a portion of the
14066 // class list currently applied to the node.
14067 // node: String|DOMNode
14068 // String ID or DomNode reference to check the class for.
14069 // classStr: String
14070 // A string class name to look for.
14071 // example:
14072 // Do something if a node with id="someNode" has class="aSillyClassName" present
14073 // | if(dojo.hasClass("someNode","aSillyClassName")){ ... }
14074
14075 return ((" " + dom.byId(node)[className] + " ").indexOf(" " + classStr + " ") >= 0); // Boolean
14076 },
14077
14078 add: function addClass(/*DomNode|String*/ node, /*String|Array*/ classStr){
14079 // summary:
14080 // Adds the specified classes to the end of the class list on the
14081 // passed node. Will not re-apply duplicate classes.
14082 //
14083 // node: String|DOMNode
14084 // String ID or DomNode reference to add a class string too
14085 //
14086 // classStr: String|Array
14087 // A String class name to add, or several space-separated class names,
14088 // or an array of class names.
14089 //
14090 // example:
14091 // Add a class to some node:
14092 // | require(["dojo/dom-class"], function(domClass){
14093 // | domClass.add("someNode", "anewClass");
14094 // | });
14095 //
14096 // example:
14097 // Add two classes at once:
14098 // | require(["dojo/dom-class"], function(domClass){
14099 // | domClass.add("someNode", "firstClass secondClass");
14100 // | });
14101 //
14102 // example:
14103 // Add two classes at once (using array):
14104 // | require(["dojo/dom-class"], function(domClass){
14105 // | domClass.add("someNode", ["firstClass", "secondClass"]);
14106 // | });
14107 //
14108 // example:
14109 // Available in `dojo/NodeList` for multiple additions
14110 // | require(["dojo/query"], function(query){
14111 // | query("ul > li").addClass("firstLevel");
14112 // | });
14113
14114 node = dom.byId(node);
14115 classStr = str2array(classStr);
14116 var cls = node[className], oldLen;
14117 cls = cls ? " " + cls + " " : " ";
14118 oldLen = cls.length;
14119 for(var i = 0, len = classStr.length, c; i < len; ++i){
14120 c = classStr[i];
14121 if(c && cls.indexOf(" " + c + " ") < 0){
14122 cls += c + " ";
14123 }
14124 }
14125 if(oldLen < cls.length){
14126 node[className] = cls.substr(1, cls.length - 2);
14127 }
14128 },
14129
14130 remove: function removeClass(/*DomNode|String*/ node, /*String|Array?*/ classStr){
14131 // summary:
14132 // Removes the specified classes from node. No `contains()`
14133 // check is required.
14134 //
14135 // node: String|DOMNode
14136 // String ID or DomNode reference to remove the class from.
14137 //
14138 // classStr: String|Array
14139 // An optional String class name to remove, or several space-separated
14140 // class names, or an array of class names. If omitted, all class names
14141 // will be deleted.
14142 //
14143 // example:
14144 // Remove a class from some node:
14145 // | require(["dojo/dom-class"], function(domClass){
14146 // | domClass.remove("someNode", "firstClass");
14147 // | });
14148 //
14149 // example:
14150 // Remove two classes from some node:
14151 // | require(["dojo/dom-class"], function(domClass){
14152 // | domClass.remove("someNode", "firstClass secondClass");
14153 // | });
14154 //
14155 // example:
14156 // Remove two classes from some node (using array):
14157 // | require(["dojo/dom-class"], function(domClass){
14158 // | domClass.remove("someNode", ["firstClass", "secondClass"]);
14159 // | });
14160 //
14161 // example:
14162 // Remove all classes from some node:
14163 // | require(["dojo/dom-class"], function(domClass){
14164 // | domClass.remove("someNode");
14165 // | });
14166 //
14167 // example:
14168 // Available in `dojo/NodeList` for multiple removal
14169 // | require(["dojo/query"], function(query){
14170 // | query("ul > li").removeClass("foo");
14171 // | });
14172
14173 node = dom.byId(node);
14174 var cls;
14175 if(classStr !== undefined){
14176 classStr = str2array(classStr);
14177 cls = " " + node[className] + " ";
14178 for(var i = 0, len = classStr.length; i < len; ++i){
14179 cls = cls.replace(" " + classStr[i] + " ", " ");
14180 }
14181 cls = lang.trim(cls);
14182 }else{
14183 cls = "";
14184 }
14185 if(node[className] != cls){ node[className] = cls; }
14186 },
14187
14188 replace: function replaceClass(/*DomNode|String*/ node, /*String|Array*/ addClassStr, /*String|Array?*/ removeClassStr){
14189 // summary:
14190 // Replaces one or more classes on a node if not present.
14191 // Operates more quickly than calling dojo.removeClass and dojo.addClass
14192 //
14193 // node: String|DOMNode
14194 // String ID or DomNode reference to remove the class from.
14195 //
14196 // addClassStr: String|Array
14197 // A String class name to add, or several space-separated class names,
14198 // or an array of class names.
14199 //
14200 // removeClassStr: String|Array?
14201 // A String class name to remove, or several space-separated class names,
14202 // or an array of class names.
14203 //
14204 // example:
14205 // | require(["dojo/dom-class"], function(domClass){
14206 // | domClass.replace("someNode", "add1 add2", "remove1 remove2");
14207 // | });
14208 //
14209 // example:
14210 // Replace all classes with addMe
14211 // | require(["dojo/dom-class"], function(domClass){
14212 // | domClass.replace("someNode", "addMe");
14213 // | });
14214 //
14215 // example:
14216 // Available in `dojo/NodeList` for multiple toggles
14217 // | require(["dojo/query"], function(query){
14218 // | query(".findMe").replaceClass("addMe", "removeMe");
14219 // | });
14220
14221 node = dom.byId(node);
14222 fakeNode[className] = node[className];
14223 cls.remove(fakeNode, removeClassStr);
14224 cls.add(fakeNode, addClassStr);
14225 if(node[className] !== fakeNode[className]){
14226 node[className] = fakeNode[className];
14227 }
14228 },
14229
14230 toggle: function toggleClass(/*DomNode|String*/ node, /*String|Array*/ classStr, /*Boolean?*/ condition){
14231 // summary:
14232 // Adds a class to node if not present, or removes if present.
14233 // Pass a boolean condition if you want to explicitly add or remove.
14234 // Returns the condition that was specified directly or indirectly.
14235 //
14236 // node: String|DOMNode
14237 // String ID or DomNode reference to toggle a class string
14238 //
14239 // classStr: String|Array
14240 // A String class name to toggle, or several space-separated class names,
14241 // or an array of class names.
14242 //
14243 // condition:
14244 // If passed, true means to add the class, false means to remove.
14245 // Otherwise dojo.hasClass(node, classStr) is used to detect the class presence.
14246 //
14247 // example:
14248 // | require(["dojo/dom-class"], function(domClass){
14249 // | domClass.toggle("someNode", "hovered");
14250 // | });
14251 //
14252 // example:
14253 // Forcefully add a class
14254 // | require(["dojo/dom-class"], function(domClass){
14255 // | domClass.toggle("someNode", "hovered", true);
14256 // | });
14257 //
14258 // example:
14259 // Available in `dojo/NodeList` for multiple toggles
14260 // | require(["dojo/query"], function(query){
14261 // | query(".toggleMe").toggleClass("toggleMe");
14262 // | });
14263
14264 node = dom.byId(node);
14265 if(condition === undefined){
14266 classStr = str2array(classStr);
14267 for(var i = 0, len = classStr.length, c; i < len; ++i){
14268 c = classStr[i];
14269 cls[cls.contains(node, c) ? "remove" : "add"](node, c);
14270 }
14271 }else{
14272 cls[condition ? "add" : "remove"](node, classStr);
14273 }
14274 return condition; // Boolean
14275 }
14276 };
14277
14278 return cls;
14279 });
14280
14281 },
14282 'dojo/_base/config':function(){
14283 define(["../has", "require"], function(has, require){
14284 // module:
14285 // dojo/_base/config
14286
14287 /*=====
14288 return {
14289 // summary:
14290 // This module defines the user configuration during bootstrap.
14291 // description:
14292 // By defining user configuration as a module value, an entire configuration can be specified in a build,
14293 // thereby eliminating the need for sniffing and or explicitly setting in the global variable dojoConfig.
14294 // Also, when multiple instances of dojo exist in a single application, each will necessarily be located
14295 // at an unique absolute module identifier as given by the package configuration. Implementing configuration
14296 // as a module allows for specifying unique, per-instance configurations.
14297 // example:
14298 // Create a second instance of dojo with a different, instance-unique configuration (assume the loader and
14299 // dojo.js are already loaded).
14300 // | // specify a configuration that creates a new instance of dojo at the absolute module identifier "myDojo"
14301 // | require({
14302 // | packages:[{
14303 // | name:"myDojo",
14304 // | location:".", //assume baseUrl points to dojo.js
14305 // | }]
14306 // | });
14307 // |
14308 // | // specify a configuration for the myDojo instance
14309 // | define("myDojo/config", {
14310 // | // normal configuration variables go here, e.g.,
14311 // | locale:"fr-ca"
14312 // | });
14313 // |
14314 // | // load and use the new instance of dojo
14315 // | require(["myDojo"], function(dojo){
14316 // | // dojo is the new instance of dojo
14317 // | // use as required
14318 // | });
14319
14320 // isDebug: Boolean
14321 // Defaults to `false`. If set to `true`, ensures that Dojo provides
14322 // extended debugging feedback via Firebug. If Firebug is not available
14323 // on your platform, setting `isDebug` to `true` will force Dojo to
14324 // pull in (and display) the version of Firebug Lite which is
14325 // integrated into the Dojo distribution, thereby always providing a
14326 // debugging/logging console when `isDebug` is enabled. Note that
14327 // Firebug's `console.*` methods are ALWAYS defined by Dojo. If
14328 // `isDebug` is false and you are on a platform without Firebug, these
14329 // methods will be defined as no-ops.
14330 isDebug: false,
14331
14332 // locale: String
14333 // The locale to assume for loading localized resources in this page,
14334 // specified according to [RFC 3066](http://www.ietf.org/rfc/rfc3066.txt).
14335 // Must be specified entirely in lowercase, e.g. `en-us` and `zh-cn`.
14336 // See the documentation for `dojo.i18n` and `dojo.requireLocalization`
14337 // for details on loading localized resources. If no locale is specified,
14338 // Dojo assumes the locale of the user agent, according to `navigator.userLanguage`
14339 // or `navigator.language` properties.
14340 locale: undefined,
14341
14342 // extraLocale: Array
14343 // No default value. Specifies additional locales whose
14344 // resources should also be loaded alongside the default locale when
14345 // calls to `dojo.requireLocalization()` are processed.
14346 extraLocale: undefined,
14347
14348 // baseUrl: String
14349 // The directory in which `dojo.js` is located. Under normal
14350 // conditions, Dojo auto-detects the correct location from which it
14351 // was loaded. You may need to manually configure `baseUrl` in cases
14352 // where you have renamed `dojo.js` or in which `<base>` tags confuse
14353 // some browsers (e.g. IE 6). The variable `dojo.baseUrl` is assigned
14354 // either the value of `djConfig.baseUrl` if one is provided or the
14355 // auto-detected root if not. Other modules are located relative to
14356 // this path. The path should end in a slash.
14357 baseUrl: undefined,
14358
14359 // modulePaths: [deprecated] Object
14360 // A map of module names to paths relative to `dojo.baseUrl`. The
14361 // key/value pairs correspond directly to the arguments which
14362 // `dojo.registerModulePath` accepts. Specifying
14363 // `djConfig.modulePaths = { "foo": "../../bar" }` is the equivalent
14364 // of calling `dojo.registerModulePath("foo", "../../bar");`. Multiple
14365 // modules may be configured via `djConfig.modulePaths`.
14366 modulePaths: {},
14367
14368 // addOnLoad: Function|Array
14369 // Adds a callback via dojo/ready. Useful when Dojo is added after
14370 // the page loads and djConfig.afterOnLoad is true. Supports the same
14371 // arguments as dojo/ready. When using a function reference, use
14372 // `djConfig.addOnLoad = function(){};`. For object with function name use
14373 // `djConfig.addOnLoad = [myObject, "functionName"];` and for object with
14374 // function reference use
14375 // `djConfig.addOnLoad = [myObject, function(){}];`
14376 addOnLoad: null,
14377
14378 // parseOnLoad: Boolean
14379 // Run the parser after the page is loaded
14380 parseOnLoad: false,
14381
14382 // require: String[]
14383 // An array of module names to be loaded immediately after dojo.js has been included
14384 // in a page.
14385 require: [],
14386
14387 // defaultDuration: Number
14388 // Default duration, in milliseconds, for wipe and fade animations within dijits.
14389 // Assigned to dijit.defaultDuration.
14390 defaultDuration: 200,
14391
14392 // dojoBlankHtmlUrl: String
14393 // Used by some modules to configure an empty iframe. Used by dojo/io/iframe and
14394 // dojo/back, and dijit/popup support in IE where an iframe is needed to make sure native
14395 // controls do not bleed through the popups. Normally this configuration variable
14396 // does not need to be set, except when using cross-domain/CDN Dojo builds.
14397 // Save dojo/resources/blank.html to your domain and set `djConfig.dojoBlankHtmlUrl`
14398 // to the path on your domain your copy of blank.html.
14399 dojoBlankHtmlUrl: undefined,
14400
14401 // ioPublish: Boolean?
14402 // Set this to true to enable publishing of topics for the different phases of
14403 // IO operations. Publishing is done via dojo/topic.publish(). See dojo/main.__IoPublish for a list
14404 // of topics that are published.
14405 ioPublish: false,
14406
14407 // useCustomLogger: Anything?
14408 // If set to a value that evaluates to true such as a string or array and
14409 // isDebug is true and Firebug is not available or running, then it bypasses
14410 // the creation of Firebug Lite allowing you to define your own console object.
14411 useCustomLogger: undefined,
14412
14413 // transparentColor: Array
14414 // Array containing the r, g, b components used as transparent color in dojo.Color;
14415 // if undefined, [255,255,255] (white) will be used.
14416 transparentColor: undefined,
14417
14418 // deps: Function|Array
14419 // Defines dependencies to be used before the loader has been loaded.
14420 // When provided, they cause the loader to execute require(deps, callback)
14421 // once it has finished loading. Should be used with callback.
14422 deps: undefined,
14423
14424 // callback: Function|Array
14425 // Defines a callback to be used when dependencies are defined before
14426 // the loader has been loaded. When provided, they cause the loader to
14427 // execute require(deps, callback) once it has finished loading.
14428 // Should be used with deps.
14429 callback: undefined,
14430
14431 // deferredInstrumentation: Boolean
14432 // Whether deferred instrumentation should be loaded or included
14433 // in builds.
14434 deferredInstrumentation: true,
14435
14436 // useDeferredInstrumentation: Boolean|String
14437 // Whether the deferred instrumentation should be used.
14438 //
14439 // * `"report-rejections"`: report each rejection as it occurs.
14440 // * `true` or `1` or `"report-unhandled-rejections"`: wait 1 second
14441 // in an attempt to detect unhandled rejections.
14442 useDeferredInstrumentation: "report-unhandled-rejections"
14443 };
14444 =====*/
14445
14446 var result = {};
14447 if( 1 ){
14448 // must be the dojo loader; take a shallow copy of require.rawConfig
14449 var src = require.rawConfig, p;
14450 for(p in src){
14451 result[p] = src[p];
14452 }
14453 }else{
14454 var adviseHas = function(featureSet, prefix, booting){
14455 for(p in featureSet){
14456 p!="has" && has.add(prefix + p, featureSet[p], 0, booting);
14457 }
14458 };
14459 result = 1 ?
14460 // must be a built version of the dojo loader; all config stuffed in require.rawConfig
14461 require.rawConfig :
14462 // a foreign loader
14463 this.dojoConfig || this.djConfig || {};
14464 adviseHas(result, "config", 1);
14465 adviseHas(result.has, "", 1);
14466 }
14467 return result;
14468 });
14469
14470
14471 },
14472 'dojo/_base/event':function(){
14473 define("dojo/_base/event", ["./kernel", "../on", "../has", "../dom-geometry"], function(dojo, on, has, dom){
14474 // module:
14475 // dojo/_base/event
14476
14477 if(on._fixEvent){
14478 var fixEvent = on._fixEvent;
14479 on._fixEvent = function(evt, se){
14480 // add some additional normalization for back-compat, this isn't in on.js because it is somewhat more expensive
14481 evt = fixEvent(evt, se);
14482 if(evt){
14483 dom.normalizeEvent(evt);
14484 }
14485 return evt;
14486 };
14487 }
14488
14489 var ret = {
14490 // summary:
14491 // This module defines dojo DOM event API. Usually you should use dojo/on, and evt.stopPropagation() +
14492 // evt.preventDefault(), rather than this module.
14493
14494 fix: function(/*Event*/ evt, /*DOMNode*/ sender){
14495 // summary:
14496 // normalizes properties on the event object including event
14497 // bubbling methods, keystroke normalization, and x/y positions
14498 // evt: Event
14499 // native event object
14500 // sender: DOMNode
14501 // node to treat as "currentTarget"
14502 if(on._fixEvent){
14503 return on._fixEvent(evt, sender);
14504 }
14505 return evt; // Event
14506 },
14507
14508 stop: function(/*Event*/ evt){
14509 // summary:
14510 // prevents propagation and clobbers the default action of the
14511 // passed event
14512 // evt: Event
14513 // The event object. If omitted, window.event is used on IE.
14514 if(has("dom-addeventlistener") || (evt && evt.preventDefault)){
14515 evt.preventDefault();
14516 evt.stopPropagation();
14517 }else{
14518 evt = evt || window.event;
14519 evt.cancelBubble = true;
14520 on._preventDefault.call(evt);
14521 }
14522 }
14523 };
14524
14525 if( 1 ){
14526 dojo.fixEvent = ret.fix;
14527 dojo.stopEvent = ret.stop;
14528 }
14529
14530 return ret;
14531 });
14532
14533 },
14534 'dojo/main':function(){
14535 define([
14536 "./_base/kernel", // kernel.isAsync
14537 "./has",
14538 "require",
14539 "./sniff",
14540 "./_base/lang",
14541 "./_base/array",
14542 "./_base/config",
14543 "./ready",
14544 "./_base/declare",
14545 "./_base/connect",
14546 "./_base/Deferred",
14547 "./_base/json",
14548 "./_base/Color",
14549 "./has!dojo-firebug?./_firebug/firebug",
14550 "./_base/browser",
14551 "./_base/loader"
14552 ], function(kernel, has, require, sniff, lang, array, config, ready){
14553 // module:
14554 // dojo/main
14555 // summary:
14556 // This is the package main module for the dojo package; it loads dojo base appropriate for the execution environment.
14557
14558 // the preferred way to load the dojo firebug console is by setting has("dojo-firebug") true in dojoConfig
14559 // the isDebug config switch is for backcompat and will work fine in sync loading mode; it works in
14560 // async mode too, but there's no guarantee when the module is loaded; therefore, if you need a firebug
14561 // console guaranteed at a particular spot in an app, either set config.has["dojo-firebug"] true before
14562 // loading dojo.js or explicitly include dojo/_firebug/firebug in a dependency list.
14563 if(config.isDebug){
14564 require(["./_firebug/firebug"]);
14565 }
14566
14567 // dojoConfig.require is deprecated; use the loader configuration property deps
14568 1 || has.add("dojo-config-require", 1);
14569 if( 1 ){
14570 var deps= config.require;
14571 if(deps){
14572 // config.require may be dot notation
14573 deps= array.map(lang.isArray(deps) ? deps : [deps], function(item){ return item.replace(/\./g, "/"); });
14574 if(kernel.isAsync){
14575 require(deps);
14576 }else{
14577 // this is a bit janky; in 1.6- dojo is defined before these requires are applied; but in 1.7+
14578 // dojo isn't defined until returning from this module; this is only a problem in sync mode
14579 // since we're in sync mode, we know we've got our loader with its priority ready queue
14580 ready(1, function(){require(deps);});
14581 }
14582 }
14583 }
14584
14585 return kernel;
14586 });
14587
14588 },
14589 'dojo/sniff':function(){
14590 define(["./has"], function(has){
14591 // module:
14592 // dojo/sniff
14593
14594 /*=====
14595 return function(){
14596 // summary:
14597 // This module sets has() flags based on the current browser.
14598 // It returns the has() function.
14599 };
14600 =====*/
14601
14602 if( 1 ){
14603 var n = navigator,
14604 dua = n.userAgent,
14605 dav = n.appVersion,
14606 tv = parseFloat(dav);
14607
14608 has.add("air", dua.indexOf("AdobeAIR") >= 0),
14609 has.add("khtml", dav.indexOf("Konqueror") >= 0 ? tv : undefined);
14610 has.add("webkit", parseFloat(dua.split("WebKit/")[1]) || undefined);
14611 has.add("chrome", parseFloat(dua.split("Chrome/")[1]) || undefined);
14612 has.add("safari", dav.indexOf("Safari")>=0 && !has("chrome") ? parseFloat(dav.split("Version/")[1]) : undefined);
14613 has.add("mac", dav.indexOf("Macintosh") >= 0);
14614 has.add("quirks", document.compatMode == "BackCompat");
14615 has.add("ios", /iPhone|iPod|iPad/.test(dua));
14616 has.add("android", parseFloat(dua.split("Android ")[1]) || undefined);
14617
14618 if(!has("webkit")){
14619 // Opera
14620 if(dua.indexOf("Opera") >= 0){
14621 // see http://dev.opera.com/articles/view/opera-ua-string-changes and http://www.useragentstring.com/pages/Opera/
14622 // 9.8 has both styles; <9.8, 9.9 only old style
14623 has.add("opera", tv >= 9.8 ? parseFloat(dua.split("Version/")[1]) || tv : tv);
14624 }
14625
14626 // Mozilla and firefox
14627 if(dua.indexOf("Gecko") >= 0 && !has("khtml") && !has("webkit")){
14628 has.add("mozilla", tv);
14629 }
14630 if(has("mozilla")){
14631 //We really need to get away from this. Consider a sane isGecko approach for the future.
14632 has.add("ff", parseFloat(dua.split("Firefox/")[1] || dua.split("Minefield/")[1]) || undefined);
14633 }
14634
14635 // IE
14636 if(document.all && !has("opera")){
14637 var isIE = parseFloat(dav.split("MSIE ")[1]) || undefined;
14638
14639 //In cases where the page has an HTTP header or META tag with
14640 //X-UA-Compatible, then it is in emulation mode.
14641 //Make sure isIE reflects the desired version.
14642 //document.documentMode of 5 means quirks mode.
14643 //Only switch the value if documentMode's major version
14644 //is different from isIE's major version.
14645 var mode = document.documentMode;
14646 if(mode && mode != 5 && Math.floor(isIE) != mode){
14647 isIE = mode;
14648 }
14649
14650 has.add("ie", isIE);
14651 }
14652
14653 // Wii
14654 has.add("wii", typeof opera != "undefined" && opera.wiiremote);
14655 }
14656 }
14657
14658 return has;
14659 });
14660
14661 },
14662 'dojo/request/handlers':function(){
14663 define([
14664 '../json',
14665 '../_base/kernel',
14666 '../_base/array',
14667 '../has'
14668 ], function(JSON, kernel, array, has){
14669 has.add('activex', typeof ActiveXObject !== 'undefined');
14670
14671 var handleXML;
14672 if(has('activex')){
14673 // GUIDs obtained from http://msdn.microsoft.com/en-us/library/ms757837(VS.85).aspx
14674 var dp = [
14675 'Msxml2.DOMDocument.6.0',
14676 'Msxml2.DOMDocument.4.0',
14677 'MSXML2.DOMDocument.3.0',
14678 'MSXML.DOMDocument' // 2.0
14679 ];
14680
14681 handleXML = function(response){
14682 var result = response.data;
14683
14684 if(!result || !result.documentElement){
14685 var text = response.text;
14686 array.some(dp, function(p){
14687 try{
14688 var dom = new ActiveXObject(p);
14689 dom.async = false;
14690 dom.loadXML(text);
14691 result = dom;
14692 }catch(e){ return false; }
14693 return true;
14694 });
14695 }
14696
14697 return result;
14698 };
14699 }
14700
14701 var handlers = {
14702 'javascript': function(response){
14703 return kernel.eval(response.text || '');
14704 },
14705 'json': function(response){
14706 return JSON.parse(response.text || null);
14707 },
14708 'xml': handleXML
14709 };
14710
14711 function handle(response){
14712 var handler = handlers[response.options.handleAs];
14713
14714 response.data = handler ? handler(response) : (response.data || response.text);
14715
14716 return response;
14717 }
14718
14719 handle.register = function(name, handler){
14720 handlers[name] = handler;
14721 };
14722
14723 return handle;
14724 });
14725
14726 },
14727 'dojo/ready':function(){
14728 define("dojo/ready", ["./_base/kernel", "./has", "require", "./domReady", "./_base/lang"], function(dojo, has, require, domReady, lang){
14729 // module:
14730 // dojo/ready
14731 // note:
14732 // This module should be unnecessary in dojo 2.0
14733
14734 var
14735 // truthy if DOMContentLoaded or better (e.g., window.onload fired) has been achieved
14736 isDomReady = 0,
14737
14738 // a function to call to cause onLoad to be called when all requested modules have been loaded
14739 requestCompleteSignal,
14740
14741 // The queue of functions waiting to execute as soon as dojo.ready conditions satisfied
14742 loadQ = [],
14743
14744 // prevent recursion in onLoad
14745 onLoadRecursiveGuard = 0,
14746
14747 handleDomReady = function(){
14748 isDomReady = 1;
14749 dojo._postLoad = dojo.config.afterOnLoad = true;
14750 if(loadQ.length){
14751 requestCompleteSignal(onLoad);
14752 }
14753 },
14754
14755 // run the next function queued with dojo.ready
14756 onLoad = function(){
14757 if(isDomReady && !onLoadRecursiveGuard && loadQ.length){
14758 //guard against recursions into this function
14759 onLoadRecursiveGuard = 1;
14760 var f = loadQ.shift();
14761 try{
14762 f();
14763 }
14764 // FIXME: signal the error via require.on
14765 finally{
14766 onLoadRecursiveGuard = 0;
14767 }
14768 onLoadRecursiveGuard = 0;
14769 if(loadQ.length){
14770 requestCompleteSignal(onLoad);
14771 }
14772 }
14773 };
14774
14775 require.on("idle", onLoad);
14776 requestCompleteSignal = function(){
14777 if(require.idle()){
14778 onLoad();
14779 } // else do nothing, onLoad will be called with the next idle signal
14780 };
14781
14782 var ready = dojo.ready = dojo.addOnLoad = function(priority, context, callback){
14783 // summary:
14784 // Add a function to execute on DOM content loaded and all requested modules have arrived and been evaluated.
14785 // In most cases, the `domReady` plug-in should suffice and this method should not be needed.
14786 // priority: Integer?
14787 // The order in which to exec this callback relative to other callbacks, defaults to 1000
14788 // context: Object?|Function
14789 // The context in which to run execute callback, or a callback if not using context
14790 // callback: Function?
14791 // The function to execute.
14792 //
14793 // example:
14794 // Simple DOM and Modules ready syntax
14795 // | require(["dojo/ready"], function(ready){
14796 // | ready(function(){ alert("Dom ready!"); });
14797 // | });
14798 //
14799 // example:
14800 // Using a priority
14801 // | require(["dojo/ready"], function(ready){
14802 // | ready(2, function(){ alert("low priority ready!"); })
14803 // | });
14804 //
14805 // example:
14806 // Using context
14807 // | require(["dojo/ready"], function(ready){
14808 // | ready(foo, function(){
14809 // | // in here, this == foo
14810 // | });
14811 // | });
14812 //
14813 // example:
14814 // Using dojo/hitch style args:
14815 // | require(["dojo/ready"], function(ready){
14816 // | var foo = { dojoReady: function(){ console.warn(this, "dojo dom and modules ready."); } };
14817 // | ready(foo, "dojoReady");
14818 // | });
14819
14820 var hitchArgs = lang._toArray(arguments);
14821 if(typeof priority != "number"){
14822 callback = context;
14823 context = priority;
14824 priority = 1000;
14825 }else{
14826 hitchArgs.shift();
14827 }
14828 callback = callback ?
14829 lang.hitch.apply(dojo, hitchArgs) :
14830 function(){
14831 context();
14832 };
14833 callback.priority = priority;
14834 for(var i = 0; i < loadQ.length && priority >= loadQ[i].priority; i++){}
14835 loadQ.splice(i, 0, callback);
14836 requestCompleteSignal();
14837 };
14838
14839 1 || has.add("dojo-config-addOnLoad", 1);
14840 if( 1 ){
14841 var dca = dojo.config.addOnLoad;
14842 if(dca){
14843 ready[(lang.isArray(dca) ? "apply" : "call")](dojo, dca);
14844 }
14845 }
14846
14847 if( 1 && dojo.config.parseOnLoad && !dojo.isAsync){
14848 ready(99, function(){
14849 if(!dojo.parser){
14850 dojo.deprecated("Add explicit require(['dojo/parser']);", "", "2.0");
14851 require(["dojo/parser"]);
14852 }
14853 });
14854 }
14855
14856 if( 1 ){
14857 domReady(handleDomReady);
14858 }else{
14859 handleDomReady();
14860 }
14861
14862 return ready;
14863 });
14864
14865 },
14866 'dojo/aspect':function(){
14867 define("dojo/aspect", [], function(){
14868
14869 // module:
14870 // dojo/aspect
14871
14872 "use strict";
14873 var undefined, nextId = 0;
14874 function advise(dispatcher, type, advice, receiveArguments){
14875 var previous = dispatcher[type];
14876 var around = type == "around";
14877 var signal;
14878 if(around){
14879 var advised = advice(function(){
14880 return previous.advice(this, arguments);
14881 });
14882 signal = {
14883 remove: function(){
14884 signal.cancelled = true;
14885 },
14886 advice: function(target, args){
14887 return signal.cancelled ?
14888 previous.advice(target, args) : // cancelled, skip to next one
14889 advised.apply(target, args); // called the advised function
14890 }
14891 };
14892 }else{
14893 // create the remove handler
14894 signal = {
14895 remove: function(){
14896 var previous = signal.previous;
14897 var next = signal.next;
14898 if(!next && !previous){
14899 delete dispatcher[type];
14900 }else{
14901 if(previous){
14902 previous.next = next;
14903 }else{
14904 dispatcher[type] = next;
14905 }
14906 if(next){
14907 next.previous = previous;
14908 }
14909 }
14910 },
14911 id: nextId++,
14912 advice: advice,
14913 receiveArguments: receiveArguments
14914 };
14915 }
14916 if(previous && !around){
14917 if(type == "after"){
14918 // add the listener to the end of the list
14919 // note that we had to change this loop a little bit to workaround a bizarre IE10 JIT bug
14920 while(previous.next && (previous = previous.next)){}
14921 previous.next = signal;
14922 signal.previous = previous;
14923 }else if(type == "before"){
14924 // add to beginning
14925 dispatcher[type] = signal;
14926 signal.next = previous;
14927 previous.previous = signal;
14928 }
14929 }else{
14930 // around or first one just replaces
14931 dispatcher[type] = signal;
14932 }
14933 return signal;
14934 }
14935 function aspect(type){
14936 return function(target, methodName, advice, receiveArguments){
14937 var existing = target[methodName], dispatcher;
14938 if(!existing || existing.target != target){
14939 // no dispatcher in place
14940 target[methodName] = dispatcher = function(){
14941 var executionId = nextId;
14942 // before advice
14943 var args = arguments;
14944 var before = dispatcher.before;
14945 while(before){
14946 args = before.advice.apply(this, args) || args;
14947 before = before.next;
14948 }
14949 // around advice
14950 if(dispatcher.around){
14951 var results = dispatcher.around.advice(this, args);
14952 }
14953 // after advice
14954 var after = dispatcher.after;
14955 while(after && after.id < executionId){
14956 if(after.receiveArguments){
14957 var newResults = after.advice.apply(this, args);
14958 // change the return value only if a new value was returned
14959 results = newResults === undefined ? results : newResults;
14960 }else{
14961 results = after.advice.call(this, results, args);
14962 }
14963 after = after.next;
14964 }
14965 return results;
14966 };
14967 if(existing){
14968 dispatcher.around = {advice: function(target, args){
14969 return existing.apply(target, args);
14970 }};
14971 }
14972 dispatcher.target = target;
14973 }
14974 var results = advise((dispatcher || existing), type, advice, receiveArguments);
14975 advice = null;
14976 return results;
14977 };
14978 }
14979
14980 // TODOC: after/before/around return object
14981
14982 var after = aspect("after");
14983 /*=====
14984 after = function(target, methodName, advice, receiveArguments){
14985 // summary:
14986 // The "after" export of the aspect module is a function that can be used to attach
14987 // "after" advice to a method. This function will be executed after the original method
14988 // is executed. By default the function will be called with a single argument, the return
14989 // value of the original method, or the the return value of the last executed advice (if a previous one exists).
14990 // The fourth (optional) argument can be set to true to so the function receives the original
14991 // arguments (from when the original method was called) rather than the return value.
14992 // If there are multiple "after" advisors, they are executed in the order they were registered.
14993 // target: Object
14994 // This is the target object
14995 // methodName: String
14996 // This is the name of the method to attach to.
14997 // advice: Function
14998 // This is function to be called after the original method
14999 // receiveArguments: Boolean?
15000 // If this is set to true, the advice function receives the original arguments (from when the original mehtod
15001 // was called) rather than the return value of the original/previous method.
15002 // returns:
15003 // A signal object that can be used to cancel the advice. If remove() is called on this signal object, it will
15004 // stop the advice function from being executed.
15005 };
15006 =====*/
15007
15008 var before = aspect("before");
15009 /*=====
15010 before = function(target, methodName, advice){
15011 // summary:
15012 // The "before" export of the aspect module is a function that can be used to attach
15013 // "before" advice to a method. This function will be executed before the original method
15014 // is executed. This function will be called with the arguments used to call the method.
15015 // This function may optionally return an array as the new arguments to use to call
15016 // the original method (or the previous, next-to-execute before advice, if one exists).
15017 // If the before method doesn't return anything (returns undefined) the original arguments
15018 // will be preserved.
15019 // If there are multiple "before" advisors, they are executed in the reverse order they were registered.
15020 // target: Object
15021 // This is the target object
15022 // methodName: String
15023 // This is the name of the method to attach to.
15024 // advice: Function
15025 // This is function to be called before the original method
15026 };
15027 =====*/
15028
15029 var around = aspect("around");
15030 /*=====
15031 around = function(target, methodName, advice){
15032 // summary:
15033 // The "around" export of the aspect module is a function that can be used to attach
15034 // "around" advice to a method. The advisor function is immediately executed when
15035 // the around() is called, is passed a single argument that is a function that can be
15036 // called to continue execution of the original method (or the next around advisor).
15037 // The advisor function should return a function, and this function will be called whenever
15038 // the method is called. It will be called with the arguments used to call the method.
15039 // Whatever this function returns will be returned as the result of the method call (unless after advise changes it).
15040 // example:
15041 // If there are multiple "around" advisors, the most recent one is executed first,
15042 // which can then delegate to the next one and so on. For example:
15043 // | around(obj, "foo", function(originalFoo){
15044 // | return function(){
15045 // | var start = new Date().getTime();
15046 // | var results = originalFoo.apply(this, arguments); // call the original
15047 // | var end = new Date().getTime();
15048 // | console.log("foo execution took " + (end - start) + " ms");
15049 // | return results;
15050 // | };
15051 // | });
15052 // target: Object
15053 // This is the target object
15054 // methodName: String
15055 // This is the name of the method to attach to.
15056 // advice: Function
15057 // This is function to be called around the original method
15058 };
15059 =====*/
15060
15061 return {
15062 // summary:
15063 // provides aspect oriented programming functionality, allowing for
15064 // one to add before, around, or after advice on existing methods.
15065 // example:
15066 // | define(["dojo/aspect"], function(aspect){
15067 // | var signal = aspect.after(targetObject, "methodName", function(someArgument){
15068 // | this will be called when targetObject.methodName() is called, after the original function is called
15069 // | });
15070 //
15071 // example:
15072 // The returned signal object can be used to cancel the advice.
15073 // | signal.remove(); // this will stop the advice from being executed anymore
15074 // | aspect.before(targetObject, "methodName", function(someArgument){
15075 // | // this will be called when targetObject.methodName() is called, before the original function is called
15076 // | });
15077
15078 before: before,
15079 around: around,
15080 after: after
15081 };
15082 });
15083
15084 },
15085 'dojo/_base/connect':function(){
15086 define(["./kernel", "../on", "../topic", "../aspect", "./event", "../mouse", "./sniff", "./lang", "../keys"], function(dojo, on, hub, aspect, eventModule, mouse, has, lang){
15087 // module:
15088 // dojo/_base/connect
15089
15090 has.add("events-keypress-typed", function(){ // keypresses should only occur a printable character is hit
15091 var testKeyEvent = {charCode: 0};
15092 try{
15093 testKeyEvent = document.createEvent("KeyboardEvent");
15094 (testKeyEvent.initKeyboardEvent || testKeyEvent.initKeyEvent).call(testKeyEvent, "keypress", true, true, null, false, false, false, false, 9, 3);
15095 }catch(e){}
15096 return testKeyEvent.charCode == 0 && !has("opera");
15097 });
15098
15099 function connect_(obj, event, context, method, dontFix){
15100 method = lang.hitch(context, method);
15101 if(!obj || !(obj.addEventListener || obj.attachEvent)){
15102 // it is a not a DOM node and we are using the dojo.connect style of treating a
15103 // method like an event, must go right to aspect
15104 return aspect.after(obj || dojo.global, event, method, true);
15105 }
15106 if(typeof event == "string" && event.substring(0, 2) == "on"){
15107 event = event.substring(2);
15108 }
15109 if(!obj){
15110 obj = dojo.global;
15111 }
15112 if(!dontFix){
15113 switch(event){
15114 // dojo.connect has special handling for these event types
15115 case "keypress":
15116 event = keypress;
15117 break;
15118 case "mouseenter":
15119 event = mouse.enter;
15120 break;
15121 case "mouseleave":
15122 event = mouse.leave;
15123 break;
15124 }
15125 }
15126 return on(obj, event, method, dontFix);
15127 }
15128
15129 var _punctMap = {
15130 106:42,
15131 111:47,
15132 186:59,
15133 187:43,
15134 188:44,
15135 189:45,
15136 190:46,
15137 191:47,
15138 192:96,
15139 219:91,
15140 220:92,
15141 221:93,
15142 222:39,
15143 229:113
15144 };
15145 var evtCopyKey = has("mac") ? "metaKey" : "ctrlKey";
15146
15147
15148 var _synthesizeEvent = function(evt, props){
15149 var faux = lang.mixin({}, evt, props);
15150 setKeyChar(faux);
15151 // FIXME: would prefer to use lang.hitch: lang.hitch(evt, evt.preventDefault);
15152 // but it throws an error when preventDefault is invoked on Safari
15153 // does Event.preventDefault not support "apply" on Safari?
15154 faux.preventDefault = function(){ evt.preventDefault(); };
15155 faux.stopPropagation = function(){ evt.stopPropagation(); };
15156 return faux;
15157 };
15158 function setKeyChar(evt){
15159 evt.keyChar = evt.charCode ? String.fromCharCode(evt.charCode) : '';
15160 evt.charOrCode = evt.keyChar || evt.keyCode;
15161 }
15162 var keypress;
15163 if(has("events-keypress-typed")){
15164 // this emulates Firefox's keypress behavior where every keydown can correspond to a keypress
15165 var _trySetKeyCode = function(e, code){
15166 try{
15167 // squelch errors when keyCode is read-only
15168 // (e.g. if keyCode is ctrl or shift)
15169 return (e.keyCode = code);
15170 }catch(e){
15171 return 0;
15172 }
15173 };
15174 keypress = function(object, listener){
15175 var keydownSignal = on(object, "keydown", function(evt){
15176 // munge key/charCode
15177 var k=evt.keyCode;
15178 // These are Windows Virtual Key Codes
15179 // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/WinUI/WindowsUserInterface/UserInput/VirtualKeyCodes.asp
15180 var unprintable = (k!=13) && k!=32 && (k!=27||!has("ie")) && (k<48||k>90) && (k<96||k>111) && (k<186||k>192) && (k<219||k>222) && k!=229;
15181 // synthesize keypress for most unprintables and CTRL-keys
15182 if(unprintable||evt.ctrlKey){
15183 var c = unprintable ? 0 : k;
15184 if(evt.ctrlKey){
15185 if(k==3 || k==13){
15186 return listener.call(evt.currentTarget, evt); // IE will post CTRL-BREAK, CTRL-ENTER as keypress natively
15187 }else if(c>95 && c<106){
15188 c -= 48; // map CTRL-[numpad 0-9] to ASCII
15189 }else if((!evt.shiftKey)&&(c>=65&&c<=90)){
15190 c += 32; // map CTRL-[A-Z] to lowercase
15191 }else{
15192 c = _punctMap[c] || c; // map other problematic CTRL combinations to ASCII
15193 }
15194 }
15195 // simulate a keypress event
15196 var faux = _synthesizeEvent(evt, {type: 'keypress', faux: true, charCode: c});
15197 listener.call(evt.currentTarget, faux);
15198 if(has("ie")){
15199 _trySetKeyCode(evt, faux.keyCode);
15200 }
15201 }
15202 });
15203 var keypressSignal = on(object, "keypress", function(evt){
15204 var c = evt.charCode;
15205 c = c>=32 ? c : 0;
15206 evt = _synthesizeEvent(evt, {charCode: c, faux: true});
15207 return listener.call(this, evt);
15208 });
15209 return {
15210 remove: function(){
15211 keydownSignal.remove();
15212 keypressSignal.remove();
15213 }
15214 };
15215 };
15216 }else{
15217 if(has("opera")){
15218 keypress = function(object, listener){
15219 return on(object, "keypress", function(evt){
15220 var c = evt.which;
15221 if(c==3){
15222 c=99; // Mozilla maps CTRL-BREAK to CTRL-c
15223 }
15224 // can't trap some keys at all, like INSERT and DELETE
15225 // there is no differentiating info between DELETE and ".", or INSERT and "-"
15226 c = c<32 && !evt.shiftKey ? 0 : c;
15227 if(evt.ctrlKey && !evt.shiftKey && c>=65 && c<=90){
15228 // lowercase CTRL-[A-Z] keys
15229 c += 32;
15230 }
15231 return listener.call(this, _synthesizeEvent(evt, { charCode: c }));
15232 });
15233 };
15234 }else{
15235 keypress = function(object, listener){
15236 return on(object, "keypress", function(evt){
15237 setKeyChar(evt);
15238 return listener.call(this, evt);
15239 });
15240 };
15241 }
15242 }
15243
15244 var connect = {
15245 // summary:
15246 // This module defines the dojo.connect API.
15247 // This modules also provides keyboard event handling helpers.
15248 // This module exports an extension event for emulating Firefox's keypress handling.
15249 // However, this extension event exists primarily for backwards compatibility and
15250 // is not recommended. WebKit and IE uses an alternate keypress handling (only
15251 // firing for printable characters, to distinguish from keydown events), and most
15252 // consider the WebKit/IE behavior more desirable.
15253
15254 _keypress:keypress,
15255
15256 connect:function(obj, event, context, method, dontFix){
15257 // summary:
15258 // `dojo.connect` is a deprecated event handling and delegation method in
15259 // Dojo. It allows one function to "listen in" on the execution of
15260 // any other, triggering the second whenever the first is called. Many
15261 // listeners may be attached to a function, and source functions may
15262 // be either regular function calls or DOM events.
15263 //
15264 // description:
15265 // Connects listeners to actions, so that after event fires, a
15266 // listener is called with the same arguments passed to the original
15267 // function.
15268 //
15269 // Since `dojo.connect` allows the source of events to be either a
15270 // "regular" JavaScript function or a DOM event, it provides a uniform
15271 // interface for listening to all the types of events that an
15272 // application is likely to deal with though a single, unified
15273 // interface. DOM programmers may want to think of it as
15274 // "addEventListener for everything and anything".
15275 //
15276 // When setting up a connection, the `event` parameter must be a
15277 // string that is the name of the method/event to be listened for. If
15278 // `obj` is null, `kernel.global` is assumed, meaning that connections
15279 // to global methods are supported but also that you may inadvertently
15280 // connect to a global by passing an incorrect object name or invalid
15281 // reference.
15282 //
15283 // `dojo.connect` generally is forgiving. If you pass the name of a
15284 // function or method that does not yet exist on `obj`, connect will
15285 // not fail, but will instead set up a stub method. Similarly, null
15286 // arguments may simply be omitted such that fewer than 4 arguments
15287 // may be required to set up a connection See the examples for details.
15288 //
15289 // The return value is a handle that is needed to
15290 // remove this connection with `dojo.disconnect`.
15291 //
15292 // obj: Object?
15293 // The source object for the event function.
15294 // Defaults to `kernel.global` if null.
15295 // If obj is a DOM node, the connection is delegated
15296 // to the DOM event manager (unless dontFix is true).
15297 //
15298 // event: String
15299 // String name of the event function in obj.
15300 // I.e. identifies a property `obj[event]`.
15301 //
15302 // context: Object|null
15303 // The object that method will receive as "this".
15304 //
15305 // If context is null and method is a function, then method
15306 // inherits the context of event.
15307 //
15308 // If method is a string then context must be the source
15309 // object object for method (context[method]). If context is null,
15310 // kernel.global is used.
15311 //
15312 // method: String|Function
15313 // A function reference, or name of a function in context.
15314 // The function identified by method fires after event does.
15315 // method receives the same arguments as the event.
15316 // See context argument comments for information on method's scope.
15317 //
15318 // dontFix: Boolean?
15319 // If obj is a DOM node, set dontFix to true to prevent delegation
15320 // of this connection to the DOM event manager.
15321 //
15322 // example:
15323 // When obj.onchange(), do ui.update():
15324 // | dojo.connect(obj, "onchange", ui, "update");
15325 // | dojo.connect(obj, "onchange", ui, ui.update); // same
15326 //
15327 // example:
15328 // Using return value for disconnect:
15329 // | var link = dojo.connect(obj, "onchange", ui, "update");
15330 // | ...
15331 // | dojo.disconnect(link);
15332 //
15333 // example:
15334 // When onglobalevent executes, watcher.handler is invoked:
15335 // | dojo.connect(null, "onglobalevent", watcher, "handler");
15336 //
15337 // example:
15338 // When ob.onCustomEvent executes, customEventHandler is invoked:
15339 // | dojo.connect(ob, "onCustomEvent", null, "customEventHandler");
15340 // | dojo.connect(ob, "onCustomEvent", "customEventHandler"); // same
15341 //
15342 // example:
15343 // When ob.onCustomEvent executes, customEventHandler is invoked
15344 // with the same scope (this):
15345 // | dojo.connect(ob, "onCustomEvent", null, customEventHandler);
15346 // | dojo.connect(ob, "onCustomEvent", customEventHandler); // same
15347 //
15348 // example:
15349 // When globalEvent executes, globalHandler is invoked
15350 // with the same scope (this):
15351 // | dojo.connect(null, "globalEvent", null, globalHandler);
15352 // | dojo.connect("globalEvent", globalHandler); // same
15353
15354 // normalize arguments
15355 var a=arguments, args=[], i=0;
15356 // if a[0] is a String, obj was omitted
15357 args.push(typeof a[0] == "string" ? null : a[i++], a[i++]);
15358 // if the arg-after-next is a String or Function, context was NOT omitted
15359 var a1 = a[i+1];
15360 args.push(typeof a1 == "string" || typeof a1 == "function" ? a[i++] : null, a[i++]);
15361 // absorb any additional arguments
15362 for(var l=a.length; i<l; i++){ args.push(a[i]); }
15363 return connect_.apply(this, args);
15364 },
15365
15366 disconnect:function(handle){
15367 // summary:
15368 // Remove a link created by dojo.connect.
15369 // description:
15370 // Removes the connection between event and the method referenced by handle.
15371 // handle: Handle
15372 // the return value of the dojo.connect call that created the connection.
15373
15374 if(handle){
15375 handle.remove();
15376 }
15377 },
15378
15379 subscribe:function(topic, context, method){
15380 // summary:
15381 // Attach a listener to a named topic. The listener function is invoked whenever the
15382 // named topic is published (see: dojo.publish).
15383 // Returns a handle which is needed to unsubscribe this listener.
15384 // topic: String
15385 // The topic to which to subscribe.
15386 // context: Object?
15387 // Scope in which method will be invoked, or null for default scope.
15388 // method: String|Function
15389 // The name of a function in context, or a function reference. This is the function that
15390 // is invoked when topic is published.
15391 // example:
15392 // | dojo.subscribe("alerts", null, function(caption, message){ alert(caption + "\n" + message); });
15393 // | dojo.publish("alerts", [ "read this", "hello world" ]);
15394 return hub.subscribe(topic, lang.hitch(context, method));
15395 },
15396
15397 publish:function(topic, args){
15398 // summary:
15399 // Invoke all listener method subscribed to topic.
15400 // topic: String
15401 // The name of the topic to publish.
15402 // args: Array?
15403 // An array of arguments. The arguments will be applied
15404 // to each topic subscriber (as first class parameters, via apply).
15405 // example:
15406 // | dojo.subscribe("alerts", null, function(caption, message){ alert(caption + "\n" + message); };
15407 // | dojo.publish("alerts", [ "read this", "hello world" ]);
15408 return hub.publish.apply(hub, [topic].concat(args));
15409 },
15410
15411 connectPublisher:function(topic, obj, event){
15412 // summary:
15413 // Ensure that every time obj.event() is called, a message is published
15414 // on the topic. Returns a handle which can be passed to
15415 // dojo.disconnect() to disable subsequent automatic publication on
15416 // the topic.
15417 // topic: String
15418 // The name of the topic to publish.
15419 // obj: Object?
15420 // The source object for the event function. Defaults to kernel.global
15421 // if null.
15422 // event: String
15423 // The name of the event function in obj.
15424 // I.e. identifies a property obj[event].
15425 // example:
15426 // | dojo.connectPublisher("/ajax/start", dojo, "xhrGet");
15427 var pf = function(){ connect.publish(topic, arguments); };
15428 return event ? connect.connect(obj, event, pf) : connect.connect(obj, pf); //Handle
15429 },
15430
15431 isCopyKey: function(e){
15432 // summary:
15433 // Checks an event for the copy key (meta on Mac, and ctrl anywhere else)
15434 // e: Event
15435 // Event object to examine
15436 return e[evtCopyKey]; // Boolean
15437 }
15438 };
15439
15440 connect.unsubscribe = connect.disconnect;
15441 /*=====
15442 connect.unsubscribe = function(handle){
15443 // summary:
15444 // Remove a topic listener.
15445 // handle: Handle
15446 // The handle returned from a call to subscribe.
15447 // example:
15448 // | var alerter = dojo.subscribe("alerts", null, function(caption, message){ alert(caption + "\n" + message); };
15449 // | ...
15450 // | dojo.unsubscribe(alerter);
15451 };
15452 =====*/
15453
15454 1 && lang.mixin(dojo, connect);
15455 return connect;
15456
15457 });
15458
15459
15460
15461 },
15462 'dojo/errors/CancelError':function(){
15463 define(["./create"], function(create){
15464 // module:
15465 // dojo/errors/CancelError
15466
15467 /*=====
15468 return function(){
15469 // summary:
15470 // Default error if a promise is canceled without a reason.
15471 };
15472 =====*/
15473
15474 return create("CancelError", null, null, { dojoType: "cancel" });
15475 });
15476
15477 }}});
15478 (function(){
15479 // must use this.require to make this work in node.js
15480 var require = this.require;
15481 // consume the cached dojo layer
15482 require({cache:{}});
15483 !require.async && require(["dojo"]);
15484 require.boot && require.apply(null, require.boot);
15485 })();