]> git.wh0rd.org - tt-rss.git/blame - lib/dojo/dojo.js.uncompressed.js
update dojo to 1.7.3
[tt-rss.git] / lib / dojo / dojo.js.uncompressed.js
CommitLineData
2f01fe57 1/*
81bea17a 2 Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
2f01fe57
AD
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
1354d172
AD
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.
2f01fe57 39
1354d172
AD
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 },
2f01fe57 81
1354d172
AD
82 isEmpty = function(it){
83 for(var p in it){
84 return 0;
85 }
86 return 1;
87 },
2f01fe57 88
1354d172 89 toString = {}.toString,
2f01fe57 90
1354d172
AD
91 isFunction = function(it){
92 return toString.call(it) == "[object Function]";
93 },
2f01fe57 94
1354d172
AD
95 isString = function(it){
96 return toString.call(it) == "[object String]";
97 },
2f01fe57 98
1354d172
AD
99 isArray = function(it){
100 return toString.call(it) == "[object Array]";
101 },
2f01fe57 102
1354d172
AD
103 forEach = function(vector, callback){
104 if(vector){
105 for(var i = 0; i < vector.length;){
106 callback(vector[i++]);
107 }
108 }
109 },
2f01fe57 110
1354d172
AD
111 mix = function(dest, src){
112 for(var p in src){
113 dest[p] = src[p];
114 }
115 return dest;
116 },
2f01fe57 117
1354d172
AD
118 makeError = function(error, info){
119 return mix(new Error(error), {src:"dojoLoader", info:info});
120 },
2f01fe57 121
1354d172 122 uidSeed = 1,
2f01fe57 123
1354d172
AD
124 uid = function(){
125 // Returns a unique indentifier (within the lifetime of the document) of the form /_d+/.
126 return "_" + uidSeed++;
127 },
2f01fe57 128
1354d172 129 // FIXME: how to doc window.require() api
2f01fe57 130
1354d172
AD
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 },
2f01fe57 139
1354d172
AD
140 // the loader uses the has.js API to control feature inclusion/exclusion; define then use throughout
141 global = this,
2f01fe57 142
1354d172 143 doc = global.document,
2f01fe57 144
1354d172 145 element = doc && doc.createElement("DiV"),
2f01fe57 146
1354d172
AD
147 has = req.has = function(name){
148 return isFunction(hasCache[name]) ? (hasCache[name] = hasCache[name](global, doc, element)) : hasCache[name];
149 },
2f01fe57 150
1354d172 151 hasCache = has.cache = defaultConfig.hasCache;
2f01fe57 152
1354d172
AD
153 has.add = function(name, test, now, force){
154 (hasCache[name]===undefined || force) && (hasCache[name] = test);
155 return now && has(name);
2f01fe57 156 };
2f01fe57 157
1354d172
AD
158 false && 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;
2f01fe57 166 }
1354d172
AD
167
168 false && 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;
2f01fe57
AD
178 }
179 }
1354d172
AD
180 load(baseUrl + "/_base/configRhino.js");
181 rhinoDojoConfig(defaultConfig, baseUrl, rhinoArgs);
2f01fe57
AD
182 }
183
1354d172
AD
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);
2f01fe57 188 }
2f01fe57 189
1354d172
AD
190 //
191 // define the loader data
192 //
2f01fe57 193
1354d172
AD
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";
2f01fe57
AD
209 }
210
1354d172
AD
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 if(!dojoRequirePlugin){
224 dojoRequirePlugin = dojoRequirePlugin_;
225 checkDojoRequirePlugin = checkDojoRequirePlugin_;
226 transformToAmd = transformToAmd_;
227 }
228 return {
229 sync:sync,
230 xd:xd,
231 arrived:arrived,
232 nonmodule:nonmodule,
233 executing:executing,
234 executed:executed,
235 syncExecStack:syncExecStack,
236 modules:modules,
237 execQ:execQ,
238 getModule:getModule,
239 injectModule:injectModule,
240 setArrived:setArrived,
241 signal:signal,
242 finishExec:finishExec,
243 execModule:execModule,
244 dojoRequirePlugin:dojoRequirePlugin,
245 getLegacyMode:function(){return legacyMode;},
246 holdIdle:function(){checkCompleteGuard++;},
247 releaseIdle:function(){checkIdle();}
248 };
249 };
250
251 if(1){
252 // in legacy sync mode, the loader needs a minimal XHR library to load dojo/_base/loader and dojo/_base/xhr
253
254 var locationProtocol = location.protocol,
255 locationHost = location.host,
256 fileProtocol = !locationHost;
257 req.isXdUrl = function(url){
258 if(fileProtocol || /^\./.test(url)){
259 // begins with a dot is always relative to page URL; therefore not xdomain
260 return false;
261 }
262 if(/^\/\//.test(url)){
263 // for v1.6- backcompat, url starting with // indicates xdomain
264 return true;
265 }
266 // get protocol and host
267 var match = url.match(/^([^\/\:]+\:)\/\/([^\/]+)/);
268 return match && (match[1] != locationProtocol || match[2] != locationHost);
269 };
270
271 // note: to get the file:// protocol to work in FF, you must set security.fileuri.strict_origin_policy to false in about:config
272 true || has.add("dojo-xhr-factory", 1);
273 has.add("dojo-force-activex-xhr", 1 && !doc.addEventListener && window.location.protocol == "file:");
274 has.add("native-xhr", typeof XMLHttpRequest != "undefined");
275 if(has("native-xhr") && !has("dojo-force-activex-xhr")){
276 getXhr = function(){
277 return new XMLHttpRequest();
278 };
279 }else{
280 // if in the browser an old IE; find an xhr
281 for(var XMLHTTP_PROGIDS = ['Msxml2.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.4.0'], progid, i = 0; i < 3;){
282 try{
283 progid = XMLHTTP_PROGIDS[i++];
284 if(new ActiveXObject(progid)){
285 // this progid works; therefore, use it from now on
286 break;
287 }
288 }catch(e){
289 // squelch; we're just trying to find a good ActiveX progid
290 // if they all fail, then progid ends up as the last attempt and that will signal the error
291 // the first time the client actually tries to exec an xhr
292 }
293 }
294 getXhr = function(){
295 return new ActiveXObject(progid);
296 };
2f01fe57 297 }
1354d172
AD
298 req.getXhr = getXhr;
299
300 has.add("dojo-gettext-api", 1);
301 req.getText = function(url, async, onLoad){
302 var xhr = getXhr();
303 xhr.open('GET', fixupUrl(url), false);
304 xhr.send(null);
305 if(xhr.status == 200 || (!location.host && !xhr.status)){
306 if(onLoad){
307 onLoad(xhr.responseText, async);
308 }
309 }else{
310 throw makeError("xhrFailed", xhr.status);
311 }
312 return xhr.responseText;
313 };
2f01fe57 314 }
1354d172
AD
315 }else{
316 req.async = 1;
2f01fe57
AD
317 }
318
1354d172
AD
319 //
320 // loader eval
321 //
322 var eval_ =
323 // use the function constructor so our eval is scoped close to (but not in) in the global space with minimal pollution
324 new Function('return eval(arguments[0]);');
2f01fe57 325
1354d172
AD
326 req.eval =
327 function(text, hint){
328 return eval_(text + "\r\n////@ sourceURL=" + hint);
329 };
2f01fe57 330
1354d172
AD
331 //
332 // loader micro events API
333 //
334 var listenerQueues = {},
335 error = "error",
336 signal = req.signal = function(type, args){
337 var queue = listenerQueues[type];
338 // notice we run a copy of the queue; this allows listeners to add/remove
339 // other listeners without affecting this particular signal
340 forEach(queue && queue.slice(0), function(listener){
341 listener.apply(null, isArray(args) ? args : [args]);
342 });
343 },
344 on = req.on = function(type, listener){
345 // notice a queue is not created until a client actually connects
346 var queue = listenerQueues[type] || (listenerQueues[type] = []);
347 queue.push(listener);
348 return {
349 remove:function(){
350 for(var i = 0; i<queue.length; i++){
351 if(queue[i]===listener){
352 queue.splice(i, 1);
353 return;
354 }
355 }
356 }
357 };
358 };
2f01fe57 359
1354d172
AD
360 // configuration machinery; with an optimized/built defaultConfig, all configuration machinery can be discarded
361 // lexical variables hold key loader data structures to help with minification; these may be completely,
362 // one-time initialized by defaultConfig for optimized/built versions
363 var
364 aliases
365 // a vector of pairs of [regexs or string, replacement] => (alias, actual)
366 = [],
367
368 paths
369 // CommonJS paths
370 = {},
371
372 pathsMapProg
373 // list of (from-path, to-path, regex, length) derived from paths;
374 // a "program" to apply paths; see computeMapProg
375 = [],
376
377 packs
378 // a map from packageId to package configuration object; see fixupPackageInfo
379 = {},
380
381 packageMap
382 // map from package name to local-installed package name
383 = {},
384
385 packageMapProg
386 // list of (from-package, to-package, regex, length) derived from packageMap;
387 // a "program" to apply paths; see computeMapProg
388 = [],
389
390 modules
391 // A hash:(mid) --> (module-object) the module namespace
392 //
393 // pid: the package identifier to which the module belongs (e.g., "dojo"); "" indicates the system or default package
394 // mid: the fully-resolved (i.e., mappings have been applied) module identifier without the package identifier (e.g., "dojo/io/script")
395 // url: the URL from which the module was retrieved
396 // pack: the package object of the package to which the module belongs
397 // executed: 0 => not executed; executing => in the process of tranversing deps and running factory; executed => factory has been executed
398 // deps: the dependency vector for this module (vector of modules objects)
399 // def: the factory for this module
400 // result: the result of the running the factory for this module
401 // injected: (requested | arrived | nonmodule) the status of the module; nonmodule means the resource did not call define
402 // load: plugin load function; applicable only for plugins
403 //
404 // Modules go through several phases in creation:
405 //
406 // 1. Requested: some other module's definition or a require application contained the requested module in
407 // its dependency vector or executing code explicitly demands a module via req.require.
408 //
409 // 2. Injected: a script element has been appended to the insert-point element demanding the resource implied by the URL
410 //
411 // 3. Loaded: the resource injected in [2] has been evalated.
412 //
413 // 4. Defined: the resource contained a define statement that advised the loader about the module. Notice that some
414 // resources may just contain a bundle of code and never formally define a module via define
415 //
416 // 5. Evaluated: the module was defined via define and the loader has evaluated the factory and computed a result.
417 = {},
2f01fe57 418
1354d172
AD
419 cacheBust
420 // query string to append to module URLs to bust browser cache
421 = "",
2f01fe57 422
1354d172
AD
423 cache
424 // hash:(mid)-->(function)
425 //
426 // Gives the contents of a cached resource; function should cause the same actions as if the given mid was downloaded
427 // and evaluated by the host environment
428 = {},
2f01fe57 429
1354d172
AD
430 pendingCacheInsert
431 // hash:(mid)-->(function)
432 //
433 // Gives a set of cache modules pending entry into cache. When cached modules are published to the loader, they are
434 // entered into pendingCacheInsert; modules are then pressed into cache upon (1) AMD define or (2) upon receiving another
435 // independent set of cached modules. (1) is the usual case, and this case allows normalizing mids given in the pending
436 // cache for the local configuration, possibly relocating modules.
437 = {},
438
439 dojoSniffConfig
440 // map of configuration variables
441 // give the data-dojo-config as sniffed from the document (if any)
442 = {};
443
444 if(1){
445 var consumePendingCacheInsert = function(referenceModule){
446 var p, item, match, now;
447 for(p in pendingCacheInsert){
448 item = pendingCacheInsert[p];
449 match = p.match(/^url\:(.+)/);
450 if(match){
451 cache[toUrl(match[1], referenceModule)] = item;
452 }else if(p=="*now"){
453 now = item;
454 }else if(p!="*noref"){
455 cache[getModuleInfo(p, referenceModule).mid] = item;
456 }
457 }
458 if(now){
459 now(createRequire(referenceModule));
460 }
461 pendingCacheInsert = {};
462 },
2f01fe57 463
1354d172
AD
464 computeMapProg = function(map, dest, packName){
465 // This routine takes a map target-prefix(string)-->replacement(string) into a vector
466 // of quads (target-prefix, replacement, regex-for-target-prefix, length-of-target-prefix)
467 //
468 // The loader contains processes that map one string prefix to another. These
469 // are encountered when applying the requirejs paths configuration and when mapping
470 // package names. We can make the mapping and any replacement easier and faster by
471 // replacing the map with a vector of quads and then using this structure in the simple machine runMapProg.
472 dest.splice(0, dest.length);
473 var p, i, item, reverseName = 0;
474 for(p in map){
475 dest.push([p, map[p]]);
476 if(map[p]==packName){
477 reverseName = p;
478 }
479 }
480 dest.sort(function(lhs, rhs){
481 return rhs[0].length - lhs[0].length;
482 });
483 for(i = 0; i < dest.length;){
484 item = dest[i++];
485 item[2] = new RegExp("^" + item[0].replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, function(c){ return "\\" + c; }) + "(\/|$)");
486 item[3] = item[0].length + 1;
487 }
488 return reverseName;
489 },
2f01fe57 490
1354d172
AD
491 fixupPackageInfo = function(packageInfo, baseUrl){
492 // calculate the precise (name, baseUrl, main, mappings) for a package
493 var name = packageInfo.name;
494 if(!name){
495 // packageInfo must be a string that gives the name
496 name = packageInfo;
497 packageInfo = {name:name};
498 }
499 packageInfo = mix({main:"main", mapProg:[]}, packageInfo);
500 packageInfo.location = (baseUrl || "") + (packageInfo.location ? packageInfo.location : name);
501 packageInfo.reverseName = computeMapProg(packageInfo.packageMap, packageInfo.mapProg, name);
2f01fe57 502
1354d172
AD
503 if(!packageInfo.main.indexOf("./")){
504 packageInfo.main = packageInfo.main.substring(2);
505 }
2f01fe57 506
1354d172
AD
507 // allow paths to be specified in the package info
508 // TODO: this is not supported; remove
509 mix(paths, packageInfo.paths);
2f01fe57 510
1354d172
AD
511 // now that we've got a fully-resolved package object, push it into the configuration
512 packs[name] = packageInfo;
513 packageMap[name] = name;
514 },
2f01fe57 515
1354d172
AD
516 config = function(config, booting){
517 for(var p in config){
518 if(p=="waitSeconds"){
519 req.waitms = (config[p] || 0) * 1000;
520 }
521 if(p=="cacheBust"){
522 cacheBust = config[p] ? (isString(config[p]) ? config[p] : (new Date()).getTime() + "") : "";
523 }
524 if(p=="baseUrl" || p=="combo"){
525 req[p] = config[p];
526 }
527 if(1 && p=="async"){
528 // falsy or "sync" => legacy sync loader
529 // "xd" => sync but loading xdomain tree and therefore loading asynchronously (not configurable, set automatically by the loader)
530 // "legacyAsync" => permanently in "xd" by choice
531 // "debugAtAllCosts" => trying to load everything via script injection (not implemented)
532 // otherwise, must be truthy => AMD
533 // legacyMode: sync | legacyAsync | xd | false
534 var mode = config[p];
535 req.legacyMode = legacyMode = (isString(mode) && /sync|legacyAsync/.test(mode) ? mode : (!mode ? "sync" : false));
536 req.async = !legacyMode;
537 }
538 if(config[p]!==hasCache){
539 // accumulate raw config info for client apps which can use this to pass their own config
540 req.rawConfig[p] = config[p];
541 p!="has" && has.add("config-"+p, config[p], 0, booting);
542 }
543 }
81bea17a 544
1354d172
AD
545 // make sure baseUrl exists
546 if(!req.baseUrl){
547 req.baseUrl = "./";
548 }
549 // make sure baseUrl ends with a slash
550 if(!/\/$/.test(req.baseUrl)){
551 req.baseUrl += "/";
552 }
2f01fe57 553
1354d172 554 // now do the special work for has, packages, packagePaths, paths, aliases, and cache
2f01fe57 555
1354d172
AD
556 for(p in config.has){
557 has.add(p, config.has[p], 0, booting);
558 }
2f01fe57 559
1354d172
AD
560 // for each package found in any packages config item, augment the packs map owned by the loader
561 forEach(config.packages, fixupPackageInfo);
2f01fe57 562
1354d172
AD
563 // for each packagePath found in any packagePaths config item, augment the packs map owned by the loader
564 for(baseUrl in config.packagePaths){
565 forEach(config.packagePaths[baseUrl], function(packageInfo){
566 fixupPackageInfo(packageInfo, baseUrl + "/");
567 });
568 }
2f01fe57 569
1354d172
AD
570 // push in any paths and recompute the internal pathmap
571 // warning: this cann't be done until the package config is processed since packages may include path info
572 computeMapProg(mix(paths, config.paths), pathsMapProg);
2f01fe57 573
1354d172
AD
574 // aliases
575 forEach(config.aliases, function(pair){
576 if(isString(pair[0])){
577 pair[0] = new RegExp("^" + pair[0].replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, function(c){return "\\" + c;}) + "$");
578 }
579 aliases.push(pair);
580 });
2f01fe57 581
1354d172
AD
582 // mix any packageMap config item and recompute the internal packageMapProg
583 computeMapProg(mix(packageMap, config.packageMap), packageMapProg);
2f01fe57 584
1354d172
AD
585 // push in any new cache values
586 if(config.cache){
587 consumePendingCacheInsert();
588 pendingCacheInsert = config.cache;
589 if(config.cache["*noref"]){
590 consumePendingCacheInsert();
591 }
592 }
2f01fe57 593
1354d172
AD
594 signal("config", [config, req.rawConfig]);
595 };
2f01fe57 596
2f01fe57 597 //
1354d172 598 // execute the various sniffs
2f01fe57 599 //
2f01fe57 600
1354d172
AD
601 if(has("dojo-cdn") || 1){
602 for(var dojoDir, src, match, scripts = doc.getElementsByTagName("script"), i = 0; i < scripts.length && !match; i++){
603 if((src = scripts[i].getAttribute("src")) && (match = src.match(/(.*)\/?dojo\.js(\W|$)/i))){
604 // if baseUrl wasn't explicitly set, set it here to the dojo directory; this is the 1.6- behavior
605 userConfig.baseUrl = dojoDir = userConfig.baseUrl || defaultConfig.baseUrl || match[1];
2f01fe57 606
1354d172
AD
607 // see if there's a dojo configuration stuffed into the node
608 src = (scripts[i].getAttribute("data-dojo-config") || scripts[i].getAttribute("djConfig"));
609 if(src){
610 dojoSniffConfig = req.eval("({ " + src + " })", "data-dojo-config");
611 }
612 if(0){
613 var dataMain = scripts[i].getAttribute("data-main");
614 if(dataMain){
615 dojoSniffConfig.deps = dojoSniffConfig.deps || [dataMain];
616 }
617 }
618 }
619 }
2f01fe57 620 }
2f01fe57 621
1354d172
AD
622 if(0){
623 // pass down doh.testConfig from parent as if it were a data-dojo-config
624 try{
625 if(window.parent != window && window.parent.require){
626 var doh = window.parent.require("doh");
627 doh && mix(dojoSniffConfig, doh.testConfig);
628 }
629 }catch(e){}
630 }
2f01fe57 631
1354d172
AD
632 // configure the loader; let the user override defaults
633 req.rawConfig = {};
634 config(defaultConfig, 1);
635 config(userConfig, 1);
636 config(dojoSniffConfig, 1);
637
638 if(has("dojo-cdn")){
639 packs.dojo.location = dojoDir;
640 packs.dijit.location = dojoDir + "../dijit/";
641 packs.dojox.location = dojoDir + "../dojox/";
2f01fe57 642 }
1354d172
AD
643
644 }else{
645 // no config API, assume defaultConfig has everything the loader needs...for the entire lifetime of the application
646 paths = defaultConfig.paths;
647 pathsMapProg = defaultConfig.pathsMapProg;
648 packs = defaultConfig.packs;
649 aliases = defaultConfig.aliases;
650 packageMap = defaultConfig.packageMap;
651 packageMapProg = defaultConfig.packageMapProg;
652 modules = defaultConfig.modules;
653 cache = defaultConfig.cache;
654 cacheBust = defaultConfig.cacheBust;
655
656 // remember the default config for other processes (e.g., dojo/config)
657 req.rawConfig = defaultConfig;
2f01fe57
AD
658 }
659
2f01fe57 660
1354d172
AD
661 if(0){
662 req.combo = req.combo || {add:noop};
663 var comboPending = 0,
664 combosPending = [],
665 comboPendingTimer = null;
2f01fe57
AD
666 }
667
1354d172
AD
668
669 // build the loader machinery iaw configuration, including has feature tests
670 var injectDependencies = function(module){
671 // checkComplete!=0 holds the idle signal; we're not idle if we're injecting dependencies
672 checkCompleteGuard++;
673 forEach(module.deps, injectModule);
674 if(0 && comboPending && !comboPendingTimer){
675 comboPendingTimer = setTimeout(function() {
676 comboPending = 0;
677 comboPendingTimer = null;
678 req.combo.done(function(mids, url) {
679 var onLoadCallback= function(){
680 // defQ is a vector of module definitions 1-to-1, onto mids
681 runDefQ(0, mids);
682 checkComplete();
683 };
684 combosPending.push(mids);
685 injectingModule = mids;
686 req.injectUrl(url, onLoadCallback, mids);
687 injectingModule = 0;
688 }, req);
689 }, 0);
690 }
691 checkIdle();
692 },
693
694 contextRequire = function(a1, a2, a3, referenceModule, contextRequire){
695 var module, syntheticMid;
696 if(isString(a1)){
697 // signature is (moduleId)
698 module = getModule(a1, referenceModule, true);
699 if(module && module.executed){
700 return module.result;
2f01fe57 701 }
1354d172 702 throw makeError("undefinedModule", a1);
2f01fe57 703 }
1354d172
AD
704 if(!isArray(a1)){
705 // a1 is a configuration
706 config(a1);
2f01fe57 707
1354d172
AD
708 // juggle args; (a2, a3) may be (dependencies, callback)
709 a1 = a2;
710 a2 = a3;
711 }
712 if(isArray(a1)){
713 // signature is (requestList [,callback])
714 if(!a1.length){
715 a2 && a2();
716 }else{
717 syntheticMid = "require*" + uid();
2f01fe57 718
1354d172
AD
719 // resolve the request list with respect to the reference module
720 for(var mid, deps = [], i = 0; i < a1.length;){
721 mid = a1[i++];
722 if(mid in {exports:1, module:1}){
723 throw makeError("illegalModuleId", mid);
724 }
725 deps.push(getModule(mid, referenceModule));
726 }
2f01fe57 727
1354d172
AD
728 // construct a synthetic module to control execution of the requestList, and, optionally, callback
729 module = mix(makeModuleInfo("", syntheticMid, 0, ""), {
730 injected: arrived,
731 deps: deps,
732 def: a2 || noop,
733 require: referenceModule ? referenceModule.require : req
734 });
735 modules[module.mid] = module;
736
737 // checkComplete!=0 holds the idle signal; we're not idle if we're injecting dependencies
738 injectDependencies(module);
739
740 // try to immediately execute
741 // if already traversing a factory tree, then strict causes circular dependency to abort the execution; maybe
742 // it's possible to execute this require later after the current traversal completes and avoid the circular dependency.
743 // ...but *always* insist on immediate in synch mode
744 var strict = checkCompleteGuard && req.async;
745 checkCompleteGuard++;
746 execModule(module, strict);
747 checkIdle();
748 if(!module.executed){
749 // some deps weren't on board or circular dependency detected and strict; therefore, push into the execQ
750 execQ.push(module);
751 }
752 checkComplete();
753 }
754 }
755 return contextRequire;
756 },
2f01fe57 757
1354d172 758 createRequire = function(module){
2f01fe57 759 if(!module){
1354d172 760 return req;
2f01fe57 761 }
1354d172
AD
762 var result = module.require;
763 if(!result){
764 result = function(a1, a2, a3){
765 return contextRequire(a1, a2, a3, module, result);
766 };
767 module.require = mix(result, req);
768 result.module = module;
769 result.toUrl = function(name){
770 return toUrl(name, module);
771 };
772 result.toAbsMid = function(mid){
773 return toAbsMid(mid, module);
774 };
775 if(0){
776 result.undef = function(mid){
777 req.undef(mid, module);
778 };
779 }
780 if(1){
781 result.syncLoadNls = function(mid){
782 var nlsModuleInfo = getModuleInfo(mid, module),
783 nlsModule = modules[nlsModuleInfo.mid];
784 if(!nlsModule || !nlsModule.executed){
785 cached = cache[nlsModuleInfo.mid] || cache[nlsModuleInfo.cacheId];
786 if(cached){
787 evalModuleText(cached);
788 nlsModule = modules[nlsModuleInfo.mid];
789 }
790 }
791 return nlsModule && nlsModule.executed && nlsModule.result;
792 };
793 }
2f01fe57 794
1354d172
AD
795 }
796 return result;
797 },
2f01fe57 798
1354d172
AD
799 execQ =
800 // The list of modules that need to be evaluated.
801 [],
2f01fe57 802
1354d172
AD
803 defQ =
804 // The queue of define arguments sent to loader.
805 [],
2f01fe57 806
1354d172
AD
807 waiting =
808 // The set of modules upon which the loader is waiting for definition to arrive
809 {},
2f01fe57 810
1354d172
AD
811 setRequested = function(module){
812 module.injected = requested;
813 waiting[module.mid] = 1;
814 if(module.url){
815 waiting[module.url] = module.pack || 1;
816 }
817 },
2f01fe57 818
1354d172
AD
819 setArrived = function(module){
820 module.injected = arrived;
821 delete waiting[module.mid];
822 if(module.url){
823 delete waiting[module.url];
824 }
825 if(isEmpty(waiting)){
826 clearTimer();
827 1 && legacyMode==xd && (legacyMode = sync);
828 }
829 },
2f01fe57 830
1354d172
AD
831 execComplete = req.idle =
832 // says the loader has completed (or not) its work
833 function(){
834 return !defQ.length && isEmpty(waiting) && !execQ.length && !checkCompleteGuard;
835 },
836
837 runMapProg = function(targetMid, map){
838 // search for targetMid in map; return the map item if found; falsy otherwise
839 for(var i = 0; i < map.length; i++){
840 if(map[i][2].test(targetMid)){
841 return map[i];
842 }
2f01fe57 843 }
1354d172
AD
844 return 0;
845 },
2f01fe57 846
1354d172
AD
847 compactPath = function(path){
848 var result = [],
849 segment, lastSegment;
850 path = path.replace(/\\/g, '/').split('/');
851 while(path.length){
852 segment = path.shift();
853 if(segment==".." && result.length && lastSegment!=".."){
854 result.pop();
855 lastSegment = result[result.length - 1];
856 }else if(segment!="."){
857 result.push(lastSegment= segment);
858 } // else ignore "."
859 }
860 return result.join("/");
861 },
862
863 makeModuleInfo = function(pid, mid, pack, url, cacheId){
864 if(1){
865 var xd= req.isXdUrl(url);
866 return {pid:pid, mid:mid, pack:pack, url:url, executed:0, def:0, isXd:xd, isAmd:!!(xd || (packs[pid] && packs[pid].isAmd)), cacheId:cacheId};
867 }else{
868 return {pid:pid, mid:mid, pack:pack, url:url, executed:0, def:0, cacheId:cacheId};
2f01fe57 869 }
1354d172 870 },
2f01fe57 871
1354d172
AD
872 getModuleInfo_ = function(mid, referenceModule, packs, modules, baseUrl, packageMapProg, pathsMapProg, alwaysCreate){
873 // arguments are passed instead of using lexical variables so that this function my be used independent of the loader (e.g., the builder)
874 // alwaysCreate is useful in this case so that getModuleInfo never returns references to real modules owned by the loader
875 var pid, pack, midInPackage, mapProg, mapItem, path, url, result, isRelative, requestedMid, cacheId=0;
876 requestedMid = mid;
877 isRelative = /^\./.test(mid);
878 if(/(^\/)|(\:)|(\.js$)/.test(mid) || (isRelative && !referenceModule)){
879 // absolute path or protocol of .js filetype, or relative path but no reference module and therefore relative to page
880 // whatever it is, it's not a module but just a URL of some sort
881 return makeModuleInfo(0, mid, 0, mid);
882 }else{
883 // relative module ids are relative to the referenceModule; get rid of any dots
884 mid = compactPath(isRelative ? (referenceModule.mid + "/../" + mid) : mid);
885 if(/^\./.test(mid)){
886 throw makeError("irrationalPath", mid);
887 }
888 // find the package indicated by the mid, if any
889 mapProg = referenceModule && referenceModule.pack && referenceModule.pack.mapProg;
890 mapItem = (mapProg && runMapProg(mid, mapProg)) || runMapProg(mid, packageMapProg);
891 if(mapItem){
892 // mid specified a module that's a member of a package; figure out the package id and module id
893 // notice we expect pack.main to be valid with no pre or post slash
894 pid = mapItem[1];
895 mid = mid.substring(mapItem[3]);
896 pack = packs[pid];
897 if(!mid){
898 mid= pack.main;
899 }
900 midInPackage = mid;
901 cacheId = pack.reverseName + "/" + mid;
902 mid = pid + "/" + mid;
903 }else{
904 pid = "";
905 }
2f01fe57 906
1354d172
AD
907 // search aliases
908 var candidateLength = 0,
909 candidate = 0;
910 forEach(aliases, function(pair){
911 var match = mid.match(pair[0]);
912 if(match && match.length>candidateLength){
913 candidate = isFunction(pair[1]) ? mid.replace(pair[0], pair[1]) : pair[1];
2f01fe57 914 }
1354d172
AD
915 });
916 if(candidate){
917 return getModuleInfo_(candidate, 0, packs, modules, baseUrl, packageMapProg, pathsMapProg, alwaysCreate);
2f01fe57 918 }
2f01fe57 919
1354d172
AD
920 result = modules[mid];
921 if(result){
922 return alwaysCreate ? makeModuleInfo(result.pid, result.mid, result.pack, result.url, cacheId) : modules[mid];
923 }
2f01fe57 924 }
1354d172
AD
925 // get here iff the sought-after module does not yet exist; therefore, we need to compute the URL given the
926 // fully resolved (i.e., all relative indicators and package mapping resolved) module id
927
928 mapItem = runMapProg(mid, pathsMapProg);
929 if(mapItem){
930 url = mapItem[1] + mid.substring(mapItem[3] - 1);
931 }else if(pid){
932 url = pack.location + "/" + midInPackage;
933 }else if(has("config-tlmSiblingOfDojo")){
934 url = "../" + mid;
935 }else{
936 url = mid;
2f01fe57 937 }
1354d172
AD
938 // if result is not absolute, add baseUrl
939 if(!(/(^\/)|(\:)/.test(url))){
940 url = baseUrl + url;
2f01fe57 941 }
1354d172
AD
942 url += ".js";
943 return makeModuleInfo(pid, mid, pack, compactPath(url), cacheId);
944 },
2f01fe57 945
1354d172
AD
946 getModuleInfo = function(mid, referenceModule){
947 return getModuleInfo_(mid, referenceModule, packs, modules, req.baseUrl, packageMapProg, pathsMapProg);
948 },
2f01fe57 949
1354d172
AD
950 resolvePluginResourceId = function(plugin, prid, referenceModule){
951 return plugin.normalize ? plugin.normalize(prid, function(mid){return toAbsMid(mid, referenceModule);}) : toAbsMid(prid, referenceModule);
952 },
2f01fe57 953
1354d172
AD
954 dynamicPluginUidGenerator = 0,
955
956 getModule = function(mid, referenceModule, immediate){
957 // compute and optionally construct (if necessary) the module implied by the mid with respect to referenceModule
958 var match, plugin, prid, result;
959 match = mid.match(/^(.+?)\!(.*)$/);
960 if(match){
961 // name was <plugin-module>!<plugin-resource-id>
962 plugin = getModule(match[1], referenceModule, immediate);
963
964 if(1 && legacyMode == sync && !plugin.executed){
965 injectModule(plugin);
966 if(plugin.injected===arrived && !plugin.executed){
967 checkCompleteGuard++;
968 execModule(plugin);
969 checkIdle();
970 }
971 if(plugin.executed){
972 promoteModuleToPlugin(plugin);
973 }else{
974 // we are in xdomain mode for some reason
975 execQ.unshift(plugin);
976 }
977 }
2f01fe57 978
2f01fe57 979
2f01fe57 980
1354d172
AD
981 if(plugin.executed === executed && !plugin.load){
982 // executed the module not knowing it was a plugin
983 promoteModuleToPlugin(plugin);
984 }
2f01fe57 985
1354d172
AD
986 // 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
987 if(plugin.load){
988 prid = resolvePluginResourceId(plugin, match[2], referenceModule);
989 mid = (plugin.mid + "!" + (plugin.dynamic ? ++dynamicPluginUidGenerator + "!" : "") + prid);
990 }else{
991 prid = match[2];
992 mid = plugin.mid + "!" + (++dynamicPluginUidGenerator) + "!waitingForPlugin";
993 }
994 result = {plugin:plugin, mid:mid, req:createRequire(referenceModule), prid:prid};
995 }else{
996 result = getModuleInfo(mid, referenceModule);
997 }
998 return modules[result.mid] || (!immediate && (modules[result.mid] = result));
999 },
81bea17a 1000
1354d172
AD
1001 toAbsMid = req.toAbsMid = function(mid, referenceModule){
1002 return getModuleInfo(mid, referenceModule).mid;
1003 },
81bea17a 1004
1354d172
AD
1005 toUrl = req.toUrl = function(name, referenceModule){
1006 var moduleInfo = getModuleInfo(name+"/x", referenceModule),
1007 url = moduleInfo.url;
1008 return fixupUrl(moduleInfo.pid===0 ?
1009 // if pid===0, then name had a protocol or absolute path; either way, toUrl is the identify function in such cases
1010 name :
1011 // "/x.js" since getModuleInfo automatically appends ".js" and we appended "/x" to make name look likde a module id
1012 url.substring(0, url.length-5)
1013 );
1014 },
81bea17a 1015
1354d172
AD
1016 nonModuleProps = {
1017 injected: arrived,
1018 executed: executed,
1019 def: nonmodule,
1020 result: nonmodule
1021 },
2f01fe57 1022
1354d172
AD
1023 makeCjs = function(mid){
1024 return modules[mid] = mix({mid:mid}, nonModuleProps);
1025 },
2f01fe57 1026
1354d172
AD
1027 cjsRequireModule = makeCjs("require"),
1028 cjsExportsModule = makeCjs("exports"),
1029 cjsModuleModule = makeCjs("module"),
2f01fe57 1030
1354d172
AD
1031 runFactory = function(module, args){
1032 req.trace("loader-run-factory", [module.mid]);
1033 var factory = module.def,
1034 result;
1035 1 && syncExecStack.unshift(module);
1036 if(has("config-dojo-loader-catches")){
1037 try{
1038 result= isFunction(factory) ? factory.apply(null, args) : factory;
1039 }catch(e){
1040 signal(error, module.result = makeError("factoryThrew", [module, e]));
1041 }
1042 }else{
1043 result= isFunction(factory) ? factory.apply(null, args) : factory;
1044 }
1045 module.result = result===undefined && module.cjs ? module.cjs.exports : result;
1046 1 && syncExecStack.shift(module);
1047 },
2f01fe57 1048
1354d172 1049 abortExec = {},
2f01fe57 1050
1354d172 1051 defOrder = 0,
2f01fe57 1052
1354d172
AD
1053 promoteModuleToPlugin = function(pluginModule){
1054 var plugin = pluginModule.result;
1055 pluginModule.dynamic = plugin.dynamic;
1056 pluginModule.normalize = plugin.normalize;
1057 pluginModule.load = plugin.load;
1058 return pluginModule;
1059 },
2f01fe57 1060
1354d172
AD
1061 resolvePluginLoadQ = function(plugin){
1062 // plugins is a newly executed module that has a loadQ waiting to run
1063
1064 // step 1: traverse the loadQ and fixup the mid and prid; remember the map from original mid to new mid
1065 // recall the original mid was created before the plugin was on board and therefore it was impossible to
1066 // compute the final mid; accordingly, prid may or may not change, but the mid will definitely change
1067 var map = {};
1068 forEach(plugin.loadQ, function(pseudoPluginResource){
1069 // manufacture and insert the real module in modules
1070 var pseudoMid = pseudoPluginResource.mid,
1071 prid = resolvePluginResourceId(plugin, pseudoPluginResource.prid, pseudoPluginResource.req.module),
1072 mid = plugin.dynamic ? pseudoPluginResource.mid.replace(/waitingForPlugin$/, prid) : (plugin.mid + "!" + prid),
1073 pluginResource = mix(mix({}, pseudoPluginResource), {mid:mid, prid:prid, injected:0});
1074 if(!modules[mid]){
1075 // create a new (the real) plugin resource and inject it normally now that the plugin is on board
1076 injectPlugin(modules[mid] = pluginResource);
1077 } // else this was a duplicate request for the same (plugin, rid) for a nondynamic plugin
1078
1079 // pluginResource is really just a placeholder with the wrong mid (because we couldn't calculate it until the plugin was on board)
1080 // mark is as arrived and delete it from modules; the real module was requested above
1081 map[pseudoPluginResource.mid] = modules[mid];
1082 setArrived(pseudoPluginResource);
1083 delete modules[pseudoPluginResource.mid];
1084 });
1085 plugin.loadQ = 0;
1086
1087 // step2: replace all references to any placeholder modules with real modules
1088 var substituteModules = function(module){
1089 for(var replacement, deps = module.deps || [], i = 0; i<deps.length; i++){
1090 replacement = map[deps[i].mid];
1091 if(replacement){
1092 deps[i] = replacement;
2f01fe57 1093 }
2f01fe57 1094 }
1354d172
AD
1095 };
1096 for(var p in modules){
1097 substituteModules(modules[p]);
2f01fe57 1098 }
1354d172
AD
1099 forEach(execQ, substituteModules);
1100 },
2f01fe57 1101
1354d172
AD
1102 finishExec = function(module){
1103 req.trace("loader-finish-exec", [module.mid]);
1104 module.executed = executed;
1105 module.defOrder = defOrder++;
1106 1 && forEach(module.provides, function(cb){ cb(); });
1107 if(module.loadQ){
1108 // the module was a plugin
1109 promoteModuleToPlugin(module);
1110 resolvePluginLoadQ(module);
1111 }
1112 // remove all occurences of this module from the execQ
1113 for(i = 0; i < execQ.length;){
1114 if(execQ[i] === module){
1115 execQ.splice(i, 1);
1116 }else{
1117 i++;
1118 }
2f01fe57 1119 }
1354d172 1120 },
2f01fe57 1121
1354d172 1122 circleTrace = [],
2f01fe57 1123
1354d172
AD
1124 execModule = function(module, strict){
1125 // run the dependency vector, then run the factory for module
1126 if(module.executed === executing){
1127 req.trace("loader-circular-dependency", [circleTrace.concat(mid).join("->")]);
1128 return (!module.def || strict) ? abortExec : (module.cjs && module.cjs.exports);
1129 }
1130 // at this point the module is either not executed or fully executed
2f01fe57 1131
2f01fe57 1132
1354d172
AD
1133 if(!module.executed){
1134 if(!module.def){
1135 return abortExec;
1136 }
1137 var mid = module.mid,
1138 deps = module.deps || [],
1139 arg, argResult,
1140 args = [],
1141 i = 0;
1142
1143 if(0){
1144 circleTrace.push(mid);
1145 req.trace("loader-exec-module", ["exec", circleTrace.length, mid]);
1146 }
2f01fe57 1147
1354d172
AD
1148 // for circular dependencies, assume the first module encountered was executed OK
1149 // modules that circularly depend on a module that has not run its factory will get
1150 // the premade cjs.exports===module.result. They can take a reference to this object and/or
1151 // add properties to it. When the module finally runs its factory, the factory can
1152 // read/write/replace this object. Notice that so long as the object isn't replaced, any
1153 // reference taken earlier while walking the deps list is still valid.
1154 module.executed = executing;
1155 while(i < deps.length){
1156 arg = deps[i++];
1157 argResult = ((arg === cjsRequireModule) ? createRequire(module) :
1158 ((arg === cjsExportsModule) ? module.cjs.exports :
1159 ((arg === cjsModuleModule) ? module.cjs :
1160 execModule(arg, strict))));
1161 if(argResult === abortExec){
1162 module.executed = 0;
1163 req.trace("loader-exec-module", ["abort", mid]);
1164 0 && circleTrace.pop();
1165 return abortExec;
2f01fe57 1166 }
1354d172 1167 args.push(argResult);
2f01fe57 1168 }
1354d172
AD
1169 runFactory(module, args);
1170 finishExec(module);
2f01fe57 1171 }
1354d172 1172 // at this point the module is guaranteed fully executed
2f01fe57 1173
1354d172
AD
1174 0 && circleTrace.pop();
1175 return module.result;
1176 },
2f01fe57 1177
2f01fe57 1178
1354d172 1179 checkCompleteGuard = 0,
2f01fe57 1180
1354d172
AD
1181 checkComplete = function(){
1182 // keep going through the execQ as long as at least one factory is executed
1183 // plugins, recursion, cached modules all make for many execution path possibilities
1184 if(checkCompleteGuard){
1185 return;
2f01fe57 1186 }
1354d172
AD
1187 checkCompleteGuard++;
1188 checkDojoRequirePlugin();
1189 for(var currentDefOrder, module, i = 0; i < execQ.length;){
1190 currentDefOrder = defOrder;
1191 module = execQ[i];
1192 execModule(module);
1193 if(currentDefOrder!=defOrder){
1194 // defOrder was bumped one or more times indicating something was executed (note, this indicates
1195 // the execQ was modified, maybe a lot (for example a later module causes an earlier module to execute)
1196 checkDojoRequirePlugin();
1197 i = 0;
1198 }else{
1199 // nothing happened; check the next module in the exec queue
1200 i++;
2f01fe57 1201 }
2f01fe57 1202 }
1354d172
AD
1203 checkIdle();
1204 },
2f01fe57 1205
1354d172
AD
1206 checkIdle = function(){
1207 checkCompleteGuard--;
1208 if(execComplete()){
1209 signal("idle", []);
2f01fe57 1210 }
2f01fe57
AD
1211 };
1212
2f01fe57 1213
1354d172
AD
1214 if(0){
1215 req.undef = function(moduleId, referenceModule){
1216 // In order to reload a module, it must be undefined (this routine) and then re-requested.
1217 // This is useful for testing frameworks (at least).
1218 var module = getModule(moduleId, referenceModule);
1219 setArrived(module);
1220 delete modules[module.mid];
2f01fe57 1221 };
1354d172 1222 }
2f01fe57 1223
1354d172
AD
1224 if(1){
1225 if(has("dojo-loader-eval-hint-url")===undefined){
1226 has.add("dojo-loader-eval-hint-url", 1);
1227 }
2f01fe57 1228
1354d172
AD
1229 var fixupUrl= function(url){
1230 url += ""; // make sure url is a Javascript string (some paths may be a Java string)
1231 return url + (cacheBust ? ((/\?/.test(url) ? "&" : "?") + cacheBust) : "");
1232 },
1233
1234 injectPlugin = function(
1235 module
1236 ){
1237 // injects the plugin module given by module; may have to inject the plugin itself
1238 var plugin = module.plugin;
2f01fe57 1239
1354d172
AD
1240 if(plugin.executed === executed && !plugin.load){
1241 // executed the module not knowing it was a plugin
1242 promoteModuleToPlugin(plugin);
1243 }
2f01fe57 1244
1354d172
AD
1245 var onLoad = function(def){
1246 module.result = def;
1247 setArrived(module);
1248 finishExec(module);
1249 checkComplete();
1250 };
1251
1252 if(plugin.load){
1253 plugin.load(module.prid, module.req, onLoad);
1254 }else if(plugin.loadQ){
1255 plugin.loadQ.push(module);
1256 }else{
1257 // the unshift instead of push is important: we don't want plugins to execute as
1258 // dependencies of some other module because this may cause circles when the plugin
1259 // loadQ is run; also, generally, we want plugins to run early since they may load
1260 // several other modules and therefore can potentially unblock many modules
1261 plugin.loadQ = [module];
1262 execQ.unshift(plugin);
1263 injectModule(plugin);
1264 }
1265 },
2f01fe57 1266
1354d172 1267 // for IE, injecting a module may result in a recursive execution if the module is in the cache
2f01fe57 1268
1354d172 1269 cached = 0,
2f01fe57 1270
1354d172 1271 injectingModule = 0,
2f01fe57 1272
1354d172 1273 injectingCachedModule = 0,
2f01fe57 1274
1354d172
AD
1275 evalModuleText = function(text, module){
1276 // see def() for the injectingCachedModule bracket; it simply causes a short, safe curcuit
1277 injectingCachedModule = 1;
1278 if(has("config-dojo-loader-catches")){
2f01fe57 1279 try{
1354d172
AD
1280 if(text===cached){
1281 cached.call(null);
1282 }else{
1283 req.eval(text, has("dojo-loader-eval-hint-url") ? module.url : module.mid);
2f01fe57 1284 }
1354d172
AD
1285 }catch(e){
1286 signal(error, makeError("evalModuleThrew", module));
1287 }
1288 }else{
1289 if(text===cached){
1290 cached.call(null);
1291 }else{
1292 req.eval(text, has("dojo-loader-eval-hint-url") ? module.url : module.mid);
1293 }
1294 }
1295 injectingCachedModule = 0;
1296 },
2f01fe57 1297
1354d172
AD
1298 injectModule = function(module){
1299 // Inject the module. In the browser environment, this means appending a script element into
1300 // the document; in other environments, it means loading a file.
1301 //
1302 // If in synchronous mode, then get the module synchronously if it's not xdomainLoading.
2f01fe57 1303
1354d172
AD
1304 var mid = module.mid,
1305 url = module.url;
1306 if(module.executed || module.injected || waiting[mid] || (module.url && ((module.pack && waiting[module.url]===module.pack) || waiting[module.url]==1))){
1307 return;
1308 }
1309 setRequested(module);
1310
1311 if(0){
1312 var viaCombo = 0;
1313 if(module.plugin && module.plugin.isCombo){
1314 // a combo plugin; therefore, must be handled by combo service
1315 // the prid should have already been converted to a URL (if required by the plugin) during
1316 // the normalze process; in any event, there is no way for the loader to know how to
1317 // to the conversion; therefore the third argument is zero
1318 req.combo.add(module.plugin.mid, module.prid, 0, req);
1319 viaCombo = 1;
1320 }else if(!module.plugin){
1321 viaCombo = req.combo.add(0, module.mid, module.url, req);
1322 }
1323 if(viaCombo){
1324 comboPending= 1;
1325 return;
1326 }
1327 }
2f01fe57 1328
1354d172
AD
1329 if(module.plugin){
1330 injectPlugin(module);
1331 return;
1332 } // else a normal module (not a plugin)
1333
1334
1335 var onLoadCallback = function(){
1336 runDefQ(module);
1337 if(module.injected !== arrived){
1338 // the script that contained the module arrived and has been executed yet
1339 // nothing was added to the defQ (so it wasn't an AMD module) and the module
1340 // wasn't marked as arrived by dojo.provide (so it wasn't a v1.6- module);
1341 // therefore, it must not have been a module; adjust state accordingly
1342 setArrived(module);
1343 mix(module, nonModuleProps);
1344 }
2f01fe57 1345
1354d172
AD
1346 if(1 && legacyMode){
1347 // must call checkComplete even in for sync loader because we may be in xdomainLoading mode;
1348 // but, if xd loading, then don't call checkComplete until out of the current sync traversal
1349 // in order to preserve order of execution of the dojo.required modules
1350 !syncExecStack.length && checkComplete();
1351 }else{
1352 checkComplete();
1353 }
1354 };
1355 cached = cache[mid] || cache[module.cacheId];
1356 if(cached){
1357 req.trace("loader-inject", ["cache", module.mid, url]);
1358 evalModuleText(cached, module);
1359 onLoadCallback();
1360 return;
1361 }
1362 if(1 && legacyMode){
1363 if(module.isXd){
1364 // switch to async mode temporarily; if current legacyMode!=sync, then is must be one of {legacyAsync, xd, false}
1365 legacyMode==sync && (legacyMode = xd);
1366 // fall through and load via script injection
1367 }else if(module.isAmd && legacyMode!=sync){
1368 // fall through and load via script injection
1369 }else{
1370 // mode may be sync, xd/legacyAsync, or async; module may be AMD or legacy; but module is always located on the same domain
1371 var xhrCallback = function(text){
1372 if(legacyMode==sync){
1373 // the top of syncExecStack gives the current synchronously executing module; the loader needs
1374 // to know this if it has to switch to async loading in the middle of evaluating a legacy module
1375 // this happens when a modules dojo.require's a module that must be loaded async because it's xdomain
1376 // (using unshift/shift because there is no back() methods for Javascript arrays)
1377 syncExecStack.unshift(module);
1378 evalModuleText(text, module);
1379 syncExecStack.shift();
1380
1381 // maybe the module was an AMD module
1382 runDefQ(module);
1383
1384 // legacy modules never get to defineModule() => cjs and injected never set; also evaluation implies executing
1385 if(!module.cjs){
1386 setArrived(module);
1387 finishExec(module);
1388 }
2f01fe57 1389
1354d172
AD
1390 if(module.finish){
1391 // while synchronously evaluating this module, dojo.require was applied referencing a module
1392 // that had to be loaded async; therefore, the loader stopped answering all dojo.require
1393 // requests so they could be answered completely in the correct sequence; module.finish gives
1394 // the list of dojo.requires that must be re-applied once all target modules are available;
1395 // make a synthetic module to execute the dojo.require's in the correct order
1396
1397 // compute a guarnateed-unique mid for the synthetic finish module; remember the finish vector; remove it from the reference module
1398 // TODO: can we just leave the module.finish...what's it hurting?
1399 var finishMid = mid + "*finish",
1400 finish = module.finish;
1401 delete module.finish;
1402
1403 def(finishMid, ["dojo", ("dojo/require!" + finish.join(",")).replace(/\./g, "/")], function(dojo){
1404 forEach(finish, function(mid){ dojo.require(mid); });
1405 });
1406 // unshift, not push, which causes the current traversal to be reattempted from the top
1407 execQ.unshift(getModule(finishMid));
1408 }
1409 onLoadCallback();
1410 }else{
1411 text = transformToAmd(module, text);
1412 if(text){
1413 evalModuleText(text, module);
1414 onLoadCallback();
1415 }else{
1416 // if transformToAmd returned falsy, then the module was already AMD and it can be script-injected
1417 // do so to improve debugability(even though it means another download...which probably won't happen with a good browser cache)
1418 injectingModule = module;
1419 req.injectUrl(fixupUrl(url), onLoadCallback, module);
1420 injectingModule = 0;
1421 }
1422 }
1423 };
1424
1425 req.trace("loader-inject", ["xhr", module.mid, url, legacyMode!=sync]);
1426 if(has("config-dojo-loader-catches")){
1427 try{
1428 req.getText(url, legacyMode!=sync, xhrCallback);
1429 }catch(e){
1430 signal(error, makeError("xhrInjectFailed", [module, e]));
1431 }
1432 }else{
1433 req.getText(url, legacyMode!=sync, xhrCallback);
1434 }
1435 return;
1436 }
1437 } // else async mode or fell through in xdomain loading mode; either way, load by script injection
1438 req.trace("loader-inject", ["script", module.mid, url]);
1439 injectingModule = module;
1440 req.injectUrl(fixupUrl(url), onLoadCallback, module);
1441 injectingModule = 0;
1442 },
2f01fe57 1443
1354d172
AD
1444 defineModule = function(module, deps, def){
1445 req.trace("loader-define-module", [module.mid, deps]);
1446
1447 if(0 && module.plugin && module.plugin.isCombo){
1448 // the module is a plugin resource loaded by the combo service
1449 // note: check for module.plugin should be enough since normal plugin resources should
1450 // not follow this path; module.plugin.isCombo is future-proofing belt and suspenders
1451 module.result = isFunction(def) ? def() : def;
1452 setArrived(module);
1453 finishExec(module);
1454 return module;
1455 };
81bea17a 1456
1354d172
AD
1457 var mid = module.mid;
1458 if(module.injected === arrived){
1459 signal(error, makeError("multipleDefine", module));
1460 return module;
1461 }
1462 mix(module, {
1463 deps: deps,
1464 def: def,
1465 cjs: {
1466 id: module.mid,
1467 uri: module.url,
1468 exports: (module.result = {}),
1469 setExports: function(exports){
1470 module.cjs.exports = exports;
1471 }
1472 }
1473 });
2f01fe57 1474
1354d172
AD
1475 // resolve deps with respect to this module
1476 for(var i = 0; i < deps.length; i++){
1477 deps[i] = getModule(deps[i], module);
1478 }
81bea17a 1479
1354d172
AD
1480 if(1 && legacyMode && !waiting[mid]){
1481 // the module showed up without being asked for; it was probably in a <script> element
1482 injectDependencies(module);
1483 execQ.push(module);
1484 checkComplete();
1485 }
1486 setArrived(module);
2f01fe57 1487
1354d172
AD
1488 if(!isFunction(def) && !deps.length){
1489 module.result = def;
1490 finishExec(module);
1491 }
2f01fe57 1492
1354d172
AD
1493 return module;
1494 },
2f01fe57 1495
1354d172
AD
1496 runDefQ = function(referenceModule, mids){
1497 // defQ is an array of [id, dependencies, factory]
1498 // mids (if any) is a vector of mids given by a combo service
1499 var definedModules = [],
1500 module, args;
1501 while(defQ.length){
1502 args = defQ.shift();
1503 mids && (args[0]= mids.shift());
1504 // explicit define indicates possible multiple modules in a single file; delay injecting dependencies until defQ fully
1505 // processed since modules earlier in the queue depend on already-arrived modules that are later in the queue
1506 // TODO: what if no args[0] and no referenceModule
1507 module = (args[0] && getModule(args[0])) || referenceModule;
1508 definedModules.push([module, args[1], args[2]]);
1509 }
1510 consumePendingCacheInsert(referenceModule);
1511 forEach(definedModules, function(args){
1512 injectDependencies(defineModule.apply(null, args));
1513 });
1514 };
1515 }
2f01fe57 1516
1354d172
AD
1517 var timerId = 0,
1518 clearTimer = noop,
1519 startTimer = noop;
1520 if(1){
1521 // Timer machinery that monitors how long the loader is waiting and signals an error when the timer runs out.
1522 clearTimer = function(){
1523 timerId && clearTimeout(timerId);
1524 timerId = 0;
1525 },
2f01fe57 1526
1354d172
AD
1527 startTimer = function(){
1528 clearTimer();
1529 req.waitms && (timerId = setTimeout(function(){
1530 clearTimer();
1531 signal(error, makeError("timeout", waiting));
1532 }, req.waitms));
1533 };
1534 }
2f01fe57 1535
1354d172
AD
1536 if(1){
1537 has.add("ie-event-behavior", doc.attachEvent && (typeof opera === "undefined" || opera.toString() != "[object Opera]"));
1538 }
2f01fe57 1539
1354d172
AD
1540 if(1 && (1 || 1)){
1541 var domOn = function(node, eventName, ieEventName, handler){
1542 // Add an event listener to a DOM node using the API appropriate for the current browser;
1543 // return a function that will disconnect the listener.
1544 if(!has("ie-event-behavior")){
1545 node.addEventListener(eventName, handler, false);
1546 return function(){
1547 node.removeEventListener(eventName, handler, false);
1548 };
1549 }else{
1550 node.attachEvent(ieEventName, handler);
1551 return function(){
1552 node.detachEvent(ieEventName, handler);
1553 };
1554 }
1555 },
1556 windowOnLoadListener = domOn(window, "load", "onload", function(){
1557 req.pageLoaded = 1;
1558 doc.readyState!="complete" && (doc.readyState = "complete");
1559 windowOnLoadListener();
1560 });
2f01fe57 1561
1354d172
AD
1562 if(1){
1563 // if the loader is on the page, there must be at least one script element
1564 // getting its parent and then doing insertBefore solves the "Operation Aborted"
1565 // error in IE from appending to a node that isn't properly closed; see
1566 // dojo/tests/_base/loader/requirejs/simple-badbase.html for an example
1567 var sibling = doc.getElementsByTagName("script")[0],
1568 insertPoint= sibling.parentNode;
1569 req.injectUrl = function(url, callback, owner){
1570 // insert a script element to the insert-point element with src=url;
1571 // apply callback upon detecting the script has loaded.
1572
1573 startTimer();
1574 var node = owner.node = doc.createElement("script"),
1575 onLoad = function(e){
1576 e = e || window.event;
1577 var node = e.target || e.srcElement;
1578 if(e.type === "load" || /complete|loaded/.test(node.readyState)){
1579 disconnector();
1580 callback && callback();
1581 }
1582 },
1583 disconnector = domOn(node, "load", "onreadystatechange", onLoad);
1584 node.type = "text/javascript";
1585 node.charset = "utf-8";
1586 node.src = url;
1587 insertPoint.insertBefore(node, sibling);
1588 return node;
1589 };
2f01fe57 1590 }
1354d172 1591 }
2f01fe57 1592
1354d172
AD
1593 if(1){
1594 req.log = function(){
1595 try{
1596 for(var i = 0; i < arguments.length; i++){
1597 console.log(arguments[i]);
1598 }
1599 }catch(e){}
1600 };
1601 }else{
1602 req.log = noop;
1603 }
2f01fe57 1604
1354d172
AD
1605 if(0){
1606 var trace = req.trace = function(
1607 group, // the trace group to which this application belongs
1608 args // the contents of the trace
1609 ){
1610 ///
1611 // Tracing interface by group.
1612 //
1613 // Sends the contents of args to the console iff (req.trace.on && req.trace[group])
1614
1615 if(trace.on && trace.group[group]){
1616 signal("trace", [group, args]);
1617 for(var arg, dump = [], text= "trace:" + group + (args.length ? (":" + args[0]) : ""), i= 1; i<args.length;){
1618 arg = args[i++];
1619 if(isString(arg)){
1620 text += ", " + arg;
1621 }else{
1622 dump.push(arg);
1623 }
1624 }
1625 req.log(text);
1626 dump.length && dump.push(".");
1627 req.log.apply(req, dump);
1628 }
1629 };
1630 mix(trace, {
1631 on:1,
1632 group:{},
1633 set:function(group, value){
1634 if(isString(group)){
1635 trace.group[group]= value;
1636 }else{
1637 mix(trace.group, group);
1638 }
1639 }
1640 });
1641 trace.set(mix(mix(mix({}, defaultConfig.trace), userConfig.trace), dojoSniffConfig.trace));
1642 on("config", function(config){
1643 config.trace && trace.set(config.trace);
1644 });
1645 }else{
1646 req.trace = noop;
1647 }
1648
1649 var def = function(
1650 mid, //(commonjs.moduleId, optional) list of modules to be loaded before running factory
1651 dependencies, //(array of commonjs.moduleId, optional)
1652 factory //(any)
1653 ){
1654 ///
1655 // Advises the loader of a module factory. //Implements http://wiki.commonjs.org/wiki/Modules/AsynchronousDefinition.
1656 ///
1657 //note
1658 // CommonJS factory scan courtesy of http://requirejs.org
1659
1660 var arity = arguments.length,
1661 args = 0,
1662 defaultDeps = ["require", "exports", "module"];
1663
1664 if(0){
1665 if(arity == 1 && isFunction(mid)){
1666 dependencies = [];
1667 mid.toString()
1668 .replace(/(\/\*([\s\S]*?)\*\/|\/\/(.*)$)/mg, "")
1669 .replace(/require\(["']([\w\!\-_\.\/]+)["']\)/g, function (match, dep){
1670 dependencies.push(dep);
1671 });
1672 args = [0, defaultDeps.concat(dependencies), mid];
1673 }
1674 }
1675 if(!args){
1676 args = arity == 1 ? [0, defaultDeps, mid] :
1677 (arity == 2 ? (isArray(mid) ? [0, mid, dependencies] : (isFunction(dependencies) ? [mid, defaultDeps, dependencies] : [mid, [], dependencies])) :
1678 [mid, dependencies, factory]);
1679 }
1680 req.trace("loader-define", args.slice(0, 2));
1681 var targetModule = args[0] && getModule(args[0]),
1682 module;
1683 if(targetModule && !waiting[targetModule.mid]){
1684 // given a mid that hasn't been requested; therefore, defined through means other than injecting
1685 // consequent to a require() or define() application; examples include defining modules on-the-fly
1686 // due to some code path or including a module in a script element. In any case,
1687 // there is no callback waiting to finish processing and nothing to trigger the defQ and the
1688 // dependencies are never requested; therefore, do it here.
1689 injectDependencies(defineModule(targetModule, args[1], args[2]));
1690 }else if(!has("ie-event-behavior") || !1 || injectingCachedModule){
1691 // not IE path: anonymous module and therefore must have been injected; therefore, onLoad will fire immediately
1692 // after script finishes being evaluated and the defQ can be run from that callback to detect the module id
1693 defQ.push(args);
1694 }else{
1695 // IE path: possibly anonymous module and therefore injected; therefore, cannot depend on 1-to-1,
1696 // in-order exec of onLoad with script eval (since it's IE) and must manually detect here
1697 targetModule = targetModule || injectingModule;
1698 if(!targetModule){
1699 for(mid in waiting){
1700 module = modules[mid];
1701 if(module && module.node && module.node.readyState === 'interactive'){
1702 targetModule = module;
1703 break;
1704 }
1705 }
1706 if(0 && !targetModule){
1707 for(var i = 0; i<combosPending.length; i++){
1708 targetModule = combosPending[i];
1709 if(targetModule.node && targetModule.node.readyState === 'interactive'){
1710 break;
1711 }
1712 targetModule= 0;
1713 }
1714 }
1715 }
1716 if(0 && isArray(targetModule)){
1717 injectDependencies(defineModule(getModule(targetModule.shift()), args[1], args[2]));
1718 if(!targetModule.length){
1719 combosPending.splice(i, 1);
1720 }
1721 }else if(targetModule){
1722 consumePendingCacheInsert(targetModule);
1723 injectDependencies(defineModule(targetModule, args[1], args[2]));
1724 }else{
1725 signal(error, makeError("ieDefineFailed", args[0]));
1726 }
1727 checkComplete();
2f01fe57 1728 }
1354d172
AD
1729 };
1730 def.amd = {
1731 vendor:"dojotoolkit.org"
81bea17a 1732 };
2f01fe57 1733
1354d172
AD
1734 if(0){
1735 req.def = def;
2f01fe57 1736 }
2f01fe57 1737
1354d172
AD
1738 // allow config to override default implemention of named functions; this is useful for
1739 // non-browser environments, e.g., overriding injectUrl, getText, log, etc. in node.js, Rhino, etc.
1740 // also useful for testing and monkey patching loader
1741 mix(mix(req, defaultConfig.loaderPatch), userConfig.loaderPatch);
2f01fe57 1742
1354d172
AD
1743 // now that req is fully initialized and won't change, we can hook it up to the error signal
1744 on(error, function(arg){
1745 try{
1746 console.error(arg);
1747 if(arg instanceof Error){
1748 for(var p in arg){
1749 console.log(p + ":", arg[p]);
1750 }
1751 console.log(".");
1752 }
1753 }catch(e){}
1754 });
1755
1756 // always publish these
1757 mix(req, {
1758 uid:uid,
1759 cache:cache,
1760 packs:packs
1761 });
1762
1763
1764 if(0){
1765 mix(req, {
1766 // these may be interesting to look at when debugging
1767 paths:paths,
1768 aliases:aliases,
1769 packageMap:packageMap,
1770 modules:modules,
1771 legacyMode:legacyMode,
1772 execQ:execQ,
1773 defQ:defQ,
1774 waiting:waiting,
1775
1776 // these are used for testing
1777 // TODO: move testing infrastructure to a different has feature
1778 pathsMapProg:pathsMapProg,
1779 packageMapProg:packageMapProg,
1780 listenerQueues:listenerQueues,
1781
1782 // these are used by the builder (at least)
1783 computeMapProg:computeMapProg,
1784 runMapProg:runMapProg,
1785 compactPath:compactPath,
1786 getModuleInfo:getModuleInfo_
1787 });
2f01fe57 1788 }
2f01fe57 1789
1354d172
AD
1790 // the loader can be defined exactly once; look for global define which is the symbol AMD loaders are
1791 // *required* to define (as opposed to require, which is optional)
1792 if(global.define){
1793 if(1){
1794 signal(error, makeError("defineAlreadyDefined", 0));
1795 }
1796 }else{
1797 global.define = def;
1798 global.require = req;
1799 }
2f01fe57 1800
1354d172
AD
1801 if(0 && req.combo && req.combo.plugins){
1802 var plugins = req.combo.plugins,
1803 pluginName;
1804 for(pluginName in plugins){
1805 mix(mix(getModule(pluginName), plugins[pluginName]), {isCombo:1, executed:"executed", load:1});
2f01fe57 1806 }
1354d172
AD
1807 }
1808
1809 if(1){
1810 var bootDeps = dojoSniffConfig.deps || userConfig.deps || defaultConfig.deps,
1811 bootCallback = dojoSniffConfig.callback || userConfig.callback || defaultConfig.callback;
1812 req.boot = (bootDeps || bootCallback) ? [bootDeps || [], bootCallback] : 0;
1813 }
1814 if(!1){
1815 !req.async && req(["dojo"]);
1816 req.boot && req.apply(null, req.boot);
1817 }
1818})
1819(this.dojoConfig || this.djConfig || this.require || {}, {
1820 async:0,
1821 hasCache:{
1822 'config-selectorEngine':"acme",
1823 'config-tlmSiblingOfDojo':1,
1824 'dojo-built':1,
1825 'dojo-loader':1,
1826 dom:1,
1827 'host-browser':1
1828 },
1829 packages:[
1830 {
1831 location:"../dijit",
1832 name:"dijit"
1833 },
1834 {
1835 location:".",
1836 name:"dojo"
1837 }
1838 ]
1839});require({cache:{
1840'dojo/_base/fx':function(){
1841define(["./kernel", "./lang", "../Evented", "./Color", "./connect", "./sniff", "../dom", "../dom-style"], function(dojo, lang, Evented, Color, connect, has, dom, style){
1842 // module:
1843 // dojo/_base/fx
1844 // summary:
1845 // This module defines the base dojo.fx implementation.
1846 // notes:
1847 // Animation loosely package based on Dan Pupius' work, contributed under CLA; see
1848 // http://pupius.co.uk/js/Toolkit.Drawing.js
1849
1850 var _mixin = lang.mixin;
2f01fe57 1851
1354d172 1852 dojo._Line = function(/*int*/ start, /*int*/ end){
2f01fe57 1853 // summary:
1354d172
AD
1854 // dojo._Line is the object used to generate values from a start value
1855 // to an end value
1856 // start: int
1857 // Beginning value for range
1858 // end: int
1859 // Ending value for range
1860 this.start = start;
1861 this.end = end;
81bea17a 1862 };
2f01fe57 1863
1354d172
AD
1864 dojo._Line.prototype.getValue = function(/*float*/ n){
1865 // summary: Returns the point on the line
1866 // n: a floating point number greater than 0 and less than 1
1867 return ((this.end - this.start) * n) + this.start; // Decimal
81bea17a 1868 };
2f01fe57 1869
1354d172 1870 dojo.Animation = function(args){
2f01fe57 1871 // summary:
1354d172
AD
1872 // A generic animation class that fires callbacks into its handlers
1873 // object at various states.
2f01fe57 1874 // description:
1354d172
AD
1875 // A generic animation class that fires callbacks into its handlers
1876 // object at various states. Nearly all dojo animation functions
1877 // return an instance of this method, usually without calling the
1878 // .play() method beforehand. Therefore, you will likely need to
1879 // call .play() on instances of `dojo.Animation` when one is
1880 // returned.
1881 // args: Object
1882 // The 'magic argument', mixing all the properties into this
1883 // animation instance.
2f01fe57 1884
1354d172
AD
1885 _mixin(this, args);
1886 if(lang.isArray(this.curve)){
1887 this.curve = new dojo._Line(this.curve[0], this.curve[1]);
1888 }
2f01fe57 1889
2f01fe57 1890 };
1354d172
AD
1891 dojo.Animation.prototype = new Evented();
1892 // Alias to drop come 2.0:
1893 dojo._Animation = dojo.Animation;
2f01fe57 1894
1354d172
AD
1895 lang.extend(dojo.Animation, {
1896 // duration: Integer
1897 // The time in milliseonds the animation will take to run
1898 duration: 350,
2f01fe57 1899
1354d172
AD
1900 /*=====
1901 // curve: dojo._Line|Array
1902 // A two element array of start and end values, or a `dojo._Line` instance to be
1903 // used in the Animation.
1904 curve: null,
2f01fe57 1905
1354d172
AD
1906 // easing: Function?
1907 // A Function to adjust the acceleration (or deceleration) of the progress
1908 // across a dojo._Line
1909 easing: null,
1910 =====*/
81bea17a 1911
1354d172
AD
1912 // repeat: Integer?
1913 // The number of times to loop the animation
1914 repeat: 0,
81bea17a 1915
1354d172
AD
1916 // rate: Integer?
1917 // the time in milliseconds to wait before advancing to next frame
1918 // (used as a fps timer: 1000/rate = fps)
1919 rate: 20 /* 50 fps */,
2f01fe57 1920
1354d172
AD
1921 /*=====
1922 // delay: Integer?
1923 // The time in milliseconds to wait before starting animation after it
1924 // has been .play()'ed
1925 delay: null,
2f01fe57 1926
1354d172
AD
1927 // beforeBegin: Event?
1928 // Synthetic event fired before a dojo.Animation begins playing (synchronous)
1929 beforeBegin: null,
2f01fe57 1930
1354d172
AD
1931 // onBegin: Event?
1932 // Synthetic event fired as a dojo.Animation begins playing (useful?)
1933 onBegin: null,
2f01fe57 1934
1354d172
AD
1935 // onAnimate: Event?
1936 // Synthetic event fired at each interval of a `dojo.Animation`
1937 onAnimate: null,
2f01fe57 1938
1354d172
AD
1939 // onEnd: Event?
1940 // Synthetic event fired after the final frame of a `dojo.Animation`
1941 onEnd: null,
2f01fe57 1942
1354d172
AD
1943 // onPlay: Event?
1944 // Synthetic event fired any time a `dojo.Animation` is play()'ed
1945 onPlay: null,
2f01fe57 1946
1354d172
AD
1947 // onPause: Event?
1948 // Synthetic event fired when a `dojo.Animation` is paused
1949 onPause: null,
2f01fe57 1950
1354d172
AD
1951 // onStop: Event
1952 // Synthetic event fires when a `dojo.Animation` is stopped
1953 onStop: null,
2f01fe57 1954
1354d172 1955 =====*/
2f01fe57 1956
1354d172
AD
1957 _percent: 0,
1958 _startRepeatCount: 0,
2f01fe57 1959
1354d172
AD
1960 _getStep: function(){
1961 var _p = this._percent,
1962 _e = this.easing
1963 ;
1964 return _e ? _e(_p) : _p;
1965 },
1966 _fire: function(/*Event*/ evt, /*Array?*/ args){
1967 // summary:
1968 // Convenience function. Fire event "evt" and pass it the
1969 // arguments specified in "args".
1970 // description:
1971 // Convenience function. Fire event "evt" and pass it the
1972 // arguments specified in "args".
1973 // Fires the callback in the scope of the `dojo.Animation`
1974 // instance.
1975 // evt:
1976 // The event to fire.
1977 // args:
1978 // The arguments to pass to the event.
1979 var a = args||[];
1980 if(this[evt]){
1981 if(dojo.config.debugAtAllCosts){
1982 this[evt].apply(this, a);
1983 }else{
1984 try{
1985 this[evt].apply(this, a);
1986 }catch(e){
1987 // squelch and log because we shouldn't allow exceptions in
1988 // synthetic event handlers to cause the internal timer to run
1989 // amuck, potentially pegging the CPU. I'm not a fan of this
1990 // squelch, but hopefully logging will make it clear what's
1991 // going on
1992 console.error("exception in animation handler for:", evt);
1993 console.error(e);
1994 }
1995 }
2f01fe57 1996 }
1354d172 1997 return this; // dojo.Animation
2f01fe57
AD
1998 },
1999
1354d172 2000 play: function(/*int?*/ delay, /*Boolean?*/ gotoStart){
2f01fe57 2001 // summary:
1354d172
AD
2002 // Start the animation.
2003 // delay:
2004 // How many milliseconds to delay before starting.
2005 // gotoStart:
2006 // If true, starts the animation from the beginning; otherwise,
2007 // starts it from its current position.
2008 // returns: dojo.Animation
2009 // The instance to allow chaining.
2f01fe57 2010
1354d172
AD
2011 var _t = this;
2012 if(_t._delayTimer){ _t._clearTimer(); }
2013 if(gotoStart){
2014 _t._stopTimer();
2015 _t._active = _t._paused = false;
2016 _t._percent = 0;
2017 }else if(_t._active && !_t._paused){
2018 return _t;
2f01fe57 2019 }
2f01fe57 2020
1354d172 2021 _t._fire("beforeBegin", [_t.node]);
2f01fe57 2022
1354d172
AD
2023 var de = delay || _t.delay,
2024 _p = lang.hitch(_t, "_play", gotoStart);
2f01fe57 2025
1354d172
AD
2026 if(de > 0){
2027 _t._delayTimer = setTimeout(_p, de);
2028 return _t;
2029 }
2030 _p();
2031 return _t; // dojo.Animation
2032 },
2f01fe57 2033
1354d172
AD
2034 _play: function(gotoStart){
2035 var _t = this;
2036 if(_t._delayTimer){ _t._clearTimer(); }
2037 _t._startTime = new Date().valueOf();
2038 if(_t._paused){
2039 _t._startTime -= _t.duration * _t._percent;
2040 }
2f01fe57 2041
1354d172
AD
2042 _t._active = true;
2043 _t._paused = false;
2044 var value = _t.curve.getValue(_t._getStep());
2045 if(!_t._percent){
2046 if(!_t._startRepeatCount){
2047 _t._startRepeatCount = _t.repeat;
2048 }
2049 _t._fire("onBegin", [value]);
2050 }
2f01fe57 2051
1354d172 2052 _t._fire("onPlay", [value]);
2f01fe57 2053
1354d172
AD
2054 _t._cycle();
2055 return _t; // dojo.Animation
2056 },
2f01fe57 2057
1354d172
AD
2058 pause: function(){
2059 // summary: Pauses a running animation.
2060 var _t = this;
2061 if(_t._delayTimer){ _t._clearTimer(); }
2062 _t._stopTimer();
2063 if(!_t._active){ return _t; /*dojo.Animation*/ }
2064 _t._paused = true;
2065 _t._fire("onPause", [_t.curve.getValue(_t._getStep())]);
2066 return _t; // dojo.Animation
2067 },
2f01fe57 2068
1354d172
AD
2069 gotoPercent: function(/*Decimal*/ percent, /*Boolean?*/ andPlay){
2070 // summary:
2071 // Sets the progress of the animation.
2072 // percent:
2073 // A percentage in decimal notation (between and including 0.0 and 1.0).
2074 // andPlay:
2075 // If true, play the animation after setting the progress.
2076 var _t = this;
2077 _t._stopTimer();
2078 _t._active = _t._paused = true;
2079 _t._percent = percent;
2080 if(andPlay){ _t.play(); }
2081 return _t; // dojo.Animation
2082 },
2f01fe57 2083
1354d172
AD
2084 stop: function(/*boolean?*/ gotoEnd){
2085 // summary: Stops a running animation.
2086 // gotoEnd: If true, the animation will end.
2087 var _t = this;
2088 if(_t._delayTimer){ _t._clearTimer(); }
2089 if(!_t._timer){ return _t; /* dojo.Animation */ }
2090 _t._stopTimer();
2091 if(gotoEnd){
2092 _t._percent = 1;
2f01fe57 2093 }
1354d172
AD
2094 _t._fire("onStop", [_t.curve.getValue(_t._getStep())]);
2095 _t._active = _t._paused = false;
2096 return _t; // dojo.Animation
2097 },
2f01fe57 2098
1354d172
AD
2099 status: function(){
2100 // summary:
2101 // Returns a string token representation of the status of
2102 // the animation, one of: "paused", "playing", "stopped"
2103 if(this._active){
2104 return this._paused ? "paused" : "playing"; // String
2105 }
2106 return "stopped"; // String
2107 },
2f01fe57 2108
1354d172
AD
2109 _cycle: function(){
2110 var _t = this;
2111 if(_t._active){
2112 var curr = new Date().valueOf();
2113 var step = (curr - _t._startTime) / (_t.duration);
2f01fe57 2114
1354d172
AD
2115 if(step >= 1){
2116 step = 1;
2117 }
2118 _t._percent = step;
2f01fe57 2119
1354d172
AD
2120 // Perform easing
2121 if(_t.easing){
2122 step = _t.easing(step);
2123 }
2f01fe57 2124
1354d172 2125 _t._fire("onAnimate", [_t.curve.getValue(step)]);
2f01fe57 2126
1354d172
AD
2127 if(_t._percent < 1){
2128 _t._startTimer();
2f01fe57 2129 }else{
1354d172
AD
2130 _t._active = false;
2131
2132 if(_t.repeat > 0){
2133 _t.repeat--;
2134 _t.play(null, true);
2135 }else if(_t.repeat == -1){
2136 _t.play(null, true);
2137 }else{
2138 if(_t._startRepeatCount){
2139 _t.repeat = _t._startRepeatCount;
2140 _t._startRepeatCount = 0;
2f01fe57
AD
2141 }
2142 }
1354d172
AD
2143 _t._percent = 0;
2144 _t._fire("onEnd", [_t.node]);
2145 !_t.repeat && _t._stopTimer();
2f01fe57
AD
2146 }
2147 }
1354d172
AD
2148 return _t; // dojo.Animation
2149 },
2150
2151 _clearTimer: function(){
2152 // summary: Clear the play delay timer
2153 clearTimeout(this._delayTimer);
2154 delete this._delayTimer;
2f01fe57
AD
2155 }
2156
1354d172 2157 });
2f01fe57 2158
1354d172
AD
2159 // the local timer, stubbed into all Animation instances
2160 var ctr = 0,
2161 timer = null,
2162 runner = {
2163 run: function(){}
2164 };
2f01fe57 2165
1354d172 2166 lang.extend(dojo.Animation, {
2f01fe57 2167
1354d172
AD
2168 _startTimer: function(){
2169 if(!this._timer){
2170 this._timer = connect.connect(runner, "run", this, "_cycle");
2171 ctr++;
2f01fe57 2172 }
1354d172
AD
2173 if(!timer){
2174 timer = setInterval(lang.hitch(runner, "run"), this.rate);
2175 }
2176 },
2f01fe57 2177
1354d172
AD
2178 _stopTimer: function(){
2179 if(this._timer){
2180 connect.disconnect(this._timer);
2181 this._timer = null;
2182 ctr--;
2f01fe57 2183 }
1354d172
AD
2184 if(ctr <= 0){
2185 clearInterval(timer);
2186 timer = null;
2187 ctr = 0;
2f01fe57
AD
2188 }
2189 }
2f01fe57 2190
1354d172
AD
2191 });
2192
2193 var _makeFadeable =
2194 has("ie") ? function(node){
2195 // only set the zoom if the "tickle" value would be the same as the
2196 // default
2197 var ns = node.style;
2198 // don't set the width to auto if it didn't already cascade that way.
2199 // We don't want to f anyones designs
2200 if(!ns.width.length && style.get(node, "width") == "auto"){
2201 ns.width = "auto";
2f01fe57 2202 }
1354d172
AD
2203 } :
2204 function(){};
2f01fe57 2205
1354d172
AD
2206 dojo._fade = function(/*Object*/ args){
2207 // summary:
2208 // Returns an animation that will fade the node defined by
2209 // args.node from the start to end values passed (args.start
2210 // args.end) (end is mandatory, start is optional)
2f01fe57 2211
1354d172
AD
2212 args.node = dom.byId(args.node);
2213 var fArgs = _mixin({ properties: {} }, args),
2214 props = (fArgs.properties.opacity = {});
2f01fe57 2215
1354d172
AD
2216 props.start = !("start" in fArgs) ?
2217 function(){
2218 return +style.get(fArgs.node, "opacity")||0;
2219 } : fArgs.start;
2220 props.end = fArgs.end;
2f01fe57 2221
1354d172
AD
2222 var anim = dojo.animateProperty(fArgs);
2223 connect.connect(anim, "beforeBegin", lang.partial(_makeFadeable, fArgs.node));
2f01fe57 2224
1354d172
AD
2225 return anim; // dojo.Animation
2226 };
2f01fe57 2227
1354d172
AD
2228 /*=====
2229 dojo.__FadeArgs = function(node, duration, easing){
2230 // node: DOMNode|String
2231 // The node referenced in the animation
2232 // duration: Integer?
2233 // Duration of the animation in milliseconds.
2234 // easing: Function?
2235 // An easing function.
2236 this.node = node;
2237 this.duration = duration;
2238 this.easing = easing;
2239 }
2240 =====*/
2f01fe57 2241
1354d172
AD
2242 dojo.fadeIn = function(/*dojo.__FadeArgs*/ args){
2243 // summary:
2244 // Returns an animation that will fade node defined in 'args' from
2245 // its current opacity to fully opaque.
2246 return dojo._fade(_mixin({ end: 1 }, args)); // dojo.Animation
2247 };
2f01fe57 2248
1354d172
AD
2249 dojo.fadeOut = function(/*dojo.__FadeArgs*/ args){
2250 // summary:
2251 // Returns an animation that will fade node defined in 'args'
2252 // from its current opacity to fully transparent.
2253 return dojo._fade(_mixin({ end: 0 }, args)); // dojo.Animation
2254 };
2f01fe57 2255
1354d172
AD
2256 dojo._defaultEasing = function(/*Decimal?*/ n){
2257 // summary: The default easing function for dojo.Animation(s)
2258 return 0.5 + ((Math.sin((n + 1.5) * Math.PI)) / 2); // Decimal
2259 };
2f01fe57 2260
1354d172
AD
2261 var PropLine = function(properties){
2262 // PropLine is an internal class which is used to model the values of
2263 // an a group of CSS properties across an animation lifecycle. In
2264 // particular, the "getValue" function handles getting interpolated
2265 // values between start and end for a particular CSS value.
2266 this._properties = properties;
2267 for(var p in properties){
2268 var prop = properties[p];
2269 if(prop.start instanceof Color){
2270 // create a reusable temp color object to keep intermediate results
2271 prop.tempColor = new Color();
2f01fe57 2272 }
1354d172
AD
2273 }
2274 };
2f01fe57 2275
1354d172
AD
2276 PropLine.prototype.getValue = function(r){
2277 var ret = {};
2278 for(var p in this._properties){
2279 var prop = this._properties[p],
2280 start = prop.start;
2281 if(start instanceof Color){
2282 ret[p] = Color.blendColors(start, prop.end, r, prop.tempColor).toCss();
2283 }else if(!lang.isArray(start)){
2284 ret[p] = ((prop.end - start) * r) + start + (p != "opacity" ? prop.units || "px" : 0);
2f01fe57 2285 }
1354d172
AD
2286 }
2287 return ret;
2288 };
2f01fe57 2289
1354d172
AD
2290 /*=====
2291 dojo.declare("dojo.__AnimArgs", [dojo.__FadeArgs], {
2292 // Properties: Object?
2293 // A hash map of style properties to Objects describing the transition,
2294 // such as the properties of dojo._Line with an additional 'units' property
2295 properties: {}
2f01fe57 2296
1354d172
AD
2297 //TODOC: add event callbacks
2298 });
2299 =====*/
2f01fe57 2300
1354d172
AD
2301 dojo.animateProperty = function(/*dojo.__AnimArgs*/ args){
2302 // summary:
2303 // Returns an animation that will transition the properties of
2304 // node defined in `args` depending how they are defined in
2305 // `args.properties`
2306 //
2307 // description:
2308 // `dojo.animateProperty` is the foundation of most `dojo.fx`
2309 // animations. It takes an object of "properties" corresponding to
2310 // style properties, and animates them in parallel over a set
2311 // duration.
2312 //
2313 // example:
2314 // A simple animation that changes the width of the specified node.
2315 // | dojo.animateProperty({
2316 // | node: "nodeId",
2317 // | properties: { width: 400 },
2318 // | }).play();
2319 // Dojo figures out the start value for the width and converts the
2320 // integer specified for the width to the more expressive but
2321 // verbose form `{ width: { end: '400', units: 'px' } }` which you
2322 // can also specify directly. Defaults to 'px' if ommitted.
2323 //
2324 // example:
2325 // Animate width, height, and padding over 2 seconds... the
2326 // pedantic way:
2327 // | dojo.animateProperty({ node: node, duration:2000,
2328 // | properties: {
2329 // | width: { start: '200', end: '400', units:"px" },
2330 // | height: { start:'200', end: '400', units:"px" },
2331 // | paddingTop: { start:'5', end:'50', units:"px" }
2332 // | }
2333 // | }).play();
2334 // Note 'paddingTop' is used over 'padding-top'. Multi-name CSS properties
2335 // are written using "mixed case", as the hyphen is illegal as an object key.
2336 //
2337 // example:
2338 // Plug in a different easing function and register a callback for
2339 // when the animation ends. Easing functions accept values between
2340 // zero and one and return a value on that basis. In this case, an
2341 // exponential-in curve.
2342 // | dojo.animateProperty({
2343 // | node: "nodeId",
2344 // | // dojo figures out the start value
2345 // | properties: { width: { end: 400 } },
2346 // | easing: function(n){
2347 // | return (n==0) ? 0 : Math.pow(2, 10 * (n - 1));
2348 // | },
2349 // | onEnd: function(node){
2350 // | // called when the animation finishes. The animation
2351 // | // target is passed to this function
2352 // | }
2353 // | }).play(500); // delay playing half a second
2354 //
2355 // example:
2356 // Like all `dojo.Animation`s, animateProperty returns a handle to the
2357 // Animation instance, which fires the events common to Dojo FX. Use `dojo.connect`
2358 // to access these events outside of the Animation definiton:
2359 // | var anim = dojo.animateProperty({
2360 // | node:"someId",
2361 // | properties:{
2362 // | width:400, height:500
2363 // | }
2364 // | });
2365 // | dojo.connect(anim,"onEnd", function(){
2366 // | console.log("animation ended");
2367 // | });
2368 // | // play the animation now:
2369 // | anim.play();
2370 //
2371 // example:
2372 // Each property can be a function whose return value is substituted along.
2373 // Additionally, each measurement (eg: start, end) can be a function. The node
2374 // reference is passed direcly to callbacks.
2375 // | dojo.animateProperty({
2376 // | node:"mine",
2377 // | properties:{
2378 // | height:function(node){
2379 // | // shrink this node by 50%
2380 // | return dojo.position(node).h / 2
2381 // | },
2382 // | width:{
2383 // | start:function(node){ return 100; },
2384 // | end:function(node){ return 200; }
2385 // | }
2386 // | }
2387 // | }).play();
2388 //
2f01fe57 2389
1354d172
AD
2390 var n = args.node = dom.byId(args.node);
2391 if(!args.easing){ args.easing = dojo._defaultEasing; }
2f01fe57 2392
1354d172
AD
2393 var anim = new dojo.Animation(args);
2394 connect.connect(anim, "beforeBegin", anim, function(){
2395 var pm = {};
2396 for(var p in this.properties){
2397 // Make shallow copy of properties into pm because we overwrite
2398 // some values below. In particular if start/end are functions
2399 // we don't want to overwrite them or the functions won't be
2400 // called if the animation is reused.
2401 if(p == "width" || p == "height"){
2402 this.node.display = "block";
2f01fe57 2403 }
1354d172
AD
2404 var prop = this.properties[p];
2405 if(lang.isFunction(prop)){
2406 prop = prop(n);
2f01fe57 2407 }
1354d172 2408 prop = pm[p] = _mixin({}, (lang.isObject(prop) ? prop: { end: prop }));
2f01fe57 2409
1354d172
AD
2410 if(lang.isFunction(prop.start)){
2411 prop.start = prop.start(n);
2412 }
2413 if(lang.isFunction(prop.end)){
2414 prop.end = prop.end(n);
2415 }
2416 var isColor = (p.toLowerCase().indexOf("color") >= 0);
2417 function getStyle(node, p){
2418 // dojo.style(node, "height") can return "auto" or "" on IE; this is more reliable:
2419 var v = { height: node.offsetHeight, width: node.offsetWidth }[p];
2420 if(v !== undefined){ return v; }
2421 v = style.get(node, p);
2422 return (p == "opacity") ? +v : (isColor ? v : parseFloat(v));
2423 }
2424 if(!("end" in prop)){
2425 prop.end = getStyle(n, p);
2426 }else if(!("start" in prop)){
2427 prop.start = getStyle(n, p);
2428 }
2f01fe57 2429
1354d172
AD
2430 if(isColor){
2431 prop.start = new Color(prop.start);
2432 prop.end = new Color(prop.end);
2433 }else{
2434 prop.start = (p == "opacity") ? +prop.start : parseFloat(prop.start);
2f01fe57
AD
2435 }
2436 }
1354d172
AD
2437 this.curve = new PropLine(pm);
2438 });
2439 connect.connect(anim, "onAnimate", lang.hitch(style, "set", anim.node));
2440 return anim; // dojo.Animation
2f01fe57
AD
2441 };
2442
1354d172
AD
2443 dojo.anim = function( /*DOMNode|String*/ node,
2444 /*Object*/ properties,
2445 /*Integer?*/ duration,
2446 /*Function?*/ easing,
2447 /*Function?*/ onEnd,
2448 /*Integer?*/ delay){
2f01fe57 2449 // summary:
1354d172
AD
2450 // A simpler interface to `dojo.animateProperty()`, also returns
2451 // an instance of `dojo.Animation` but begins the animation
2452 // immediately, unlike nearly every other Dojo animation API.
2f01fe57 2453 // description:
1354d172
AD
2454 // `dojo.anim` is a simpler (but somewhat less powerful) version
2455 // of `dojo.animateProperty`. It uses defaults for many basic properties
2456 // and allows for positional parameters to be used in place of the
2457 // packed "property bag" which is used for other Dojo animation
2458 // methods.
2f01fe57 2459 //
1354d172
AD
2460 // The `dojo.Animation` object returned from `dojo.anim` will be
2461 // already playing when it is returned from this function, so
2462 // calling play() on it again is (usually) a no-op.
2463 // node:
2464 // a DOM node or the id of a node to animate CSS properties on
2465 // duration:
2466 // The number of milliseconds over which the animation
2467 // should run. Defaults to the global animation default duration
2468 // (350ms).
2469 // easing:
2470 // An easing function over which to calculate acceleration
2471 // and deceleration of the animation through its duration.
2472 // A default easing algorithm is provided, but you may
2473 // plug in any you wish. A large selection of easing algorithms
2474 // are available in `dojo.fx.easing`.
2475 // onEnd:
2476 // A function to be called when the animation finishes
2477 // running.
2478 // delay:
2479 // The number of milliseconds to delay beginning the
2480 // animation by. The default is 0.
2481 // example:
2482 // Fade out a node
2483 // | dojo.anim("id", { opacity: 0 });
2484 // example:
2485 // Fade out a node over a full second
2486 // | dojo.anim("id", { opacity: 0 }, 1000);
2487 return dojo.animateProperty({ // dojo.Animation
2488 node: node,
2489 duration: duration || dojo.Animation.prototype.duration,
2490 properties: properties,
2491 easing: easing,
2492 onEnd: onEnd
2493 }).play(delay || 0);
2494 };
2495
2496 return {
2497 _Line: dojo._Line,
2498 Animation: dojo.Animation,
2499 _fade: dojo._fade,
2500 fadeIn: dojo.fadeIn,
2501 fadeOut: dojo.fadeOut,
2502 _defaultEasing: dojo._defaultEasing,
2503 animateProperty: dojo.animateProperty,
2504 anim: dojo.anim
2505 };
2506});
2507
2508},
2509'dojo/dom-form':function(){
2510define("dojo/dom-form", ["./_base/lang", "./dom", "./io-query", "./json"], function(lang, dom, ioq, json){
2511 // module:
2512 // dojo/dom-form
2513 // summary:
2514 // This module defines form-processing functions.
2515
2516 /*=====
2517 dojo.fieldToObject = function(inputNode){
2518 // summary:
2519 // Serialize a form field to a JavaScript object.
2520 // description:
2521 // Returns the value encoded in a form field as
2522 // as a string or an array of strings. Disabled form elements
2523 // and unchecked radio and checkboxes are skipped. Multi-select
2524 // elements are returned as an array of string values.
2525 // inputNode: DOMNode|String
2526 // returns: Object
2527 };
2528 =====*/
2529
2530 /*=====
2531 dojo.formToObject = function(formNode){
2532 // summary:
2533 // Serialize a form node to a JavaScript object.
2534 // description:
2535 // Returns the values encoded in an HTML form as
2536 // string properties in an object which it then returns. Disabled form
2537 // elements, buttons, and other non-value form elements are skipped.
2538 // Multi-select elements are returned as an array of string values.
2539 // formNode: DOMNode|String
2540 // returns: Object
2541 //
2542 // example:
2543 // This form:
2544 // | <form id="test_form">
2545 // | <input type="text" name="blah" value="blah">
2546 // | <input type="text" name="no_value" value="blah" disabled>
2547 // | <input type="button" name="no_value2" value="blah">
2548 // | <select type="select" multiple name="multi" size="5">
2549 // | <option value="blah">blah</option>
2550 // | <option value="thud" selected>thud</option>
2551 // | <option value="thonk" selected>thonk</option>
2552 // | </select>
2553 // | </form>
2554 //
2555 // yields this object structure as the result of a call to
2556 // formToObject():
2557 //
2558 // | {
2559 // | blah: "blah",
2560 // | multi: [
2561 // | "thud",
2562 // | "thonk"
2563 // | ]
2564 // | };
2565 };
2566 =====*/
2567
2568 /*=====
2569 dojo.formToQuery = function(formNode){
2570 // summary:
2571 // Returns a URL-encoded string representing the form passed as either a
2572 // node or string ID identifying the form to serialize
2573 // formNode: DOMNode|String
2574 // returns: String
2575 };
2576 =====*/
2577
2578 /*=====
2579 dojo.formToJson = function(formNode, prettyPrint){
2580 // summary:
2581 // Create a serialized JSON string from a form node or string
2582 // ID identifying the form to serialize
2583 // formNode: DOMNode|String
2584 // prettyPrint: Boolean?
2585 // returns: String
2586 };
2587 =====*/
2588
2589 function setValue(/*Object*/obj, /*String*/name, /*String*/value){
2590 // summary:
2591 // For the named property in object, set the value. If a value
2592 // already exists and it is a string, convert the value to be an
2593 // array of values.
2594
2595 // Skip it if there is no value
2596 if(value === null){
2597 return;
2598 }
2599
2600 var val = obj[name];
2601 if(typeof val == "string"){ // inline'd type check
2602 obj[name] = [val, value];
2603 }else if(lang.isArray(val)){
2604 val.push(value);
2605 }else{
2606 obj[name] = value;
2607 }
2608 }
2609
2610 var exclude = "file|submit|image|reset|button";
2611
2612 var form = {
2613 fieldToObject: function fieldToObject(/*DOMNode|String*/ inputNode){
2614 var ret = null;
2615 inputNode = dom.byId(inputNode);
2616 if(inputNode){
2617 var _in = inputNode.name, type = (inputNode.type || "").toLowerCase();
2618 if(_in && type && !inputNode.disabled){
2619 if(type == "radio" || type == "checkbox"){
2620 if(inputNode.checked){
2621 ret = inputNode.value;
2622 }
2623 }else if(inputNode.multiple){
2624 ret = [];
2625 var nodes = [inputNode.firstChild];
2626 while(nodes.length){
2627 for(var node = nodes.pop(); node; node = node.nextSibling){
2628 if(node.nodeType == 1 && node.tagName.toLowerCase() == "option"){
2629 if(node.selected){
2630 ret.push(node.value);
2631 }
2632 }else{
2633 if(node.nextSibling){
2634 nodes.push(node.nextSibling);
2635 }
2636 if(node.firstChild){
2637 nodes.push(node.firstChild);
2638 }
2639 break;
2640 }
2641 }
2642 }
2643 }else{
2644 ret = inputNode.value;
2645 }
2646 }
2647 }
2648 return ret; // Object
2649 },
2650
2651 toObject: function formToObject(/*DOMNode|String*/ formNode){
2652 var ret = {}, elems = dom.byId(formNode).elements;
2653 for(var i = 0, l = elems.length; i < l; ++i){
2654 var item = elems[i], _in = item.name, type = (item.type || "").toLowerCase();
2655 if(_in && type && exclude.indexOf(type) < 0 && !item.disabled){
2656 setValue(ret, _in, form.fieldToObject(item));
2657 if(type == "image"){
2658 ret[_in + ".x"] = ret[_in + ".y"] = ret[_in].x = ret[_in].y = 0;
2659 }
2660 }
2661 }
2662 return ret; // Object
2663 },
2664
2665 toQuery: function formToQuery(/*DOMNode|String*/ formNode){
2666 return ioq.objectToQuery(form.toObject(formNode)); // String
2667 },
2668
2669 toJson: function formToJson(/*DOMNode|String*/ formNode, /*Boolean?*/prettyPrint){
2670 return json.stringify(form.toObject(formNode), null, prettyPrint ? 4 : 0); // String
2671 }
2672 };
2673
2674 return form;
2675});
2676
2677},
2678'dojo/_base/html':function(){
2679define(["./kernel", "../dom", "../dom-style", "../dom-attr", "../dom-prop", "../dom-class", "../dom-construct", "../dom-geometry"], function(dojo, dom, style, attr, prop, cls, ctr, geom){
2680 // module:
2681 // dojo/dom
2682 // summary:
2683 // This module is a stub for the core dojo DOM API.
2684
2685 // mix-in dom
2686 dojo.byId = dom.byId;
2687 dojo.isDescendant = dom.isDescendant;
2688 dojo.setSelectable = dom.setSelectable;
2689
2690 // mix-in dom-attr
2691 dojo.getAttr = attr.get;
2692 dojo.setAttr = attr.set;
2693 dojo.hasAttr = attr.has;
2694 dojo.removeAttr = attr.remove;
2695 dojo.getNodeProp = attr.getNodeProp;
2696
2697 dojo.attr = function(node, name, value){
2698 // summary:
2699 // Gets or sets an attribute on an HTML element.
2700 // description:
2701 // Handles normalized getting and setting of attributes on DOM
2702 // Nodes. If 2 arguments are passed, and a the second argument is a
2703 // string, acts as a getter.
2f01fe57 2704 //
1354d172
AD
2705 // If a third argument is passed, or if the second argument is a
2706 // map of attributes, acts as a setter.
2f01fe57 2707 //
1354d172
AD
2708 // When passing functions as values, note that they will not be
2709 // directly assigned to slots on the node, but rather the default
2710 // behavior will be removed and the new behavior will be added
2711 // using `dojo.connect()`, meaning that event handler properties
2712 // will be normalized and that some caveats with regards to
2713 // non-standard behaviors for onsubmit apply. Namely that you
2714 // should cancel form submission using `dojo.stopEvent()` on the
2715 // passed event object instead of returning a boolean value from
2716 // the handler itself.
2717 // node: DOMNode|String
2718 // id or reference to the element to get or set the attribute on
2719 // name: String|Object
2720 // the name of the attribute to get or set.
2721 // value: String?
2722 // The value to set for the attribute
2723 // returns:
2724 // when used as a getter, the value of the requested attribute
2725 // or null if that attribute does not have a specified or
2726 // default value;
2f01fe57 2727 //
1354d172 2728 // when used as a setter, the DOM node
2f01fe57 2729 //
1354d172
AD
2730 // example:
2731 // | // get the current value of the "foo" attribute on a node
2732 // | dojo.attr(dojo.byId("nodeId"), "foo");
2733 // | // or we can just pass the id:
2734 // | dojo.attr("nodeId", "foo");
2f01fe57 2735 //
1354d172
AD
2736 // example:
2737 // | // use attr() to set the tab index
2738 // | dojo.attr("nodeId", "tabIndex", 3);
2739 // |
2f01fe57 2740 //
1354d172
AD
2741 // example:
2742 // Set multiple values at once, including event handlers:
2743 // | dojo.attr("formId", {
2744 // | "foo": "bar",
2745 // | "tabIndex": -1,
2746 // | "method": "POST",
2747 // | "onsubmit": function(e){
2748 // | // stop submitting the form. Note that the IE behavior
2749 // | // of returning true or false will have no effect here
2750 // | // since our handler is connect()ed to the built-in
2751 // | // onsubmit behavior and so we need to use
2752 // | // dojo.stopEvent() to ensure that the submission
2753 // | // doesn't proceed.
2754 // | dojo.stopEvent(e);
2755 // |
2756 // | // submit the form with Ajax
2757 // | dojo.xhrPost({ form: "formId" });
2f01fe57
AD
2758 // | }
2759 // | });
2760 //
1354d172
AD
2761 // example:
2762 // Style is s special case: Only set with an object hash of styles
2763 // | dojo.attr("someNode",{
2764 // | id:"bar",
2765 // | style:{
2766 // | width:"200px", height:"100px", color:"#000"
2f01fe57
AD
2767 // | }
2768 // | });
2f01fe57 2769 //
1354d172
AD
2770 // example:
2771 // Again, only set style as an object hash of styles:
2772 // | var obj = { color:"#fff", backgroundColor:"#000" };
2773 // | dojo.attr("someNode", "style", obj);
2774 // |
2775 // | // though shorter to use `dojo.style()` in this case:
2776 // | dojo.style("someNode", obj);
2777
2778 if(arguments.length == 2){
2779 return attr[typeof name == "string" ? "get" : "set"](node, name);
2780 }
2781 return attr.set(node, name, value);
2782 };
2783
2784 // mix-in dom-class
2785 dojo.hasClass = cls.contains;
2786 dojo.addClass = cls.add;
2787 dojo.removeClass = cls.remove;
2788 dojo.toggleClass = cls.toggle;
2789 dojo.replaceClass = cls.replace;
2790
2791 // mix-in dom-construct
2792 dojo._toDom = dojo.toDom = ctr.toDom;
2793 dojo.place = ctr.place;
2794 dojo.create = ctr.create;
2795 dojo.empty = function(node){ ctr.empty(node); };
2796 dojo._destroyElement = dojo.destroy = function(node){ ctr.destroy(node); };
2797
2798 // mix-in dom-geometry
2799 dojo._getPadExtents = dojo.getPadExtents = geom.getPadExtents;
2800 dojo._getBorderExtents = dojo.getBorderExtents = geom.getBorderExtents;
2801 dojo._getPadBorderExtents = dojo.getPadBorderExtents = geom.getPadBorderExtents;
2802 dojo._getMarginExtents = dojo.getMarginExtents = geom.getMarginExtents;
2803 dojo._getMarginSize = dojo.getMarginSize = geom.getMarginSize;
2804 dojo._getMarginBox = dojo.getMarginBox = geom.getMarginBox;
2805 dojo.setMarginBox = geom.setMarginBox;
2806 dojo._getContentBox = dojo.getContentBox = geom.getContentBox;
2807 dojo.setContentSize = geom.setContentSize;
2808 dojo._isBodyLtr = dojo.isBodyLtr = geom.isBodyLtr;
2809 dojo._docScroll = dojo.docScroll = geom.docScroll;
2810 dojo._getIeDocumentElementOffset = dojo.getIeDocumentElementOffset = geom.getIeDocumentElementOffset;
2811 dojo._fixIeBiDiScrollLeft = dojo.fixIeBiDiScrollLeft = geom.fixIeBiDiScrollLeft;
2812 dojo.position = geom.position;
2813
2814 dojo.marginBox = function marginBox(/*DomNode|String*/node, /*Object?*/box){
2815 // summary:
2816 // Getter/setter for the margin-box of node.
2817 // description:
2818 // Getter/setter for the margin-box of node.
2819 // Returns an object in the expected format of box (regardless
2820 // if box is passed). The object might look like:
2821 // `{ l: 50, t: 200, w: 300: h: 150 }`
2822 // for a node offset from its parent 50px to the left, 200px from
2823 // the top with a margin width of 300px and a margin-height of
2824 // 150px.
2825 // node:
2826 // id or reference to DOM Node to get/set box for
2827 // box:
2828 // If passed, denotes that dojo.marginBox() should
2829 // update/set the margin box for node. Box is an object in the
2830 // above format. All properties are optional if passed.
2831 // example:
2832 // Retrieve the margin box of a passed node
2833 // | var box = dojo.marginBox("someNodeId");
2834 // | console.dir(box);
2f01fe57 2835 //
1354d172
AD
2836 // example:
2837 // Set a node's margin box to the size of another node
2838 // | var box = dojo.marginBox("someNodeId");
2839 // | dojo.marginBox("someOtherNode", box);
2840 return box ? geom.setMarginBox(node, box) : geom.getMarginBox(node); // Object
2841 };
2842
2843 dojo.contentBox = function contentBox(/*DomNode|String*/node, /*Object?*/box){
2844 // summary:
2845 // Getter/setter for the content-box of node.
2846 // description:
2847 // Returns an object in the expected format of box (regardless if box is passed).
2848 // The object might look like:
2849 // `{ l: 50, t: 200, w: 300: h: 150 }`
2850 // for a node offset from its parent 50px to the left, 200px from
2851 // the top with a content width of 300px and a content-height of
2852 // 150px. Note that the content box may have a much larger border
2853 // or margin box, depending on the box model currently in use and
2854 // CSS values set/inherited for node.
2855 // While the getter will return top and left values, the
2856 // setter only accepts setting the width and height.
2857 // node:
2858 // id or reference to DOM Node to get/set box for
2859 // box:
2860 // If passed, denotes that dojo.contentBox() should
2861 // update/set the content box for node. Box is an object in the
2862 // above format, but only w (width) and h (height) are supported.
2863 // All properties are optional if passed.
2864 return box ? geom.setContentSize(node, box) : geom.getContentBox(node); // Object
2865 };
2866
2867 dojo.coords = function(/*DomNode|String*/node, /*Boolean?*/includeScroll){
2868 // summary:
2869 // Deprecated: Use position() for border-box x/y/w/h
2870 // or marginBox() for margin-box w/h/l/t.
2871 // Returns an object representing a node's size and position.
2f01fe57 2872 //
1354d172
AD
2873 // description:
2874 // Returns an object that measures margin-box (w)idth/(h)eight
2875 // and absolute position x/y of the border-box. Also returned
2876 // is computed (l)eft and (t)op values in pixels from the
2877 // node's offsetParent as returned from marginBox().
2878 // Return value will be in the form:
2879 //| { l: 50, t: 200, w: 300: h: 150, x: 100, y: 300 }
2880 // Does not act as a setter. If includeScroll is passed, the x and
2881 // y params are affected as one would expect in dojo.position().
2882 dojo.deprecated("dojo.coords()", "Use dojo.position() or dojo.marginBox().");
2883 node = dom.byId(node);
2884 var s = style.getComputedStyle(node), mb = geom.getMarginBox(node, s);
2885 var abs = geom.position(node, includeScroll);
2886 mb.x = abs.x;
2887 mb.y = abs.y;
2888 return mb; // Object
2f01fe57 2889 };
2f01fe57 2890
1354d172
AD
2891 // mix-in dom-prop
2892 dojo.getProp = prop.get;
2893 dojo.setProp = prop.set;
2894
2895 dojo.prop = function(/*DomNode|String*/node, /*String|Object*/name, /*String?*/value){
2896 // summary:
2897 // Gets or sets a property on an HTML element.
2898 // description:
2899 // Handles normalized getting and setting of properties on DOM
2900 // Nodes. If 2 arguments are passed, and a the second argument is a
2901 // string, acts as a getter.
2f01fe57 2902 //
1354d172
AD
2903 // If a third argument is passed, or if the second argument is a
2904 // map of attributes, acts as a setter.
2f01fe57 2905 //
1354d172
AD
2906 // When passing functions as values, note that they will not be
2907 // directly assigned to slots on the node, but rather the default
2908 // behavior will be removed and the new behavior will be added
2909 // using `dojo.connect()`, meaning that event handler properties
2910 // will be normalized and that some caveats with regards to
2911 // non-standard behaviors for onsubmit apply. Namely that you
2912 // should cancel form submission using `dojo.stopEvent()` on the
2913 // passed event object instead of returning a boolean value from
2914 // the handler itself.
2915 // node:
2916 // id or reference to the element to get or set the property on
2917 // name:
2918 // the name of the property to get or set.
2919 // value:
2920 // The value to set for the property
2921 // returns:
2922 // when used as a getter, the value of the requested property
2923 // or null if that attribute does not have a specified or
2924 // default value;
2f01fe57 2925 //
1354d172
AD
2926 // when used as a setter, the DOM node
2927 //
2928 // example:
2929 // | // get the current value of the "foo" property on a node
2930 // | dojo.prop(dojo.byId("nodeId"), "foo");
2931 // | // or we can just pass the id:
2932 // | dojo.prop("nodeId", "foo");
2933 //
2934 // example:
2935 // | // use prop() to set the tab index
2936 // | dojo.prop("nodeId", "tabIndex", 3);
2937 // |
2938 //
2939 // example:
2940 // Set multiple values at once, including event handlers:
2941 // | dojo.prop("formId", {
2942 // | "foo": "bar",
2943 // | "tabIndex": -1,
2944 // | "method": "POST",
2945 // | "onsubmit": function(e){
2946 // | // stop submitting the form. Note that the IE behavior
2947 // | // of returning true or false will have no effect here
2948 // | // since our handler is connect()ed to the built-in
2949 // | // onsubmit behavior and so we need to use
2950 // | // dojo.stopEvent() to ensure that the submission
2951 // | // doesn't proceed.
2952 // | dojo.stopEvent(e);
2953 // |
2954 // | // submit the form with Ajax
2955 // | dojo.xhrPost({ form: "formId" });
2f01fe57
AD
2956 // | }
2957 // | });
1354d172
AD
2958 //
2959 // example:
2960 // Style is s special case: Only set with an object hash of styles
2961 // | dojo.prop("someNode",{
2962 // | id:"bar",
2963 // | style:{
2964 // | width:"200px", height:"100px", color:"#000"
2f01fe57
AD
2965 // | }
2966 // | });
1354d172
AD
2967 //
2968 // example:
2969 // Again, only set style as an object hash of styles:
2970 // | var obj = { color:"#fff", backgroundColor:"#000" };
2971 // | dojo.prop("someNode", "style", obj);
2972 // |
2973 // | // though shorter to use `dojo.style()` in this case:
2974 // | dojo.style("someNode", obj);
2f01fe57 2975
1354d172
AD
2976 if(arguments.length == 2){
2977 return prop[typeof name == "string" ? "get" : "set"](node, name);
2978 }
2979 // setter
2980 return prop.set(node, name, value);
2981 };
2982
2983 // mix-in dom-style
2984 dojo.getStyle = style.get;
2985 dojo.setStyle = style.set;
2986 dojo.getComputedStyle = style.getComputedStyle;
2987 dojo.__toPixelValue = dojo.toPixelValue = style.toPixelValue;
2988
2989 dojo.style = function(node, name, value){
2990 // summary:
2991 // Accesses styles on a node. If 2 arguments are
2992 // passed, acts as a getter. If 3 arguments are passed, acts
2993 // as a setter.
2994 // description:
2995 // Getting the style value uses the computed style for the node, so the value
2996 // will be a calculated value, not just the immediate node.style value.
2997 // Also when getting values, use specific style names,
2998 // like "borderBottomWidth" instead of "border" since compound values like
2999 // "border" are not necessarily reflected as expected.
3000 // If you want to get node dimensions, use `dojo.marginBox()`,
3001 // `dojo.contentBox()` or `dojo.position()`.
3002 // node: DOMNode|String
3003 // id or reference to node to get/set style for
3004 // name: String?|Object?
3005 // the style property to set in DOM-accessor format
3006 // ("borderWidth", not "border-width") or an object with key/value
3007 // pairs suitable for setting each property.
3008 // value: String?
3009 // If passed, sets value on the node for style, handling
3010 // cross-browser concerns. When setting a pixel value,
3011 // be sure to include "px" in the value. For instance, top: "200px".
3012 // Otherwise, in some cases, some browsers will not apply the style.
3013 // returns:
3014 // when used as a getter, return the computed style of the node if passing in an ID or node,
3015 // or return the normalized, computed value for the property when passing in a node and a style property
3016 // example:
3017 // Passing only an ID or node returns the computed style object of
3018 // the node:
3019 // | dojo.style("thinger");
3020 // example:
3021 // Passing a node and a style property returns the current
3022 // normalized, computed value for that property:
3023 // | dojo.style("thinger", "opacity"); // 1 by default
2f01fe57 3024 //
1354d172
AD
3025 // example:
3026 // Passing a node, a style property, and a value changes the
3027 // current display of the node and returns the new computed value
3028 // | dojo.style("thinger", "opacity", 0.5); // == 0.5
2f01fe57 3029 //
1354d172
AD
3030 // example:
3031 // Passing a node, an object-style style property sets each of the values in turn and returns the computed style object of the node:
3032 // | dojo.style("thinger", {
3033 // | "opacity": 0.5,
3034 // | "border": "3px solid black",
3035 // | "height": "300px"
3036 // | });
2f01fe57 3037 //
1354d172
AD
3038 // example:
3039 // When the CSS style property is hyphenated, the JavaScript property is camelCased.
3040 // font-size becomes fontSize, and so on.
3041 // | dojo.style("thinger",{
3042 // | fontSize:"14pt",
3043 // | letterSpacing:"1.2em"
2f01fe57 3044 // | });
1354d172
AD
3045 //
3046 // example:
3047 // dojo.NodeList implements .style() using the same syntax, omitting the "node" parameter, calling
3048 // dojo.style() on every element of the list. See: `dojo.query()` and `dojo.NodeList()`
3049 // | dojo.query(".someClassName").style("visibility","hidden");
3050 // | // or
3051 // | dojo.query("#baz > div").style({
3052 // | opacity:0.75,
3053 // | fontSize:"13pt"
2f01fe57 3054 // | });
1354d172
AD
3055
3056 switch(arguments.length){
3057 case 1:
3058 return style.get(node);
3059 case 2:
3060 return style[typeof name == "string" ? "get" : "set"](node, name);
3061 }
3062 // setter
3063 return style.set(node, name, value);
3064 };
3065
3066 return dojo;
3067});
3068
3069},
3070'dojo/_base/kernel':function(){
3071define(["../has", "./config", "require", "module"], function(has, config, require, module){
3072 // module:
3073 // dojo/_base/kernel
3074 // summary:
3075 // This module is the foundational module of the dojo boot sequence; it defines the dojo object.
3076 var
3077 // loop variables for this module
3078 i, p,
3079
3080 // create dojo, dijit, and dojox
3081 // FIXME: in 2.0 remove dijit, dojox being created by dojo
3082 dijit = {},
3083 dojox = {},
3084 dojo = {
3085 // notice dojo takes ownership of the value of the config module
3086 config:config,
3087 global:this,
3088 dijit:dijit,
3089 dojox:dojox
3090 };
3091
3092
3093 // Configure the scope map. For a 100% AMD application, the scope map is not needed other than to provide
3094 // a _scopeName property for the dojo, dijit, and dojox root object so those packages can create
3095 // unique names in the global space.
3096 //
3097 // Built, legacy modules use the scope map to allow those modules to be expressed as if dojo, dijit, and dojox,
3098 // where global when in fact they are either global under different names or not global at all. In v1.6-, the
3099 // config variable "scopeMap" was used to map names as used within a module to global names. This has been
3100 // subsumed by the dojo packageMap configuration variable which relocates packages to different names. See
3101 // http://livedocs.dojotoolkit.org/developer/design/loader#legacy-cross-domain-mode for details.
3102 //
3103 // The following computations contort the packageMap for this dojo instance into a scopeMap.
3104 var scopeMap =
3105 // a map from a name used in a legacy module to the (global variable name, object addressed by that name)
3106 // always map dojo, dijit, and dojox
3107 {
3108 dojo:["dojo", dojo],
3109 dijit:["dijit", dijit],
3110 dojox:["dojox", dojox]
3111 },
3112
3113 packageMap =
3114 // the package map for this dojo instance; note, a foreign loader or no pacakgeMap results in the above default config
3115 (require.packs && require.packs[module.id.match(/[^\/]+/)[0]].packageMap) || {},
3116
3117 item;
3118
3119 // process all mapped top-level names for this instance of dojo
3120 for(p in packageMap){
3121 if(scopeMap[p]){
3122 // mapped dojo, dijit, or dojox
3123 scopeMap[p][0] = packageMap[p];
3124 }else{
3125 // some other top-level name
3126 scopeMap[p] = [packageMap[p], {}];
3127 }
2f01fe57 3128 }
2f01fe57 3129
1354d172
AD
3130 // publish those names to _scopeName and, optionally, the global namespace
3131 for(p in scopeMap){
3132 item = scopeMap[p];
3133 item[1]._scopeName = item[0];
3134 if(!config.noGlobals){
3135 this[item[0]] = item[1];
3136 }
2f01fe57 3137 }
1354d172
AD
3138 dojo.scopeMap = scopeMap;
3139
3140 // FIXME: dojo.baseUrl and dojo.config.baseUrl should be deprecated
3141 dojo.baseUrl = dojo.config.baseUrl = require.baseUrl;
3142 dojo.isAsync = !1 || require.async;
3143 dojo.locale = config.locale;
2f01fe57
AD
3144
3145 /*=====
1354d172
AD
3146 dojo.version = function(){
3147 // summary:
3148 // Version number of the Dojo Toolkit
3149 // major: Integer
3150 // Major version. If total version is "1.2.0beta1", will be 1
3151 // minor: Integer
3152 // Minor version. If total version is "1.2.0beta1", will be 2
3153 // patch: Integer
3154 // Patch version. If total version is "1.2.0beta1", will be 0
3155 // flag: String
3156 // Descriptor flag. If total version is "1.2.0beta1", will be "beta1"
3157 // revision: Number
3158 // The SVN rev from which dojo was pulled
3159 this.major = 0;
3160 this.minor = 0;
3161 this.patch = 0;
3162 this.flag = "";
3163 this.revision = 0;
3164 }
3165 =====*/
3166 var rev = "$Rev: 28982 $".match(/\d+/);
3167 dojo.version = {
3168 major: 1, minor: 7, patch: 3, flag: "",
3169 revision: rev ? +rev[0] : NaN,
3170 toString: function(){
3171 var v = dojo.version;
3172 return v.major + "." + v.minor + "." + v.patch + v.flag + " (" + v.revision + ")"; // String
3173 }
3174 };
3175
3176
3177 // If 1 is truthy, then as a dojo module is defined it should push it's definitions
3178 // into the dojo object, and conversely. In 2.0, it will likely be unusual to augment another object
3179 // as a result of defining a module. This has feature gives a way to force 2.0 behavior as the code
3180 // is migrated. Absent specific advice otherwise, set extend-dojo to truthy.
3181 true || has.add("extend-dojo", 1);
3182
3183
3184 dojo.eval = function(scriptText){
2f01fe57 3185 // summary:
1354d172
AD
3186 // A legacy method created for use exclusively by internal Dojo methods. Do not use this method
3187 // directly unless you understand its possibly-different implications on the platforms your are targeting.
2f01fe57 3188 // description:
1354d172
AD
3189 // Makes an attempt to evaluate scriptText in the global scope. The function works correctly for browsers
3190 // that support indirect eval.
2f01fe57 3191 //
1354d172
AD
3192 // As usual, IE does not. On IE, the only way to implement global eval is to
3193 // use execScript. Unfortunately, execScript does not return a value and breaks some current usages of dojo.eval.
3194 // This implementation uses the technique of executing eval in the scope of a function that is a single scope
3195 // frame below the global scope; thereby coming close to the global scope. Note carefully that
3196 //
3197 // dojo.eval("var pi = 3.14;");
3198 //
3199 // will define global pi in non-IE environments, but define pi only in a temporary local scope for IE. If you want
3200 // to define a global variable using dojo.eval, write something like
3201 //
3202 // dojo.eval("window.pi = 3.14;")
3203 // scriptText:
3204 // The text to evaluation.
3205 // returns:
3206 // The result of the evaluation. Often `undefined`
3207 };
3208
3209 (Function("d", "d.eval = function(){return d.global.eval ? d.global.eval(arguments[0]) : eval(arguments[0]);}"))(dojo);
3210
3211
3212 if(0){
3213 dojo.exit = function(exitcode){
3214 quit(exitcode);
3215 };
3216 } else{
3217 dojo.exit = function(){
3218 };
2f01fe57 3219 }
2f01fe57 3220
1354d172
AD
3221 true || has.add("dojo-guarantee-console",
3222 // ensure that console.log, console.warn, etc. are defined
3223 1
3224 );
3225 if(1){
3226 typeof console != "undefined" || (console = {});
3227 // Be careful to leave 'log' always at the end
3228 var cn = [
3229 "assert", "count", "debug", "dir", "dirxml", "error", "group",
3230 "groupEnd", "info", "profile", "profileEnd", "time", "timeEnd",
3231 "trace", "warn", "log"
3232 ];
3233 var tn;
3234 i = 0;
3235 while((tn = cn[i++])){
3236 if(!console[tn]){
3237 (function(){
3238 var tcn = tn + "";
3239 console[tcn] = ('log' in console) ? function(){
3240 var a = Array.apply({}, arguments);
3241 a.unshift(tcn + ":");
3242 console["log"](a.join(" "));
3243 } : function(){};
3244 console[tcn]._fake = true;
3245 })();
2f01fe57 3246 }
2f01fe57
AD
3247 }
3248 }
2f01fe57 3249
1354d172
AD
3250 has.add("dojo-debug-messages",
3251 // include dojo.deprecated/dojo.experimental implementations
3252 !!config.isDebug
3253 );
3254 if(has("dojo-debug-messages")){
3255 dojo.deprecated = function(/*String*/ behaviour, /*String?*/ extra, /*String?*/ removal){
3256 // summary:
3257 // Log a debug message to indicate that a behavior has been
3258 // deprecated.
3259 // behaviour: String
3260 // The API or behavior being deprecated. Usually in the form
3261 // of "myApp.someFunction()".
3262 // extra: String?
3263 // Text to append to the message. Often provides advice on a
3264 // new function or facility to achieve the same goal during
3265 // the deprecation period.
3266 // removal: String?
3267 // Text to indicate when in the future the behavior will be
3268 // removed. Usually a version number.
3269 // example:
3270 // | dojo.deprecated("myApp.getTemp()", "use myApp.getLocaleTemp() instead", "1.0");
2f01fe57 3271
1354d172
AD
3272 var message = "DEPRECATED: " + behaviour;
3273 if(extra){ message += " " + extra; }
3274 if(removal){ message += " -- will be removed in version: " + removal; }
3275 console.warn(message);
3276 };
2f01fe57 3277
1354d172
AD
3278 dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
3279 // summary: Marks code as experimental.
3280 // description:
3281 // This can be used to mark a function, file, or module as
3282 // experimental. Experimental code is not ready to be used, and the
3283 // APIs are subject to change without notice. Experimental code may be
3284 // completed deleted without going through the normal deprecation
3285 // process.
3286 // moduleName: String
3287 // The name of a module, or the name of a module file or a specific
3288 // function
3289 // extra: String?
3290 // some additional message for the user
3291 // example:
3292 // | dojo.experimental("dojo.data.Result");
3293 // example:
3294 // | dojo.experimental("dojo.weather.toKelvin()", "PENDING approval from NOAA");
2f01fe57 3295
1354d172
AD
3296 var message = "EXPERIMENTAL: " + moduleName + " -- APIs subject to change without notice.";
3297 if(extra){ message += " " + extra; }
3298 console.warn(message);
3299 };
3300 }else{
3301 dojo.deprecated = dojo.experimental = function(){};
2f01fe57 3302 }
2f01fe57 3303
1354d172
AD
3304 true || has.add("dojo-modulePaths",
3305 // consume dojo.modulePaths processing
3306 1
3307 );
3308 if(1){
3309 // notice that modulePaths won't be applied to any require's before the dojo/_base/kernel factory is run;
3310 // this is the v1.6- behavior.
3311 if(config.modulePaths){
3312 dojo.deprecated("dojo.modulePaths", "use paths configuration");
3313 var paths = {};
3314 for(p in config.modulePaths){
3315 paths[p.replace(/\./g, "/")] = config.modulePaths[p];
3316 }
3317 require({paths:paths});
3318 }
2f01fe57 3319 }
2f01fe57 3320
1354d172
AD
3321 true || has.add("dojo-moduleUrl",
3322 // include dojo.moduleUrl
3323 1
3324 );
3325 if(1){
3326 dojo.moduleUrl = function(/*String*/module, /*String?*/url){
3327 // summary:
3328 // Returns a URL relative to a module.
3329 // example:
3330 // | var pngPath = dojo.moduleUrl("acme","images/small.png");
3331 // | console.dir(pngPath); // list the object properties
3332 // | // create an image and set it's source to pngPath's value:
3333 // | var img = document.createElement("img");
3334 // | img.src = pngPath;
3335 // | // add our image to the document
3336 // | dojo.body().appendChild(img);
3337 // example:
3338 // you may de-reference as far as you like down the package
3339 // hierarchy. This is sometimes handy to avoid lenghty relative
3340 // urls or for building portable sub-packages. In this example,
3341 // the `acme.widget` and `acme.util` directories may be located
3342 // under different roots (see `dojo.registerModulePath`) but the
3343 // the modules which reference them can be unaware of their
3344 // relative locations on the filesystem:
3345 // | // somewhere in a configuration block
3346 // | dojo.registerModulePath("acme.widget", "../../acme/widget");
3347 // | dojo.registerModulePath("acme.util", "../../util");
3348 // |
3349 // | // ...
3350 // |
3351 // | // code in a module using acme resources
3352 // | var tmpltPath = dojo.moduleUrl("acme.widget","templates/template.html");
3353 // | var dataPath = dojo.moduleUrl("acme.util","resources/data.json");
2f01fe57 3354
1354d172 3355 dojo.deprecated("dojo.moduleUrl()", "use require.toUrl", "2.0");
2f01fe57 3356
1354d172
AD
3357 // require.toUrl requires a filetype; therefore, just append the suffix "/*.*" to guarantee a filetype, then
3358 // remove the suffix from the result. This way clients can request a url w/out a filetype. This should be
3359 // rare, but it maintains backcompat for the v1.x line (note: dojo.moduleUrl will be removed in v2.0).
3360 // Notice * is an illegal filename so it won't conflict with any real path map that may exist the paths config.
3361 var result = null;
3362 if(module){
3363 result = require.toUrl(module.replace(/\./g, "/") + (url ? ("/" + url) : "") + "/*.*").replace(/\/\*\.\*/, "") + (url ? "" : "/");
3364 }
3365 return result;
3366 };
3367 }
2f01fe57 3368
1354d172 3369 dojo._hasResource = {}; // for backward compatibility with layers built with 1.6 tooling
2f01fe57 3370
1354d172
AD
3371 return dojo;
3372});
2f01fe57 3373
1354d172
AD
3374},
3375'dojo/io-query':function(){
3376define(["./_base/lang"], function(lang){
3377 // module:
3378 // dojo/io-query
3379 // summary:
3380 // This module defines query string processing functions.
3381
3382 var backstop = {};
3383
3384 function objectToQuery(/*Object*/ map){
3385 // summary:
3386 // takes a name/value mapping object and returns a string representing
3387 // a URL-encoded version of that object.
3388 // example:
3389 // this object:
3390 //
3391 // | {
3392 // | blah: "blah",
3393 // | multi: [
3394 // | "thud",
3395 // | "thonk"
3396 // | ]
3397 // | };
3398 //
3399 // yields the following query string:
3400 //
3401 // | "blah=blah&multi=thud&multi=thonk"
3402
3403 // FIXME: need to implement encodeAscii!!
3404 var enc = encodeURIComponent, pairs = [];
3405 for(var name in map){
3406 var value = map[name];
3407 if(value != backstop[name]){
3408 var assign = enc(name) + "=";
3409 if(lang.isArray(value)){
3410 for(var i = 0, l = value.length; i < l; ++i){
3411 pairs.push(assign + enc(value[i]));
3412 }
3413 }else{
3414 pairs.push(assign + enc(value));
3415 }
3416 }
3417 }
3418 return pairs.join("&"); // String
3419 }
3420
3421 function queryToObject(/*String*/ str){
3422 // summary:
3423 // Create an object representing a de-serialized query section of a
3424 // URL. Query keys with multiple values are returned in an array.
3425 //
3426 // example:
3427 // This string:
3428 //
3429 // | "foo=bar&foo=baz&thinger=%20spaces%20=blah&zonk=blarg&"
3430 //
3431 // results in this object structure:
3432 //
3433 // | {
3434 // | foo: [ "bar", "baz" ],
3435 // | thinger: " spaces =blah",
3436 // | zonk: "blarg"
3437 // | }
3438 //
3439 // Note that spaces and other urlencoded entities are correctly
3440 // handled.
3441
3442 // FIXME: should we grab the URL string if we're not passed one?
3443 var dec = decodeURIComponent, qp = str.split("&"), ret = {}, name, val;
3444 for(var i = 0, l = qp.length, item; i < l; ++i){
3445 item = qp[i];
3446 if(item.length){
3447 var s = item.indexOf("=");
3448 if(s < 0){
3449 name = dec(item);
3450 val = "";
3451 }else{
3452 name = dec(item.slice(0, s));
3453 val = dec(item.slice(s + 1));
3454 }
3455 if(typeof ret[name] == "string"){ // inline'd type check
3456 ret[name] = [ret[name]];
3457 }
3458
3459 if(lang.isArray(ret[name])){
3460 ret[name].push(val);
3461 }else{
3462 ret[name] = val;
3463 }
3464 }
3465 }
3466 return ret; // Object
3467 }
3468
3469 return {
3470 objectToQuery: objectToQuery,
3471 queryToObject: queryToObject
3472 };
3473});
3474},
3475'dojo/_base/Deferred':function(){
3476define("dojo/_base/Deferred", ["./kernel", "./lang"], function(dojo, lang){
3477 // module:
3478 // dojo/_base/Deferred
3479 // summary:
3480 // This module defines dojo.Deferred.
81bea17a 3481
81bea17a 3482 var mutator = function(){};
2f01fe57
AD
3483 var freeze = Object.freeze || function(){};
3484 // A deferred provides an API for creating and resolving a promise.
1354d172
AD
3485 dojo.Deferred = function(/*Function?*/ canceller){
3486 // summary:
3487 // Deferreds provide a generic means for encapsulating an asynchronous
3488 // operation and notifying users of the completion and result of the operation.
3489 // description:
3490 // The dojo.Deferred API is based on the concept of promises that provide a
3491 // generic interface into the eventual completion of an asynchronous action.
3492 // The motivation for promises fundamentally is about creating a
3493 // separation of concerns that allows one to achieve the same type of
3494 // call patterns and logical data flow in asynchronous code as can be
3495 // achieved in synchronous code. Promises allows one
3496 // to be able to call a function purely with arguments needed for
3497 // execution, without conflating the call with concerns of whether it is
3498 // sync or async. One shouldn't need to alter a call's arguments if the
3499 // implementation switches from sync to async (or vice versa). By having
3500 // async functions return promises, the concerns of making the call are
3501 // separated from the concerns of asynchronous interaction (which are
3502 // handled by the promise).
3503 //
3504 // The dojo.Deferred is a type of promise that provides methods for fulfilling the
3505 // promise with a successful result or an error. The most important method for
3506 // working with Dojo's promises is the then() method, which follows the
3507 // CommonJS proposed promise API. An example of using a Dojo promise:
3508 //
3509 // | var resultingPromise = someAsyncOperation.then(function(result){
3510 // | ... handle result ...
3511 // | },
3512 // | function(error){
3513 // | ... handle error ...
3514 // | });
3515 //
3516 // The .then() call returns a new promise that represents the result of the
3517 // execution of the callback. The callbacks will never affect the original promises value.
3518 //
3519 // The dojo.Deferred instances also provide the following functions for backwards compatibility:
3520 //
3521 // * addCallback(handler)
3522 // * addErrback(handler)
3523 // * callback(result)
3524 // * errback(result)
3525 //
3526 // Callbacks are allowed to return promises themselves, so
3527 // you can build complicated sequences of events with ease.
3528 //
3529 // The creator of the Deferred may specify a canceller. The canceller
3530 // is a function that will be called if Deferred.cancel is called
3531 // before the Deferred fires. You can use this to implement clean
3532 // aborting of an XMLHttpRequest, etc. Note that cancel will fire the
3533 // deferred with a CancelledError (unless your canceller returns
3534 // another kind of error), so the errbacks should be prepared to
3535 // handle that error for cancellable Deferreds.
3536 // example:
3537 // | var deferred = new dojo.Deferred();
3538 // | setTimeout(function(){ deferred.callback({success: true}); }, 1000);
3539 // | return deferred;
3540 // example:
3541 // Deferred objects are often used when making code asynchronous. It
3542 // may be easiest to write functions in a synchronous manner and then
3543 // split code using a deferred to trigger a response to a long-lived
3544 // operation. For example, instead of register a callback function to
3545 // denote when a rendering operation completes, the function can
3546 // simply return a deferred:
3547 //
3548 // | // callback style:
3549 // | function renderLotsOfData(data, callback){
3550 // | var success = false
3551 // | try{
3552 // | for(var x in data){
3553 // | renderDataitem(data[x]);
3554 // | }
3555 // | success = true;
3556 // | }catch(e){ }
3557 // | if(callback){
3558 // | callback(success);
3559 // | }
3560 // | }
3561 //
3562 // | // using callback style
3563 // | renderLotsOfData(someDataObj, function(success){
3564 // | // handles success or failure
3565 // | if(!success){
3566 // | promptUserToRecover();
3567 // | }
3568 // | });
3569 // | // NOTE: no way to add another callback here!!
3570 // example:
3571 // Using a Deferred doesn't simplify the sending code any, but it
3572 // provides a standard interface for callers and senders alike,
3573 // providing both with a simple way to service multiple callbacks for
3574 // an operation and freeing both sides from worrying about details
3575 // such as "did this get called already?". With Deferreds, new
3576 // callbacks can be added at any time.
3577 //
3578 // | // Deferred style:
3579 // | function renderLotsOfData(data){
3580 // | var d = new dojo.Deferred();
3581 // | try{
3582 // | for(var x in data){
3583 // | renderDataitem(data[x]);
3584 // | }
3585 // | d.callback(true);
3586 // | }catch(e){
3587 // | d.errback(new Error("rendering failed"));
3588 // | }
3589 // | return d;
3590 // | }
3591 //
3592 // | // using Deferred style
3593 // | renderLotsOfData(someDataObj).then(null, function(){
3594 // | promptUserToRecover();
3595 // | });
3596 // | // NOTE: addErrback and addCallback both return the Deferred
3597 // | // again, so we could chain adding callbacks or save the
3598 // | // deferred for later should we need to be notified again.
3599 // example:
3600 // In this example, renderLotsOfData is synchronous and so both
3601 // versions are pretty artificial. Putting the data display on a
3602 // timeout helps show why Deferreds rock:
3603 //
3604 // | // Deferred style and async func
3605 // | function renderLotsOfData(data){
3606 // | var d = new dojo.Deferred();
3607 // | setTimeout(function(){
3608 // | try{
3609 // | for(var x in data){
3610 // | renderDataitem(data[x]);
3611 // | }
3612 // | d.callback(true);
3613 // | }catch(e){
3614 // | d.errback(new Error("rendering failed"));
3615 // | }
3616 // | }, 100);
3617 // | return d;
3618 // | }
3619 //
3620 // | // using Deferred style
3621 // | renderLotsOfData(someDataObj).then(null, function(){
3622 // | promptUserToRecover();
3623 // | });
3624 //
3625 // Note that the caller doesn't have to change his code at all to
3626 // handle the asynchronous case.
3627
2f01fe57 3628 var result, finished, isError, head, nextListener;
81bea17a 3629 var promise = (this.promise = {});
1354d172 3630
2f01fe57
AD
3631 function complete(value){
3632 if(finished){
81bea17a 3633 throw new Error("This deferred has already been resolved");
2f01fe57
AD
3634 }
3635 result = value;
3636 finished = true;
3637 notify();
3638 }
3639 function notify(){
3640 var mutated;
3641 while(!mutated && nextListener){
3642 var listener = nextListener;
3643 nextListener = nextListener.next;
81bea17a 3644 if((mutated = (listener.progress == mutator))){ // assignment and check
2f01fe57
AD
3645 finished = false;
3646 }
3647 var func = (isError ? listener.error : listener.resolved);
1354d172
AD
3648 if(func){
3649 try{
2f01fe57 3650 var newResult = func(result);
1354d172
AD
3651 if (newResult && typeof newResult.then === "function"){
3652 newResult.then(lang.hitch(listener.deferred, "resolve"), lang.hitch(listener.deferred, "reject"), lang.hitch(listener.deferred, "progress"));
2f01fe57
AD
3653 continue;
3654 }
3655 var unchanged = mutated && newResult === undefined;
81bea17a
AD
3656 if(mutated && !unchanged){
3657 isError = newResult instanceof Error;
3658 }
2f01fe57 3659 listener.deferred[unchanged && isError ? "reject" : "resolve"](unchanged ? result : newResult);
1354d172 3660 }catch(e){
2f01fe57
AD
3661 listener.deferred.reject(e);
3662 }
1354d172 3663 }else{
2f01fe57
AD
3664 if(isError){
3665 listener.deferred.reject(result);
3666 }else{
3667 listener.deferred.resolve(result);
3668 }
3669 }
81bea17a 3670 }
2f01fe57
AD
3671 }
3672 // calling resolve will resolve the promise
3673 this.resolve = this.callback = function(value){
3674 // summary:
3675 // Fulfills the Deferred instance successfully with the provide value
3676 this.fired = 0;
3677 this.results = [value, null];
3678 complete(value);
3679 };
1354d172
AD
3680
3681
2f01fe57
AD
3682 // calling error will indicate that the promise failed
3683 this.reject = this.errback = function(error){
3684 // summary:
81bea17a 3685 // Fulfills the Deferred instance as an error with the provided error
2f01fe57
AD
3686 isError = true;
3687 this.fired = 1;
3688 complete(error);
3689 this.results = [null, error];
3690 if(!error || error.log !== false){
3691 (dojo.config.deferredOnError || function(x){ console.error(x); })(error);
3692 }
3693 };
3694 // call progress to provide updates on the progress on the completion of the promise
3695 this.progress = function(update){
1354d172 3696 // summary:
2f01fe57
AD
3697 // Send progress events to all listeners
3698 var listener = nextListener;
3699 while(listener){
3700 var progress = listener.progress;
3701 progress && progress(update);
81bea17a 3702 listener = listener.next;
2f01fe57
AD
3703 }
3704 };
1354d172
AD
3705 this.addCallbacks = function(callback, errback){
3706 // summary:
3707 // Adds callback and error callback for this deferred instance.
3708 // callback: Function?
3709 // The callback attached to this deferred object.
3710 // errback: Function?
3711 // The error callback attached to this deferred object.
3712 // returns:
3713 // Returns this deferred object.
2f01fe57 3714 this.then(callback, errback, mutator);
1354d172 3715 return this; // dojo.Deferred
2f01fe57
AD
3716 };
3717 // provide the implementation of the promise
1354d172 3718 promise.then = this.then = function(/*Function?*/resolvedCallback, /*Function?*/errorCallback, /*Function?*/progressCallback){
81bea17a 3719 // summary:
1354d172
AD
3720 // Adds a fulfilledHandler, errorHandler, and progressHandler to be called for
3721 // completion of a promise. The fulfilledHandler is called when the promise
3722 // is fulfilled. The errorHandler is called when a promise fails. The
3723 // progressHandler is called for progress events. All arguments are optional
3724 // and non-function values are ignored. The progressHandler is not only an
3725 // optional argument, but progress events are purely optional. Promise
3726 // providers are not required to ever create progress events.
81bea17a 3727 //
1354d172
AD
3728 // This function will return a new promise that is fulfilled when the given
3729 // fulfilledHandler or errorHandler callback is finished. This allows promise
3730 // operations to be chained together. The value returned from the callback
3731 // handler is the fulfillment value for the returned promise. If the callback
3732 // throws an error, the returned promise will be moved to failed state.
81bea17a 3733 //
1354d172
AD
3734 // returns:
3735 // Returns a new promise that represents the result of the
3736 // execution of the callback. The callbacks will never affect the original promises value.
2f01fe57 3737 // example:
1354d172
AD
3738 // An example of using a CommonJS compliant promise:
3739 // | asyncComputeTheAnswerToEverything().
2f01fe57
AD
3740 // | then(addTwo).
3741 // | then(printResult, onError);
1354d172 3742 // | >44
81bea17a 3743 //
2f01fe57
AD
3744 var returnDeferred = progressCallback == mutator ? this : new dojo.Deferred(promise.cancel);
3745 var listener = {
81bea17a
AD
3746 resolved: resolvedCallback,
3747 error: errorCallback,
3748 progress: progressCallback,
2f01fe57 3749 deferred: returnDeferred
81bea17a 3750 };
2f01fe57
AD
3751 if(nextListener){
3752 head = head.next = listener;
3753 }
3754 else{
3755 nextListener = head = listener;
3756 }
3757 if(finished){
3758 notify();
3759 }
1354d172 3760 return returnDeferred.promise; // Promise
2f01fe57
AD
3761 };
3762 var deferred = this;
1354d172 3763 promise.cancel = this.cancel = function (){
2f01fe57
AD
3764 // summary:
3765 // Cancels the asynchronous operation
3766 if(!finished){
3767 var error = canceller && canceller(deferred);
3768 if(!finished){
1354d172 3769 if (!(error instanceof Error)){
2f01fe57
AD
3770 error = new Error(error);
3771 }
3772 error.log = false;
3773 deferred.reject(error);
3774 }
3775 }
81bea17a 3776 };
2f01fe57
AD
3777 freeze(promise);
3778 };
1354d172
AD
3779 lang.extend(dojo.Deferred, {
3780 addCallback: function (/*Function*/ callback){
3781 // summary:
3782 // Adds successful callback for this deferred instance.
3783 // returns:
3784 // Returns this deferred object.
3785 return this.addCallbacks(lang.hitch.apply(dojo, arguments)); // dojo.Deferred
2f01fe57 3786 },
1354d172
AD
3787
3788 addErrback: function (/*Function*/ errback){
3789 // summary:
3790 // Adds error callback for this deferred instance.
3791 // returns:
3792 // Returns this deferred object.
3793 return this.addCallbacks(null, lang.hitch.apply(dojo, arguments)); // dojo.Deferred
2f01fe57 3794 },
1354d172
AD
3795
3796 addBoth: function (/*Function*/ callback){
3797 // summary:
3798 // Add handler as both successful callback and error callback for this deferred instance.
3799 // returns:
3800 // Returns this deferred object.
3801 var enclosed = lang.hitch.apply(dojo, arguments);
3802 return this.addCallbacks(enclosed, enclosed); // dojo.Deferred
2f01fe57
AD
3803 },
3804 fired: -1
3805 });
2f01fe57 3806
1354d172
AD
3807 dojo.Deferred.when = dojo.when = function(promiseOrValue, /*Function?*/ callback, /*Function?*/ errback, /*Function?*/ progressHandler){
3808 // summary:
3809 // This provides normalization between normal synchronous values and
3810 // asynchronous promises, so you can interact with them in a common way
3811 // returns:
3812 // Returns a new promise that represents the result of the execution of callback
3813 // when parameter "promiseOrValue" is promise.
3814 // Returns the execution result of callback when parameter "promiseOrValue" is value.
3815 // example:
3816 // | function printFirstAndLast(items){
3817 // | dojo.when(findFirst(items), console.log);
3818 // | dojo.when(findLast(items), console.log);
3819 // | }
3820 // | function findFirst(items){
3821 // | return dojo.when(items, function(items){
3822 // | return items[0];
3823 // | });
3824 // | }
3825 // | function findLast(items){
3826 // | return dojo.when(items, function(items){
3827 // | return items[items.length - 1];
3828 // | });
3829 // | }
3830 // And now all three of his functions can be used sync or async.
3831 // | printFirstAndLast([1,2,3,4]) will work just as well as
3832 // | printFirstAndLast(dojo.xhrGet(...));
2f01fe57 3833
1354d172
AD
3834 if(promiseOrValue && typeof promiseOrValue.then === "function"){
3835 return promiseOrValue.then(callback, errback, progressHandler);
3836 }
3837 return callback ? callback(promiseOrValue) : promiseOrValue; // Promise
3838 };
2f01fe57 3839
1354d172
AD
3840 return dojo.Deferred;
3841});
2f01fe57 3842
1354d172
AD
3843},
3844'dojo/NodeList-dom':function(){
3845define(["./_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){
3846 /*===== var NodeList = dojo.NodeList; =====*/
3847 var magicGuard = function(a){
3848 // summary:
3849 // the guard function for dojo.attr() and dojo.style()
3850 return a.length == 1 && (typeof a[0] == "string"); // inline'd type check
3851 };
2f01fe57 3852
1354d172
AD
3853 var orphan = function(node){
3854 // summary:
3855 // function to orphan nodes
3856 var p = node.parentNode;
3857 if(p){
3858 p.removeChild(node);
2f01fe57 3859 }
1354d172
AD
3860 };
3861 // FIXME: should we move orphan() to dojo.html?
2f01fe57 3862
1354d172
AD
3863 var NodeList = query.NodeList,
3864 awc = NodeList._adaptWithCondition,
3865 aafe = NodeList._adaptAsForEach,
3866 aam = NodeList._adaptAsMap;
2f01fe57 3867
1354d172
AD
3868 function getSet(module){
3869 return function(node, name, value){
3870 if(arguments.length == 2){
3871 return module[typeof name == "string" ? "get" : "set"](node, name);
2f01fe57 3872 }
1354d172
AD
3873 // setter
3874 return module.set(node, name, value);
3875 };
2f01fe57 3876 }
2f01fe57 3877
1354d172
AD
3878 lang.extend(NodeList, {
3879 _normalize: function(/*String||Element||Object||NodeList*/content, /*DOMNode?*/refNode){
3880 // summary:
3881 // normalizes data to an array of items to insert.
3882 // description:
3883 // If content is an object, it can have special properties "template" and
3884 // "parse". If "template" is defined, then the template value is run through
3885 // dojo.string.substitute (if dojo.string.substitute has been dojo.required elsewhere),
3886 // or if templateFunc is a function on the content, that function will be used to
3887 // transform the template into a final string to be used for for passing to dojo._toDom.
3888 // If content.parse is true, then it is remembered for later, for when the content
3889 // nodes are inserted into the DOM. At that point, the nodes will be parsed for widgets
3890 // (if dojo.parser has been dojo.required elsewhere).
2f01fe57 3891
1354d172
AD
3892 //Wanted to just use a DocumentFragment, but for the array/NodeList
3893 //case that meant using cloneNode, but we may not want that.
3894 //Cloning should only happen if the node operations span
3895 //multiple refNodes. Also, need a real array, not a NodeList from the
3896 //DOM since the node movements could change those NodeLists.
81bea17a 3897
1354d172 3898 var parse = content.parse === true;
2f01fe57 3899
1354d172
AD
3900 //Do we have an object that needs to be run through a template?
3901 if(typeof content.template == "string"){
3902 var templateFunc = content.templateFunc || (dojo.string && dojo.string.substitute);
3903 content = templateFunc ? templateFunc(content.template, content) : content;
3904 }
2f01fe57 3905
1354d172
AD
3906 var type = (typeof content);
3907 if(type == "string" || type == "number"){
3908 content = domCtr.toDom(content, (refNode && refNode.ownerDocument));
3909 if(content.nodeType == 11){
3910 //DocumentFragment. It cannot handle cloneNode calls, so pull out the children.
3911 content = lang._toArray(content.childNodes);
3912 }else{
3913 content = [content];
3914 }
3915 }else if(!lang.isArrayLike(content)){
3916 content = [content];
3917 }else if(!lang.isArray(content)){
3918 //To get to this point, content is array-like, but
3919 //not an array, which likely means a DOM NodeList. Convert it now.
3920 content = lang._toArray(content);
3921 }
2f01fe57 3922
1354d172
AD
3923 //Pass around the parse info
3924 if(parse){
3925 content._runParse = true;
3926 }
3927 return content; //Array
2f01fe57 3928 },
1354d172
AD
3929
3930 _cloneNode: function(/*DOMNode*/ node){
2f01fe57 3931 // summary:
1354d172
AD
3932 // private utility to clone a node. Not very interesting in the vanilla
3933 // dojo.NodeList case, but delegates could do interesting things like
3934 // clone event handlers if that is derivable from the node.
3935 return node.cloneNode(true);
2f01fe57 3936 },
1354d172
AD
3937
3938 _place: function(/*Array*/ary, /*DOMNode*/refNode, /*String*/position, /*Boolean*/useClone){
2f01fe57 3939 // summary:
1354d172 3940 // private utility to handle placing an array of nodes relative to another node.
2f01fe57 3941 // description:
1354d172
AD
3942 // Allows for cloning the nodes in the array, and for
3943 // optionally parsing widgets, if ary._runParse is true.
3944
3945 //Avoid a disallowed operation if trying to do an innerHTML on a non-element node.
3946 if(refNode.nodeType != 1 && position == "only"){
3947 return;
3948 }
3949 var rNode = refNode, tempNode;
3950
3951 //Always cycle backwards in case the array is really a
3952 //DOM NodeList and the DOM operations take it out of the live collection.
3953 var length = ary.length;
3954 for(var i = length - 1; i >= 0; i--){
3955 var node = (useClone ? this._cloneNode(ary[i]) : ary[i]);
3956
3957 //If need widget parsing, use a temp node, instead of waiting after inserting into
3958 //real DOM because we need to start widget parsing at one node up from current node,
3959 //which could cause some already parsed widgets to be parsed again.
3960 if(ary._runParse && dojo.parser && dojo.parser.parse){
3961 if(!tempNode){
3962 tempNode = rNode.ownerDocument.createElement("div");
3963 }
3964 tempNode.appendChild(node);
3965 dojo.parser.parse(tempNode);
3966 node = tempNode.firstChild;
3967 while(tempNode.firstChild){
3968 tempNode.removeChild(tempNode.firstChild);
3969 }
3970 }
3971
3972 if(i == length - 1){
3973 domCtr.place(node, rNode, position);
3974 }else{
3975 rNode.parentNode.insertBefore(node, rNode);
3976 }
3977 rNode = node;
3978 }
2f01fe57 3979 },
1354d172
AD
3980
3981 /*=====
3982 position: function(){
2f01fe57 3983 // summary:
1354d172
AD
3984 // Returns border-box objects (x/y/w/h) of all elements in a node list
3985 // as an Array (*not* a NodeList). Acts like `dojo.position`, though
3986 // assumes the node passed is each node in this list.
3987
3988 return dojo.map(this, dojo.position); // Array
2f01fe57 3989 },
1354d172
AD
3990
3991 attr: function(property, value){
2f01fe57 3992 // summary:
1354d172
AD
3993 // gets or sets the DOM attribute for every element in the
3994 // NodeList. See also `dojo.attr`
3995 // property: String
3996 // the attribute to get/set
3997 // value: String?
3998 // optional. The value to set the property to
3999 // returns:
4000 // if no value is passed, the result is an array of attribute values
4001 // If a value is passed, the return is this NodeList
4002 // example:
4003 // Make all nodes with a particular class focusable:
4004 // | dojo.query(".focusable").attr("tabIndex", -1);
4005 // example:
4006 // Disable a group of buttons:
4007 // | dojo.query("button.group").attr("disabled", true);
4008 // example:
4009 // innerHTML can be assigned or retrieved as well:
4010 // | // get the innerHTML (as an array) for each list item
4011 // | var ih = dojo.query("li.replaceable").attr("innerHTML");
4012 return; // dojo.NodeList
4013 return; // Array
2f01fe57 4014 },
1354d172
AD
4015
4016 style: function(property, value){
2f01fe57 4017 // summary:
1354d172
AD
4018 // gets or sets the CSS property for every element in the NodeList
4019 // property: String
4020 // the CSS property to get/set, in JavaScript notation
4021 // ("lineHieght" instead of "line-height")
4022 // value: String?
4023 // optional. The value to set the property to
4024 // returns:
4025 // if no value is passed, the result is an array of strings.
4026 // If a value is passed, the return is this NodeList
4027 return; // dojo.NodeList
4028 return; // Array
2f01fe57 4029 },
1354d172
AD
4030
4031 addClass: function(className){
2f01fe57 4032 // summary:
1354d172
AD
4033 // adds the specified class to every node in the list
4034 // className: String|Array
4035 // A String class name to add, or several space-separated class names,
4036 // or an array of class names.
4037 return; // dojo.NodeList
2f01fe57 4038 },
1354d172
AD
4039
4040 removeClass: function(className){
2f01fe57 4041 // summary:
1354d172
AD
4042 // removes the specified class from every node in the list
4043 // className: String|Array?
4044 // An optional String class name to remove, or several space-separated
4045 // class names, or an array of class names. If omitted, all class names
4046 // will be deleted.
4047 // returns:
4048 // dojo.NodeList, this list
4049 return; // dojo.NodeList
4050 },
2f01fe57 4051
1354d172
AD
4052 toggleClass: function(className, condition){
4053 // summary:
4054 // Adds a class to node if not present, or removes if present.
4055 // Pass a boolean condition if you want to explicitly add or remove.
4056 // condition: Boolean?
4057 // If passed, true means to add the class, false means to remove.
4058 // className: String
4059 // the CSS class to add
4060 return; // dojo.NodeList
4061 },
2f01fe57 4062
1354d172
AD
4063 empty: function(){
4064 // summary:
4065 // clears all content from each node in the list. Effectively
4066 // equivalent to removing all child nodes from every item in
4067 // the list.
4068 return this.forEach("item.innerHTML='';"); // dojo.NodeList
4069 // FIXME: should we be checking for and/or disposing of widgets below these nodes?
4070 },
4071 =====*/
2f01fe57 4072
1354d172
AD
4073 // useful html methods
4074 attr: awc(getSet(domAttr), magicGuard),
4075 style: awc(getSet(domStyle), magicGuard),
2f01fe57 4076
1354d172
AD
4077 addClass: aafe(domCls.add),
4078 removeClass: aafe(domCls.remove),
4079 replaceClass: aafe(domCls.replace),
4080 toggleClass: aafe(domCls.toggle),
2f01fe57 4081
1354d172
AD
4082 empty: aafe(domCtr.empty),
4083 removeAttr: aafe(domAttr.remove),
2f01fe57 4084
1354d172
AD
4085 position: aam(domGeom.position),
4086 marginBox: aam(domGeom.getMarginBox),
2f01fe57 4087
1354d172 4088 // FIXME: connectPublisher()? connectRunOnce()?
2f01fe57 4089
1354d172
AD
4090 /*
4091 destroy: function(){
4092 // summary:
4093 // destroys every item in the list.
4094 this.forEach(d.destroy);
4095 // FIXME: should we be checking for and/or disposing of widgets below these nodes?
4096 },
4097 */
81bea17a 4098
1354d172
AD
4099 place: function(/*String||Node*/ queryOrNode, /*String*/ position){
4100 // summary:
4101 // places elements of this node list relative to the first element matched
4102 // by queryOrNode. Returns the original NodeList. See: `dojo.place`
4103 // queryOrNode:
4104 // may be a string representing any valid CSS3 selector or a DOM node.
4105 // In the selector case, only the first matching element will be used
4106 // for relative positioning.
4107 // position:
4108 // can be one of:
4109 // | "last" (default)
4110 // | "first"
4111 // | "before"
4112 // | "after"
4113 // | "only"
4114 // | "replace"
4115 // or an offset in the childNodes property
4116 var item = query(queryOrNode)[0];
4117 return this.forEach(function(node){ domCtr.place(node, item, position); }); // dojo.NodeList
4118 },
2f01fe57 4119
1354d172
AD
4120 orphan: function(/*String?*/ filter){
4121 // summary:
4122 // removes elements in this list that match the filter
4123 // from their parents and returns them as a new NodeList.
4124 // filter:
4125 // CSS selector like ".foo" or "div > span"
4126 // returns:
4127 // `dojo.NodeList` containing the orphaned elements
4128 return (filter ? query._filterResult(this, filter) : this).forEach(orphan); // dojo.NodeList
4129 },
2f01fe57 4130
1354d172
AD
4131 adopt: function(/*String||Array||DomNode*/ queryOrListOrNode, /*String?*/ position){
4132 // summary:
4133 // places any/all elements in queryOrListOrNode at a
4134 // position relative to the first element in this list.
4135 // Returns a dojo.NodeList of the adopted elements.
4136 // queryOrListOrNode:
4137 // a DOM node or a query string or a query result.
4138 // Represents the nodes to be adopted relative to the
4139 // first element of this NodeList.
4140 // position:
4141 // can be one of:
4142 // | "last" (default)
4143 // | "first"
4144 // | "before"
4145 // | "after"
4146 // | "only"
4147 // | "replace"
4148 // or an offset in the childNodes property
4149 return query(queryOrListOrNode).place(this[0], position)._stash(this); // dojo.NodeList
4150 },
2f01fe57 4151
1354d172
AD
4152 // FIXME: do we need this?
4153 query: function(/*String*/ queryStr){
4154 // summary:
4155 // Returns a new list whose members match the passed query,
4156 // assuming elements of the current NodeList as the root for
4157 // each search.
4158 // example:
4159 // assume a DOM created by this markup:
4160 // | <div id="foo">
4161 // | <p>
4162 // | bacon is tasty, <span>dontcha think?</span>
4163 // | </p>
4164 // | </div>
4165 // | <div id="bar">
4166 // | <p>great comedians may not be funny <span>in person</span></p>
4167 // | </div>
4168 // If we are presented with the following definition for a NodeList:
4169 // | var l = new dojo.NodeList(dojo.byId("foo"), dojo.byId("bar"));
4170 // it's possible to find all span elements under paragraphs
4171 // contained by these elements with this sub-query:
4172 // | var spans = l.query("p span");
2f01fe57 4173
1354d172
AD
4174 // FIXME: probably slow
4175 if(!queryStr){ return this; }
4176 var ret = new NodeList;
4177 this.map(function(node){
4178 // FIXME: why would we ever get undefined here?
4179 query(queryStr, node).forEach(function(subNode){
4180 if(subNode !== undefined){
4181 ret.push(subNode);
4182 }
4183 });
4184 });
4185 return ret._stash(this); // dojo.NodeList
4186 },
81bea17a 4187
1354d172
AD
4188 filter: function(/*String|Function*/ filter){
4189 // summary:
4190 // "masks" the built-in javascript filter() method (supported
4191 // in Dojo via `dojo.filter`) to support passing a simple
4192 // string filter in addition to supporting filtering function
4193 // objects.
4194 // filter:
4195 // If a string, a CSS rule like ".thinger" or "div > span".
4196 // example:
4197 // "regular" JS filter syntax as exposed in dojo.filter:
4198 // | dojo.query("*").filter(function(item){
4199 // | // highlight every paragraph
4200 // | return (item.nodeName == "p");
4201 // | }).style("backgroundColor", "yellow");
4202 // example:
4203 // the same filtering using a CSS selector
4204 // | dojo.query("*").filter("p").styles("backgroundColor", "yellow");
2f01fe57 4205
1354d172
AD
4206 var a = arguments, items = this, start = 0;
4207 if(typeof filter == "string"){ // inline'd type check
4208 items = query._filterResult(this, a[0]);
4209 if(a.length == 1){
4210 // if we only got a string query, pass back the filtered results
4211 return items._stash(this); // dojo.NodeList
2f01fe57 4212 }
1354d172
AD
4213 // if we got a callback, run it over the filtered items
4214 start = 1;
2f01fe57 4215 }
1354d172 4216 return this._wrap(array.filter(items, a[start], a[start + 1]), this); // dojo.NodeList
2f01fe57 4217 },
1354d172
AD
4218
4219 /*
4220 // FIXME: should this be "copyTo" and include parenting info?
4221 clone: function(){
2f01fe57 4222 // summary:
1354d172
AD
4223 // creates node clones of each element of this list
4224 // and returns a new list containing the clones
2f01fe57 4225 },
1354d172
AD
4226 */
4227
4228 addContent: function(/*String||DomNode||Object||dojo.NodeList*/ content, /*String||Integer?*/ position){
4229 // summary:
4230 // add a node, NodeList or some HTML as a string to every item in the
4231 // list. Returns the original list.
4232 // description:
4233 // a copy of the HTML content is added to each item in the
4234 // list, with an optional position argument. If no position
4235 // argument is provided, the content is appended to the end of
4236 // each item.
4237 // content:
4238 // DOM node, HTML in string format, a NodeList or an Object. If a DOM node or
4239 // NodeList, the content will be cloned if the current NodeList has more than one
4240 // element. Only the DOM nodes are cloned, no event handlers. If it is an Object,
4241 // it should be an object with at "template" String property that has the HTML string
4242 // to insert. If dojo.string has already been dojo.required, then dojo.string.substitute
4243 // will be used on the "template" to generate the final HTML string. Other allowed
4244 // properties on the object are: "parse" if the HTML
4245 // string should be parsed for widgets (dojo.require("dojo.parser") to get that
4246 // option to work), and "templateFunc" if a template function besides dojo.string.substitute
4247 // should be used to transform the "template".
4248 // position:
4249 // can be one of:
4250 // | "last"||"end" (default)
4251 // | "first||"start"
4252 // | "before"
4253 // | "after"
4254 // | "replace" (replaces nodes in this NodeList with new content)
4255 // | "only" (removes other children of the nodes so new content is the only child)
4256 // or an offset in the childNodes property
4257 // example:
4258 // appends content to the end if the position is omitted
4259 // | dojo.query("h3 > p").addContent("hey there!");
4260 // example:
4261 // add something to the front of each element that has a
4262 // "thinger" property:
4263 // | dojo.query("[thinger]").addContent("...", "first");
4264 // example:
4265 // adds a header before each element of the list
4266 // | dojo.query(".note").addContent("<h4>NOTE:</h4>", "before");
4267 // example:
4268 // add a clone of a DOM node to the end of every element in
4269 // the list, removing it from its existing parent.
4270 // | dojo.query(".note").addContent(dojo.byId("foo"));
4271 // example:
4272 // Append nodes from a templatized string.
4273 // dojo.require("dojo.string");
4274 // dojo.query(".note").addContent({
4275 // template: '<b>${id}: </b><span>${name}</span>',
4276 // id: "user332",
4277 // name: "Mr. Anderson"
4278 // });
4279 // example:
4280 // Append nodes from a templatized string that also has widgets parsed.
4281 // dojo.require("dojo.string");
4282 // dojo.require("dojo.parser");
4283 // var notes = dojo.query(".note").addContent({
4284 // template: '<button dojoType="dijit.form.Button">${text}</button>',
4285 // parse: true,
4286 // text: "Send"
4287 // });
4288 content = this._normalize(content, this[0]);
4289 for(var i = 0, node; (node = this[i]); i++){
4290 this._place(content, node, position, i > 0);
4291 }
4292 return this; //dojo.NodeList
2f01fe57
AD
4293 }
4294 });
4295
1354d172
AD
4296 /*===== return dojo.NodeList; =====*/
4297 return NodeList;
4298});
4299
4300},
4301'dojo/query':function(){
4302define(["./_base/kernel", "./has", "./dom", "./on", "./_base/array", "./_base/lang", "./selector/_loader", "./selector/_loader!default"],
4303 function(dojo, has, dom, on, array, lang, loader, defaultEngine){
4304"use strict";
4305
4306 has.add("array-extensible", function(){
4307 // test to see if we can extend an array (not supported in old IE)
4308 return lang.delegate([], {length: 1}).length == 1 && !has("bug-for-in-skips-shadowed");
4309 });
2f01fe57 4310
1354d172
AD
4311 var ap = Array.prototype, aps = ap.slice, apc = ap.concat, forEach = array.forEach;
4312
4313 var tnl = function(/*Array*/ a, /*dojo.NodeList?*/ parent, /*Function?*/ NodeListCtor){
2f01fe57 4314 // summary:
1354d172
AD
4315 // decorate an array to make it look like a `dojo.NodeList`.
4316 // a:
4317 // Array of nodes to decorate.
4318 // parent:
4319 // An optional parent NodeList that generated the current
4320 // list of nodes. Used to call _stash() so the parent NodeList
4321 // can be accessed via end() later.
4322 // NodeListCtor:
4323 // An optional constructor function to use for any
4324 // new NodeList calls. This allows a certain chain of
4325 // NodeList calls to use a different object than dojo.NodeList.
4326 var nodeList = new (NodeListCtor || this._NodeListCtor || nl)(a);
4327 return parent ? nodeList._stash(parent) : nodeList;
81bea17a 4328 };
2f01fe57 4329
1354d172
AD
4330 var loopBody = function(f, a, o){
4331 a = [0].concat(aps.call(a, 0));
4332 o = o || dojo.global;
4333 return function(node){
4334 a[0] = node;
4335 return f.apply(o, a);
4336 };
81bea17a 4337 };
2f01fe57 4338
1354d172
AD
4339 // adapters
4340
4341 var adaptAsForEach = function(f, o){
2f01fe57 4342 // summary:
1354d172
AD
4343 // adapts a single node function to be used in the forEach-type
4344 // actions. The initial object is returned from the specialized
4345 // function.
4346 // f: Function
4347 // a function to adapt
4348 // o: Object?
4349 // an optional context for f
4350 return function(){
4351 this.forEach(loopBody(f, arguments, o));
4352 return this; // Object
4353 };
2f01fe57 4354 };
1354d172
AD
4355
4356 var adaptAsMap = function(f, o){
2f01fe57 4357 // summary:
1354d172
AD
4358 // adapts a single node function to be used in the map-type
4359 // actions. The return is a new array of values, as via `dojo.map`
4360 // f: Function
4361 // a function to adapt
4362 // o: Object?
4363 // an optional context for f
4364 return function(){
4365 return this.map(loopBody(f, arguments, o));
4366 };
2f01fe57
AD
4367 };
4368
1354d172
AD
4369 var adaptAsFilter = function(f, o){
4370 // summary:
4371 // adapts a single node function to be used in the filter-type actions
4372 // f: Function
4373 // a function to adapt
4374 // o: Object?
4375 // an optional context for f
4376 return function(){
4377 return this.filter(loopBody(f, arguments, o));
4378 };
2f01fe57 4379 };
2f01fe57 4380
1354d172
AD
4381 var adaptWithCondition = function(f, g, o){
4382 // summary:
4383 // adapts a single node function to be used in the map-type
4384 // actions, behaves like forEach() or map() depending on arguments
4385 // f: Function
4386 // a function to adapt
4387 // g: Function
4388 // a condition function, if true runs as map(), otherwise runs as forEach()
4389 // o: Object?
4390 // an optional context for f and g
4391 return function(){
4392 var a = arguments, body = loopBody(f, a, o);
4393 if(g.call(o || dojo.global, a)){
4394 return this.map(body); // self
4395 }
4396 this.forEach(body);
4397 return this; // self
2f01fe57 4398 };
81bea17a 4399 };
2f01fe57 4400
1354d172
AD
4401 var NodeList = function(array){
4402 // summary:
4403 // dojo.NodeList is an of Array-like object which adds syntactic
4404 // sugar for chaining, common iteration operations, animation, and
4405 // node manipulation. NodeLists are most often returned as the
4406 // result of dojo.query() calls.
4407 // description:
4408 // dojo.NodeList instances provide many utilities that reflect
4409 // core Dojo APIs for Array iteration and manipulation, DOM
4410 // manipulation, and event handling. Instead of needing to dig up
4411 // functions in the dojo.* namespace, NodeLists generally make the
4412 // full power of Dojo available for DOM manipulation tasks in a
4413 // simple, chainable way.
4414 // example:
4415 // create a node list from a node
4416 // | new dojo.NodeList(dojo.byId("foo"));
4417 // example:
4418 // get a NodeList from a CSS query and iterate on it
4419 // | var l = dojo.query(".thinger");
4420 // | l.forEach(function(node, index, nodeList){
4421 // | console.log(index, node.innerHTML);
4422 // | });
4423 // example:
4424 // use native and Dojo-provided array methods to manipulate a
4425 // NodeList without needing to use dojo.* functions explicitly:
4426 // | var l = dojo.query(".thinger");
4427 // | // since NodeLists are real arrays, they have a length
4428 // | // property that is both readable and writable and
4429 // | // push/pop/shift/unshift methods
4430 // | console.log(l.length);
4431 // | l.push(dojo.create("span"));
4432 // |
4433 // | // dojo's normalized array methods work too:
4434 // | console.log( l.indexOf(dojo.byId("foo")) );
4435 // | // ...including the special "function as string" shorthand
4436 // | console.log( l.every("item.nodeType == 1") );
4437 // |
4438 // | // NodeLists can be [..] indexed, or you can use the at()
4439 // | // function to get specific items wrapped in a new NodeList:
4440 // | var node = l[3]; // the 4th element
4441 // | var newList = l.at(1, 3); // the 2nd and 4th elements
4442 // example:
4443 // the style functions you expect are all there too:
4444 // | // style() as a getter...
4445 // | var borders = dojo.query(".thinger").style("border");
4446 // | // ...and as a setter:
4447 // | dojo.query(".thinger").style("border", "1px solid black");
4448 // | // class manipulation
4449 // | dojo.query("li:nth-child(even)").addClass("even");
4450 // | // even getting the coordinates of all the items
4451 // | var coords = dojo.query(".thinger").coords();
4452 // example:
4453 // DOM manipulation functions from the dojo.* namespace area also
4454 // available:
4455 // | // remove all of the elements in the list from their
4456 // | // parents (akin to "deleting" them from the document)
4457 // | dojo.query(".thinger").orphan();
4458 // | // place all elements in the list at the front of #foo
4459 // | dojo.query(".thinger").place("foo", "first");
4460 // example:
4461 // Event handling couldn't be easier. `dojo.connect` is mapped in,
4462 // and shortcut handlers are provided for most DOM events:
4463 // | // like dojo.connect(), but with implicit scope
4464 // | dojo.query("li").connect("onclick", console, "log");
4465 // |
4466 // | // many common event handlers are already available directly:
4467 // | dojo.query("li").onclick(console, "log");
4468 // | var toggleHovered = dojo.hitch(dojo, "toggleClass", "hovered");
4469 // | dojo.query("p")
4470 // | .onmouseenter(toggleHovered)
4471 // | .onmouseleave(toggleHovered);
4472 // example:
4473 // chainability is a key advantage of NodeLists:
4474 // | dojo.query(".thinger")
4475 // | .onclick(function(e){ /* ... */ })
4476 // | .at(1, 3, 8) // get a subset
4477 // | .style("padding", "5px")
4478 // | .forEach(console.log);
4479 var isNew = this instanceof nl && has("array-extensible");
4480 if(typeof array == "number"){
4481 array = Array(array);
4482 }
4483 var nodeArray = (array && "length" in array) ? array : arguments;
4484 if(isNew || !nodeArray.sort){
4485 // make sure it's a real array before we pass it on to be wrapped
4486 var target = isNew ? this : [],
4487 l = target.length = nodeArray.length;
4488 for(var i = 0; i < l; i++){
4489 target[i] = nodeArray[i];
4490 }
4491 if(isNew){
4492 // called with new operator, this means we are going to use this instance and push
4493 // the nodes on to it. This is usually much faster since the NodeList properties
4494 // don't need to be copied (unless the list of nodes is extremely large).
4495 return target;
4496 }
4497 nodeArray = target;
4498 }
4499 // called without new operator, use a real array and copy prototype properties,
4500 // this is slower and exists for back-compat. Should be removed in 2.0.
4501 lang._mixin(nodeArray, nlp);
4502 nodeArray._NodeListCtor = function(array){
4503 // call without new operator to preserve back-compat behavior
4504 return nl(array);
4505 };
4506 return nodeArray;
81bea17a 4507 };
1354d172
AD
4508
4509 var nl = NodeList, nlp = nl.prototype =
4510 has("array-extensible") ? [] : {};// extend an array if it is extensible
2f01fe57 4511
1354d172 4512 // expose adapters and the wrapper as private functions
81bea17a 4513
1354d172
AD
4514 nl._wrap = nlp._wrap = tnl;
4515 nl._adaptAsMap = adaptAsMap;
4516 nl._adaptAsForEach = adaptAsForEach;
4517 nl._adaptAsFilter = adaptAsFilter;
4518 nl._adaptWithCondition = adaptWithCondition;
81bea17a 4519
1354d172 4520 // mass assignment
2f01fe57 4521
1354d172
AD
4522 // add array redirectors
4523 forEach(["slice", "splice"], function(name){
4524 var f = ap[name];
4525 //Use a copy of the this array via this.slice() to allow .end() to work right in the splice case.
4526 // CANNOT apply ._stash()/end() to splice since it currently modifies
4527 // the existing this array -- it would break backward compatibility if we copy the array before
4528 // the splice so that we can use .end(). So only doing the stash option to this._wrap for slice.
4529 nlp[name] = function(){ return this._wrap(f.apply(this, arguments), name == "slice" ? this : null); };
4530 });
4531 // concat should be here but some browsers with native NodeList have problems with it
2f01fe57 4532
1354d172
AD
4533 // add array.js redirectors
4534 forEach(["indexOf", "lastIndexOf", "every", "some"], function(name){
4535 var f = array[name];
4536 nlp[name] = function(){ return f.apply(dojo, [this].concat(aps.call(arguments, 0))); };
4537 });
2f01fe57 4538
1354d172
AD
4539 /*===== var NodeList = dojo.NodeList; =====*/
4540 lang.extend(NodeList, {
4541 // copy the constructors
4542 constructor: nl,
4543 _NodeListCtor: nl,
4544 toString: function(){
4545 // Array.prototype.toString can't be applied to objects, so we use join
4546 return this.join(",");
4547 },
4548 _stash: function(parent){
4549 // summary:
4550 // private function to hold to a parent NodeList. end() to return the parent NodeList.
4551 //
4552 // example:
4553 // How to make a `dojo.NodeList` method that only returns the third node in
4554 // the dojo.NodeList but allows access to the original NodeList by using this._stash:
4555 // | dojo.extend(dojo.NodeList, {
4556 // | third: function(){
4557 // | var newNodeList = dojo.NodeList(this[2]);
4558 // | return newNodeList._stash(this);
4559 // | }
4560 // | });
4561 // | // then see how _stash applies a sub-list, to be .end()'ed out of
4562 // | dojo.query(".foo")
4563 // | .third()
4564 // | .addClass("thirdFoo")
4565 // | .end()
4566 // | // access to the orig .foo list
4567 // | .removeClass("foo")
4568 // |
4569 //
4570 this._parent = parent;
4571 return this; //dojo.NodeList
4572 },
2f01fe57 4573
1354d172
AD
4574 on: function(eventName, listener){
4575 // summary:
4576 // Listen for events on the nodes in the NodeList. Basic usage is:
4577 // | query(".my-class").on("click", listener);
4578 // This supports event delegation by using selectors as the first argument with the event names as
4579 // pseudo selectors. For example:
4580 // | dojo.query("#my-list").on("li:click", listener);
4581 // This will listen for click events within <li> elements that are inside the #my-list element.
4582 // Because on supports CSS selector syntax, we can use comma-delimited events as well:
4583 // | dojo.query("#my-list").on("li button:mouseover, li:click", listener);
4584 var handles = this.map(function(node){
4585 return on(node, eventName, listener); // TODO: apply to the NodeList so the same selector engine is used for matches
4586 });
4587 handles.remove = function(){
4588 for(var i = 0; i < handles.length; i++){
4589 handles[i].remove();
2f01fe57 4590 }
1354d172
AD
4591 };
4592 return handles;
4593 },
2f01fe57 4594
1354d172
AD
4595 end: function(){
4596 // summary:
4597 // Ends use of the current `dojo.NodeList` by returning the previous dojo.NodeList
4598 // that generated the current dojo.NodeList.
4599 // description:
4600 // Returns the `dojo.NodeList` that generated the current `dojo.NodeList`. If there
4601 // is no parent dojo.NodeList, an empty dojo.NodeList is returned.
4602 // example:
4603 // | dojo.query("a")
4604 // | .filter(".disabled")
4605 // | // operate on the anchors that only have a disabled class
4606 // | .style("color", "grey")
4607 // | .end()
4608 // | // jump back to the list of anchors
4609 // | .style(...)
4610 //
4611 if(this._parent){
4612 return this._parent;
2f01fe57 4613 }else{
1354d172
AD
4614 //Just return empty list.
4615 return new this._NodeListCtor(0);
2f01fe57 4616 }
1354d172 4617 },
2f01fe57 4618
1354d172 4619 // http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array#Methods
2f01fe57 4620
1354d172
AD
4621 // FIXME: handle return values for #3244
4622 // http://trac.dojotoolkit.org/ticket/3244
2f01fe57 4623
1354d172
AD
4624 // FIXME:
4625 // need to wrap or implement:
4626 // join (perhaps w/ innerHTML/outerHTML overload for toString() of items?)
4627 // reduce
4628 // reduceRight
2f01fe57 4629
1354d172
AD
4630 /*=====
4631 slice: function(begin, end){
4632 // summary:
4633 // Returns a new NodeList, maintaining this one in place
4634 // description:
4635 // This method behaves exactly like the Array.slice method
4636 // with the caveat that it returns a dojo.NodeList and not a
4637 // raw Array. For more details, see Mozilla's (slice
4638 // documentation)[http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:slice]
4639 // begin: Integer
4640 // Can be a positive or negative integer, with positive
4641 // integers noting the offset to begin at, and negative
4642 // integers denoting an offset from the end (i.e., to the left
4643 // of the end)
4644 // end: Integer?
4645 // Optional parameter to describe what position relative to
4646 // the NodeList's zero index to end the slice at. Like begin,
4647 // can be positive or negative.
4648 return this._wrap(a.slice.apply(this, arguments));
4649 },
2f01fe57 4650
1354d172
AD
4651 splice: function(index, howmany, item){
4652 // summary:
4653 // Returns a new NodeList, manipulating this NodeList based on
4654 // the arguments passed, potentially splicing in new elements
4655 // at an offset, optionally deleting elements
4656 // description:
4657 // This method behaves exactly like the Array.splice method
4658 // with the caveat that it returns a dojo.NodeList and not a
4659 // raw Array. For more details, see Mozilla's (splice
4660 // documentation)[http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:splice]
4661 // For backwards compatibility, calling .end() on the spliced NodeList
4662 // does not return the original NodeList -- splice alters the NodeList in place.
4663 // index: Integer
4664 // begin can be a positive or negative integer, with positive
4665 // integers noting the offset to begin at, and negative
4666 // integers denoting an offset from the end (i.e., to the left
4667 // of the end)
4668 // howmany: Integer?
4669 // Optional parameter to describe what position relative to
4670 // the NodeList's zero index to end the slice at. Like begin,
4671 // can be positive or negative.
4672 // item: Object...?
4673 // Any number of optional parameters may be passed in to be
4674 // spliced into the NodeList
4675 // returns:
4676 // dojo.NodeList
4677 return this._wrap(a.splice.apply(this, arguments));
4678 },
2f01fe57 4679
1354d172
AD
4680 indexOf: function(value, fromIndex){
4681 // summary:
4682 // see dojo.indexOf(). The primary difference is that the acted-on
4683 // array is implicitly this NodeList
4684 // value: Object:
4685 // The value to search for.
4686 // fromIndex: Integer?:
4687 // The location to start searching from. Optional. Defaults to 0.
4688 // description:
4689 // For more details on the behavior of indexOf, see Mozilla's
4690 // (indexOf
4691 // docs)[http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:indexOf]
4692 // returns:
4693 // Positive Integer or 0 for a match, -1 of not found.
4694 return d.indexOf(this, value, fromIndex); // Integer
4695 },
2f01fe57 4696
1354d172
AD
4697 lastIndexOf: function(value, fromIndex){
4698 // summary:
4699 // see dojo.lastIndexOf(). The primary difference is that the
4700 // acted-on array is implicitly this NodeList
4701 // description:
4702 // For more details on the behavior of lastIndexOf, see
4703 // Mozilla's (lastIndexOf
4704 // docs)[http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:lastIndexOf]
4705 // value: Object
4706 // The value to search for.
4707 // fromIndex: Integer?
4708 // The location to start searching from. Optional. Defaults to 0.
4709 // returns:
4710 // Positive Integer or 0 for a match, -1 of not found.
4711 return d.lastIndexOf(this, value, fromIndex); // Integer
4712 },
2f01fe57 4713
1354d172
AD
4714 every: function(callback, thisObject){
4715 // summary:
4716 // see `dojo.every()` and the (Array.every
4717 // docs)[http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:every].
4718 // Takes the same structure of arguments and returns as
4719 // dojo.every() with the caveat that the passed array is
4720 // implicitly this NodeList
4721 // callback: Function: the callback
4722 // thisObject: Object?: the context
4723 return d.every(this, callback, thisObject); // Boolean
4724 },
2f01fe57 4725
1354d172
AD
4726 some: function(callback, thisObject){
4727 // summary:
4728 // Takes the same structure of arguments and returns as
4729 // `dojo.some()` with the caveat that the passed array is
4730 // implicitly this NodeList. See `dojo.some()` and Mozilla's
4731 // (Array.some
4732 // documentation)[http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:some].
4733 // callback: Function: the callback
4734 // thisObject: Object?: the context
4735 return d.some(this, callback, thisObject); // Boolean
4736 },
4737 =====*/
2f01fe57 4738
1354d172
AD
4739 concat: function(item){
4740 // summary:
4741 // Returns a new NodeList comprised of items in this NodeList
4742 // as well as items passed in as parameters
4743 // description:
4744 // This method behaves exactly like the Array.concat method
4745 // with the caveat that it returns a `dojo.NodeList` and not a
4746 // raw Array. For more details, see the (Array.concat
4747 // docs)[http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:concat]
4748 // item: Object?
4749 // Any number of optional parameters may be passed in to be
4750 // spliced into the NodeList
4751 // returns:
4752 // dojo.NodeList
2f01fe57 4753
1354d172
AD
4754 //return this._wrap(apc.apply(this, arguments));
4755 // the line above won't work for the native NodeList :-(
2f01fe57 4756
1354d172
AD
4757 // implementation notes:
4758 // 1) Native NodeList is not an array, and cannot be used directly
4759 // in concat() --- the latter doesn't recognize it as an array, and
4760 // does not inline it, but append as a single entity.
4761 // 2) On some browsers (e.g., Safari) the "constructor" property is
4762 // read-only and cannot be changed. So we have to test for both
4763 // native NodeList and dojo.NodeList in this property to recognize
4764 // the node list.
2f01fe57 4765
1354d172
AD
4766 var t = lang.isArray(this) ? this : aps.call(this, 0),
4767 m = array.map(arguments, function(a){
4768 return a && !lang.isArray(a) &&
4769 (typeof NodeList != "undefined" && a.constructor === NodeList || a.constructor === this._NodeListCtor) ?
4770 aps.call(a, 0) : a;
4771 });
4772 return this._wrap(apc.apply(t, m), this); // dojo.NodeList
4773 },
2f01fe57 4774
1354d172
AD
4775 map: function(/*Function*/ func, /*Function?*/ obj){
4776 // summary:
4777 // see dojo.map(). The primary difference is that the acted-on
4778 // array is implicitly this NodeList and the return is a
4779 // dojo.NodeList (a subclass of Array)
4780 ///return d.map(this, func, obj, d.NodeList); // dojo.NodeList
4781 return this._wrap(array.map(this, func, obj), this); // dojo.NodeList
4782 },
2f01fe57 4783
1354d172
AD
4784 forEach: function(callback, thisObj){
4785 // summary:
4786 // see `dojo.forEach()`. The primary difference is that the acted-on
4787 // array is implicitly this NodeList. If you want the option to break out
4788 // of the forEach loop, use every() or some() instead.
4789 forEach(this, callback, thisObj);
4790 // non-standard return to allow easier chaining
4791 return this; // dojo.NodeList
4792 },
4793 filter: function(/*String|Function*/ filter){
4794 // summary:
4795 // "masks" the built-in javascript filter() method (supported
4796 // in Dojo via `dojo.filter`) to support passing a simple
4797 // string filter in addition to supporting filtering function
4798 // objects.
4799 // filter:
4800 // If a string, a CSS rule like ".thinger" or "div > span".
4801 // example:
4802 // "regular" JS filter syntax as exposed in dojo.filter:
4803 // | dojo.query("*").filter(function(item){
4804 // | // highlight every paragraph
4805 // | return (item.nodeName == "p");
4806 // | }).style("backgroundColor", "yellow");
4807 // example:
4808 // the same filtering using a CSS selector
4809 // | dojo.query("*").filter("p").styles("backgroundColor", "yellow");
2f01fe57 4810
1354d172
AD
4811 var a = arguments, items = this, start = 0;
4812 if(typeof filter == "string"){ // inline'd type check
4813 items = query._filterResult(this, a[0]);
4814 if(a.length == 1){
4815 // if we only got a string query, pass back the filtered results
4816 return items._stash(this); // dojo.NodeList
2f01fe57 4817 }
1354d172
AD
4818 // if we got a callback, run it over the filtered items
4819 start = 1;
2f01fe57 4820 }
1354d172
AD
4821 return this._wrap(array.filter(items, a[start], a[start + 1]), this); // dojo.NodeList
4822 },
4823 instantiate: function(/*String|Object*/ declaredClass, /*Object?*/ properties){
4824 // summary:
4825 // Create a new instance of a specified class, using the
4826 // specified properties and each node in the nodeList as a
4827 // srcNodeRef.
4828 // example:
4829 // Grabs all buttons in the page and converts them to diji.form.Buttons.
4830 // | var buttons = dojo.query("button").instantiate("dijit.form.Button", {showLabel: true});
4831 var c = lang.isFunction(declaredClass) ? declaredClass : lang.getObject(declaredClass);
4832 properties = properties || {};
4833 return this.forEach(function(node){
4834 new c(properties, node);
4835 }); // dojo.NodeList
4836 },
4837 at: function(/*===== index =====*/){
4838 // summary:
4839 // Returns a new NodeList comprised of items in this NodeList
4840 // at the given index or indices.
4841 //
4842 // index: Integer...
4843 // One or more 0-based indices of items in the current
4844 // NodeList. A negative index will start at the end of the
4845 // list and go backwards.
4846 //
4847 // example:
4848 // Shorten the list to the first, second, and third elements
4849 // | dojo.query("a").at(0, 1, 2).forEach(fn);
4850 //
4851 // example:
4852 // Retrieve the first and last elements of a unordered list:
4853 // | dojo.query("ul > li").at(0, -1).forEach(cb);
4854 //
4855 // example:
4856 // Do something for the first element only, but end() out back to
4857 // the original list and continue chaining:
4858 // | dojo.query("a").at(0).onclick(fn).end().forEach(function(n){
4859 // | console.log(n); // all anchors on the page.
4860 // | })
4861 //
4862 // returns:
4863 // dojo.NodeList
4864 var t = new this._NodeListCtor(0);
4865 forEach(arguments, function(i){
4866 if(i < 0){ i = this.length + i; }
4867 if(this[i]){ t.push(this[i]); }
4868 }, this);
4869 return t._stash(this); // dojo.NodeList
2f01fe57 4870 }
1354d172 4871 });
2f01fe57 4872
2f01fe57 4873
1354d172
AD
4874/*=====
4875dojo.query = function(selector, context){
4876 // summary:
4877 // This modules provides DOM querying functionality. The module export is a function
4878 // that can be used to query for DOM nodes by CSS selector and returns a dojo.NodeList
4879 // representing the matching nodes.
4880 //
4881 // selector: String
4882 // A CSS selector to search for.
4883 // context: String|DomNode?
4884 // An optional context to limit the searching scope. Only nodes under `context` will be
4885 // scanned.
4886 //
4887 // example:
4888 // add an onclick handler to every submit button in the document
4889 // which causes the form to be sent via Ajax instead:
4890 // | define(["dojo/query"], function(query){
4891 // | query("input[type='submit']").on("click", function(e){
4892 // | dojo.stopEvent(e); // prevent sending the form
4893 // | var btn = e.target;
4894 // | dojo.xhrPost({
4895 // | form: btn.form,
4896 // | load: function(data){
4897 // | // replace the form with the response
4898 // | var div = dojo.doc.createElement("div");
4899 // | dojo.place(div, btn.form, "after");
4900 // | div.innerHTML = data;
4901 // | dojo.style(btn.form, "display", "none");
4902 // | }
4903 // | });
4904 // | });
4905 //
4906 // description:
4907 // dojo/query is responsible for loading the appropriate query engine and wrapping
4908 // its results with a `dojo.NodeList`. You can use dojo/query with a specific selector engine
4909 // by using it as a plugin. For example, if you installed the sizzle package, you could
4910 // use it as the selector engine with:
4911 // | define("dojo/query!sizzle", function(query){
4912 // | query("div")...
4913 //
4914 // The id after the ! can be a module id of the selector engine or one of the following values:
4915 // | + acme: This is the default engine used by Dojo base, and will ensure that the full
4916 // | Acme engine is always loaded.
4917 // |
4918 // | + css2: If the browser has a native selector engine, this will be used, otherwise a
4919 // | very minimal lightweight selector engine will be loaded that can do simple CSS2 selectors
4920 // | (by #id, .class, tag, and [name=value] attributes, with standard child or descendant (>)
4921 // | operators) and nothing more.
4922 // |
4923 // | + css2.1: If the browser has a native selector engine, this will be used, otherwise the
4924 // | full Acme engine will be loaded.
4925 // |
4926 // | + css3: If the browser has a native selector engine with support for CSS3 pseudo
4927 // | selectors (most modern browsers except IE8), this will be used, otherwise the
4928 // | full Acme engine will be loaded.
4929 // |
4930 // | + Or the module id of a selector engine can be used to explicitly choose the selector engine
4931 //
4932 // For example, if you are using CSS3 pseudo selectors in module, you can specify that
4933 // you will need support them with:
4934 // | define("dojo/query!css3", function(query){
4935 // | query('#t > h3:nth-child(odd)')...
4936 //
4937 // You can also choose the selector engine/load configuration by setting the <FIXME:what is the configuration setting?>.
4938 // For example:
4939 // | <script data-dojo-config="query-selector:'css3'" src="dojo.js"></script>
4940 //
4941 return new dojo.NodeList(); // dojo.NodeList
4942};
4943=====*/
2f01fe57 4944
1354d172
AD
4945function queryForEngine(engine, NodeList){
4946 var query = function(/*String*/ query, /*String|DOMNode?*/ root){
2f01fe57 4947 // summary:
1354d172
AD
4948 // Returns nodes which match the given CSS selector, searching the
4949 // entire document by default but optionally taking a node to scope
4950 // the search by. Returns an instance of dojo.NodeList.
4951 if(typeof root == "string"){
4952 root = dom.byId(root);
4953 if(!root){
4954 return new NodeList([]);
2f01fe57 4955 }
2f01fe57 4956 }
1354d172
AD
4957 var results = typeof query == "string" ? engine(query, root) : query.orphan ? query : [query];
4958 if(results.orphan){
4959 // already wrapped
4960 return results;
4961 }
4962 return new NodeList(results);
81bea17a 4963 };
1354d172
AD
4964 query.matches = engine.match || function(node, selector, root){
4965 // summary:
4966 // Test to see if a node matches a selector
4967 return query.filter([node], selector, root).length > 0;
4968 };
4969 // the engine provides a filtering function, use it to for matching
4970 query.filter = engine.filter || function(nodes, selector, root){
4971 // summary:
4972 // Filters an array of nodes. Note that this does not guarantee to return a dojo.NodeList, just an array.
4973 return query(selector, root).filter(function(node){
4974 return array.indexOf(nodes, node) > -1;
4975 });
4976 };
4977 if(typeof engine != "function"){
4978 var search = engine.search;
4979 engine = function(selector, root){
4980 // Slick does it backwards (or everyone else does it backwards, probably the latter)
4981 return search(root || document, selector);
4982 };
4983 }
4984 return query;
4985}
4986var query = queryForEngine(defaultEngine, NodeList);
4987// the query that is returned from this module is slightly different than dojo.query,
4988// because dojo.query has to maintain backwards compatibility with returning a
4989// true array which has performance problems. The query returned from the module
4990// does not use true arrays, but rather inherits from Array, making it much faster to
4991// instantiate.
4992dojo.query = queryForEngine(defaultEngine, function(array){
4993 // call it without the new operator to invoke the back-compat behavior that returns a true array
4994 return NodeList(array);
4995});
4996
4997query.load = /*===== dojo.query.load= ======*/ function(id, parentRequire, loaded, config){
4998 // summary: can be used as AMD plugin to conditionally load new query engine
4999 // example:
5000 // | define(["dojo/query!custom"], function(qsa){
5001 // | // loaded selector/custom.js as engine
5002 // | qsa("#foobar").forEach(...);
5003 // | });
5004 loader.load(id, parentRequire, function(engine){
5005 loaded(queryForEngine(engine, NodeList));
5006 });
5007};
2f01fe57 5008
1354d172
AD
5009dojo._filterQueryResult = query._filterResult = function(nodes, selector, root){
5010 return new NodeList(query.filter(nodes, selector, root));
5011};
5012dojo.NodeList = query.NodeList = NodeList;
5013return query;
5014});
5015
5016},
5017'dojo/has':function(){
5018define(["require"], function(require) {
5019 // module:
5020 // dojo/has
5021 // summary:
5022 // Defines the has.js API and several feature tests used by dojo.
5023 // description:
5024 // This module defines the has API as described by the project has.js with the following additional features:
5025 //
5026 // * the has test cache is exposed at has.cache.
5027 // * the method has.add includes a forth parameter that controls whether or not existing tests are replaced
5028 // * the loader's has cache may be optionally copied into this module's has cahce.
5029 //
5030 // This module adopted from https://github.com/phiggins42/has.js; thanks has.js team!
5031
5032 // try to pull the has implementation from the loader; both the dojo loader and bdLoad provide one
5033 // WARNING: if a foreign loader defines require.has to be something other than the has.js API, then this implementation fail
5034 var has = require.has || function(){};
5035 if(!1){
5036 // notice the condition is written so that if 1 is transformed to 1 during a build
5037 // the conditional will be (!1 && typeof has=="function") which is statically false and the closure
5038 // compiler will discard the block.
81bea17a 5039 var
1354d172
AD
5040 isBrowser =
5041 // the most fundamental decision: are we in the browser?
5042 typeof window != "undefined" &&
5043 typeof location != "undefined" &&
5044 typeof document != "undefined" &&
5045 window.location == location && window.document == document,
5046
5047 // has API variables
5048 global = this,
5049 doc = isBrowser && document,
5050 element = doc && doc.createElement("DiV"),
5051 cache = {};
5052
5053 has = /*===== dojo.has= =====*/ function(name){
5054 // summary:
5055 // Return the current value of the named feature.
5056 //
5057 // name: String|Integer
5058 // The name (if a string) or identifier (if an integer) of the feature to test.
5059 //
5060 // description:
5061 // Returns the value of the feature named by name. The feature must have been
5062 // previously added to the cache by has.add.
5063
5064 return typeof cache[name] == "function" ? (cache[name] = cache[name](global, doc, element)) : cache[name]; // Boolean
2f01fe57 5065 };
2f01fe57 5066
1354d172
AD
5067 has.cache = cache;
5068
5069 has.add = /*====== dojo.has.add= ======*/ function(name, test, now, force){
5070 // summary:
5071 // Register a new feature test for some named feature.
5072 //
5073 // name: String|Integer
5074 // The name (if a string) or identifier (if an integer) of the feature to test.
5075 //
5076 // test: Function
5077 // A test function to register. If a function, queued for testing until actually
5078 // needed. The test function should return a boolean indicating
5079 // the presence of a feature or bug.
5080 //
5081 // now: Boolean?
5082 // Optional. Omit if `test` is not a function. Provides a way to immediately
5083 // run the test and cache the result.
5084 //
5085 // force: Boolean?
5086 // Optional. If the test already exists and force is truthy, then the existing
5087 // test will be replaced; otherwise, add does not replace an existing test (that
5088 // is, by default, the first test advice wins).
5089 //
5090 // example:
5091 // A redundant test, testFn with immediate execution:
5092 // | has.add("javascript", function(){ return true; }, true);
5093 //
5094 // example:
5095 // Again with the redundantness. You can do this in your tests, but we should
5096 // not be doing this in any internal has.js tests
5097 // | has.add("javascript", true);
5098 //
5099 // example:
5100 // Three things are passed to the testFunction. `global`, `document`, and a generic element
5101 // from which to work your test should the need arise.
5102 // | has.add("bug-byid", function(g, d, el){
5103 // | // g == global, typically window, yadda yadda
5104 // | // d == document object
5105 // | // el == the generic element. a `has` element.
5106 // | return false; // fake test, byid-when-form-has-name-matching-an-id is slightly longer
5107 // | });
5108
5109 (typeof cache[name]=="undefined" || force) && (cache[name]= test);
5110 return now && has(name);
2f01fe57 5111 };
1354d172
AD
5112
5113 // since we're operating under a loader that doesn't provide a has API, we must explicitly initialize
5114 // has as it would have otherwise been initialized by the dojo loader; use has.add to the builder
5115 // can optimize these away iff desired
5116 true || has.add("host-browser", isBrowser);
5117 true || has.add("dom", isBrowser);
5118 true || has.add("dojo-dom-ready-api", 1);
5119 true || has.add("dojo-sniff", 1);
5120 }
5121
5122 if(1){
5123 var agent = navigator.userAgent;
5124 // Common application level tests
5125 has.add("dom-addeventlistener", !!document.addEventListener);
5126 has.add("touch", "ontouchstart" in document);
5127 // I don't know if any of these tests are really correct, just a rough guess
5128 has.add("device-width", screen.availWidth || innerWidth);
5129 has.add("agent-ios", !!agent.match(/iPhone|iP[ao]d/));
5130 has.add("agent-android", agent.indexOf("android") > 1);
5131 }
5132
5133 has.clearElement = /*===== dojo.has.clearElement= ======*/ function(element) {
5134 // summary:
5135 // Deletes the contents of the element passed to test functions.
5136 element.innerHTML= "";
5137 return element;
81bea17a 5138 };
2f01fe57 5139
1354d172
AD
5140 has.normalize = /*===== dojo.has.normalize= ======*/ function(id, toAbsMid){
5141 // summary:
5142 // Resolves id into a module id based on possibly-nested tenary expression that branches on has feature test value(s).
2f01fe57 5143 //
1354d172
AD
5144 // toAbsMid: Function
5145 // Resolves a relative module id into an absolute module id
81bea17a 5146 var
1354d172
AD
5147 tokens = id.match(/[\?:]|[^:\?]*/g), i = 0,
5148 get = function(skip){
5149 var term = tokens[i++];
5150 if(term == ":"){
5151 // empty string module name, resolves to 0
5152 return 0;
5153 }else{
5154 // postfixed with a ? means it is a feature to branch on, the term is the name of the feature
5155 if(tokens[i++] == "?"){
5156 if(!skip && has(term)){
5157 // matched the feature, get the first value from the options
5158 return get();
5159 }else{
5160 // did not match, get the second value, passing over the first
5161 get(true);
5162 return get(skip);
5163 }
5164 }
5165 // a module
5166 return term || 0;
5167 }
5168 };
5169 id = get();
5170 return id && toAbsMid(id);
81bea17a 5171 };
2f01fe57 5172
1354d172
AD
5173 has.load = /*===== dojo.has.load= ======*/ function(id, parentRequire, loaded){
5174 // summary:
5175 // Conditional loading of AMD modules based on a has feature test value.
2f01fe57 5176 //
1354d172
AD
5177 // id: String
5178 // Gives the resolved module id to load.
2f01fe57 5179 //
1354d172
AD
5180 // parentRequire: Function
5181 // The loader require function with respect to the module that contained the plugin resource in it's
5182 // dependency list.
5183 //
5184 // loaded: Function
5185 // Callback to loader that consumes result of plugin demand.
5186
5187 if(id){
5188 parentRequire([id], loaded);
5189 }else{
5190 loaded();
2f01fe57 5191 }
81bea17a 5192 };
2f01fe57 5193
1354d172
AD
5194 return has;
5195});
2f01fe57 5196
1354d172
AD
5197},
5198'dojo/_base/loader':function(){
5199define(["./kernel", "../has", "require", "module", "./json", "./lang", "./array"], function(dojo, has, require, thisModule, json, lang, array) {
5200 // module:
5201 // dojo/_base/lader
5202 // summary:
5203 // This module defines the v1.x synchronous loader API.
2f01fe57 5204
1354d172
AD
5205 // signal the loader in sync mode...
5206 //>>pure-amd
81bea17a 5207
1354d172
AD
5208 if (!1){
5209 console.error("cannot load the Dojo v1.x loader with a foreign loader");
5210 return 0;
81bea17a 5211 }
2f01fe57 5212
1354d172
AD
5213 var makeErrorToken = function(id){
5214 return {src:thisModule.id, id:id};
5215 },
2f01fe57 5216
1354d172
AD
5217 slashName = function(name){
5218 return name.replace(/\./g, "/");
5219 },
2f01fe57 5220
1354d172 5221 buildDetectRe = /\/\/>>built/,
2f01fe57 5222
1354d172
AD
5223 dojoRequireCallbacks = [],
5224 dojoRequireModuleStack = [],
2f01fe57 5225
1354d172
AD
5226 dojoRequirePlugin = function(mid, require, loaded){
5227 dojoRequireCallbacks.push(loaded);
5228 array.forEach(mid.split(","), function(mid){
5229 var module = getModule(mid, require.module);
5230 dojoRequireModuleStack.push(module);
5231 injectModule(module);
5232 });
5233 checkDojoRequirePlugin();
5234 },
2f01fe57 5235
1354d172
AD
5236 // checkDojoRequirePlugin inspects all of the modules demanded by a dojo/require!<module-list> dependency
5237 // to see if they have arrived. The loader does not release *any* of these modules to be instantiated
5238 // until *all* of these modules are on board, thereby preventing the evaluation of a module with dojo.require's
5239 // that reference modules that are not available.
5240 //
5241 // The algorithm works by traversing the dependency graphs (remember, there can be cycles so they are not trees)
5242 // of each module in the dojoRequireModuleStack array (which contains the list of modules demanded by dojo/require!).
5243 // The moment a single module is discovered that is missing, the algorithm gives up and indicates that not all
5244 // modules are on board. dojo/loadInit! and dojo/require! are ignored because there dependencies are inserted
5245 // directly in dojoRequireModuleStack. For example, if "your/module" module depends on "dojo/require!my/module", then
5246 // *both* "dojo/require!my/module" and "my/module" will be in dojoRequireModuleStack. Obviously, if "my/module"
5247 // is on board, then "dojo/require!my/module" is also satisfied, so the algorithm doesn't check for "dojo/require!my/module".
5248 //
5249 // Note: inserting a dojo/require!<some-module-list> dependency in the dojoRequireModuleStack achieves nothing
5250 // with the current algorithm; however, having such modules present makes it possible to optimize the algorithm
5251 //
5252 // Note: prior versions of this algorithm had an optimization that signaled loaded on dojo/require! dependencies
5253 // individually (rather than waiting for them all to be resolved). The implementation proved problematic with cycles
5254 // and plugins. However, it is possible to reattach that strategy in the future.
5255
5256 // a set from module-id to {undefined | 1 | 0}, where...
5257 // undefined => the module has not been inspected
5258 // 0 => the module or at least one of its dependencies has not arrived
5259 // 1 => the module is a loadInit! or require! plugin resource, or is currently being traversed (therefore, assume
5260 // OK until proven otherwise), or has been completely traversed and all dependencies have arrived
5261 touched,
5262
5263 traverse = function(m){
5264 touched[m.mid] = 1;
5265 for(var t, module, deps = m.deps || [], i= 0; i<deps.length; i++){
5266 module = deps[i];
5267 if(!(t = touched[module.mid])){
5268 if(t===0 || !traverse(module)){
5269 touched[m.mid] = 0;
5270 return false;
5271 }
5272 }
5273 }
5274 return true;
5275 },
2f01fe57 5276
1354d172
AD
5277 checkDojoRequirePlugin = function(){
5278 // initialize the touched hash with easy-to-compute values that help short circuit recursive algorithm;
5279 // recall loadInit/require plugin modules are dependencies of modules in dojoRequireModuleStack...
5280 // which would cause a circular dependency chain that would never be resolved if checked here
5281 // notice all dependencies of any particular loadInit/require plugin module will already
5282 // be checked since those are pushed into dojoRequireModuleStack explicitly by the
5283 // plugin...so if a particular loadInitPlugin module's dependencies are not really
5284 // on board, that *will* be detected elsewhere in the traversal.
5285 var module, mid;
5286 touched = {};
5287 for(mid in modules){
5288 module = modules[mid];
5289 // this could be improved by remembering the result of the regex tests
5290 if(module.executed || module.noReqPluginCheck){
5291 touched[mid] = 1;
5292 }else{
5293 if(module.noReqPluginCheck!==0){
5294 // tag the module as either a loadInit or require plugin or not for future reference
5295 module.noReqPluginCheck = /loadInit\!/.test(mid) || /require\!/.test(mid) ? 1 : 0;
5296 }
5297 if(module.noReqPluginCheck){
5298 touched[mid] = 1;
5299 }else if(module.injected!==arrived){
5300 // not executed, has not arrived, and is not a loadInit or require plugin resource
5301 touched[mid] = 0;
5302 }// else, leave undefined and we'll traverse the dependencies
5303 }
5304 }
2f01fe57 5305
1354d172
AD
5306 for(var t, i = 0, end = dojoRequireModuleStack.length; i<end; i++){
5307 module = dojoRequireModuleStack[i];
5308 if(!(t = touched[module.mid])){
5309 if(t===0 || !traverse(module)){
5310 return;
5311 }
5312 }
5313 }
5314 loaderVars.holdIdle();
5315 var oldCallbacks = dojoRequireCallbacks;
5316 dojoRequireCallbacks = [];
5317 array.forEach(oldCallbacks, function(cb){cb(1);});
5318 loaderVars.releaseIdle();
5319 },
2f01fe57 5320
1354d172
AD
5321 dojoLoadInitPlugin = function(mid, require, loaded){
5322 // mid names a module that defines a "dojo load init" bundle, an object with two properties:
5323 //
5324 // * names: a vector of module ids that give top-level names to define in the lexical scope of def
5325 // * def: a function that contains some some legacy loader API applications
5326 //
5327 // The point of def is to possibly cause some modules to be loaded (but not executed) by dojo/require! where the module
5328 // ids are possibly-determined at runtime. For example, here is dojox.gfx from v1.6 expressed as an AMD module using the dojo/loadInit
5329 // and dojo/require plugins.
5330 //
5331 // // dojox/gfx:
5332 //
5333 // define("*loadInit_12, {
5334 // names:["dojo", "dijit", "dojox"],
5335 // def: function(){
5336 // dojo.loadInit(function(){
5337 // var gfx = lang.getObject("dojox.gfx", true);
5338 //
5339 // //
5340 // // code required to set gfx properties ommitted...
5341 // //
5342 //
5343 // // now use the calculations to include the runtime-dependent module
5344 // dojo.require("dojox.gfx." + gfx.renderer);
5345 // });
5346 // }
5347 // });
5348 //
5349 // define(["dojo", "dojo/loadInit!" + id].concat("dojo/require!dojox/gfx/matric,dojox/gfx/_base"), function(dojo){
5350 // // when this AMD factory function is executed, the following modules are guaranteed downloaded but not executed:
5351 // // "dojox.gfx." + gfx.renderer
5352 // // dojox.gfx.matrix
5353 // // dojox.gfx._base
5354 // dojo.provide("dojo.gfx");
5355 // dojo.require("dojox.gfx.matrix");
5356 // dojo.require("dojox.gfx._base");
5357 // dojo.require("dojox.gfx." + gfx.renderer);
5358 // return lang.getObject("dojo.gfx");
5359 // });
5360 // })();
5361 //
5362 // The idea is to run the legacy loader API with global variables shadowed, which allows these variables to
5363 // be relocated. For example, dojox and dojo could be relocated to different names by giving a packageMap and the code above will
5364 // execute properly (because the plugin below resolves the load init bundle.names module with respect to the module that demanded
5365 // the plugin resource).
5366 //
5367 // Note that the relocation is specified in the runtime configuration; relocated names need not be set at build-time.
5368 //
5369 // Warning: this is not the best way to express dojox.gfx as and AMD module. In fact, the module has been properly converted in
5370 // v1.7. However, this technique allows the builder to convert legacy modules into AMD modules and guarantee the codepath is the
5371 // same in the converted AMD module.
5372 require([mid], function(bundle){
5373 // notice how names is resolved with respect to the module that demanded the plugin resource
5374 require(bundle.names, function(){
5375 // bring the bundle names into scope
5376 for(var scopeText = "", args= [], i = 0; i<arguments.length; i++){
5377 scopeText+= "var " + bundle.names[i] + "= arguments[" + i + "]; ";
5378 args.push(arguments[i]);
5379 }
5380 eval(scopeText);
5381
5382 var callingModule = require.module,
5383 deps = [],
5384 hold = {},
5385 requireList = [],
5386 p,
5387 syncLoaderApi = {
5388 provide:function(moduleName){
5389 // mark modules that arrive consequent to multiple provides in this module as arrived since they can't be injected
5390 moduleName = slashName(moduleName);
5391 var providedModule = getModule(moduleName, callingModule);
5392 if(providedModule!==callingModule){
5393 setArrived(providedModule);
5394 }
5395 },
5396 require:function(moduleName, omitModuleCheck){
5397 moduleName = slashName(moduleName);
5398 omitModuleCheck && (getModule(moduleName, callingModule).result = nonmodule);
5399 requireList.push(moduleName);
5400 },
5401 requireLocalization:function(moduleName, bundleName, locale){
5402 // since we're going to need dojo/i8n, add it to deps if not already there
5403 deps.length || (deps = ["dojo/i18n"]);
5404
5405 // figure out if the bundle is xdomain; if so, add it to the depsSet
5406 locale = (locale || dojo.locale).toLowerCase();
5407 moduleName = slashName(moduleName) + "/nls/" + (/root/i.test(locale) ? "" : locale + "/") + slashName(bundleName);
5408 if(getModule(moduleName, callingModule).isXd){
5409 deps.push("dojo/i18n!" + moduleName);
5410 }// else the bundle will be loaded synchronously when the module is evaluated
5411 },
5412 loadInit:function(f){
5413 f();
5414 }
5415 };
2f01fe57 5416
1354d172
AD
5417 // hijack the correct dojo and apply bundle.def
5418 try{
5419 for(p in syncLoaderApi){
5420 hold[p] = dojo[p];
5421 dojo[p] = syncLoaderApi[p];
5422 }
5423 bundle.def.apply(null, args);
5424 }catch(e){
5425 signal("error", [makeErrorToken("failedDojoLoadInit"), e]);
5426 }finally{
5427 for(p in syncLoaderApi){
5428 dojo[p] = hold[p];
5429 }
5430 }
2f01fe57 5431
1354d172
AD
5432 // requireList is the list of modules that need to be downloaded but not executed before the callingModule can be executed
5433 requireList.length && deps.push("dojo/require!" + requireList.join(","));
2f01fe57 5434
1354d172
AD
5435 dojoRequireCallbacks.push(loaded);
5436 array.forEach(requireList, function(mid){
5437 var module = getModule(mid, require.module);
5438 dojoRequireModuleStack.push(module);
5439 injectModule(module);
5440 });
5441 checkDojoRequirePlugin();
5442 });
5443 });
5444 },
2f01fe57 5445
1354d172
AD
5446 extractApplication = function(
5447 text, // the text to search
5448 startSearch, // the position in text to start looking for the closing paren
5449 startApplication // the position in text where the function application expression starts
5450 ){
5451 // find end of the call by finding the matching end paren
5452 // Warning: as usual, this will fail in the presense of unmatched right parans contained in strings, regexs, or unremoved comments
5453 var parenRe = /\(|\)/g,
5454 matchCount = 1,
5455 match;
5456 parenRe.lastIndex = startSearch;
5457 while((match = parenRe.exec(text))){
5458 if(match[0] == ")"){
5459 matchCount -= 1;
5460 }else{
5461 matchCount += 1;
5462 }
5463 if(matchCount == 0){
5464 break;
5465 }
2f01fe57 5466 }
2f01fe57 5467
1354d172
AD
5468 if(matchCount != 0){
5469 throw "unmatched paren around character " + parenRe.lastIndex + " in: " + text;
5470 }
2f01fe57 5471
1354d172
AD
5472 //Put the master matching string in the results.
5473 return [dojo.trim(text.substring(startApplication, parenRe.lastIndex))+";\n", parenRe.lastIndex];
5474 },
2f01fe57 5475
1354d172
AD
5476 // the following regex is taken from 1.6. It is a very poor technique to remove comments and
5477 // will fail in some cases; for example, consider the code...
2f01fe57 5478 //
1354d172
AD
5479 // var message = "Category-1 */* Category-2";
5480 //
5481 // The regex that follows will see a /* comment and trash the code accordingly. In fact, there are all
5482 // kinds of cases like this with strings and regexs that will cause this design to fail miserably.
5483 //
5484 // Alternative regex designs exist that will result in less-likely failures, but will still fail in many cases.
5485 // The only solution guaranteed 100% correct is to parse the code and that seems overkill for this
5486 // backcompat/unbuilt-xdomain layer. In the end, since it's been this way for a while, we won't change it.
5487 // See the opening paragraphs of Chapter 7 or ECME-262 which describes the lexical abiguity further.
5488 removeCommentRe = /(\/\*([\s\S]*?)\*\/|\/\/(.*)$)/mg,
2f01fe57 5489
1354d172 5490 syncLoaderApiRe = /(^|\s)dojo\.(loadInit|require|provide|requireLocalization|requireIf|requireAfterIf|platformRequire)\s*\(/mg,
2f01fe57 5491
1354d172
AD
5492 amdLoaderApiRe = /(^|\s)(require|define)\s*\(/m,
5493
5494 extractLegacyApiApplications = function(text, noCommentText){
5495 // scan the noCommentText for any legacy loader API applications. Copy such applications into result (this is
5496 // used by the builder). Move dojo.loadInit applications to loadInitApplications string. Copy all other applications
5497 // to otherApplications string. If no applications were found, return 0, signalling an AMD module. Otherwise, return
5498 // loadInitApplications + otherApplications. Fixup text by replacing
5499 //
5500 // dojo.loadInit(// etc...
5501 //
5502 // with
5503 //
5504 // \n 0 && dojo.loadInit(// etc...
5505 //
5506 // Which results in the dojo.loadInit from *not* being applied. This design goes a long way towards protecting the
5507 // code from an over-agressive removeCommentRe. However...
5508 //
5509 // WARNING: the removeCommentRe will cause an error if a detected comment removes all or part of a legacy-loader application
5510 // that is not in a comment.
5511
5512 var match, startSearch, startApplication, application,
5513 loadInitApplications = [],
5514 otherApplications = [],
5515 allApplications = [];
5516
5517 // noCommentText may be provided by a build app with comments extracted by a better method than regex (hopefully)
5518 noCommentText = noCommentText || text.replace(removeCommentRe, function(match){
5519 // remove iff the detected comment has text that looks like a sync loader API application; this helps by
5520 // removing as little as possible, minimizing the changes the janky regex will kill the module
5521 syncLoaderApiRe.lastIndex = amdLoaderApiRe.lastIndex = 0;
5522 return (syncLoaderApiRe.test(match) || amdLoaderApiRe.test(match)) ? "" : match;
5523 });
2f01fe57 5524
1354d172
AD
5525 // find and extract all dojo.loadInit applications
5526 while((match = syncLoaderApiRe.exec(noCommentText))){
5527 startSearch = syncLoaderApiRe.lastIndex;
5528 startApplication = startSearch - match[0].length;
5529 application = extractApplication(noCommentText, startSearch, startApplication);
5530 if(match[2]=="loadInit"){
5531 loadInitApplications.push(application[0]);
5532 }else{
5533 otherApplications.push(application[0]);
5534 }
5535 syncLoaderApiRe.lastIndex = application[1];
5536 }
5537 allApplications = loadInitApplications.concat(otherApplications);
5538 if(allApplications.length || !amdLoaderApiRe.test(noCommentText)){
5539 // either there were some legacy loader API applications or there were no AMD API applications
5540 return [text.replace(/(^|\s)dojo\.loadInit\s*\(/g, "\n0 && dojo.loadInit("), allApplications.join(""), allApplications];
5541 }else{
5542 // legacy loader API *was not* detected and AMD API *was* detected; therefore, assume it's an AMD module
2f01fe57
AD
5543 return 0;
5544 }
1354d172
AD
5545 },
5546
5547 transformToAmd = function(module, text){
5548 // This is roughly the equivalent of dojo._xdCreateResource in 1.6-; however, it expresses a v1.6- dojo
5549 // module in terms of AMD define instead of creating the dojo proprietary xdomain module expression.
5550 // The module could have originated from several sources:
5551 //
5552 // * amd require() a module, e.g., require(["my/module"])
5553 // * amd require() a nonmodule, e.g., require(["my/resource.js"')
5554 // * amd define() deps vector (always a module)
5555 // * dojo.require() a module, e.g. dojo.require("my.module")
5556 // * dojo.require() a nonmodule, e.g., dojo.require("my.module", true)
5557 // * dojo.requireIf/requireAfterIf/platformRequire a module
5558 //
5559 // The module is scanned for legacy loader API applications; if none are found, then assume the module is an
5560 // AMD module and return 0. Otherwise, a synthetic dojo/loadInit plugin resource is created and the module text
5561 // is rewritten as an AMD module with the single dependency of this synthetic resource. When the dojo/loadInit
5562 // plugin loaded the synthetic resource, it will cause all dojo.loadInit's to be executed, find all dojo.require's
5563 // (either directly consequent to dojo.require or indirectly consequent to dojo.require[After]If or
5564 // dojo.platformRequire, and finally cause loading of all dojo.required modules with the dojo/require plugin. Thus,
5565 // when the dojo/loadInit plugin reports it has been loaded, all modules required by the given module are guaranteed
5566 // loaded (but not executed). This then allows the module to execute it's code path without interupts, thereby
5567 // following the synchronous code path.
5568
5569 var extractResult, id, names = [], namesAsStrings = [];
5570 if(buildDetectRe.test(text) || !(extractResult = extractLegacyApiApplications(text))){
5571 // buildDetectRe.test(text) => a built module, always AMD
5572 // extractResult==0 => no sync API
5573 return 0;
2f01fe57 5574 }
2f01fe57 5575
1354d172
AD
5576 // manufacture a synthetic module id that can never be a real mdule id (just like require does)
5577 id = module.mid + "-*loadInit";
2f01fe57 5578
1354d172
AD
5579 // construct the dojo/loadInit names vector which causes any relocated names to be defined as lexical variables under their not-relocated name
5580 // the dojo/loadInit plugin assumes the first name in names is "dojo"
2f01fe57 5581
1354d172
AD
5582 for(var p in getModule("dojo", module).result.scopeMap){
5583 names.push(p);
5584 namesAsStrings.push('"' + p + '"');
5585 }
2f01fe57 5586
1354d172
AD
5587 // rewrite the module as a synthetic dojo/loadInit plugin resource + the module expressed as an AMD module that depends on this synthetic resource
5588 return "// xdomain rewrite of " + module.path + "\n" +
5589 "define('" + id + "',{\n" +
5590 "\tnames:" + dojo.toJson(names) + ",\n" +
5591 "\tdef:function(" + names.join(",") + "){" + extractResult[1] + "}" +
5592 "});\n\n" +
5593 "define(" + dojo.toJson(names.concat(["dojo/loadInit!"+id])) + ", function(" + names.join(",") + "){\n" + extractResult[0] + "});";
5594 },
2f01fe57 5595
1354d172 5596 loaderVars = require.initSyncLoader(dojoRequirePlugin, checkDojoRequirePlugin, transformToAmd),
2f01fe57 5597
1354d172
AD
5598 sync =
5599 loaderVars.sync,
2f01fe57 5600
1354d172
AD
5601 xd =
5602 loaderVars.xd,
2f01fe57 5603
1354d172
AD
5604 arrived =
5605 loaderVars.arrived,
2f01fe57 5606
1354d172
AD
5607 nonmodule =
5608 loaderVars.nonmodule,
2f01fe57 5609
1354d172
AD
5610 executing =
5611 loaderVars.executing,
5612
5613 executed =
5614 loaderVars.executed,
5615
5616 syncExecStack =
5617 loaderVars.syncExecStack,
5618
5619 modules =
5620 loaderVars.modules,
5621
5622 execQ =
5623 loaderVars.execQ,
5624
5625 getModule =
5626 loaderVars.getModule,
5627
5628 injectModule =
5629 loaderVars.injectModule,
5630
5631 setArrived =
5632 loaderVars.setArrived,
5633
5634 signal =
5635 loaderVars.signal,
5636
5637 finishExec =
5638 loaderVars.finishExec,
5639
5640 execModule =
5641 loaderVars.execModule,
5642
5643 getLegacyMode =
5644 loaderVars.getLegacyMode;
5645
5646 dojo.provide = function(mid){
5647 var executingModule = syncExecStack[0],
5648 module = lang.mixin(getModule(slashName(mid), require.module), {
5649 executed:executing,
5650 result:lang.getObject(mid, true)
5651 });
5652 setArrived(module);
5653 if(executingModule){
5654 (executingModule.provides || (executingModule.provides = [])).push(function(){
5655 module.result = lang.getObject(mid);
5656 delete module.provides;
5657 module.executed!==executed && finishExec(module);
5658 });
5659 }// else dojo.provide called not consequent to loading; therefore, give up trying to publish module value to loader namespace
5660 return module.result;
5661 };
5662
5663 has.add("config-publishRequireResult", 1, 0, 0);
5664
5665 dojo.require = function(moduleName, omitModuleCheck) {
5666 // summary:
5667 // loads a Javascript module from the appropriate URI
5668 //
5669 // moduleName: String
5670 // module name to load, using periods for separators,
5671 // e.g. "dojo.date.locale". Module paths are de-referenced by dojo's
5672 // internal mapping of locations to names and are disambiguated by
5673 // longest prefix. See `dojo.registerModulePath()` for details on
5674 // registering new modules.
5675 //
5676 // omitModuleCheck: Boolean?
5677 // if `true`, omitModuleCheck skips the step of ensuring that the
5678 // loaded file actually defines the symbol it is referenced by.
5679 // For example if it called as `dojo.require("a.b.c")` and the
5680 // file located at `a/b/c.js` does not define an object `a.b.c`,
5681 // and exception will be throws whereas no exception is raised
5682 // when called as `dojo.require("a.b.c", true)`
5683 //
5684 // description:
5685 // Modules are loaded via dojo.require by using one of two loaders: the normal loader
5686 // and the xdomain loader. The xdomain loader is used when dojo was built with a
5687 // custom build that specified loader=xdomain and the module lives on a modulePath
5688 // that is a whole URL, with protocol and a domain. The versions of Dojo that are on
5689 // the Google and AOL CDNs use the xdomain loader.
5690 //
5691 // If the module is loaded via the xdomain loader, it is an asynchronous load, since
5692 // the module is added via a dynamically created script tag. This
5693 // means that dojo.require() can return before the module has loaded. However, this
5694 // should only happen in the case where you do dojo.require calls in the top-level
5695 // HTML page, or if you purposely avoid the loader checking for dojo.require
5696 // dependencies in your module by using a syntax like dojo["require"] to load the module.
5697 //
5698 // Sometimes it is useful to not have the loader detect the dojo.require calls in the
5699 // module so that you can dynamically load the modules as a result of an action on the
5700 // page, instead of right at module load time.
5701 //
5702 // Also, for script blocks in an HTML page, the loader does not pre-process them, so
5703 // it does not know to download the modules before the dojo.require calls occur.
5704 //
5705 // So, in those two cases, when you want on-the-fly module loading or for script blocks
5706 // in the HTML page, special care must be taken if the dojo.required code is loaded
5707 // asynchronously. To make sure you can execute code that depends on the dojo.required
5708 // modules, be sure to add the code that depends on the modules in a dojo.addOnLoad()
5709 // callback. dojo.addOnLoad waits for all outstanding modules to finish loading before
5710 // executing.
5711 //
5712 // This type of syntax works with both xdomain and normal loaders, so it is good
5713 // practice to always use this idiom for on-the-fly code loading and in HTML script
5714 // blocks. If at some point you change loaders and where the code is loaded from,
5715 // it will all still work.
5716 //
5717 // More on how dojo.require
5718 // `dojo.require("A.B")` first checks to see if symbol A.B is
5719 // defined. If it is, it is simply returned (nothing to do).
5720 //
5721 // If it is not defined, it will look for `A/B.js` in the script root
5722 // directory.
5723 //
5724 // `dojo.require` throws an exception if it cannot find a file
5725 // to load, or if the symbol `A.B` is not defined after loading.
5726 //
5727 // It returns the object `A.B`, but note the caveats above about on-the-fly loading and
5728 // HTML script blocks when the xdomain loader is loading a module.
5729 //
5730 // `dojo.require()` does nothing about importing symbols into
5731 // the current namespace. It is presumed that the caller will
5732 // take care of that.
5733 //
5734 // example:
5735 // To use dojo.require in conjunction with dojo.ready:
5736 //
5737 // | dojo.require("foo");
5738 // | dojo.require("bar");
5739 // | dojo.addOnLoad(function(){
5740 // | //you can now safely do something with foo and bar
5741 // | });
5742 //
5743 // example:
5744 // For example, to import all symbols into a local block, you might write:
5745 //
5746 // | with (dojo.require("A.B")) {
5747 // | ...
5748 // | }
5749 //
5750 // And to import just the leaf symbol to a local variable:
5751 //
5752 // | var B = dojo.require("A.B");
5753 // | ...
5754 //
5755 // returns:
5756 // the required namespace object
5757 function doRequire(mid, omitModuleCheck){
5758 var module = getModule(slashName(mid), require.module);
5759 if(syncExecStack.length && syncExecStack[0].finish){
5760 // switched to async loading in the middle of evaluating a legacy module; stop
5761 // applying dojo.require so the remaining dojo.requires are applied in order
5762 syncExecStack[0].finish.push(mid);
5763 return undefined;
5764 }
5765
5766 // recall module.executed has values {0, executing, executed}; therefore, truthy indicates executing or executed
5767 if(module.executed){
5768 return module.result;
5769 }
5770 omitModuleCheck && (module.result = nonmodule);
5771
5772 var currentMode = getLegacyMode();
5773
5774 // recall, in sync mode to inject is to *eval* the module text
5775 // if the module is a legacy module, this is the same as executing
5776 // but if the module is an AMD module, this means defining, not executing
5777 injectModule(module);
5778 // the inject may have changed the mode
5779 currentMode = getLegacyMode();
5780
5781 // in sync mode to dojo.require is to execute
5782 if(module.executed!==executed && module.injected===arrived){
5783 // the module was already here before injectModule was called probably finishing up a xdomain
5784 // load, but maybe a module given to the loader directly rather than having the loader retrieve it
5785 loaderVars.holdIdle();
5786 execModule(module);
5787 loaderVars.releaseIdle();
5788 }
5789 if(module.executed){
5790 return module.result;
5791 }
5792
5793 if(currentMode==sync){
5794 // the only way to get here is in sync mode and dojo.required a module that
5795 // * was loaded async in the injectModule application a few lines up
5796 // * was an AMD module that had deps that are being loaded async and therefore couldn't execute
5797 if(module.cjs){
5798 // the module was an AMD module; unshift, not push, which causes the current traversal to be reattempted from the top
5799 execQ.unshift(module);
5800 }else{
5801 // the module was a legacy module
5802 syncExecStack.length && (syncExecStack[0].finish= [mid]);
5803 }
5804 }else{
5805 // the loader wasn't in sync mode on entry; probably async mode; therefore, no expectation of getting
5806 // the module value synchronously; make sure it gets executed though
5807 execQ.push(module);
2f01fe57 5808 }
1354d172 5809 return undefined;
2f01fe57
AD
5810 }
5811
1354d172
AD
5812 var result = doRequire(moduleName, omitModuleCheck);
5813 if(has("config-publishRequireResult") && !lang.exists(moduleName) && result!==undefined){
5814 lang.setObject(moduleName, result);
5815 }
5816 return result;
81bea17a 5817 };
2f01fe57 5818
1354d172
AD
5819 dojo.loadInit = function(f) {
5820 f();
5821 };
5822
5823 dojo.registerModulePath = function(/*String*/moduleName, /*String*/prefix){
2f01fe57 5824 // summary:
1354d172 5825 // Maps a module name to a path
2f01fe57 5826 // description:
1354d172
AD
5827 // An unregistered module is given the default path of ../[module],
5828 // relative to Dojo root. For example, module acme is mapped to
5829 // ../acme. If you want to use a different module name, use
5830 // dojo.registerModulePath.
5831 // example:
5832 // If your dojo.js is located at this location in the web root:
5833 // | /myapp/js/dojo/dojo/dojo.js
5834 // and your modules are located at:
5835 // | /myapp/js/foo/bar.js
5836 // | /myapp/js/foo/baz.js
5837 // | /myapp/js/foo/thud/xyzzy.js
5838 // Your application can tell Dojo to locate the "foo" namespace by calling:
5839 // | dojo.registerModulePath("foo", "../../foo");
5840 // At which point you can then use dojo.require() to load the
5841 // modules (assuming they provide() the same things which are
5842 // required). The full code might be:
5843 // | <script type="text/javascript"
5844 // | src="/myapp/js/dojo/dojo/dojo.js"></script>
5845 // | <script type="text/javascript">
5846 // | dojo.registerModulePath("foo", "../../foo");
5847 // | dojo.require("foo.bar");
5848 // | dojo.require("foo.baz");
5849 // | dojo.require("foo.thud.xyzzy");
5850 // | </script>
5851
5852 var paths = {};
5853 paths[moduleName.replace(/\./g, "/")] = prefix;
5854 require({paths:paths});
81bea17a 5855 };
2f01fe57 5856
1354d172
AD
5857 dojo.platformRequire = function(/*Object*/modMap){
5858 // summary:
5859 // require one or more modules based on which host environment
5860 // Dojo is currently operating in
5861 // description:
5862 // This method takes a "map" of arrays which one can use to
5863 // optionally load dojo modules. The map is indexed by the
5864 // possible dojo.name_ values, with two additional values:
5865 // "default" and "common". The items in the "default" array will
5866 // be loaded if none of the other items have been choosen based on
5867 // dojo.name_, set by your host environment. The items in the
5868 // "common" array will *always* be loaded, regardless of which
5869 // list is chosen.
5870 // example:
5871 // | dojo.platformRequire({
5872 // | browser: [
5873 // | "foo.sample", // simple module
5874 // | "foo.test",
5875 // | ["foo.bar.baz", true] // skip object check in _loadModule (dojo.require)
5876 // | ],
5877 // | default: [ "foo.sample._base" ],
5878 // | common: [ "important.module.common" ]
5879 // | });
2f01fe57 5880
1354d172
AD
5881 var result = (modMap.common || []).concat(modMap[dojo._name] || modMap["default"] || []),
5882 temp;
5883 while(result.length){
5884 if(lang.isArray(temp = result.shift())){
5885 dojo.require.apply(dojo, temp);
5886 }else{
5887 dojo.require(temp);
5888 }
5889 }
5890 };
2f01fe57 5891
1354d172
AD
5892 dojo.requireIf = dojo.requireAfterIf = function(/*Boolean*/ condition, /*String*/ moduleName, /*Boolean?*/omitModuleCheck){
5893 // summary:
5894 // If the condition is true then call `dojo.require()` for the specified
5895 // resource
5896 //
5897 // example:
5898 // | dojo.requireIf(dojo.isBrowser, "my.special.Module");
2f01fe57 5899
1354d172
AD
5900 if(condition){
5901 dojo.require(moduleName, omitModuleCheck);
5902 }
2f01fe57
AD
5903 };
5904
1354d172
AD
5905 dojo.requireLocalization = function(/*String*/moduleName, /*String*/bundleName, /*String?*/locale){
5906 require(["../i18n"], function(i18n){
5907 i18n.getLocalization(moduleName, bundleName, locale);
5908 });
5909 };
5910
5911 return {
5912 extractLegacyApiApplications:extractLegacyApiApplications,
5913 require:loaderVars.dojoRequirePlugin,
5914 loadInit:dojoLoadInitPlugin
5915 };
5916});
5917
5918},
5919'dojo/json':function(){
5920define(["./has"], function(has){
5921 "use strict";
5922 var hasJSON = typeof JSON != "undefined";
5923 has.add("json-parse", hasJSON); // all the parsers work fine
5924 // Firefox 3.5/Gecko 1.9 fails to use replacer in stringify properly https://bugzilla.mozilla.org/show_bug.cgi?id=509184
5925 has.add("json-stringify", hasJSON && JSON.stringify({a:0}, function(k,v){return v||1;}) == '{"a":1}');
5926 if(has("json-stringify")){
5927 return JSON;
5928 }
5929 else{
5930 var escapeString = function(/*String*/str){
5931 //summary:
5932 // Adds escape sequences for non-visual characters, double quote and
5933 // backslash and surrounds with double quotes to form a valid string
5934 // literal.
5935 return ('"' + str.replace(/(["\\])/g, '\\$1') + '"').
5936 replace(/[\f]/g, "\\f").replace(/[\b]/g, "\\b").replace(/[\n]/g, "\\n").
5937 replace(/[\t]/g, "\\t").replace(/[\r]/g, "\\r"); // string
5938 };
5939 return {
5940 parse: has("json-parse") ? JSON.parse : function(str, strict){
5941 // summary:
5942 // Parses a [JSON](http://json.org) string to return a JavaScript object.
5943 // description:
5944 // This function follows [native JSON API](https://developer.mozilla.org/en/JSON)
5945 // Throws for invalid JSON strings. This delegates to eval() if native JSON
5946 // support is not available. By default this will evaluate any valid JS expression.
5947 // With the strict parameter set to true, the parser will ensure that only
5948 // valid JSON strings are parsed (otherwise throwing an error). Without the strict
5949 // parameter, the content passed to this method must come
5950 // from a trusted source.
5951 // str:
5952 // a string literal of a JSON item, for instance:
5953 // `'{ "foo": [ "bar", 1, { "baz": "thud" } ] }'`
5954 // strict:
5955 // When set to true, this will ensure that only valid, secure JSON is ever parsed.
5956 // Make sure this is set to true for untrusted content. Note that on browsers/engines
5957 // without native JSON support, setting this to true will run slower.
5958 if(strict && !/^([\s\[\{]*(?:"(?:\\.|[^"])+"|-?\d[\d\.]*(?:[Ee][+-]?\d+)?|null|true|false|)[\s\]\}]*(?:,|:|$))+$/.test(str)){
5959 throw new SyntaxError("Invalid characters in JSON");
5960 }
5961 return eval('(' + str + ')');
5962 },
5963 stringify: function(value, replacer, spacer){
5964 // summary:
5965 // Returns a [JSON](http://json.org) serialization of an object.
5966 // description:
5967 // Returns a [JSON](http://json.org) serialization of an object.
5968 // This function follows [native JSON API](https://developer.mozilla.org/en/JSON)
5969 // Note that this doesn't check for infinite recursion, so don't do that!
5970 // value:
5971 // A value to be serialized.
5972 // replacer:
5973 // A replacer function that is called for each value and can return a replacement
5974 // spacer:
5975 // A spacer string to be used for pretty printing of JSON
5976 //
5977 // example:
5978 // simple serialization of a trivial object
5979 // | define(["dojo/json"], function(JSON){
5980 // | var jsonStr = JSON.stringify({ howdy: "stranger!", isStrange: true });
5981 // | doh.is('{"howdy":"stranger!","isStrange":true}', jsonStr);
5982 var undef;
5983 if(typeof replacer == "string"){
5984 spacer = replacer;
5985 replacer = null;
5986 }
5987 function stringify(it, indent, key){
5988 if(replacer){
5989 it = replacer(key, it);
5990 }
5991 var val, objtype = typeof it;
5992 if(objtype == "number"){
5993 return isFinite(it) ? it + "" : "null";
5994 }
5995 if(objtype == "boolean"){
5996 return it + "";
5997 }
5998 if(it === null){
5999 return "null";
6000 }
6001 if(typeof it == "string"){
6002 return escapeString(it);
6003 }
6004 if(objtype == "function" || objtype == "undefined"){
6005 return undef; // undefined
6006 }
6007 // short-circuit for objects that support "json" serialization
6008 // if they return "self" then just pass-through...
6009 if(typeof it.toJSON == "function"){
6010 return stringify(it.toJSON(key), indent, key);
6011 }
6012 if(it instanceof Date){
6013 return '"{FullYear}-{Month+}-{Date}T{Hours}:{Minutes}:{Seconds}Z"'.replace(/\{(\w+)(\+)?\}/g, function(t, prop, plus){
6014 var num = it["getUTC" + prop]() + (plus ? 1 : 0);
6015 return num < 10 ? "0" + num : num;
6016 });
6017 }
6018 if(it.valueOf() !== it){
6019 // primitive wrapper, try again unwrapped:
6020 return stringify(it.valueOf(), indent, key);
6021 }
6022 var nextIndent= spacer ? (indent + spacer) : "";
6023 /* we used to test for DOM nodes and throw, but FF serializes them as {}, so cross-browser consistency is probably not efficiently attainable */
6024
6025 var sep = spacer ? " " : "";
6026 var newLine = spacer ? "\n" : "";
6027
6028 // array
6029 if(it instanceof Array){
6030 var itl = it.length, res = [];
6031 for(key = 0; key < itl; key++){
6032 var obj = it[key];
6033 val = stringify(obj, nextIndent, key);
6034 if(typeof val != "string"){
6035 val = "null";
6036 }
6037 res.push(newLine + nextIndent + val);
6038 }
6039 return "[" + res.join(",") + newLine + indent + "]";
6040 }
6041 // generic object code path
6042 var output = [];
6043 for(key in it){
6044 var keyStr;
6045 if(typeof key == "number"){
6046 keyStr = '"' + key + '"';
6047 }else if(typeof key == "string"){
6048 keyStr = escapeString(key);
6049 }else{
6050 // skip non-string or number keys
6051 continue;
6052 }
6053 val = stringify(it[key], nextIndent, key);
6054 if(typeof val != "string"){
6055 // skip non-serializable values
6056 continue;
6057 }
6058 // At this point, the most non-IE browsers don't get in this branch
6059 // (they have native JSON), so push is definitely the way to
6060 output.push(newLine + nextIndent + keyStr + ":" + sep + val);
6061 }
6062 return "{" + output.join(",") + newLine + indent + "}"; // String
6063 }
6064 return stringify(value, "", "");
6065 }
6066 };
6067 }
6068});
6069
6070},
6071'dojo/_base/declare':function(){
6072define(["./kernel", "../has", "./lang"], function(dojo, has, lang){
6073 // module:
6074 // dojo/_base/declare
6075 // summary:
6076 // This module defines dojo.declare.
6077
6078 var mix = lang.mixin, op = Object.prototype, opts = op.toString,
6079 xtor = new Function, counter = 0, cname = "constructor";
6080
6081 function err(msg, cls){ throw new Error("declare" + (cls ? " " + cls : "") + ": " + msg); }
6082
6083 // C3 Method Resolution Order (see http://www.python.org/download/releases/2.3/mro/)
6084 function c3mro(bases, className){
6085 var result = [], roots = [{cls: 0, refs: []}], nameMap = {}, clsCount = 1,
6086 l = bases.length, i = 0, j, lin, base, top, proto, rec, name, refs;
6087
6088 // build a list of bases naming them if needed
6089 for(; i < l; ++i){
6090 base = bases[i];
6091 if(!base){
6092 err("mixin #" + i + " is unknown. Did you use dojo.require to pull it in?", className);
6093 }else if(opts.call(base) != "[object Function]"){
6094 err("mixin #" + i + " is not a callable constructor.", className);
6095 }
6096 lin = base._meta ? base._meta.bases : [base];
6097 top = 0;
6098 // add bases to the name map
6099 for(j = lin.length - 1; j >= 0; --j){
6100 proto = lin[j].prototype;
6101 if(!proto.hasOwnProperty("declaredClass")){
6102 proto.declaredClass = "uniqName_" + (counter++);
6103 }
6104 name = proto.declaredClass;
6105 if(!nameMap.hasOwnProperty(name)){
6106 nameMap[name] = {count: 0, refs: [], cls: lin[j]};
6107 ++clsCount;
6108 }
6109 rec = nameMap[name];
6110 if(top && top !== rec){
6111 rec.refs.push(top);
6112 ++top.count;
6113 }
6114 top = rec;
6115 }
6116 ++top.count;
6117 roots[0].refs.push(top);
6118 }
6119
6120 // remove classes without external references recursively
6121 while(roots.length){
6122 top = roots.pop();
6123 result.push(top.cls);
6124 --clsCount;
6125 // optimization: follow a single-linked chain
6126 while(refs = top.refs, refs.length == 1){
6127 top = refs[0];
6128 if(!top || --top.count){
6129 // branch or end of chain => do not end to roots
6130 top = 0;
6131 break;
6132 }
6133 result.push(top.cls);
6134 --clsCount;
6135 }
6136 if(top){
6137 // branch
6138 for(i = 0, l = refs.length; i < l; ++i){
6139 top = refs[i];
6140 if(!--top.count){
6141 roots.push(top);
6142 }
6143 }
6144 }
6145 }
6146 if(clsCount){
6147 err("can't build consistent linearization", className);
6148 }
6149
6150 // calculate the superclass offset
6151 base = bases[0];
6152 result[0] = base ?
6153 base._meta && base === result[result.length - base._meta.bases.length] ?
6154 base._meta.bases.length : 1 : 0;
6155
6156 return result;
6157 }
6158
6159 function inherited(args, a, f){
6160 var name, chains, bases, caller, meta, base, proto, opf, pos,
6161 cache = this._inherited = this._inherited || {};
6162
6163 // crack arguments
6164 if(typeof args == "string"){
6165 name = args;
6166 args = a;
6167 a = f;
6168 }
6169 f = 0;
6170
6171 caller = args.callee;
6172 name = name || caller.nom;
6173 if(!name){
6174 err("can't deduce a name to call inherited()", this.declaredClass);
6175 }
6176
6177 meta = this.constructor._meta;
6178 bases = meta.bases;
6179
6180 pos = cache.p;
6181 if(name != cname){
6182 // method
6183 if(cache.c !== caller){
6184 // cache bust
6185 pos = 0;
6186 base = bases[0];
6187 meta = base._meta;
6188 if(meta.hidden[name] !== caller){
6189 // error detection
6190 chains = meta.chains;
6191 if(chains && typeof chains[name] == "string"){
6192 err("calling chained method with inherited: " + name, this.declaredClass);
6193 }
6194 // find caller
6195 do{
6196 meta = base._meta;
6197 proto = base.prototype;
6198 if(meta && (proto[name] === caller && proto.hasOwnProperty(name) || meta.hidden[name] === caller)){
6199 break;
6200 }
6201 }while(base = bases[++pos]); // intentional assignment
6202 pos = base ? pos : -1;
6203 }
6204 }
6205 // find next
6206 base = bases[++pos];
6207 if(base){
6208 proto = base.prototype;
6209 if(base._meta && proto.hasOwnProperty(name)){
6210 f = proto[name];
6211 }else{
6212 opf = op[name];
6213 do{
6214 proto = base.prototype;
6215 f = proto[name];
6216 if(f && (base._meta ? proto.hasOwnProperty(name) : f !== opf)){
6217 break;
6218 }
6219 }while(base = bases[++pos]); // intentional assignment
6220 }
6221 }
6222 f = base && f || op[name];
6223 }else{
6224 // constructor
6225 if(cache.c !== caller){
6226 // cache bust
6227 pos = 0;
6228 meta = bases[0]._meta;
6229 if(meta && meta.ctor !== caller){
6230 // error detection
6231 chains = meta.chains;
6232 if(!chains || chains.constructor !== "manual"){
6233 err("calling chained constructor with inherited", this.declaredClass);
6234 }
6235 // find caller
6236 while(base = bases[++pos]){ // intentional assignment
6237 meta = base._meta;
6238 if(meta && meta.ctor === caller){
6239 break;
6240 }
6241 }
6242 pos = base ? pos : -1;
6243 }
6244 }
6245 // find next
6246 while(base = bases[++pos]){ // intentional assignment
6247 meta = base._meta;
6248 f = meta ? meta.ctor : base;
6249 if(f){
6250 break;
6251 }
6252 }
6253 f = base && f;
6254 }
6255
6256 // cache the found super method
6257 cache.c = f;
6258 cache.p = pos;
6259
6260 // now we have the result
6261 if(f){
6262 return a === true ? f : f.apply(this, a || args);
6263 }
6264 // intentionally no return if a super method was not found
6265 }
6266
6267 function getInherited(name, args){
6268 if(typeof name == "string"){
6269 return this.__inherited(name, args, true);
6270 }
6271 return this.__inherited(name, true);
6272 }
6273
6274 function inherited__debug(args, a1, a2){
6275 var f = this.getInherited(args, a1);
6276 if(f){ return f.apply(this, a2 || a1 || args); }
6277 // intentionally no return if a super method was not found
6278 }
6279
6280 var inheritedImpl = dojo.config.isDebug ? inherited__debug : inherited;
6281
6282 // emulation of "instanceof"
6283 function isInstanceOf(cls){
6284 var bases = this.constructor._meta.bases;
6285 for(var i = 0, l = bases.length; i < l; ++i){
6286 if(bases[i] === cls){
6287 return true;
6288 }
6289 }
6290 return this instanceof cls;
6291 }
6292
6293 function mixOwn(target, source){
6294 // add props adding metadata for incoming functions skipping a constructor
6295 for(var name in source){
6296 if(name != cname && source.hasOwnProperty(name)){
6297 target[name] = source[name];
6298 }
6299 }
6300 if(has("bug-for-in-skips-shadowed")){
6301 for(var extraNames= lang._extraNames, i= extraNames.length; i;){
6302 name = extraNames[--i];
6303 if(name != cname && source.hasOwnProperty(name)){
6304 target[name] = source[name];
6305 }
6306 }
6307 }
6308 }
6309
6310 // implementation of safe mixin function
6311 function safeMixin(target, source){
6312 var name, t;
6313 // add props adding metadata for incoming functions skipping a constructor
6314 for(name in source){
6315 t = source[name];
6316 if((t !== op[name] || !(name in op)) && name != cname){
6317 if(opts.call(t) == "[object Function]"){
6318 // non-trivial function method => attach its name
6319 t.nom = name;
6320 }
6321 target[name] = t;
6322 }
6323 }
6324 if(has("bug-for-in-skips-shadowed")){
6325 for(var extraNames= lang._extraNames, i= extraNames.length; i;){
6326 name = extraNames[--i];
6327 t = source[name];
6328 if((t !== op[name] || !(name in op)) && name != cname){
6329 if(opts.call(t) == "[object Function]"){
6330 // non-trivial function method => attach its name
6331 t.nom = name;
6332 }
6333 target[name] = t;
6334 }
6335 }
6336 }
6337 return target;
6338 }
6339
6340 function extend(source){
6341 declare.safeMixin(this.prototype, source);
6342 return this;
6343 }
6344
6345 // chained constructor compatible with the legacy dojo.declare()
6346 function chainedConstructor(bases, ctorSpecial){
6347 return function(){
6348 var a = arguments, args = a, a0 = a[0], f, i, m,
6349 l = bases.length, preArgs;
6350
6351 if(!(this instanceof a.callee)){
6352 // not called via new, so force it
6353 return applyNew(a);
6354 }
6355
6356 //this._inherited = {};
6357 // perform the shaman's rituals of the original dojo.declare()
6358 // 1) call two types of the preamble
6359 if(ctorSpecial && (a0 && a0.preamble || this.preamble)){
6360 // full blown ritual
6361 preArgs = new Array(bases.length);
6362 // prepare parameters
6363 preArgs[0] = a;
6364 for(i = 0;;){
6365 // process the preamble of the 1st argument
6366 a0 = a[0];
6367 if(a0){
6368 f = a0.preamble;
6369 if(f){
6370 a = f.apply(this, a) || a;
6371 }
6372 }
6373 // process the preamble of this class
6374 f = bases[i].prototype;
6375 f = f.hasOwnProperty("preamble") && f.preamble;
6376 if(f){
6377 a = f.apply(this, a) || a;
6378 }
6379 // one peculiarity of the preamble:
6380 // it is called if it is not needed,
6381 // e.g., there is no constructor to call
6382 // let's watch for the last constructor
6383 // (see ticket #9795)
6384 if(++i == l){
6385 break;
6386 }
6387 preArgs[i] = a;
6388 }
6389 }
6390 // 2) call all non-trivial constructors using prepared arguments
6391 for(i = l - 1; i >= 0; --i){
6392 f = bases[i];
6393 m = f._meta;
6394 f = m ? m.ctor : f;
6395 if(f){
6396 f.apply(this, preArgs ? preArgs[i] : a);
6397 }
6398 }
6399 // 3) continue the original ritual: call the postscript
6400 f = this.postscript;
6401 if(f){
6402 f.apply(this, args);
6403 }
6404 };
6405 }
6406
6407
6408 // chained constructor compatible with the legacy dojo.declare()
6409 function singleConstructor(ctor, ctorSpecial){
6410 return function(){
6411 var a = arguments, t = a, a0 = a[0], f;
6412
6413 if(!(this instanceof a.callee)){
6414 // not called via new, so force it
6415 return applyNew(a);
6416 }
6417
6418 //this._inherited = {};
6419 // perform the shaman's rituals of the original dojo.declare()
6420 // 1) call two types of the preamble
6421 if(ctorSpecial){
6422 // full blown ritual
6423 if(a0){
6424 // process the preamble of the 1st argument
6425 f = a0.preamble;
6426 if(f){
6427 t = f.apply(this, t) || t;
6428 }
6429 }
6430 f = this.preamble;
6431 if(f){
6432 // process the preamble of this class
6433 f.apply(this, t);
6434 // one peculiarity of the preamble:
6435 // it is called even if it is not needed,
6436 // e.g., there is no constructor to call
6437 // let's watch for the last constructor
6438 // (see ticket #9795)
6439 }
6440 }
6441 // 2) call a constructor
6442 if(ctor){
6443 ctor.apply(this, a);
6444 }
6445 // 3) continue the original ritual: call the postscript
6446 f = this.postscript;
6447 if(f){
6448 f.apply(this, a);
6449 }
6450 };
6451 }
6452
6453 // plain vanilla constructor (can use inherited() to call its base constructor)
6454 function simpleConstructor(bases){
6455 return function(){
6456 var a = arguments, i = 0, f, m;
6457
6458 if(!(this instanceof a.callee)){
6459 // not called via new, so force it
6460 return applyNew(a);
6461 }
6462
6463 //this._inherited = {};
6464 // perform the shaman's rituals of the original dojo.declare()
6465 // 1) do not call the preamble
6466 // 2) call the top constructor (it can use this.inherited())
6467 for(; f = bases[i]; ++i){ // intentional assignment
6468 m = f._meta;
6469 f = m ? m.ctor : f;
6470 if(f){
6471 f.apply(this, a);
6472 break;
6473 }
6474 }
6475 // 3) call the postscript
6476 f = this.postscript;
6477 if(f){
6478 f.apply(this, a);
6479 }
6480 };
6481 }
6482
6483 function chain(name, bases, reversed){
6484 return function(){
6485 var b, m, f, i = 0, step = 1;
6486 if(reversed){
6487 i = bases.length - 1;
6488 step = -1;
6489 }
6490 for(; b = bases[i]; i += step){ // intentional assignment
6491 m = b._meta;
6492 f = (m ? m.hidden : b.prototype)[name];
6493 if(f){
6494 f.apply(this, arguments);
6495 }
6496 }
6497 };
6498 }
6499
6500 // forceNew(ctor)
6501 // return a new object that inherits from ctor.prototype but
6502 // without actually running ctor on the object.
6503 function forceNew(ctor){
6504 // create object with correct prototype using a do-nothing
6505 // constructor
6506 xtor.prototype = ctor.prototype;
6507 var t = new xtor;
6508 xtor.prototype = null; // clean up
6509 return t;
6510 }
6511
6512 // applyNew(args)
6513 // just like 'new ctor()' except that the constructor and its arguments come
6514 // from args, which must be an array or an arguments object
6515 function applyNew(args){
6516 // create an object with ctor's prototype but without
6517 // calling ctor on it.
6518 var ctor = args.callee, t = forceNew(ctor);
6519 // execute the real constructor on the new object
6520 ctor.apply(t, args);
6521 return t;
6522 }
6523
6524 function declare(className, superclass, props){
6525 // crack parameters
6526 if(typeof className != "string"){
6527 props = superclass;
6528 superclass = className;
6529 className = "";
6530 }
6531 props = props || {};
6532
6533 var proto, i, t, ctor, name, bases, chains, mixins = 1, parents = superclass;
6534
6535 // build a prototype
6536 if(opts.call(superclass) == "[object Array]"){
6537 // C3 MRO
6538 bases = c3mro(superclass, className);
6539 t = bases[0];
6540 mixins = bases.length - t;
6541 superclass = bases[mixins];
6542 }else{
6543 bases = [0];
6544 if(superclass){
6545 if(opts.call(superclass) == "[object Function]"){
6546 t = superclass._meta;
6547 bases = bases.concat(t ? t.bases : superclass);
6548 }else{
6549 err("base class is not a callable constructor.", className);
6550 }
6551 }else if(superclass !== null){
6552 err("unknown base class. Did you use dojo.require to pull it in?", className);
6553 }
6554 }
6555 if(superclass){
6556 for(i = mixins - 1;; --i){
6557 proto = forceNew(superclass);
6558 if(!i){
6559 // stop if nothing to add (the last base)
6560 break;
6561 }
6562 // mix in properties
6563 t = bases[i];
6564 (t._meta ? mixOwn : mix)(proto, t.prototype);
6565 // chain in new constructor
6566 ctor = new Function;
6567 ctor.superclass = superclass;
6568 ctor.prototype = proto;
6569 superclass = proto.constructor = ctor;
6570 }
6571 }else{
6572 proto = {};
6573 }
6574 // add all properties
6575 declare.safeMixin(proto, props);
6576 // add constructor
6577 t = props.constructor;
6578 if(t !== op.constructor){
6579 t.nom = cname;
6580 proto.constructor = t;
6581 }
6582
6583 // collect chains and flags
6584 for(i = mixins - 1; i; --i){ // intentional assignment
6585 t = bases[i]._meta;
6586 if(t && t.chains){
6587 chains = mix(chains || {}, t.chains);
6588 }
6589 }
6590 if(proto["-chains-"]){
6591 chains = mix(chains || {}, proto["-chains-"]);
6592 }
6593
6594 // build ctor
6595 t = !chains || !chains.hasOwnProperty(cname);
6596 bases[0] = ctor = (chains && chains.constructor === "manual") ? simpleConstructor(bases) :
6597 (bases.length == 1 ? singleConstructor(props.constructor, t) : chainedConstructor(bases, t));
6598
6599 // add meta information to the constructor
6600 ctor._meta = {bases: bases, hidden: props, chains: chains,
6601 parents: parents, ctor: props.constructor};
6602 ctor.superclass = superclass && superclass.prototype;
6603 ctor.extend = extend;
6604 ctor.prototype = proto;
6605 proto.constructor = ctor;
6606
6607 // add "standard" methods to the prototype
6608 proto.getInherited = getInherited;
6609 proto.isInstanceOf = isInstanceOf;
6610 proto.inherited = inheritedImpl;
6611 proto.__inherited = inherited;
6612
6613 // add name if specified
6614 if(className){
6615 proto.declaredClass = className;
6616 lang.setObject(className, ctor);
6617 }
6618
6619 // build chains and add them to the prototype
6620 if(chains){
6621 for(name in chains){
6622 if(proto[name] && typeof chains[name] == "string" && name != cname){
6623 t = proto[name] = chain(name, bases, chains[name] === "after");
6624 t.nom = name;
6625 }
6626 }
6627 }
6628 // chained methods do not return values
6629 // no need to chain "invisible" functions
6630
6631 return ctor; // Function
6632 }
6633
6634 /*=====
6635 dojo.declare = function(className, superclass, props){
6636 // summary:
6637 // Create a feature-rich constructor from compact notation.
6638 // className: String?:
6639 // The optional name of the constructor (loosely, a "class")
6640 // stored in the "declaredClass" property in the created prototype.
6641 // It will be used as a global name for a created constructor.
6642 // superclass: Function|Function[]:
6643 // May be null, a Function, or an Array of Functions. This argument
6644 // specifies a list of bases (the left-most one is the most deepest
6645 // base).
6646 // props: Object:
6647 // An object whose properties are copied to the created prototype.
6648 // Add an instance-initialization function by making it a property
6649 // named "constructor".
6650 // returns:
6651 // New constructor function.
6652 // description:
6653 // Create a constructor using a compact notation for inheritance and
6654 // prototype extension.
6655 //
6656 // Mixin ancestors provide a type of multiple inheritance.
6657 // Prototypes of mixin ancestors are copied to the new class:
6658 // changes to mixin prototypes will not affect classes to which
6659 // they have been mixed in.
6660 //
6661 // Ancestors can be compound classes created by this version of
6662 // dojo.declare. In complex cases all base classes are going to be
6663 // linearized according to C3 MRO algorithm
6664 // (see http://www.python.org/download/releases/2.3/mro/ for more
6665 // details).
6666 //
6667 // "className" is cached in "declaredClass" property of the new class,
6668 // if it was supplied. The immediate super class will be cached in
6669 // "superclass" property of the new class.
6670 //
6671 // Methods in "props" will be copied and modified: "nom" property
6672 // (the declared name of the method) will be added to all copied
6673 // functions to help identify them for the internal machinery. Be
6674 // very careful, while reusing methods: if you use the same
6675 // function under different names, it can produce errors in some
6676 // cases.
6677 //
6678 // It is possible to use constructors created "manually" (without
6679 // dojo.declare) as bases. They will be called as usual during the
6680 // creation of an instance, their methods will be chained, and even
6681 // called by "this.inherited()".
6682 //
6683 // Special property "-chains-" governs how to chain methods. It is
6684 // a dictionary, which uses method names as keys, and hint strings
6685 // as values. If a hint string is "after", this method will be
6686 // called after methods of its base classes. If a hint string is
6687 // "before", this method will be called before methods of its base
6688 // classes.
6689 //
6690 // If "constructor" is not mentioned in "-chains-" property, it will
6691 // be chained using the legacy mode: using "after" chaining,
6692 // calling preamble() method before each constructor, if available,
6693 // and calling postscript() after all constructors were executed.
6694 // If the hint is "after", it is chained as a regular method, but
6695 // postscript() will be called after the chain of constructors.
6696 // "constructor" cannot be chained "before", but it allows
6697 // a special hint string: "manual", which means that constructors
6698 // are not going to be chained in any way, and programmer will call
6699 // them manually using this.inherited(). In the latter case
6700 // postscript() will be called after the construction.
6701 //
6702 // All chaining hints are "inherited" from base classes and
6703 // potentially can be overridden. Be very careful when overriding
6704 // hints! Make sure that all chained methods can work in a proposed
6705 // manner of chaining.
6706 //
6707 // Once a method was chained, it is impossible to unchain it. The
6708 // only exception is "constructor". You don't need to define a
6709 // method in order to supply a chaining hint.
6710 //
6711 // If a method is chained, it cannot use this.inherited() because
6712 // all other methods in the hierarchy will be called automatically.
6713 //
6714 // Usually constructors and initializers of any kind are chained
6715 // using "after" and destructors of any kind are chained as
6716 // "before". Note that chaining assumes that chained methods do not
6717 // return any value: any returned value will be discarded.
6718 //
6719 // example:
6720 // | dojo.declare("my.classes.bar", my.classes.foo, {
6721 // | // properties to be added to the class prototype
6722 // | someValue: 2,
6723 // | // initialization function
6724 // | constructor: function(){
6725 // | this.myComplicatedObject = new ReallyComplicatedObject();
6726 // | },
6727 // | // other functions
6728 // | someMethod: function(){
6729 // | doStuff();
6730 // | }
6731 // | });
6732 //
6733 // example:
6734 // | var MyBase = dojo.declare(null, {
6735 // | // constructor, properties, and methods go here
6736 // | // ...
6737 // | });
6738 // | var MyClass1 = dojo.declare(MyBase, {
6739 // | // constructor, properties, and methods go here
6740 // | // ...
6741 // | });
6742 // | var MyClass2 = dojo.declare(MyBase, {
6743 // | // constructor, properties, and methods go here
6744 // | // ...
6745 // | });
6746 // | var MyDiamond = dojo.declare([MyClass1, MyClass2], {
6747 // | // constructor, properties, and methods go here
6748 // | // ...
6749 // | });
6750 //
6751 // example:
6752 // | var F = function(){ console.log("raw constructor"); };
6753 // | F.prototype.method = function(){
6754 // | console.log("raw method");
6755 // | };
6756 // | var A = dojo.declare(F, {
6757 // | constructor: function(){
6758 // | console.log("A.constructor");
6759 // | },
6760 // | method: function(){
6761 // | console.log("before calling F.method...");
6762 // | this.inherited(arguments);
6763 // | console.log("...back in A");
6764 // | }
6765 // | });
6766 // | new A().method();
6767 // | // will print:
6768 // | // raw constructor
6769 // | // A.constructor
6770 // | // before calling F.method...
6771 // | // raw method
6772 // | // ...back in A
6773 //
6774 // example:
6775 // | var A = dojo.declare(null, {
6776 // | "-chains-": {
6777 // | destroy: "before"
6778 // | }
6779 // | });
6780 // | var B = dojo.declare(A, {
6781 // | constructor: function(){
6782 // | console.log("B.constructor");
6783 // | },
6784 // | destroy: function(){
6785 // | console.log("B.destroy");
6786 // | }
6787 // | });
6788 // | var C = dojo.declare(B, {
6789 // | constructor: function(){
6790 // | console.log("C.constructor");
6791 // | },
6792 // | destroy: function(){
6793 // | console.log("C.destroy");
6794 // | }
6795 // | });
6796 // | new C().destroy();
6797 // | // prints:
6798 // | // B.constructor
6799 // | // C.constructor
6800 // | // C.destroy
6801 // | // B.destroy
6802 //
6803 // example:
6804 // | var A = dojo.declare(null, {
6805 // | "-chains-": {
6806 // | constructor: "manual"
6807 // | }
6808 // | });
6809 // | var B = dojo.declare(A, {
6810 // | constructor: function(){
6811 // | // ...
6812 // | // call the base constructor with new parameters
6813 // | this.inherited(arguments, [1, 2, 3]);
6814 // | // ...
6815 // | }
6816 // | });
6817 //
6818 // example:
6819 // | var A = dojo.declare(null, {
6820 // | "-chains-": {
6821 // | m1: "before"
6822 // | },
6823 // | m1: function(){
6824 // | console.log("A.m1");
6825 // | },
6826 // | m2: function(){
6827 // | console.log("A.m2");
6828 // | }
6829 // | });
6830 // | var B = dojo.declare(A, {
6831 // | "-chains-": {
6832 // | m2: "after"
6833 // | },
6834 // | m1: function(){
6835 // | console.log("B.m1");
6836 // | },
6837 // | m2: function(){
6838 // | console.log("B.m2");
6839 // | }
6840 // | });
6841 // | var x = new B();
6842 // | x.m1();
6843 // | // prints:
6844 // | // B.m1
6845 // | // A.m1
6846 // | x.m2();
6847 // | // prints:
6848 // | // A.m2
6849 // | // B.m2
6850 return new Function(); // Function
2f01fe57 6851 };
1354d172 6852 =====*/
2f01fe57 6853
1354d172
AD
6854 /*=====
6855 dojo.safeMixin = function(target, source){
2f01fe57 6856 // summary:
1354d172
AD
6857 // Mix in properties skipping a constructor and decorating functions
6858 // like it is done by dojo.declare.
6859 // target: Object
6860 // Target object to accept new properties.
6861 // source: Object
6862 // Source object for new properties.
6863 // description:
6864 // This function is used to mix in properties like lang.mixin does,
6865 // but it skips a constructor property and decorates functions like
6866 // dojo.declare does.
6867 //
6868 // It is meant to be used with classes and objects produced with
6869 // dojo.declare. Functions mixed in with dojo.safeMixin can use
6870 // this.inherited() like normal methods.
6871 //
6872 // This function is used to implement extend() method of a constructor
6873 // produced with dojo.declare().
6874 //
6875 // example:
6876 // | var A = dojo.declare(null, {
6877 // | m1: function(){
6878 // | console.log("A.m1");
6879 // | },
6880 // | m2: function(){
6881 // | console.log("A.m2");
6882 // | }
6883 // | });
6884 // | var B = dojo.declare(A, {
6885 // | m1: function(){
6886 // | this.inherited(arguments);
6887 // | console.log("B.m1");
6888 // | }
6889 // | });
6890 // | B.extend({
6891 // | m2: function(){
6892 // | this.inherited(arguments);
6893 // | console.log("B.m2");
6894 // | }
6895 // | });
6896 // | var x = new B();
6897 // | dojo.safeMixin(x, {
6898 // | m1: function(){
6899 // | this.inherited(arguments);
6900 // | console.log("X.m1");
6901 // | },
6902 // | m2: function(){
6903 // | this.inherited(arguments);
6904 // | console.log("X.m2");
6905 // | }
6906 // | });
6907 // | x.m2();
6908 // | // prints:
6909 // | // A.m1
6910 // | // B.m1
6911 // | // X.m1
81bea17a 6912 };
1354d172 6913 =====*/
2f01fe57 6914
1354d172
AD
6915 /*=====
6916 Object.inherited = function(name, args, newArgs){
2f01fe57 6917 // summary:
1354d172
AD
6918 // Calls a super method.
6919 // name: String?
6920 // The optional method name. Should be the same as the caller's
6921 // name. Usually "name" is specified in complex dynamic cases, when
6922 // the calling method was dynamically added, undecorated by
6923 // dojo.declare, and it cannot be determined.
6924 // args: Arguments
6925 // The caller supply this argument, which should be the original
6926 // "arguments".
6927 // newArgs: Object?
6928 // If "true", the found function will be returned without
6929 // executing it.
6930 // If Array, it will be used to call a super method. Otherwise
6931 // "args" will be used.
6932 // returns:
6933 // Whatever is returned by a super method, or a super method itself,
6934 // if "true" was specified as newArgs.
2f01fe57 6935 // description:
1354d172
AD
6936 // This method is used inside method of classes produced with
6937 // dojo.declare to call a super method (next in the chain). It is
6938 // used for manually controlled chaining. Consider using the regular
6939 // chaining, because it is faster. Use "this.inherited()" only in
6940 // complex cases.
2f01fe57 6941 //
1354d172
AD
6942 // This method cannot me called from automatically chained
6943 // constructors including the case of a special (legacy)
6944 // constructor chaining. It cannot be called from chained methods.
2f01fe57 6945 //
1354d172
AD
6946 // If "this.inherited()" cannot find the next-in-chain method, it
6947 // does nothing and returns "undefined". The last method in chain
6948 // can be a default method implemented in Object, which will be
6949 // called last.
2f01fe57 6950 //
1354d172
AD
6951 // If "name" is specified, it is assumed that the method that
6952 // received "args" is the parent method for this call. It is looked
6953 // up in the chain list and if it is found the next-in-chain method
6954 // is called. If it is not found, the first-in-chain method is
6955 // called.
6956 //
6957 // If "name" is not specified, it will be derived from the calling
6958 // method (using a methoid property "nom").
2f01fe57
AD
6959 //
6960 // example:
1354d172
AD
6961 // | var B = dojo.declare(A, {
6962 // | method1: function(a, b, c){
6963 // | this.inherited(arguments);
6964 // | },
6965 // | method2: function(a, b){
6966 // | return this.inherited(arguments, [a + b]);
6967 // | }
6968 // | });
6969 // | // next method is not in the chain list because it is added
6970 // | // manually after the class was created.
6971 // | B.prototype.method3 = function(){
6972 // | console.log("This is a dynamically-added method.");
6973 // | this.inherited("method3", arguments);
6974 // | };
6975 // example:
6976 // | var B = dojo.declare(A, {
6977 // | method: function(a, b){
6978 // | var super = this.inherited(arguments, true);
6979 // | // ...
6980 // | if(!super){
6981 // | console.log("there is no super method");
6982 // | return 0;
6983 // | }
6984 // | return super.apply(this, arguments);
6985 // | }
6986 // | });
6987 return {}; // Object
6988 }
6989 =====*/
6990
6991 /*=====
6992 Object.getInherited = function(name, args){
6993 // summary:
6994 // Returns a super method.
6995 // name: String?
6996 // The optional method name. Should be the same as the caller's
6997 // name. Usually "name" is specified in complex dynamic cases, when
6998 // the calling method was dynamically added, undecorated by
6999 // dojo.declare, and it cannot be determined.
7000 // args: Arguments
7001 // The caller supply this argument, which should be the original
7002 // "arguments".
7003 // returns:
7004 // Returns a super method (Function) or "undefined".
7005 // description:
7006 // This method is a convenience method for "this.inherited()".
7007 // It uses the same algorithm but instead of executing a super
7008 // method, it returns it, or "undefined" if not found.
2f01fe57
AD
7009 //
7010 // example:
1354d172
AD
7011 // | var B = dojo.declare(A, {
7012 // | method: function(a, b){
7013 // | var super = this.getInherited(arguments);
7014 // | // ...
7015 // | if(!super){
7016 // | console.log("there is no super method");
7017 // | return 0;
7018 // | }
7019 // | return super.apply(this, arguments);
7020 // | }
7021 // | });
7022 return {}; // Object
7023 }
7024 =====*/
7025
7026 /*=====
7027 Object.isInstanceOf = function(cls){
7028 // summary:
7029 // Checks the inheritance chain to see if it is inherited from this
7030 // class.
7031 // cls: Function
7032 // Class constructor.
7033 // returns:
7034 // "true", if this object is inherited from this class, "false"
7035 // otherwise.
7036 // description:
7037 // This method is used with instances of classes produced with
7038 // dojo.declare to determine of they support a certain interface or
7039 // not. It models "instanceof" operator.
7040 //
7041 // example:
7042 // | var A = dojo.declare(null, {
7043 // | // constructor, properties, and methods go here
7044 // | // ...
7045 // | });
7046 // | var B = dojo.declare(null, {
7047 // | // constructor, properties, and methods go here
7048 // | // ...
7049 // | });
7050 // | var C = dojo.declare([A, B], {
7051 // | // constructor, properties, and methods go here
7052 // | // ...
7053 // | });
7054 // | var D = dojo.declare(A, {
7055 // | // constructor, properties, and methods go here
7056 // | // ...
7057 // | });
7058 // |
7059 // | var a = new A(), b = new B(), c = new C(), d = new D();
7060 // |
7061 // | console.log(a.isInstanceOf(A)); // true
7062 // | console.log(b.isInstanceOf(A)); // false
7063 // | console.log(c.isInstanceOf(A)); // true
7064 // | console.log(d.isInstanceOf(A)); // true
7065 // |
7066 // | console.log(a.isInstanceOf(B)); // false
7067 // | console.log(b.isInstanceOf(B)); // true
7068 // | console.log(c.isInstanceOf(B)); // true
7069 // | console.log(d.isInstanceOf(B)); // false
7070 // |
7071 // | console.log(a.isInstanceOf(C)); // false
7072 // | console.log(b.isInstanceOf(C)); // false
7073 // | console.log(c.isInstanceOf(C)); // true
7074 // | console.log(d.isInstanceOf(C)); // false
2f01fe57 7075 // |
1354d172
AD
7076 // | console.log(a.isInstanceOf(D)); // false
7077 // | console.log(b.isInstanceOf(D)); // false
7078 // | console.log(c.isInstanceOf(D)); // false
7079 // | console.log(d.isInstanceOf(D)); // true
7080 return {}; // Object
7081 }
7082 =====*/
7083
7084 /*=====
7085 Object.extend = function(source){
7086 // summary:
7087 // Adds all properties and methods of source to constructor's
7088 // prototype, making them available to all instances created with
7089 // constructor. This method is specific to constructors created with
7090 // dojo.declare.
7091 // source: Object
7092 // Source object which properties are going to be copied to the
7093 // constructor's prototype.
7094 // description:
7095 // Adds source properties to the constructor's prototype. It can
7096 // override existing properties.
2f01fe57 7097 //
1354d172
AD
7098 // This method is similar to dojo.extend function, but it is specific
7099 // to constructors produced by dojo.declare. It is implemented
7100 // using dojo.safeMixin, and it skips a constructor property,
7101 // and properly decorates copied functions.
2f01fe57
AD
7102 //
7103 // example:
1354d172
AD
7104 // | var A = dojo.declare(null, {
7105 // | m1: function(){},
7106 // | s1: "Popokatepetl"
7107 // | });
7108 // | A.extend({
7109 // | m1: function(){},
7110 // | m2: function(){},
7111 // | f1: true,
7112 // | d1: 42
2f01fe57 7113 // | });
81bea17a 7114 };
1354d172 7115 =====*/
2f01fe57 7116
1354d172
AD
7117 dojo.safeMixin = declare.safeMixin = safeMixin;
7118 dojo.declare = declare;
2f01fe57 7119
1354d172
AD
7120 return declare;
7121});
2f01fe57 7122
1354d172
AD
7123},
7124'dojo/dom':function(){
7125define(["./_base/sniff", "./_base/lang", "./_base/window"],
7126 function(has, lang, win){
7127 // module:
7128 // dojo/dom
7129 // summary:
7130 // This module defines the core dojo DOM API.
7131
7132 // FIXME: need to add unit tests for all the semi-public methods
7133
7134 try{
7135 document.execCommand("BackgroundImageCache", false, true);
7136 }catch(e){
7137 // sane browsers don't have cache "issues"
7138 }
7139
7140 // =============================
7141 // DOM Functions
7142 // =============================
7143
7144 /*=====
7145 dojo.byId = function(id, doc){
7146 // summary:
7147 // Returns DOM node with matching `id` attribute or `null`
7148 // if not found. If `id` is a DomNode, this function is a no-op.
2f01fe57 7149 //
1354d172
AD
7150 // id: String|DOMNode
7151 // A string to match an HTML id attribute or a reference to a DOM Node
2f01fe57 7152 //
1354d172
AD
7153 // doc: Document?
7154 // Document to work in. Defaults to the current value of
7155 // dojo.doc. Can be used to retrieve
7156 // node references from other documents.
2f01fe57
AD
7157 //
7158 // example:
1354d172
AD
7159 // Look up a node by ID:
7160 // | var n = dojo.byId("foo");
2f01fe57
AD
7161 //
7162 // example:
1354d172
AD
7163 // Check if a node exists, and use it.
7164 // | var n = dojo.byId("bar");
7165 // | if(n){ doStuff() ... }
2f01fe57
AD
7166 //
7167 // example:
1354d172
AD
7168 // Allow string or DomNode references to be passed to a custom function:
7169 // | var foo = function(nodeOrId){
7170 // | nodeOrId = dojo.byId(nodeOrId);
7171 // | // ... more stuff
7172 // | }
7173 =====*/
7174
7175 /*=====
7176 dojo.isDescendant = function(node, ancestor){
7177 // summary:
7178 // Returns true if node is a descendant of ancestor
7179 // node: DOMNode|String
7180 // string id or node reference to test
7181 // ancestor: DOMNode|String
7182 // string id or node reference of potential parent to test against
2f01fe57
AD
7183 //
7184 // example:
1354d172
AD
7185 // Test is node id="bar" is a descendant of node id="foo"
7186 // | if(dojo.isDescendant("bar", "foo")){ ... }
81bea17a 7187 };
2f01fe57
AD
7188 =====*/
7189
1354d172 7190 // TODO: do we need this function in the base?
2f01fe57
AD
7191
7192 /*=====
1354d172
AD
7193 dojo.setSelectable = function(node, selectable){
7194 // summary:
7195 // Enable or disable selection on a node
7196 // node: DOMNode|String
7197 // id or reference to node
7198 // selectable: Boolean
7199 // state to put the node in. false indicates unselectable, true
7200 // allows selection.
7201 // example:
7202 // Make the node id="bar" unselectable
7203 // | dojo.setSelectable("bar");
7204 // example:
7205 // Make the node id="bar" selectable
7206 // | dojo.setSelectable("bar", true);
7207 };
7208 =====*/
2f01fe57 7209
1354d172 7210 var dom = {}; // the result object
2f01fe57 7211
1354d172
AD
7212 if(has("ie")){
7213 dom.byId = function(id, doc){
7214 if(typeof id != "string"){
7215 return id;
7216 }
7217 var _d = doc || win.doc, te = id && _d.getElementById(id);
7218 // attributes.id.value is better than just id in case the
7219 // user has a name=id inside a form
7220 if(te && (te.attributes.id.value == id || te.id == id)){
7221 return te;
7222 }else{
7223 var eles = _d.all[id];
7224 if(!eles || eles.nodeName){
7225 eles = [eles];
7226 }
7227 // if more than 1, choose first with the correct id
7228 var i = 0;
7229 while((te = eles[i++])){
7230 if((te.attributes && te.attributes.id && te.attributes.id.value == id) || te.id == id){
7231 return te;
7232 }
7233 }
7234 }
7235 };
7236 }else{
7237 dom.byId = function(id, doc){
7238 // inline'd type check.
7239 // be sure to return null per documentation, to match IE branch.
7240 return ((typeof id == "string") ? (doc || win.doc).getElementById(id) : id) || null; // DOMNode
7241 };
2f01fe57 7242 }
1354d172
AD
7243 /*=====
7244 };
7245 =====*/
2f01fe57 7246
1354d172
AD
7247 dom.isDescendant = function(/*DOMNode|String*/node, /*DOMNode|String*/ancestor){
7248 try{
7249 node = dom.byId(node);
7250 ancestor = dom.byId(ancestor);
7251 while(node){
7252 if(node == ancestor){
7253 return true; // Boolean
7254 }
7255 node = node.parentNode;
2f01fe57 7256 }
1354d172
AD
7257 }catch(e){ /* squelch, return false */ }
7258 return false; // Boolean
7259 };
2f01fe57 7260
1354d172 7261 // TODO: do we need this function in the base?
2f01fe57 7262
1354d172
AD
7263 dom.setSelectable = function(/*DOMNode|String*/node, /*Boolean*/selectable){
7264 node = dom.byId(node);
7265 if(has("mozilla")){
7266 node.style.MozUserSelect = selectable ? "" : "none";
7267 }else if(has("khtml") || has("webkit")){
7268 node.style.KhtmlUserSelect = selectable ? "auto" : "none";
7269 }else if(has("ie")){
7270 var v = (node.unselectable = selectable ? "" : "on"),
7271 cs = node.getElementsByTagName("*"), i = 0, l = cs.length;
7272 for(; i < l; ++i){
7273 cs.item(i).unselectable = v;
7274 }
2f01fe57 7275 }
1354d172 7276 //FIXME: else? Opera?
81bea17a 7277 };
2f01fe57 7278
1354d172
AD
7279 return dom;
7280});
7281
7282},
7283'dojo/_base/browser':function(){
7284if(require.has){
7285 require.has.add("config-selectorEngine", "acme");
7286}
7287define("dojo/_base/browser", [
7288 "../ready",
7289 "./kernel",
7290 "./connect", // until we decide if connect is going back into non-browser environments
7291 "./unload",
7292 "./window",
7293 "./event",
7294 "./html",
7295 "./NodeList",
7296 "../query",
7297 "./xhr",
7298 "./fx"], function(dojo) {
7299 // module:
7300 // dojo/_base/browser
7301 // summary:
7302 // This module causes the browser-only base modules to be loaded.
7303 return dojo;
7304});
7305
7306},
7307'dojo/dom-style':function(){
7308define(["./_base/sniff", "./dom"], function(has, dom){
7309 // module:
7310 // dojo/dom-style
7311 // summary:
7312 // This module defines the core dojo DOM style API.
7313
2f01fe57 7314 // =============================
1354d172 7315 // Style Functions
2f01fe57 7316 // =============================
2f01fe57 7317
1354d172
AD
7318 // getComputedStyle drives most of the style code.
7319 // Wherever possible, reuse the returned object.
7320 //
7321 // API functions below that need to access computed styles accept an
7322 // optional computedStyle parameter.
7323 // If this parameter is omitted, the functions will call getComputedStyle themselves.
7324 // This way, calling code can access computedStyle once, and then pass the reference to
7325 // multiple API functions.
7326
7327 /*=====
7328 dojo.getComputedStyle = function(node){
7329 // summary:
7330 // Returns a "computed style" object.
2f01fe57 7331 //
1354d172
AD
7332 // description:
7333 // Gets a "computed style" object which can be used to gather
7334 // information about the current state of the rendered node.
2f01fe57 7335 //
1354d172
AD
7336 // Note that this may behave differently on different browsers.
7337 // Values may have different formats and value encodings across
7338 // browsers.
2f01fe57 7339 //
1354d172
AD
7340 // Note also that this method is expensive. Wherever possible,
7341 // reuse the returned object.
7342 //
7343 // Use the dojo.style() method for more consistent (pixelized)
7344 // return values.
7345 //
7346 // node: DOMNode
7347 // A reference to a DOM node. Does NOT support taking an
7348 // ID string for speed reasons.
7349 // example:
7350 // | dojo.getComputedStyle(dojo.byId('foo')).borderWidth;
7351 //
7352 // example:
7353 // Reusing the returned object, avoiding multiple lookups:
7354 // | var cs = dojo.getComputedStyle(dojo.byId("someNode"));
7355 // | var w = cs.width, h = cs.height;
7356 return; // CSS2Properties
7357 }
7358 =====*/
2f01fe57 7359
1354d172
AD
7360 /*=====
7361 dojo.toPixelValue = function(node, value){
7362 // summary:
7363 // converts style value to pixels on IE or return a numeric value.
7364 // node: DOMNode
7365 // value: String
7366 // returns: Number
2f01fe57 7367 };
1354d172 7368 =====*/
2f01fe57 7369
1354d172
AD
7370 /*=====
7371 dojo._toPixelValue = function(node, value){
7372 // summary:
7373 // Existing alias for `dojo._toPixelValue`. Deprecated, will be removed in 2.0.
7374 };
7375 =====*/
2f01fe57 7376
1354d172
AD
7377 /*=====
7378 dojo.getStyle = function(node, name){
7379 // summary:
7380 // Accesses styles on a node.
7381 // description:
7382 // Getting the style value uses the computed style for the node, so the value
7383 // will be a calculated value, not just the immediate node.style value.
7384 // Also when getting values, use specific style names,
7385 // like "borderBottomWidth" instead of "border" since compound values like
7386 // "border" are not necessarily reflected as expected.
7387 // If you want to get node dimensions, use `dojo.marginBox()`,
7388 // `dojo.contentBox()` or `dojo.position()`.
7389 // node: DOMNode|String
7390 // id or reference to node to get style for
7391 // name: String?
7392 // the style property to get
7393 // example:
7394 // Passing only an ID or node returns the computed style object of
7395 // the node:
7396 // | dojo.getStyle("thinger");
7397 // example:
7398 // Passing a node and a style property returns the current
7399 // normalized, computed value for that property:
7400 // | dojo.getStyle("thinger", "opacity"); // 1 by default
7401 };
7402 =====*/
7403
7404 /*=====
7405 dojo.setStyle = function(node, name, value){
7406 // summary:
7407 // Sets styles on a node.
7408 // node: DOMNode|String
7409 // id or reference to node to set style for
7410 // name: String|Object
7411 // the style property to set in DOM-accessor format
7412 // ("borderWidth", not "border-width") or an object with key/value
7413 // pairs suitable for setting each property.
7414 // value: String?
7415 // If passed, sets value on the node for style, handling
7416 // cross-browser concerns. When setting a pixel value,
7417 // be sure to include "px" in the value. For instance, top: "200px".
7418 // Otherwise, in some cases, some browsers will not apply the style.
2f01fe57
AD
7419 //
7420 // example:
1354d172
AD
7421 // Passing a node, a style property, and a value changes the
7422 // current display of the node and returns the new computed value
7423 // | dojo.setStyle("thinger", "opacity", 0.5); // == 0.5
2f01fe57
AD
7424 //
7425 // example:
1354d172
AD
7426 // Passing a node, an object-style style property sets each of the values in turn and returns the computed style object of the node:
7427 // | dojo.setStyle("thinger", {
7428 // | "opacity": 0.5,
7429 // | "border": "3px solid black",
7430 // | "height": "300px"
7431 // | });
2f01fe57
AD
7432 //
7433 // example:
1354d172
AD
7434 // When the CSS style property is hyphenated, the JavaScript property is camelCased.
7435 // font-size becomes fontSize, and so on.
7436 // | dojo.setStyle("thinger",{
7437 // | fontSize:"14pt",
7438 // | letterSpacing:"1.2em"
7439 // | });
2f01fe57
AD
7440 //
7441 // example:
1354d172
AD
7442 // dojo.NodeList implements .style() using the same syntax, omitting the "node" parameter, calling
7443 // dojo.style() on every element of the list. See: `dojo.query()` and `dojo.NodeList()`
7444 // | dojo.query(".someClassName").style("visibility","hidden");
7445 // | // or
7446 // | dojo.query("#baz > div").style({
7447 // | opacity:0.75,
7448 // | fontSize:"13pt"
7449 // | });
7450 };
7451 =====*/
7452
7453 // Although we normally eschew argument validation at this
7454 // level, here we test argument 'node' for (duck)type,
7455 // by testing nodeType, ecause 'document' is the 'parentNode' of 'body'
7456 // it is frequently sent to this function even
7457 // though it is not Element.
7458 var getComputedStyle, style = {};
7459 if(has("webkit")){
7460 getComputedStyle = function(/*DomNode*/node){
7461 var s;
7462 if(node.nodeType == 1){
7463 var dv = node.ownerDocument.defaultView;
7464 s = dv.getComputedStyle(node, null);
7465 if(!s && node.style){
7466 node.style.display = "";
7467 s = dv.getComputedStyle(node, null);
7468 }
7469 }
7470 return s || {};
7471 };
7472 }else if(has("ie") && (has("ie") < 9 || has("quirks"))){
7473 getComputedStyle = function(node){
7474 // IE (as of 7) doesn't expose Element like sane browsers
7475 return node.nodeType == 1 /* ELEMENT_NODE*/ ? node.currentStyle : {};
7476 };
7477 }else{
7478 getComputedStyle = function(node){
7479 return node.nodeType == 1 ?
7480 node.ownerDocument.defaultView.getComputedStyle(node, null) : {};
7481 };
7482 }
7483 style.getComputedStyle = getComputedStyle;
7484
7485 var toPixel;
7486 if(!has("ie")){
7487 toPixel = function(element, value){
7488 // style values can be floats, client code may want
7489 // to round for integer pixels.
7490 return parseFloat(value) || 0;
7491 };
7492 }else{
7493 toPixel = function(element, avalue){
7494 if(!avalue){ return 0; }
7495 // on IE7, medium is usually 4 pixels
7496 if(avalue == "medium"){ return 4; }
7497 // style values can be floats, client code may
7498 // want to round this value for integer pixels.
7499 if(avalue.slice && avalue.slice(-2) == 'px'){ return parseFloat(avalue); }
7500 var s = element.style, rs = element.runtimeStyle, cs = element.currentStyle,
7501 sLeft = s.left, rsLeft = rs.left;
7502 rs.left = cs.left;
7503 try{
7504 // 'avalue' may be incompatible with style.left, which can cause IE to throw
7505 // this has been observed for border widths using "thin", "medium", "thick" constants
7506 // those particular constants could be trapped by a lookup
7507 // but perhaps there are more
7508 s.left = avalue;
7509 avalue = s.pixelLeft;
7510 }catch(e){
7511 avalue = 0;
7512 }
7513 s.left = sLeft;
7514 rs.left = rsLeft;
7515 return avalue;
7516 }
7517 }
7518 style.toPixelValue = toPixel;
7519
7520 // FIXME: there opacity quirks on FF that we haven't ported over. Hrm.
7521
7522 var astr = "DXImageTransform.Microsoft.Alpha";
7523 var af = function(n, f){
7524 try{
7525 return n.filters.item(astr);
7526 }catch(e){
7527 return f ? {} : null;
7528 }
7529 };
7530
7531 var _getOpacity =
7532 has("ie") < 9 || (has("ie") && has("quirks")) ? function(node){
7533 try{
7534 return af(node).Opacity / 100; // Number
7535 }catch(e){
7536 return 1; // Number
7537 }
7538 } :
7539 function(node){
7540 return getComputedStyle(node).opacity;
7541 };
7542
7543 var _setOpacity =
7544 has("ie") < 9 || (has("ie") && has("quirks")) ? function(/*DomNode*/node, /*Number*/opacity){
7545 var ov = opacity * 100, opaque = opacity == 1;
7546 node.style.zoom = opaque ? "" : 1;
7547
7548 if(!af(node)){
7549 if(opaque){
7550 return opacity;
7551 }
7552 node.style.filter += " progid:" + astr + "(Opacity=" + ov + ")";
7553 }else{
7554 af(node, 1).Opacity = ov;
7555 }
7556
7557 // on IE7 Alpha(Filter opacity=100) makes text look fuzzy so disable it altogether (bug #2661),
7558 //but still update the opacity value so we can get a correct reading if it is read later.
7559 af(node, 1).Enabled = !opaque;
7560
7561 if(node.tagName.toLowerCase() == "tr"){
7562 for(var td = node.firstChild; td; td = td.nextSibling){
7563 if(td.tagName.toLowerCase() == "td"){
7564 _setOpacity(td, opacity);
7565 }
7566 }
7567 }
7568 return opacity;
7569 } :
7570 function(node, opacity){
7571 return node.style.opacity = opacity;
7572 };
2f01fe57 7573
1354d172
AD
7574 var _pixelNamesCache = {
7575 left: true, top: true
7576 };
7577 var _pixelRegExp = /margin|padding|width|height|max|min|offset/; // |border
7578 function _toStyleValue(node, type, value){
7579 //TODO: should we really be doing string case conversion here? Should we cache it? Need to profile!
7580 type = type.toLowerCase();
7581 if(has("ie")){
7582 if(value == "auto"){
7583 if(type == "height"){ return node.offsetHeight; }
7584 if(type == "width"){ return node.offsetWidth; }
7585 }
7586 if(type == "fontweight"){
7587 switch(value){
7588 case 700: return "bold";
7589 case 400:
7590 default: return "normal";
7591 }
2f01fe57
AD
7592 }
7593 }
1354d172
AD
7594 if(!(type in _pixelNamesCache)){
7595 _pixelNamesCache[type] = _pixelRegExp.test(type);
2f01fe57 7596 }
1354d172
AD
7597 return _pixelNamesCache[type] ? toPixel(node, value) : value;
7598 }
2f01fe57 7599
1354d172
AD
7600 var _floatStyle = has("ie") ? "styleFloat" : "cssFloat",
7601 _floatAliases = {"cssFloat": _floatStyle, "styleFloat": _floatStyle, "float": _floatStyle};
2f01fe57 7602
1354d172
AD
7603 // public API
7604
7605 style.get = function getStyle(/*DOMNode|String*/ node, /*String?*/ name){
7606 var n = dom.byId(node), l = arguments.length, op = (name == "opacity");
7607 if(l == 2 && op){
7608 return _getOpacity(n);
2f01fe57 7609 }
1354d172
AD
7610 name = _floatAliases[name] || name;
7611 var s = style.getComputedStyle(n);
7612 return (l == 1) ? s : _toStyleValue(n, name, s[name] || n.style[name]); /* CSS2Properties||String||Number */
2f01fe57
AD
7613 };
7614
1354d172
AD
7615 style.set = function setStyle(/*DOMNode|String*/ node, /*String|Object*/ name, /*String?*/ value){
7616 var n = dom.byId(node), l = arguments.length, op = (name == "opacity");
7617 name = _floatAliases[name] || name;
7618 if(l == 3){
7619 return op ? _setOpacity(n, value) : n.style[name] = value; // Number
81bea17a 7620 }
1354d172
AD
7621 for(var x in name){
7622 style.set(node, x, name[x]);
7623 }
7624 return style.getComputedStyle(n);
81bea17a
AD
7625 };
7626
1354d172
AD
7627 return style;
7628});
2f01fe57 7629
1354d172
AD
7630},
7631'dojo/dom-geometry':function(){
7632define(["./_base/sniff", "./_base/window","./dom", "./dom-style"],
7633 function(has, win, dom, style){
7634 // module:
7635 // dojo/dom-geometry
7636 // summary:
7637 // This module defines the core dojo DOM geometry API.
2f01fe57 7638
1354d172 7639 var geom = {}; // the result object
2f01fe57 7640
1354d172
AD
7641 // Box functions will assume this model.
7642 // On IE/Opera, BORDER_BOX will be set if the primary document is in quirks mode.
7643 // Can be set to change behavior of box setters.
7644
7645 // can be either:
7646 // "border-box"
7647 // "content-box" (default)
7648 geom.boxModel = "content-box";
7649
7650 // We punt per-node box mode testing completely.
7651 // If anybody cares, we can provide an additional (optional) unit
7652 // that overrides existing code to include per-node box sensitivity.
2f01fe57 7653
1354d172
AD
7654 // Opera documentation claims that Opera 9 uses border-box in BackCompat mode.
7655 // but experiments (Opera 9.10.8679 on Windows Vista) indicate that it actually continues to use content-box.
7656 // IIRC, earlier versions of Opera did in fact use border-box.
7657 // Opera guys, this is really confusing. Opera being broken in quirks mode is not our fault.
2f01fe57 7658
1354d172
AD
7659 if(has("ie") /*|| has("opera")*/){
7660 // client code may have to adjust if compatMode varies across iframes
7661 geom.boxModel = document.compatMode == "BackCompat" ? "border-box" : "content-box";
7662 }
7663
7664 // =============================
7665 // Box Functions
7666 // =============================
2f01fe57 7667
1354d172
AD
7668 /*=====
7669 dojo.getPadExtents = function(node, computedStyle){
7670 // summary:
7671 // Returns object with special values specifically useful for node
7672 // fitting.
7673 // description:
7674 // Returns an object with `w`, `h`, `l`, `t` properties:
7675 // | l/t/r/b = left/top/right/bottom padding (respectively)
7676 // | w = the total of the left and right padding
7677 // | h = the total of the top and bottom padding
7678 // If 'node' has position, l/t forms the origin for child nodes.
7679 // The w/h are used for calculating boxes.
7680 // Normally application code will not need to invoke this
7681 // directly, and will use the ...box... functions instead.
7682 // node: DOMNode
7683 // computedStyle: Object?
7684 // This parameter accepts computed styles object.
7685 // If this parameter is omitted, the functions will call
7686 // dojo.getComputedStyle to get one. It is a better way, calling
7687 // dojo.computedStyle once, and then pass the reference to this
7688 // computedStyle parameter. Wherever possible, reuse the returned
7689 // object of dojo.getComputedStyle.
2f01fe57 7690
81bea17a 7691
1354d172
AD
7692 };
7693 =====*/
81bea17a 7694
1354d172
AD
7695 /*=====
7696 dojo._getPadExtents = function(node, computedStyle){
7697 // summary:
7698 // Existing alias for `dojo.getPadExtents`. Deprecated, will be removed in 2.0.
7699 };
7700 =====*/
81bea17a 7701
1354d172
AD
7702 /*=====
7703 dojo.getBorderExtents = function(node, computedStyle){
7704 // summary:
7705 // returns an object with properties useful for noting the border
7706 // dimensions.
7707 // description:
7708 // * l/t/r/b = the sum of left/top/right/bottom border (respectively)
7709 // * w = the sum of the left and right border
7710 // * h = the sum of the top and bottom border
7711 //
7712 // The w/h are used for calculating boxes.
7713 // Normally application code will not need to invoke this
7714 // directly, and will use the ...box... functions instead.
7715 // node: DOMNode
7716 // computedStyle: Object?
7717 // This parameter accepts computed styles object.
7718 // If this parameter is omitted, the functions will call
7719 // dojo.getComputedStyle to get one. It is a better way, calling
7720 // dojo.computedStyle once, and then pass the reference to this
7721 // computedStyle parameter. Wherever possible, reuse the returned
7722 // object of dojo.getComputedStyle.
2f01fe57 7723
2f01fe57 7724
1354d172
AD
7725 };
7726 =====*/
2f01fe57 7727
1354d172
AD
7728 /*=====
7729 dojo._getBorderExtents = function(node, computedStyle){
2f01fe57 7730 // summary:
1354d172 7731 // Existing alias for `dojo.getBorderExtents`. Deprecated, will be removed in 2.0.
2f01fe57 7732 };
1354d172
AD
7733 =====*/
7734
7735 /*=====
7736 dojo.getPadBorderExtents = function(node, computedStyle){
7737 // summary:
7738 // Returns object with properties useful for box fitting with
7739 // regards to padding.
7740 // description:
7741 // * l/t/r/b = the sum of left/top/right/bottom padding and left/top/right/bottom border (respectively)
7742 // * w = the sum of the left and right padding and border
7743 // * h = the sum of the top and bottom padding and border
7744 //
7745 // The w/h are used for calculating boxes.
7746 // Normally application code will not need to invoke this
7747 // directly, and will use the ...box... functions instead.
7748 // node: DOMNode
7749 // computedStyle: Object?
7750 // This parameter accepts computed styles object.
7751 // If this parameter is omitted, the functions will call
7752 // dojo.getComputedStyle to get one. It is a better way, calling
7753 // dojo.computedStyle once, and then pass the reference to this
7754 // computedStyle parameter. Wherever possible, reuse the returned
7755 // object of dojo.getComputedStyle.
7756
2f01fe57 7757
2f01fe57 7758 };
1354d172 7759 =====*/
2f01fe57 7760
1354d172
AD
7761 /*=====
7762 dojo._getPadBorderExtents = function(node, computedStyle){
7763 // summary:
7764 // Existing alias for `dojo.getPadBorderExtents`. Deprecated, will be removed in 2.0.
7765 };
7766 =====*/
2f01fe57 7767
1354d172
AD
7768 /*=====
7769 dojo.getMarginExtents = function(node, computedStyle){
7770 // summary:
7771 // returns object with properties useful for box fitting with
7772 // regards to box margins (i.e., the outer-box).
7773 //
7774 // * l/t = marginLeft, marginTop, respectively
7775 // * w = total width, margin inclusive
7776 // * h = total height, margin inclusive
7777 //
7778 // The w/h are used for calculating boxes.
7779 // Normally application code will not need to invoke this
7780 // directly, and will use the ...box... functions instead.
7781 // node: DOMNode
7782 // computedStyle: Object?
7783 // This parameter accepts computed styles object.
7784 // If this parameter is omitted, the functions will call
7785 // dojo.getComputedStyle to get one. It is a better way, calling
7786 // dojo.computedStyle once, and then pass the reference to this
7787 // computedStyle parameter. Wherever possible, reuse the returned
7788 // object of dojo.getComputedStyle.
2f01fe57 7789 };
1354d172 7790 =====*/
2f01fe57 7791
1354d172
AD
7792 /*=====
7793 dojo._getMarginExtents = function(node, computedStyle){
7794 // summary:
7795 // Existing alias for `dojo.getMarginExtents`. Deprecated, will be removed in 2.0.
2f01fe57 7796 };
1354d172 7797 =====*/
2f01fe57 7798
1354d172
AD
7799 /*=====
7800 dojo.getMarginSize = function(node, computedStyle){
7801 // summary:
7802 // returns an object that encodes the width and height of
7803 // the node's margin box
7804 // node: DOMNode|String
7805 // computedStyle: Object?
7806 // This parameter accepts computed styles object.
7807 // If this parameter is omitted, the functions will call
7808 // dojo.getComputedStyle to get one. It is a better way, calling
7809 // dojo.computedStyle once, and then pass the reference to this
7810 // computedStyle parameter. Wherever possible, reuse the returned
7811 // object of dojo.getComputedStyle.
2f01fe57 7812 };
1354d172 7813 =====*/
2f01fe57 7814
1354d172
AD
7815 /*=====
7816 dojo._getMarginSize = function(node, computedStyle){
7817 // summary:
7818 // Existing alias for `dojo.getMarginSize`. Deprecated, will be removed in 2.0.
2f01fe57 7819 };
1354d172 7820 =====*/
2f01fe57 7821
1354d172
AD
7822 /*=====
7823 dojo.getMarginBox = function(node, computedStyle){
7824 // summary:
7825 // returns an object that encodes the width, height, left and top
7826 // positions of the node's margin box.
7827 // node: DOMNode
7828 // computedStyle: Object?
7829 // This parameter accepts computed styles object.
7830 // If this parameter is omitted, the functions will call
7831 // dojo.getComputedStyle to get one. It is a better way, calling
7832 // dojo.computedStyle once, and then pass the reference to this
7833 // computedStyle parameter. Wherever possible, reuse the returned
7834 // object of dojo.getComputedStyle.
2f01fe57 7835 };
1354d172 7836 =====*/
2f01fe57 7837
1354d172
AD
7838 /*=====
7839 dojo._getMarginBox = function(node, computedStyle){
7840 // summary:
7841 // Existing alias for `dojo.getMarginBox`. Deprecated, will be removed in 2.0.
2f01fe57 7842 };
1354d172 7843 =====*/
2f01fe57 7844
1354d172
AD
7845 /*=====
7846 dojo.setMarginBox = function(node, box, computedStyle){
7847 // summary:
7848 // sets the size of the node's margin box and placement
7849 // (left/top), irrespective of box model. Think of it as a
7850 // passthrough to setBox that handles box-model vagaries for
7851 // you.
7852 // node: DOMNode
7853 // box: Object
7854 // hash with optional "l", "t", "w", and "h" properties for "left", "right", "width", and "height"
7855 // respectively. All specified properties should have numeric values in whole pixels.
7856 // computedStyle: Object?
7857 // This parameter accepts computed styles object.
7858 // If this parameter is omitted, the functions will call
7859 // dojo.getComputedStyle to get one. It is a better way, calling
7860 // dojo.computedStyle once, and then pass the reference to this
7861 // computedStyle parameter. Wherever possible, reuse the returned
7862 // object of dojo.getComputedStyle.
2f01fe57 7863 };
1354d172 7864 =====*/
2f01fe57 7865
1354d172
AD
7866 /*=====
7867 dojo.getContentBox = function(node, computedStyle){
7868 // summary:
7869 // Returns an object that encodes the width, height, left and top
7870 // positions of the node's content box, irrespective of the
7871 // current box model.
7872 // node: DOMNode
7873 // computedStyle: Object?
7874 // This parameter accepts computed styles object.
7875 // If this parameter is omitted, the functions will call
7876 // dojo.getComputedStyle to get one. It is a better way, calling
7877 // dojo.computedStyle once, and then pass the reference to this
7878 // computedStyle parameter. Wherever possible, reuse the returned
7879 // object of dojo.getComputedStyle.
7880 };
7881 =====*/
2f01fe57 7882
1354d172
AD
7883 /*=====
7884 dojo._getContentBox = function(node, computedStyle){
7885 // summary:
7886 // Existing alias for `dojo.getContentBox`. Deprecated, will be removed in 2.0.
7887 };
7888 =====*/
2f01fe57 7889
1354d172
AD
7890 /*=====
7891 dojo.setContentSize = function(node, box, computedStyle){
7892 // summary:
7893 // Sets the size of the node's contents, irrespective of margins,
7894 // padding, or borders.
7895 // node: DOMNode
7896 // box: Object
7897 // hash with optional "w", and "h" properties for "width", and "height"
7898 // respectively. All specified properties should have numeric values in whole pixels.
7899 // computedStyle: Object?
7900 // This parameter accepts computed styles object.
7901 // If this parameter is omitted, the functions will call
7902 // dojo.getComputedStyle to get one. It is a better way, calling
7903 // dojo.computedStyle once, and then pass the reference to this
7904 // computedStyle parameter. Wherever possible, reuse the returned
7905 // object of dojo.getComputedStyle.
7906 };
7907 =====*/
2f01fe57 7908
1354d172
AD
7909 /*=====
7910 dojo.isBodyLtr = function(){
7911 // summary:
7912 // Returns true if the current language is left-to-right, and false otherwise.
7913 // returns: Boolean
7914 };
7915 =====*/
2f01fe57 7916
1354d172
AD
7917 /*=====
7918 dojo._isBodyLtr = function(){
7919 // summary:
7920 // Existing alias for `dojo.isBodyLtr`. Deprecated, will be removed in 2.0.
7921 };
7922 =====*/
2f01fe57 7923
1354d172
AD
7924 /*=====
7925 dojo.docScroll = function(){
7926 // summary:
7927 // Returns an object with {node, x, y} with corresponding offsets.
7928 // returns: Object
7929 };
7930 =====*/
2f01fe57 7931
1354d172
AD
7932 /*=====
7933 dojo._docScroll = function(){
7934 // summary:
7935 // Existing alias for `dojo.docScroll`. Deprecated, will be removed in 2.0.
7936 };
7937 =====*/
2f01fe57 7938
1354d172
AD
7939 /*=====
7940 dojo.getIeDocumentElementOffset = function(){
7941 // summary:
7942 // returns the offset in x and y from the document body to the
7943 // visual edge of the page for IE
7944 // description:
7945 // The following values in IE contain an offset:
7946 // | event.clientX
7947 // | event.clientY
7948 // | node.getBoundingClientRect().left
7949 // | node.getBoundingClientRect().top
7950 // But other position related values do not contain this offset,
7951 // such as node.offsetLeft, node.offsetTop, node.style.left and
7952 // node.style.top. The offset is always (2, 2) in LTR direction.
7953 // When the body is in RTL direction, the offset counts the width
7954 // of left scroll bar's width. This function computes the actual
7955 // offset.
7956 };
7957 =====*/
2f01fe57 7958
1354d172
AD
7959 /*=====
7960 dojo._getIeDocumentElementOffset = function(){
7961 // summary:
7962 // Existing alias for `dojo.getIeDocumentElementOffset`. Deprecated, will be removed in 2.0.
7963 };
7964 =====*/
2f01fe57 7965
1354d172
AD
7966 /*=====
7967 dojo.fixIeBiDiScrollLeft = function(scrollLeft){
7968 // summary:
7969 // In RTL direction, scrollLeft should be a negative value, but IE
7970 // returns a positive one. All codes using documentElement.scrollLeft
7971 // must call this function to fix this error, otherwise the position
7972 // will offset to right when there is a horizontal scrollbar.
7973 // scrollLeft: NUmber
7974 // returns: Number
7975 };
7976 =====*/
2f01fe57 7977
1354d172
AD
7978 /*=====
7979 dojo._fixIeBiDiScrollLeft = function(scrollLeft){
7980 // summary:
7981 // Existing alias for `dojo.fixIeBiDiScrollLeft`. Deprecated, will be removed in 2.0.
7982 };
7983 =====*/
2f01fe57 7984
1354d172
AD
7985 /*=====
7986 dojo.position = function(node, includeScroll){
7987 // summary:
7988 // Gets the position and size of the passed element relative to
7989 // the viewport (if includeScroll==false), or relative to the
7990 // document root (if includeScroll==true).
7991 //
7992 // description:
7993 // Returns an object of the form:
7994 // { x: 100, y: 300, w: 20, h: 15 }
7995 // If includeScroll==true, the x and y values will include any
7996 // document offsets that may affect the position relative to the
7997 // viewport.
7998 // Uses the border-box model (inclusive of border and padding but
7999 // not margin). Does not act as a setter.
8000 // node: DOMNode|String
8001 // includeScroll: Boolean?
8002 // returns: Object
8003 };
8004 =====*/
2f01fe57 8005
1354d172
AD
8006 geom.getPadExtents = function getPadExtents(/*DomNode*/node, /*Object*/computedStyle){
8007 node = dom.byId(node);
8008 var s = computedStyle || style.getComputedStyle(node), px = style.toPixelValue,
8009 l = px(node, s.paddingLeft), t = px(node, s.paddingTop), r = px(node, s.paddingRight), b = px(node, s.paddingBottom);
8010 return {l: l, t: t, r: r, b: b, w: l + r, h: t + b};
8011 };
2f01fe57 8012
1354d172 8013 var none = "none";
2f01fe57 8014
1354d172
AD
8015 geom.getBorderExtents = function getBorderExtents(/*DomNode*/node, /*Object*/computedStyle){
8016 node = dom.byId(node);
8017 var px = style.toPixelValue, s = computedStyle || style.getComputedStyle(node),
8018 l = s.borderLeftStyle != none ? px(node, s.borderLeftWidth) : 0,
8019 t = s.borderTopStyle != none ? px(node, s.borderTopWidth) : 0,
8020 r = s.borderRightStyle != none ? px(node, s.borderRightWidth) : 0,
8021 b = s.borderBottomStyle != none ? px(node, s.borderBottomWidth) : 0;
8022 return {l: l, t: t, r: r, b: b, w: l + r, h: t + b};
8023 };
2f01fe57 8024
1354d172
AD
8025 geom.getPadBorderExtents = function getPadBorderExtents(/*DomNode*/node, /*Object*/computedStyle){
8026 node = dom.byId(node);
8027 var s = computedStyle || style.getComputedStyle(node),
8028 p = geom.getPadExtents(node, s),
8029 b = geom.getBorderExtents(node, s);
8030 return {
8031 l: p.l + b.l,
8032 t: p.t + b.t,
8033 r: p.r + b.r,
8034 b: p.b + b.b,
8035 w: p.w + b.w,
8036 h: p.h + b.h
8037 };
8038 };
2f01fe57 8039
1354d172
AD
8040 geom.getMarginExtents = function getMarginExtents(node, computedStyle){
8041 node = dom.byId(node);
8042 var s = computedStyle || style.getComputedStyle(node), px = style.toPixelValue,
8043 l = px(node, s.marginLeft), t = px(node, s.marginTop), r = px(node, s.marginRight), b = px(node, s.marginBottom);
8044 if(has("webkit") && (s.position != "absolute")){
8045 // FIXME: Safari's version of the computed right margin
8046 // is the space between our right edge and the right edge
8047 // of our offsetParent.
8048 // What we are looking for is the actual margin value as
8049 // determined by CSS.
8050 // Hack solution is to assume left/right margins are the same.
8051 r = l;
8052 }
8053 return {l: l, t: t, r: r, b: b, w: l + r, h: t + b};
8054 };
2f01fe57 8055
1354d172
AD
8056 // Box getters work in any box context because offsetWidth/clientWidth
8057 // are invariant wrt box context
8058 //
8059 // They do *not* work for display: inline objects that have padding styles
8060 // because the user agent ignores padding (it's bogus styling in any case)
8061 //
8062 // Be careful with IMGs because they are inline or block depending on
8063 // browser and browser mode.
2f01fe57 8064
1354d172
AD
8065 // Although it would be easier to read, there are not separate versions of
8066 // _getMarginBox for each browser because:
8067 // 1. the branching is not expensive
8068 // 2. factoring the shared code wastes cycles (function call overhead)
8069 // 3. duplicating the shared code wastes bytes
2f01fe57 8070
1354d172
AD
8071 geom.getMarginBox = function getMarginBox(/*DomNode*/node, /*Object*/computedStyle){
8072 // summary:
8073 // returns an object that encodes the width, height, left and top
8074 // positions of the node's margin box.
8075 node = dom.byId(node);
8076 var s = computedStyle || style.getComputedStyle(node), me = geom.getMarginExtents(node, s),
8077 l = node.offsetLeft - me.l, t = node.offsetTop - me.t, p = node.parentNode, px = style.toPixelValue, pcs;
8078 if(has("mozilla")){
8079 // Mozilla:
8080 // If offsetParent has a computed overflow != visible, the offsetLeft is decreased
8081 // by the parent's border.
8082 // We don't want to compute the parent's style, so instead we examine node's
8083 // computed left/top which is more stable.
8084 var sl = parseFloat(s.left), st = parseFloat(s.top);
8085 if(!isNaN(sl) && !isNaN(st)){
8086 l = sl, t = st;
8087 }else{
8088 // If child's computed left/top are not parseable as a number (e.g. "auto"), we
8089 // have no choice but to examine the parent's computed style.
8090 if(p && p.style){
8091 pcs = style.getComputedStyle(p);
8092 if(pcs.overflow != "visible"){
8093 l += pcs.borderLeftStyle != none ? px(node, pcs.borderLeftWidth) : 0;
8094 t += pcs.borderTopStyle != none ? px(node, pcs.borderTopWidth) : 0;
2f01fe57
AD
8095 }
8096 }
2f01fe57 8097 }
1354d172
AD
8098 }else if(has("opera") || (has("ie") == 8 && !has("quirks"))){
8099 // On Opera and IE 8, offsetLeft/Top includes the parent's border
8100 if(p){
8101 pcs = style.getComputedStyle(p);
8102 l -= pcs.borderLeftStyle != none ? px(node, pcs.borderLeftWidth) : 0;
8103 t -= pcs.borderTopStyle != none ? px(node, pcs.borderTopWidth) : 0;
2f01fe57 8104 }
1354d172
AD
8105 }
8106 return {l: l, t: t, w: node.offsetWidth + me.w, h: node.offsetHeight + me.h};
8107 };
2f01fe57 8108
1354d172
AD
8109 geom.getContentBox = function getContentBox(node, computedStyle){
8110 // clientWidth/Height are important since the automatically account for scrollbars
8111 // fallback to offsetWidth/Height for special cases (see #3378)
8112 node = dom.byId(node);
8113 var s = computedStyle || style.getComputedStyle(node), w = node.clientWidth, h,
8114 pe = geom.getPadExtents(node, s), be = geom.getBorderExtents(node, s);
8115 if(!w){
8116 w = node.offsetWidth;
8117 h = node.offsetHeight;
8118 }else{
8119 h = node.clientHeight;
8120 be.w = be.h = 0;
8121 }
8122 // On Opera, offsetLeft includes the parent's border
8123 if(has("opera")){
8124 pe.l += be.l;
8125 pe.t += be.t;
8126 }
8127 return {l: pe.l, t: pe.t, w: w - pe.w - be.w, h: h - pe.h - be.h};
8128 };
2f01fe57 8129
1354d172
AD
8130 // Box setters depend on box context because interpretation of width/height styles
8131 // vary wrt box context.
8132 //
8133 // The value of dojo.boxModel is used to determine box context.
8134 // dojo.boxModel can be set directly to change behavior.
8135 //
8136 // Beware of display: inline objects that have padding styles
8137 // because the user agent ignores padding (it's a bogus setup anyway)
8138 //
8139 // Be careful with IMGs because they are inline or block depending on
8140 // browser and browser mode.
8141 //
8142 // Elements other than DIV may have special quirks, like built-in
8143 // margins or padding, or values not detectable via computedStyle.
8144 // In particular, margins on TABLE do not seems to appear
8145 // at all in computedStyle on Mozilla.
2f01fe57 8146
1354d172
AD
8147 function setBox(/*DomNode*/node, /*Number?*/l, /*Number?*/t, /*Number?*/w, /*Number?*/h, /*String?*/u){
8148 // summary:
8149 // sets width/height/left/top in the current (native) box-model
8150 // dimensions. Uses the unit passed in u.
8151 // node:
8152 // DOM Node reference. Id string not supported for performance
8153 // reasons.
8154 // l:
8155 // left offset from parent.
8156 // t:
8157 // top offset from parent.
8158 // w:
8159 // width in current box model.
8160 // h:
8161 // width in current box model.
8162 // u:
8163 // unit measure to use for other measures. Defaults to "px".
8164 u = u || "px";
8165 var s = node.style;
8166 if(!isNaN(l)){
8167 s.left = l + u;
8168 }
8169 if(!isNaN(t)){
8170 s.top = t + u;
8171 }
8172 if(w >= 0){
8173 s.width = w + u;
8174 }
8175 if(h >= 0){
8176 s.height = h + u;
8177 }
8178 }
2f01fe57 8179
1354d172
AD
8180 function isButtonTag(/*DomNode*/node){
8181 // summary:
8182 // True if the node is BUTTON or INPUT.type="button".
8183 return node.tagName.toLowerCase() == "button" ||
8184 node.tagName.toLowerCase() == "input" && (node.getAttribute("type") || "").toLowerCase() == "button"; // boolean
8185 }
2f01fe57 8186
1354d172
AD
8187 function usesBorderBox(/*DomNode*/node){
8188 // summary:
8189 // True if the node uses border-box layout.
2f01fe57 8190
1354d172
AD
8191 // We could test the computed style of node to see if a particular box
8192 // has been specified, but there are details and we choose not to bother.
2f01fe57 8193
1354d172
AD
8194 // TABLE and BUTTON (and INPUT type=button) are always border-box by default.
8195 // If you have assigned a different box to either one via CSS then
8196 // box functions will break.
2f01fe57 8197
1354d172
AD
8198 return geom.boxModel == "border-box" || node.tagName.toLowerCase() == "table" || isButtonTag(node); // boolean
8199 }
2f01fe57 8200
1354d172
AD
8201 geom.setContentSize = function setContentSize(/*DomNode*/node, /*Object*/box, /*Object*/computedStyle){
8202 // summary:
8203 // Sets the size of the node's contents, irrespective of margins,
8204 // padding, or borders.
2f01fe57 8205
1354d172
AD
8206 node = dom.byId(node);
8207 var w = box.w, h = box.h;
8208 if(usesBorderBox(node)){
8209 var pb = geom.getPadBorderExtents(node, computedStyle);
8210 if(w >= 0){
8211 w += pb.w;
8212 }
8213 if(h >= 0){
8214 h += pb.h;
8215 }
8216 }
8217 setBox(node, NaN, NaN, w, h);
8218 };
2f01fe57 8219
1354d172 8220 var nilExtents = {l: 0, t: 0, w: 0, h: 0};
2f01fe57 8221
1354d172
AD
8222 geom.setMarginBox = function setMarginBox(/*DomNode*/node, /*Object*/box, /*Object*/computedStyle){
8223 node = dom.byId(node);
8224 var s = computedStyle || style.getComputedStyle(node), w = box.w, h = box.h,
8225 // Some elements have special padding, margin, and box-model settings.
8226 // To use box functions you may need to set padding, margin explicitly.
8227 // Controlling box-model is harder, in a pinch you might set dojo.boxModel.
8228 pb = usesBorderBox(node) ? nilExtents : geom.getPadBorderExtents(node, s),
8229 mb = geom.getMarginExtents(node, s);
8230 if(has("webkit")){
8231 // on Safari (3.1.2), button nodes with no explicit size have a default margin
8232 // setting an explicit size eliminates the margin.
8233 // We have to swizzle the width to get correct margin reading.
8234 if(isButtonTag(node)){
8235 var ns = node.style;
8236 if(w >= 0 && !ns.width){
8237 ns.width = "4px";
8238 }
8239 if(h >= 0 && !ns.height){
8240 ns.height = "4px";
8241 }
8242 }
8243 }
8244 if(w >= 0){
8245 w = Math.max(w - pb.w - mb.w, 0);
8246 }
8247 if(h >= 0){
8248 h = Math.max(h - pb.h - mb.h, 0);
8249 }
8250 setBox(node, box.l, box.t, w, h);
8251 };
2f01fe57 8252
1354d172
AD
8253 // =============================
8254 // Positioning
8255 // =============================
2f01fe57 8256
1354d172
AD
8257 geom.isBodyLtr = function isBodyLtr(){
8258 return (win.body().dir || win.doc.documentElement.dir || "ltr").toLowerCase() == "ltr"; // Boolean
8259 };
2f01fe57 8260
1354d172
AD
8261 geom.docScroll = function docScroll(){
8262 var node = win.doc.parentWindow || win.doc.defaultView; // use UI window, not dojo.global window
8263 return "pageXOffset" in node ? {x: node.pageXOffset, y: node.pageYOffset } :
8264 (node = has("quirks") ? win.body() : win.doc.documentElement,
8265 {x: geom.fixIeBiDiScrollLeft(node.scrollLeft || 0), y: node.scrollTop || 0 });
8266 };
2f01fe57 8267
1354d172
AD
8268 geom.getIeDocumentElementOffset = function getIeDocumentElementOffset(){
8269 //NOTE: assumes we're being called in an IE browser
2f01fe57 8270
1354d172 8271 var de = win.doc.documentElement; // only deal with HTML element here, position() handles body/quirks
2f01fe57 8272
1354d172
AD
8273 if(has("ie") < 8){
8274 var r = de.getBoundingClientRect(), // works well for IE6+
8275 l = r.left, t = r.top;
8276 if(has("ie") < 7){
8277 l += de.clientLeft; // scrollbar size in strict/RTL, or,
8278 t += de.clientTop; // HTML border size in strict
8279 }
8280 return {
8281 x: l < 0 ? 0 : l, // FRAME element border size can lead to inaccurate negative values
8282 y: t < 0 ? 0 : t
8283 };
8284 }else{
8285 return {
8286 x: 0,
8287 y: 0
8288 };
8289 }
8290 };
8291
8292 geom.fixIeBiDiScrollLeft = function fixIeBiDiScrollLeft(/*Integer*/ scrollLeft){
8293 // In RTL direction, scrollLeft should be a negative value, but IE
8294 // returns a positive one. All codes using documentElement.scrollLeft
8295 // must call this function to fix this error, otherwise the position
8296 // will offset to right when there is a horizontal scrollbar.
2f01fe57 8297
1354d172
AD
8298 var ie = has("ie");
8299 if(ie && !geom.isBodyLtr()){
8300 var qk = has("quirks"),
8301 de = qk ? win.body() : win.doc.documentElement;
8302 if(ie == 6 && !qk && win.global.frameElement && de.scrollHeight > de.clientHeight){
8303 scrollLeft += de.clientLeft; // workaround ie6+strict+rtl+iframe+vertical-scrollbar bug where clientWidth is too small by clientLeft pixels
8304 }
8305 return (ie < 8 || qk) ? (scrollLeft + de.clientWidth - de.scrollWidth) : -scrollLeft; // Integer
8306 }
8307 return scrollLeft; // Integer
8308 };
2f01fe57 8309
1354d172
AD
8310 geom.position = function(/*DomNode*/node, /*Boolean?*/includeScroll){
8311 node = dom.byId(node);
8312 var db = win.body(),
8313 dh = db.parentNode,
8314 ret = node.getBoundingClientRect();
8315 ret = {x: ret.left, y: ret.top, w: ret.right - ret.left, h: ret.bottom - ret.top};
8316 if(has("ie")){
8317 // On IE there's a 2px offset that we need to adjust for, see dojo.getIeDocumentElementOffset()
8318 var offset = geom.getIeDocumentElementOffset();
8319
8320 // fixes the position in IE, quirks mode
8321 ret.x -= offset.x + (has("quirks") ? db.clientLeft + db.offsetLeft : 0);
8322 ret.y -= offset.y + (has("quirks") ? db.clientTop + db.offsetTop : 0);
8323 }else if(has("ff") == 3){
8324 // In FF3 you have to subtract the document element margins.
8325 // Fixed in FF3.5 though.
8326 var cs = style.getComputedStyle(dh), px = style.toPixelValue;
8327 ret.x -= px(dh, cs.marginLeft) + px(dh, cs.borderLeftWidth);
8328 ret.y -= px(dh, cs.marginTop) + px(dh, cs.borderTopWidth);
8329 }
8330 // account for document scrolling
8331 // if offsetParent is used, ret value already includes scroll position
8332 // so we may have to actually remove that value if !includeScroll
8333 if(includeScroll){
8334 var scroll = geom.docScroll();
8335 ret.x += scroll.x;
8336 ret.y += scroll.y;
8337 }
2f01fe57 8338
1354d172
AD
8339 return ret; // Object
8340 };
2f01fe57 8341
1354d172 8342 // random "private" functions wildly used throughout the toolkit
2f01fe57 8343
1354d172
AD
8344 geom.getMarginSize = function getMarginSize(/*DomNode*/node, /*Object*/computedStyle){
8345 node = dom.byId(node);
8346 var me = geom.getMarginExtents(node, computedStyle || style.getComputedStyle(node));
8347 var size = node.getBoundingClientRect();
8348 return {
8349 w: (size.right - size.left) + me.w,
8350 h: (size.bottom - size.top) + me.h
8351 }
8352 };
2f01fe57 8353
1354d172
AD
8354 geom.normalizeEvent = function(event){
8355 // summary:
8356 // Normalizes the geometry of a DOM event, normalizing the pageX, pageY,
8357 // offsetX, offsetY, layerX, and layerX properties
8358 // event: Object
8359 if(!("layerX" in event)){
8360 event.layerX = event.offsetX;
8361 event.layerY = event.offsetY;
8362 }
8363 if(!has("dom-addeventlistener")){
8364 // old IE version
8365 // FIXME: scroll position query is duped from dojo.html to
8366 // avoid dependency on that entire module. Now that HTML is in
8367 // Base, we should convert back to something similar there.
8368 var se = event.target;
8369 var doc = (se && se.ownerDocument) || document;
8370 // DO NOT replace the following to use dojo.body(), in IE, document.documentElement should be used
8371 // here rather than document.body
8372 var docBody = has("quirks") ? doc.body : doc.documentElement;
8373 var offset = geom.getIeDocumentElementOffset();
8374 event.pageX = event.clientX + geom.fixIeBiDiScrollLeft(docBody.scrollLeft || 0) - offset.x;
8375 event.pageY = event.clientY + (docBody.scrollTop || 0) - offset.y;
8376 }
8377 };
8378
8379 // TODO: evaluate separate getters/setters for position and sizes?
8380
8381 return geom;
8382});
8383
8384},
8385'dojo/dom-prop':function(){
8386define("dojo/dom-prop", ["exports", "./_base/kernel", "./_base/sniff", "./_base/lang", "./dom", "./dom-style", "./dom-construct", "./_base/connect"],
8387 function(exports, dojo, has, lang, dom, style, ctr, conn){
8388 // module:
8389 // dojo/dom-prop
8390 // summary:
8391 // This module defines the core dojo DOM properties API.
8392 // Indirectly depends on dojo.empty() and dojo.toDom().
2f01fe57 8393
1354d172
AD
8394 // =============================
8395 // Element properties Functions
8396 // =============================
2f01fe57 8397
1354d172
AD
8398 /*=====
8399 prop.get = function(node, name){
8400 // summary:
8401 // Gets a property on an HTML element.
8402 // description:
8403 // Handles normalized getting of properties on DOM nodes.
8404 //
8405 // node: DOMNode|String
8406 // id or reference to the element to get the property on
8407 // name: String
8408 // the name of the property to get.
8409 // returns:
8410 // the value of the requested property or its default value
8411 //
8412 // example:
8413 // | // get the current value of the "foo" property on a node
8414 // | dojo.getProp(dojo.byId("nodeId"), "foo");
8415 // | // or we can just pass the id:
8416 // | dojo.getProp("nodeId", "foo");
8417 };
8418 =====*/
2f01fe57 8419
1354d172
AD
8420 /*=====
8421 prop.set = function(node, name, value){
8422 // summary:
8423 // Sets a property on an HTML element.
8424 // description:
8425 // Handles normalized setting of properties on DOM nodes.
8426 //
8427 // When passing functions as values, note that they will not be
8428 // directly assigned to slots on the node, but rather the default
8429 // behavior will be removed and the new behavior will be added
8430 // using `dojo.connect()`, meaning that event handler properties
8431 // will be normalized and that some caveats with regards to
8432 // non-standard behaviors for onsubmit apply. Namely that you
8433 // should cancel form submission using `dojo.stopEvent()` on the
8434 // passed event object instead of returning a boolean value from
8435 // the handler itself.
8436 // node: DOMNode|String
8437 // id or reference to the element to set the property on
8438 // name: String|Object
8439 // the name of the property to set, or a hash object to set
8440 // multiple properties at once.
8441 // value: String?
8442 // The value to set for the property
8443 // returns:
8444 // the DOM node
8445 //
8446 // example:
8447 // | // use prop() to set the tab index
8448 // | dojo.setProp("nodeId", "tabIndex", 3);
8449 // |
8450 //
8451 // example:
8452 // Set multiple values at once, including event handlers:
8453 // | dojo.setProp("formId", {
8454 // | "foo": "bar",
8455 // | "tabIndex": -1,
8456 // | "method": "POST",
8457 // | "onsubmit": function(e){
8458 // | // stop submitting the form. Note that the IE behavior
8459 // | // of returning true or false will have no effect here
8460 // | // since our handler is connect()ed to the built-in
8461 // | // onsubmit behavior and so we need to use
8462 // | // dojo.stopEvent() to ensure that the submission
8463 // | // doesn't proceed.
8464 // | dojo.stopEvent(e);
8465 // |
8466 // | // submit the form with Ajax
8467 // | dojo.xhrPost({ form: "formId" });
8468 // | }
8469 // | });
8470 //
8471 // example:
8472 // Style is s special case: Only set with an object hash of styles
8473 // | dojo.setProp("someNode",{
8474 // | id:"bar",
8475 // | style:{
8476 // | width:"200px", height:"100px", color:"#000"
8477 // | }
8478 // | });
8479 //
8480 // example:
8481 // Again, only set style as an object hash of styles:
8482 // | var obj = { color:"#fff", backgroundColor:"#000" };
8483 // | dojo.setProp("someNode", "style", obj);
8484 // |
8485 // | // though shorter to use `dojo.style()` in this case:
8486 // | dojo.style("someNode", obj);
8487 };
8488 =====*/
2f01fe57 8489
1354d172
AD
8490 // helper to connect events
8491 var _evtHdlrMap = {}, _ctr = 0, _attrId = dojo._scopeName + "attrid";
2f01fe57 8492
1354d172
AD
8493 // the next dictionary lists elements with read-only innerHTML on IE
8494 var _roInnerHtml = {col: 1, colgroup: 1,
8495 // frameset: 1, head: 1, html: 1, style: 1,
8496 table: 1, tbody: 1, tfoot: 1, thead: 1, tr: 1, title: 1};
8497
8498 exports.names = {
8499 // properties renamed to avoid clashes with reserved words
8500 "class": "className",
8501 "for": "htmlFor",
8502 // properties written as camelCase
8503 tabindex: "tabIndex",
8504 readonly: "readOnly",
8505 colspan: "colSpan",
8506 frameborder: "frameBorder",
8507 rowspan: "rowSpan",
8508 valuetype: "valueType"
8509 };
8510
8511 exports.get = function getProp(/*DOMNode|String*/node, /*String*/name){
8512 node = dom.byId(node);
8513 var lc = name.toLowerCase(), propName = exports.names[lc] || name;
8514 return node[propName]; // Anything
8515 };
8516
8517 exports.set = function setProp(/*DOMNode|String*/node, /*String|Object*/name, /*String?*/value){
8518 node = dom.byId(node);
8519 var l = arguments.length;
8520 if(l == 2 && typeof name != "string"){ // inline'd type check
8521 // the object form of setter: the 2nd argument is a dictionary
8522 for(var x in name){
8523 exports.set(node, x, name[x]);
8524 }
8525 return node; // DomNode
8526 }
8527 var lc = name.toLowerCase(), propName = exports.names[lc] || name;
8528 if(propName == "style" && typeof value != "string"){ // inline'd type check
8529 // special case: setting a style
8530 style.style(node, value);
8531 return node; // DomNode
8532 }
8533 if(propName == "innerHTML"){
8534 // special case: assigning HTML
8535 if(has("ie") && node.tagName.toLowerCase() in _roInnerHtml){
8536 ctr.empty(node);
8537 node.appendChild(ctr.toDom(value, node.ownerDocument));
8538 }else{
8539 node[propName] = value;
8540 }
8541 return node; // DomNode
8542 }
8543 if(lang.isFunction(value)){
8544 // special case: assigning an event handler
8545 // clobber if we can
8546 var attrId = node[_attrId];
8547 if(!attrId){
8548 attrId = _ctr++;
8549 node[_attrId] = attrId;
8550 }
8551 if(!_evtHdlrMap[attrId]){
8552 _evtHdlrMap[attrId] = {};
8553 }
8554 var h = _evtHdlrMap[attrId][propName];
8555 if(h){
8556 //h.remove();
8557 conn.disconnect(h);
8558 }else{
8559 try{
8560 delete node[propName];
8561 }catch(e){}
8562 }
8563 // ensure that event objects are normalized, etc.
8564 if(value){
8565 //_evtHdlrMap[attrId][propName] = on(node, propName, value);
8566 _evtHdlrMap[attrId][propName] = conn.connect(node, propName, value);
8567 }else{
8568 node[propName] = null;
8569 }
8570 return node; // DomNode
8571 }
8572 node[propName] = value;
8573 return node; // DomNode
8574 };
8575});
2f01fe57 8576
1354d172
AD
8577},
8578'dojo/dom-attr':function(){
8579define(["exports", "./_base/sniff", "./_base/lang", "./dom", "./dom-style", "./dom-prop"],
8580 function(exports, has, lang, dom, style, prop){
8581 // module:
8582 // dojo/dom-attr
8583 // summary:
8584 // This module defines the core dojo DOM attributes API.
2f01fe57 8585
1354d172
AD
8586 // =============================
8587 // Element attribute Functions
8588 // =============================
2f01fe57 8589
1354d172 8590 // This module will be obsolete soon. Use dojo.prop instead.
2f01fe57 8591
1354d172 8592 // dojo.attr() should conform to http://www.w3.org/TR/DOM-Level-2-Core/
2f01fe57 8593
1354d172 8594 // attribute-related functions (to be obsolete soon)
2f01fe57 8595
1354d172
AD
8596 /*=====
8597 dojo.hasAttr = function(node, name){
8598 // summary:
8599 // Returns true if the requested attribute is specified on the
8600 // given element, and false otherwise.
8601 // node: DOMNode|String
8602 // id or reference to the element to check
8603 // name: String
8604 // the name of the attribute
8605 // returns: Boolean
8606 // true if the requested attribute is specified on the
8607 // given element, and false otherwise
8608 };
8609 =====*/
2f01fe57 8610
1354d172
AD
8611 /*=====
8612 dojo.getAttr = function(node, name){
8613 // summary:
8614 // Gets an attribute on an HTML element.
8615 // description:
8616 // Handles normalized getting of attributes on DOM Nodes.
8617 // node: DOMNode|String
8618 // id or reference to the element to get the attribute on
8619 // name: String
8620 // the name of the attribute to get.
8621 // returns:
8622 // the value of the requested attribute or null if that attribute does not have a specified or
8623 // default value;
8624 //
8625 // example:
8626 // | // get the current value of the "foo" attribute on a node
8627 // | dojo.getAttr(dojo.byId("nodeId"), "foo");
8628 // | // or we can just pass the id:
8629 // | dojo.getAttr("nodeId", "foo");
8630 };
8631 =====*/
2f01fe57 8632
1354d172
AD
8633 /*=====
8634 dojo.setAttr = function(node, name, value){
8635 // summary:
8636 // Sets an attribute on an HTML element.
8637 // description:
8638 // Handles normalized setting of attributes on DOM Nodes.
8639 //
8640 // When passing functions as values, note that they will not be
8641 // directly assigned to slots on the node, but rather the default
8642 // behavior will be removed and the new behavior will be added
8643 // using `dojo.connect()`, meaning that event handler properties
8644 // will be normalized and that some caveats with regards to
8645 // non-standard behaviors for onsubmit apply. Namely that you
8646 // should cancel form submission using `dojo.stopEvent()` on the
8647 // passed event object instead of returning a boolean value from
8648 // the handler itself.
8649 // node: DOMNode|String
8650 // id or reference to the element to set the attribute on
8651 // name: String|Object
8652 // the name of the attribute to set, or a hash of key-value pairs to set.
8653 // value: String?
8654 // the value to set for the attribute, if the name is a string.
8655 // returns:
8656 // the DOM node
8657 //
8658 // example:
8659 // | // use attr() to set the tab index
8660 // | dojo.setAttr("nodeId", "tabIndex", 3);
8661 //
8662 // example:
8663 // Set multiple values at once, including event handlers:
8664 // | dojo.setAttr("formId", {
8665 // | "foo": "bar",
8666 // | "tabIndex": -1,
8667 // | "method": "POST",
8668 // | "onsubmit": function(e){
8669 // | // stop submitting the form. Note that the IE behavior
8670 // | // of returning true or false will have no effect here
8671 // | // since our handler is connect()ed to the built-in
8672 // | // onsubmit behavior and so we need to use
8673 // | // dojo.stopEvent() to ensure that the submission
8674 // | // doesn't proceed.
8675 // | dojo.stopEvent(e);
8676 // |
8677 // | // submit the form with Ajax
8678 // | dojo.xhrPost({ form: "formId" });
8679 // | }
8680 // | });
8681 //
8682 // example:
8683 // Style is s special case: Only set with an object hash of styles
8684 // | dojo.setAttr("someNode",{
8685 // | id:"bar",
8686 // | style:{
8687 // | width:"200px", height:"100px", color:"#000"
8688 // | }
8689 // | });
8690 //
8691 // example:
8692 // Again, only set style as an object hash of styles:
8693 // | var obj = { color:"#fff", backgroundColor:"#000" };
8694 // | dojo.setAttr("someNode", "style", obj);
8695 // |
8696 // | // though shorter to use `dojo.style()` in this case:
8697 // | dojo.setStyle("someNode", obj);
8698 };
8699 =====*/
2f01fe57 8700
1354d172
AD
8701 /*=====
8702 dojo.removeAttr = function(node, name){
8703 // summary:
8704 // Removes an attribute from an HTML element.
8705 // node: DOMNode|String
8706 // id or reference to the element to remove the attribute from
8707 // name: String
8708 // the name of the attribute to remove
8709 };
8710 =====*/
2f01fe57 8711
1354d172
AD
8712 /*=====
8713 dojo.getNodeProp = function(node, name){
8714 // summary:
8715 // Returns an effective value of a property or an attribute.
8716 // node: DOMNode|String
8717 // id or reference to the element to remove the attribute from
8718 // name: String
8719 // the name of the attribute
8720 // returns:
8721 // the value of the attribute
8722 };
8723 =====*/
2f01fe57 8724
1354d172
AD
8725 var forcePropNames = {
8726 innerHTML: 1,
8727 className: 1,
8728 htmlFor: has("ie"),
8729 value: 1
8730 },
8731 attrNames = {
8732 // original attribute names
8733 classname: "class",
8734 htmlfor: "for",
8735 // for IE
8736 tabindex: "tabIndex",
8737 readonly: "readOnly"
8738 };
2f01fe57 8739
1354d172
AD
8740 function _hasAttr(node, name){
8741 var attr = node.getAttributeNode && node.getAttributeNode(name);
8742 return attr && attr.specified; // Boolean
8743 }
2f01fe57 8744
1354d172
AD
8745 // There is a difference in the presence of certain properties and their default values
8746 // between browsers. For example, on IE "disabled" is present on all elements,
8747 // but it is value is "false"; "tabIndex" of <div> returns 0 by default on IE, yet other browsers
8748 // can return -1.
2f01fe57 8749
1354d172
AD
8750 exports.has = function hasAttr(/*DOMNode|String*/node, /*String*/name){
8751 var lc = name.toLowerCase();
8752 return forcePropNames[prop.names[lc] || name] || _hasAttr(dom.byId(node), attrNames[lc] || name); // Boolean
8753 };
2f01fe57 8754
1354d172
AD
8755 exports.get = function getAttr(/*DOMNode|String*/node, /*String*/name){
8756 node = dom.byId(node);
8757 var lc = name.toLowerCase(),
8758 propName = prop.names[lc] || name,
8759 forceProp = forcePropNames[propName];
8760 // should we access this attribute via a property or via getAttribute()?
8761 value = node[propName];
8762 if(forceProp && typeof value != "undefined"){
8763 // node's property
8764 return value; // Anything
8765 }
8766 if(propName != "href" && (typeof value == "boolean" || lang.isFunction(value))){
8767 // node's property
8768 return value; // Anything
8769 }
8770 // node's attribute
8771 // we need _hasAttr() here to guard against IE returning a default value
8772 var attrName = attrNames[lc] || name;
8773 return _hasAttr(node, attrName) ? node.getAttribute(attrName) : null; // Anything
8774 };
2f01fe57 8775
1354d172
AD
8776 exports.set = function setAttr(/*DOMNode|String*/node, /*String|Object*/name, /*String?*/value){
8777 node = dom.byId(node);
8778 if(arguments.length == 2){ // inline'd type check
8779 // the object form of setter: the 2nd argument is a dictionary
8780 for(var x in name){
8781 exports.set(node, x, name[x]);
8782 }
8783 return node; // DomNode
2f01fe57 8784 }
1354d172
AD
8785 var lc = name.toLowerCase(),
8786 propName = prop.names[lc] || name,
8787 forceProp = forcePropNames[propName];
8788 if(propName == "style" && typeof value != "string"){ // inline'd type check
8789 // special case: setting a style
8790 style.set(node, value);
8791 return node; // DomNode
8792 }
8793 if(forceProp || typeof value == "boolean" || lang.isFunction(value)){
8794 return prop.set(node, name, value)
8795 }
8796 // node's attribute
8797 node.setAttribute(attrNames[lc] || name, value);
8798 return node; // DomNode
8799 };
2f01fe57 8800
1354d172
AD
8801 exports.remove = function removeAttr(/*DOMNode|String*/ node, /*String*/ name){
8802 dom.byId(node).removeAttribute(attrNames[name.toLowerCase()] || name);
8803 };
2f01fe57 8804
1354d172
AD
8805 exports.getNodeProp = function getNodeProp(/*DomNode|String*/ node, /*String*/ name){
8806 node = dom.byId(node);
8807 var lc = name.toLowerCase(), propName = prop.names[lc] || name;
8808 if((propName in node) && propName != "href"){
8809 // node's property
8810 return node[propName]; // Anything
8811 }
8812 // node's attribute
8813 var attrName = attrNames[lc] || name;
8814 return _hasAttr(node, attrName) ? node.getAttribute(attrName) : null; // Anything
8815 };
8816});
2f01fe57 8817
1354d172
AD
8818},
8819'dojo/dom-construct':function(){
8820define("dojo/dom-construct", ["exports", "./_base/kernel", "./_base/sniff", "./_base/window", "./dom", "./dom-attr", "./on"],
8821 function(exports, dojo, has, win, dom, attr, on){
8822 // module:
8823 // dojo/dom-construct
8824 // summary:
8825 // This module defines the core dojo DOM construction API.
2f01fe57 8826
1354d172
AD
8827 /*=====
8828 dojo.toDom = function(frag, doc){
8829 // summary:
8830 // instantiates an HTML fragment returning the corresponding DOM.
8831 // frag: String
8832 // the HTML fragment
8833 // doc: DocumentNode?
8834 // optional document to use when creating DOM nodes, defaults to
8835 // dojo.doc if not specified.
8836 // returns: DocumentFragment
8837 //
8838 // example:
8839 // Create a table row:
8840 // | var tr = dojo.toDom("<tr><td>First!</td></tr>");
8841 };
8842 =====*/
2f01fe57 8843
1354d172
AD
8844 /*=====
8845 dojo._toDom = function(frag, doc){
8846 // summary:
8847 // Existing alias for `dojo.toDom`. Deprecated, will be removed in 2.0.
8848 };
8849 =====*/
2f01fe57 8850
1354d172
AD
8851 /*=====
8852 dojo.place = function(node, refNode, position){
8853 // summary:
8854 // Attempt to insert node into the DOM, choosing from various positioning options.
8855 // Returns the first argument resolved to a DOM node.
8856 //
8857 // node: DOMNode|String
8858 // id or node reference, or HTML fragment starting with "<" to place relative to refNode
8859 //
8860 // refNode: DOMNode|String
8861 // id or node reference to use as basis for placement
8862 //
8863 // position: String|Number?
8864 // string noting the position of node relative to refNode or a
8865 // number indicating the location in the childNodes collection of refNode.
8866 // Accepted string values are:
8867 // | * before
8868 // | * after
8869 // | * replace
8870 // | * only
8871 // | * first
8872 // | * last
8873 // "first" and "last" indicate positions as children of refNode, "replace" replaces refNode,
8874 // "only" replaces all children. position defaults to "last" if not specified
8875 //
8876 // returns: DOMNode
8877 // Returned values is the first argument resolved to a DOM node.
8878 //
8879 // .place() is also a method of `dojo.NodeList`, allowing `dojo.query` node lookups.
8880 //
8881 // example:
8882 // Place a node by string id as the last child of another node by string id:
8883 // | dojo.place("someNode", "anotherNode");
8884 //
8885 // example:
8886 // Place a node by string id before another node by string id
8887 // | dojo.place("someNode", "anotherNode", "before");
8888 //
8889 // example:
8890 // Create a Node, and place it in the body element (last child):
8891 // | dojo.place("<div></div>", dojo.body());
8892 //
8893 // example:
8894 // Put a new LI as the first child of a list by id:
8895 // | dojo.place("<li></li>", "someUl", "first");
8896 };
8897 =====*/
2f01fe57 8898
1354d172
AD
8899 /*=====
8900 dojo.create = function(tag, attrs, refNode, pos){
8901 // summary:
8902 // Create an element, allowing for optional attribute decoration
8903 // and placement.
8904 //
8905 // description:
8906 // A DOM Element creation function. A shorthand method for creating a node or
8907 // a fragment, and allowing for a convenient optional attribute setting step,
8908 // as well as an optional DOM placement reference.
8909 //|
8910 // Attributes are set by passing the optional object through `dojo.setAttr`.
8911 // See `dojo.setAttr` for noted caveats and nuances, and API if applicable.
8912 //|
8913 // Placement is done via `dojo.place`, assuming the new node to be the action
8914 // node, passing along the optional reference node and position.
8915 //
8916 // tag: DOMNode|String
8917 // A string of the element to create (eg: "div", "a", "p", "li", "script", "br"),
8918 // or an existing DOM node to process.
8919 //
8920 // attrs: Object
8921 // An object-hash of attributes to set on the newly created node.
8922 // Can be null, if you don't want to set any attributes/styles.
8923 // See: `dojo.setAttr` for a description of available attributes.
8924 //
8925 // refNode: DOMNode?|String?
8926 // Optional reference node. Used by `dojo.place` to place the newly created
8927 // node somewhere in the dom relative to refNode. Can be a DomNode reference
8928 // or String ID of a node.
8929 //
8930 // pos: String?
8931 // Optional positional reference. Defaults to "last" by way of `dojo.place`,
8932 // though can be set to "first","after","before","last", "replace" or "only"
8933 // to further control the placement of the new node relative to the refNode.
8934 // 'refNode' is required if a 'pos' is specified.
8935 //
8936 // returns: DOMNode
8937 //
8938 // example:
8939 // Create a DIV:
8940 // | var n = dojo.create("div");
8941 //
8942 // example:
8943 // Create a DIV with content:
8944 // | var n = dojo.create("div", { innerHTML:"<p>hi</p>" });
8945 //
8946 // example:
8947 // Place a new DIV in the BODY, with no attributes set
8948 // | var n = dojo.create("div", null, dojo.body());
8949 //
8950 // example:
8951 // Create an UL, and populate it with LI's. Place the list as the first-child of a
8952 // node with id="someId":
8953 // | var ul = dojo.create("ul", null, "someId", "first");
8954 // | var items = ["one", "two", "three", "four"];
8955 // | dojo.forEach(items, function(data){
8956 // | dojo.create("li", { innerHTML: data }, ul);
8957 // | });
8958 //
8959 // example:
8960 // Create an anchor, with an href. Place in BODY:
8961 // | dojo.create("a", { href:"foo.html", title:"Goto FOO!" }, dojo.body());
8962 //
8963 // example:
8964 // Create a `dojo.NodeList()` from a new element (for syntatic sugar):
8965 // | dojo.query(dojo.create('div'))
8966 // | .addClass("newDiv")
8967 // | .onclick(function(e){ console.log('clicked', e.target) })
8968 // | .place("#someNode"); // redundant, but cleaner.
8969 };
8970 =====*/
2f01fe57 8971
1354d172
AD
8972 /*=====
8973 dojo.empty = function(node){
8974 // summary:
8975 // safely removes all children of the node.
8976 // node: DOMNode|String
8977 // a reference to a DOM node or an id.
8978 // example:
8979 // Destroy node's children byId:
8980 // | dojo.empty("someId");
8981 //
8982 // example:
8983 // Destroy all nodes' children in a list by reference:
8984 // | dojo.query(".someNode").forEach(dojo.empty);
8985 }
8986 =====*/
2f01fe57 8987
1354d172
AD
8988 /*=====
8989 dojo.destroy = function(node){
8990 // summary:
8991 // Removes a node from its parent, clobbering it and all of its
8992 // children.
8993 //
8994 // description:
8995 // Removes a node from its parent, clobbering it and all of its
8996 // children. Function only works with DomNodes, and returns nothing.
8997 //
8998 // node: DOMNode|String
8999 // A String ID or DomNode reference of the element to be destroyed
9000 //
9001 // example:
9002 // Destroy a node byId:
9003 // | dojo.destroy("someId");
9004 //
9005 // example:
9006 // Destroy all nodes in a list by reference:
9007 // | dojo.query(".someNode").forEach(dojo.destroy);
9008 };
9009 =====*/
2f01fe57 9010
1354d172
AD
9011 /*=====
9012 dojo._destroyElement = function(node){
9013 // summary:
9014 // Existing alias for `dojo.destroy`. Deprecated, will be removed in 2.0.
9015 };
9016 =====*/
2f01fe57 9017
1354d172
AD
9018 // support stuff for dojo.toDom
9019 var tagWrap = {
9020 option: ["select"],
9021 tbody: ["table"],
9022 thead: ["table"],
9023 tfoot: ["table"],
9024 tr: ["table", "tbody"],
9025 td: ["table", "tbody", "tr"],
9026 th: ["table", "thead", "tr"],
9027 legend: ["fieldset"],
9028 caption: ["table"],
9029 colgroup: ["table"],
9030 col: ["table", "colgroup"],
9031 li: ["ul"]
9032 },
9033 reTag = /<\s*([\w\:]+)/,
9034 masterNode = {}, masterNum = 0,
9035 masterName = "__" + dojo._scopeName + "ToDomId";
2f01fe57 9036
1354d172
AD
9037 // generate start/end tag strings to use
9038 // for the injection for each special tag wrap case.
9039 for(var param in tagWrap){
9040 if(tagWrap.hasOwnProperty(param)){
9041 var tw = tagWrap[param];
9042 tw.pre = param == "option" ? '<select multiple="multiple">' : "<" + tw.join("><") + ">";
9043 tw.post = "</" + tw.reverse().join("></") + ">";
9044 // the last line is destructive: it reverses the array,
9045 // but we don't care at this point
9046 }
9047 }
2f01fe57 9048
1354d172
AD
9049 function _insertBefore(/*DomNode*/node, /*DomNode*/ref){
9050 var parent = ref.parentNode;
9051 if(parent){
9052 parent.insertBefore(node, ref);
9053 }
9054 }
2f01fe57 9055
1354d172
AD
9056 function _insertAfter(/*DomNode*/node, /*DomNode*/ref){
9057 // summary:
9058 // Try to insert node after ref
9059 var parent = ref.parentNode;
9060 if(parent){
9061 if(parent.lastChild == ref){
9062 parent.appendChild(node);
9063 }else{
9064 parent.insertBefore(node, ref.nextSibling);
9065 }
9066 }
9067 }
2f01fe57 9068
1354d172
AD
9069 var _destroyContainer = null,
9070 _destroyDoc;
9071 on(window, "unload", function(){
9072 _destroyContainer = null; //prevent IE leak
9073 });
9074
9075 exports.toDom = function toDom(frag, doc){
9076 doc = doc || win.doc;
9077 var masterId = doc[masterName];
9078 if(!masterId){
9079 doc[masterName] = masterId = ++masterNum + "";
9080 masterNode[masterId] = doc.createElement("div");
9081 }
2f01fe57 9082
1354d172
AD
9083 // make sure the frag is a string.
9084 frag += "";
2f01fe57 9085
1354d172
AD
9086 // find the starting tag, and get node wrapper
9087 var match = frag.match(reTag),
9088 tag = match ? match[1].toLowerCase() : "",
9089 master = masterNode[masterId],
9090 wrap, i, fc, df;
9091 if(match && tagWrap[tag]){
9092 wrap = tagWrap[tag];
9093 master.innerHTML = wrap.pre + frag + wrap.post;
9094 for(i = wrap.length; i; --i){
9095 master = master.firstChild;
9096 }
2f01fe57 9097 }else{
1354d172 9098 master.innerHTML = frag;
2f01fe57
AD
9099 }
9100
1354d172
AD
9101 // one node shortcut => return the node itself
9102 if(master.childNodes.length == 1){
9103 return master.removeChild(master.firstChild); // DOMNode
2f01fe57
AD
9104 }
9105
1354d172
AD
9106 // return multiple nodes as a document fragment
9107 df = doc.createDocumentFragment();
9108 while(fc = master.firstChild){ // intentional assignment
9109 df.appendChild(fc);
9110 }
9111 return df; // DOMNode
9112 };
2f01fe57 9113
1354d172
AD
9114 exports.place = function place(/*DOMNode|String*/node, /*DOMNode|String*/refNode, /*String|Number?*/position){
9115 refNode = dom.byId(refNode);
9116 if(typeof node == "string"){ // inline'd type check
9117 node = /^\s*</.test(node) ? exports.toDom(node, refNode.ownerDocument) : dom.byId(node);
9118 }
9119 if(typeof position == "number"){ // inline'd type check
9120 var cn = refNode.childNodes;
9121 if(!cn.length || cn.length <= position){
9122 refNode.appendChild(node);
9123 }else{
9124 _insertBefore(node, cn[position < 0 ? 0 : position]);
9125 }
9126 }else{
9127 switch(position){
9128 case "before":
9129 _insertBefore(node, refNode);
9130 break;
9131 case "after":
9132 _insertAfter(node, refNode);
9133 break;
9134 case "replace":
9135 refNode.parentNode.replaceChild(node, refNode);
9136 break;
9137 case "only":
9138 exports.empty(refNode);
9139 refNode.appendChild(node);
9140 break;
9141 case "first":
9142 if(refNode.firstChild){
9143 _insertBefore(node, refNode.firstChild);
9144 break;
9145 }
9146 // else fallthrough...
9147 default: // aka: last
9148 refNode.appendChild(node);
2f01fe57
AD
9149 }
9150 }
1354d172
AD
9151 return node; // DomNode
9152 };
2f01fe57 9153
1354d172
AD
9154 exports.create = function create(/*DOMNode|String*/tag, /*Object*/attrs, /*DOMNode?|String?*/refNode, /*String?*/pos){
9155 var doc = win.doc;
9156 if(refNode){
9157 refNode = dom.byId(refNode);
9158 doc = refNode.ownerDocument;
9159 }
9160 if(typeof tag == "string"){ // inline'd type check
9161 tag = doc.createElement(tag);
2f01fe57 9162 }
1354d172
AD
9163 if(attrs){ attr.set(tag, attrs); }
9164 if(refNode){ exports.place(tag, refNode, pos); }
9165 return tag; // DomNode
9166 };
2f01fe57 9167
1354d172
AD
9168 exports.empty =
9169 has("ie") ? function(node){
9170 node = dom.byId(node);
9171 for(var c; c = node.lastChild;){ // intentional assignment
9172 exports.destroy(c);
2f01fe57 9173 }
1354d172
AD
9174 } :
9175 function(node){
9176 dom.byId(node).innerHTML = "";
9177 };
2f01fe57 9178
1354d172
AD
9179 exports.destroy = function destroy(/*DOMNode|String*/node){
9180 node = dom.byId(node);
9181 try{
9182 var doc = node.ownerDocument;
9183 // cannot use _destroyContainer.ownerDocument since this can throw an exception on IE
9184 if(!_destroyContainer || _destroyDoc != doc){
9185 _destroyContainer = doc.createElement("div");
9186 _destroyDoc = doc;
9187 }
9188 _destroyContainer.appendChild(node.parentNode ? node.parentNode.removeChild(node) : node);
9189 // NOTE: see http://trac.dojotoolkit.org/ticket/2931. This may be a bug and not a feature
9190 _destroyContainer.innerHTML = "";
9191 }catch(e){
9192 /* squelch */
2f01fe57 9193 }
1354d172
AD
9194 };
9195});
2f01fe57 9196
1354d172
AD
9197},
9198'dojo/keys':function(){
9199define("dojo/keys", ["./_base/kernel", "./_base/sniff"], function(dojo, has) {
9200 // module:
9201 // dojo/keys
9202 // summary:
9203 // key constants
9204// Constants
9205
9206// Public: client code should test
9207// keyCode against these named constants, as the
9208// actual codes can vary by browser.
9209return dojo.keys = {
9210 // summary:
9211 // Definitions for common key values
9212 BACKSPACE: 8,
9213 TAB: 9,
9214 CLEAR: 12,
9215 ENTER: 13,
9216 SHIFT: 16,
9217 CTRL: 17,
9218 ALT: 18,
9219 META: has("safari") ? 91 : 224, // the apple key on macs
9220 PAUSE: 19,
9221 CAPS_LOCK: 20,
9222 ESCAPE: 27,
9223 SPACE: 32,
9224 PAGE_UP: 33,
9225 PAGE_DOWN: 34,
9226 END: 35,
9227 HOME: 36,
9228 LEFT_ARROW: 37,
9229 UP_ARROW: 38,
9230 RIGHT_ARROW: 39,
9231 DOWN_ARROW: 40,
9232 INSERT: 45,
9233 DELETE: 46,
9234 HELP: 47,
9235 LEFT_WINDOW: 91,
9236 RIGHT_WINDOW: 92,
9237 SELECT: 93,
9238 NUMPAD_0: 96,
9239 NUMPAD_1: 97,
9240 NUMPAD_2: 98,
9241 NUMPAD_3: 99,
9242 NUMPAD_4: 100,
9243 NUMPAD_5: 101,
9244 NUMPAD_6: 102,
9245 NUMPAD_7: 103,
9246 NUMPAD_8: 104,
9247 NUMPAD_9: 105,
9248 NUMPAD_MULTIPLY: 106,
9249 NUMPAD_PLUS: 107,
9250 NUMPAD_ENTER: 108,
9251 NUMPAD_MINUS: 109,
9252 NUMPAD_PERIOD: 110,
9253 NUMPAD_DIVIDE: 111,
9254 F1: 112,
9255 F2: 113,
9256 F3: 114,
9257 F4: 115,
9258 F5: 116,
9259 F6: 117,
9260 F7: 118,
9261 F8: 119,
9262 F9: 120,
9263 F10: 121,
9264 F11: 122,
9265 F12: 123,
9266 F13: 124,
9267 F14: 125,
9268 F15: 126,
9269 NUM_LOCK: 144,
9270 SCROLL_LOCK: 145,
9271 UP_DPAD: 175,
9272 DOWN_DPAD: 176,
9273 LEFT_DPAD: 177,
9274 RIGHT_DPAD: 178,
9275 // virtual key mapping
9276 copyKey: has("mac") && !has("air") ? (has("safari") ? 91 : 224 ) : 17
9277};
9278});
9279
9280},
9281'dojo/domReady':function(){
9282define(['./has'], function(has){
9283 var global = this,
9284 doc = document,
9285 readyStates = { 'loaded': 1, 'complete': 1 },
9286 fixReadyState = typeof doc.readyState != "string",
9287 ready = !!readyStates[doc.readyState];
9288
9289 // For FF <= 3.5
9290 if(fixReadyState){ doc.readyState = "loading"; }
9291
9292 if(!ready){
9293 var readyQ = [], tests = [],
9294 detectReady = function(evt){
9295 evt = evt || global.event;
9296 if(ready || (evt.type == "readystatechange" && !readyStates[doc.readyState])){ return; }
9297 ready = 1;
9298
9299 // For FF <= 3.5
9300 if(fixReadyState){ doc.readyState = "complete"; }
9301
9302 while(readyQ.length){
9303 (readyQ.shift())();
9304 }
9305 },
9306 on = function(node, event){
9307 node.addEventListener(event, detectReady, false);
9308 readyQ.push(function(){ node.removeEventListener(event, detectReady, false); });
9309 };
9310
9311 if(!has("dom-addeventlistener")){
9312 on = function(node, event){
9313 event = "on" + event;
9314 node.attachEvent(event, detectReady);
9315 readyQ.push(function(){ node.detachEvent(event, detectReady); });
9316 };
2f01fe57 9317
1354d172
AD
9318 var div = doc.createElement("div");
9319 try{
9320 if(div.doScroll && global.frameElement === null){
9321 // the doScroll test is only useful if we're in the top-most frame
9322 tests.push(function(){
9323 // Derived with permission from Diego Perini's IEContentLoaded
9324 // http://javascript.nwbox.com/IEContentLoaded/
9325 try{
9326 div.doScroll("left");
9327 return 1;
9328 }catch(e){}
9329 });
9330 }
9331 }catch(e){}
9332 }
2f01fe57 9333
1354d172
AD
9334 on(doc, "DOMContentLoaded");
9335 on(global, "load");
2f01fe57 9336
1354d172
AD
9337 if("onreadystatechange" in doc){
9338 on(doc, "readystatechange");
9339 }else if(!fixReadyState){
9340 // if the ready state property exists and there's
9341 // no readystatechange event, poll for the state
9342 // to change
9343 tests.push(function(){
9344 return readyStates[doc.readyState];
9345 });
9346 }
2f01fe57 9347
1354d172
AD
9348 if(tests.length){
9349 var poller = function(){
9350 if(ready){ return; }
9351 var i = tests.length;
9352 while(i--){
9353 if(tests[i]()){
9354 detectReady("poller");
9355 return;
2f01fe57 9356 }
1354d172
AD
9357 }
9358 setTimeout(poller, 30);
9359 };
9360 poller();
9361 }
9362 }
2f01fe57 9363
1354d172
AD
9364 function domReady(callback){
9365 if(ready){
9366 callback(1);
9367 }else{
9368 readyQ.push(callback);
2f01fe57 9369 }
1354d172
AD
9370 }
9371 domReady.load = function(id, req, load){
9372 domReady(load);
2f01fe57 9373 };
2f01fe57 9374
1354d172
AD
9375 return domReady;
9376});
2f01fe57 9377
1354d172
AD
9378},
9379'dojo/_base/lang':function(){
9380define(["./kernel", "../has", "./sniff"], function(dojo, has){
9381 // module:
9382 // dojo/_base/lang
9383 // summary:
9384 // This module defines Javascript language extensions.
2f01fe57 9385
1354d172
AD
9386 has.add("bug-for-in-skips-shadowed", function(){
9387 // if true, the for-in interator skips object properties that exist in Object's prototype (IE 6 - ?)
9388 for(var i in {toString: 1}){
9389 return 0;
2f01fe57 9390 }
1354d172
AD
9391 return 1;
9392 });
2f01fe57 9393
1354d172
AD
9394 var _extraNames =
9395 has("bug-for-in-skips-shadowed") ?
9396 "hasOwnProperty.valueOf.isPrototypeOf.propertyIsEnumerable.toLocaleString.toString.constructor".split(".") : [],
2f01fe57 9397
1354d172 9398 _extraLen = _extraNames.length,
2f01fe57 9399
1354d172
AD
9400 _mixin = function(dest, source, copyFunc){
9401 var name, s, i, empty = {};
9402 for(name in source){
9403 // the (!(name in empty) || empty[name] !== s) condition avoids copying properties in "source"
9404 // inherited from Object.prototype. For example, if dest has a custom toString() method,
9405 // don't overwrite it with the toString() method that source inherited from Object.prototype
9406 s = source[name];
9407 if(!(name in dest) || (dest[name] !== s && (!(name in empty) || empty[name] !== s))){
9408 dest[name] = copyFunc ? copyFunc(s) : s;
9409 }
9410 }
2f01fe57 9411
1354d172
AD
9412 if(has("bug-for-in-skips-shadowed")){
9413 if(source){
9414 for(i = 0; i < _extraLen; ++i){
9415 name = _extraNames[i];
9416 s = source[name];
9417 if(!(name in dest) || (dest[name] !== s && (!(name in empty) || empty[name] !== s))){
9418 dest[name] = copyFunc ? copyFunc(s) : s;
9419 }
9420 }
9421 }
2f01fe57 9422 }
1354d172
AD
9423
9424 return dest; // Object
2f01fe57 9425 },
1354d172
AD
9426
9427 mixin = function(dest, sources){
9428 if(!dest){ dest = {}; }
9429 for(var i = 1, l = arguments.length; i < l; i++){
9430 lang._mixin(dest, arguments[i]);
2f01fe57 9431 }
1354d172 9432 return dest; // Object
2f01fe57 9433 },
1354d172
AD
9434
9435 getProp = function(/*Array*/parts, /*Boolean*/create, /*Object*/context){
9436 var p, i = 0, dojoGlobal = dojo.global;
9437 if(!context){
9438 if(!parts.length){
9439 return dojoGlobal;
9440 }else{
9441 p = parts[i++];
9442 try{
9443 context = dojo.scopeMap[p] && dojo.scopeMap[p][1];
9444 }catch(e){}
9445 context = context || (p in dojoGlobal ? dojoGlobal[p] : (create ? dojoGlobal[p] = {} : undefined));
9446 }
9447 }
9448 while(context && (p = parts[i++])){
9449 context = (p in context ? context[p] : (create ? context[p] = {} : undefined));
2f01fe57 9450 }
1354d172 9451 return context; // mixed
2f01fe57 9452 },
2f01fe57 9453
1354d172
AD
9454 setObject = function(name, value, context){
9455 var parts = name.split("."), p = parts.pop(), obj = getProp(parts, true, context);
9456 return obj && p ? (obj[p] = value) : undefined; // Object
2f01fe57 9457 },
1354d172
AD
9458
9459 getObject = function(name, create, context){
9460 return getProp(name.split("."), create, context); // Object
2f01fe57 9461 },
2f01fe57 9462
1354d172
AD
9463 exists = function(name, obj){
9464 return lang.getObject(name, false, obj) !== undefined; // Boolean
9465 },
2f01fe57 9466
1354d172 9467 opts = Object.prototype.toString,
2f01fe57 9468
1354d172
AD
9469 // Crockford (ish) functions
9470
9471 isString = function(it){
9472 return (typeof it == "string" || it instanceof String); // Boolean
9473 },
9474
9475 isArray = function(it){
9476 return it && (it instanceof Array || typeof it == "array"); // Boolean
9477 },
9478
9479 isFunction = function(it){
9480 return opts.call(it) === "[object Function]";
9481 },
2f01fe57 9482
1354d172
AD
9483 isObject = function(it){
9484 return it !== undefined &&
9485 (it === null || typeof it == "object" || lang.isArray(it) || lang.isFunction(it)); // Boolean
9486 },
2f01fe57 9487
1354d172
AD
9488 isArrayLike = function(it){
9489 return it && it !== undefined && // Boolean
9490 // keep out built-in constructors (Number, String, ...) which have length
9491 // properties
9492 !lang.isString(it) && !lang.isFunction(it) &&
9493 !(it.tagName && it.tagName.toLowerCase() == 'form') &&
9494 (lang.isArray(it) || isFinite(it.length));
9495 },
2f01fe57 9496
1354d172
AD
9497 isAlien = function(it){
9498 return it && !lang.isFunction(it) && /\{\s*\[native code\]\s*\}/.test(String(it)); // Boolean
9499 },
2f01fe57 9500
1354d172
AD
9501 extend = function(constructor, props){
9502 for(var i=1, l=arguments.length; i<l; i++){
9503 lang._mixin(constructor.prototype, arguments[i]);
2f01fe57 9504 }
1354d172
AD
9505 return constructor; // Object
9506 },
2f01fe57 9507
1354d172
AD
9508 _hitchArgs = function(scope, method){
9509 var pre = _toArray(arguments, 2);
9510 var named = lang.isString(method);
9511 return function(){
9512 // arrayify arguments
9513 var args = _toArray(arguments);
9514 // locate our method
9515 var f = named ? (scope||dojo.global)[method] : method;
9516 // invoke with collected args
9517 return f && f.apply(scope || this, pre.concat(args)); // mixed
9518 }; // Function
9519 },
2f01fe57 9520
1354d172
AD
9521 hitch = function(scope, method){
9522 if(arguments.length > 2){
9523 return lang._hitchArgs.apply(dojo, arguments); // Function
2f01fe57 9524 }
1354d172
AD
9525 if(!method){
9526 method = scope;
9527 scope = null;
9528 }
9529 if(lang.isString(method)){
9530 scope = scope || dojo.global;
9531 if(!scope[method]){ throw(['dojo.hitch: scope["', method, '"] is null (scope="', scope, '")'].join('')); }
9532 return function(){ return scope[method].apply(scope, arguments || []); }; // Function
9533 }
9534 return !scope ? method : function(){ return method.apply(scope, arguments || []); }; // Function
2f01fe57 9535 },
1354d172
AD
9536
9537 delegate = (function(){
9538 // boodman/crockford delegation w/ cornford optimization
9539 function TMP(){}
9540 return function(obj, props){
9541 TMP.prototype = obj;
9542 var tmp = new TMP();
9543 TMP.prototype = null;
9544 if(props){
9545 lang._mixin(tmp, props);
2f01fe57 9546 }
1354d172
AD
9547 return tmp; // Object
9548 };
9549 })(),
9550
9551 efficient = function(obj, offset, startWith){
9552 return (startWith||[]).concat(Array.prototype.slice.call(obj, offset||0));
2f01fe57 9553 },
1354d172
AD
9554
9555 _toArray =
9556 has("ie") ?
9557 (function(){
9558 function slow(obj, offset, startWith){
9559 var arr = startWith||[];
9560 for(var x = offset || 0; x < obj.length; x++){
9561 arr.push(obj[x]);
2f01fe57 9562 }
1354d172 9563 return arr;
2f01fe57 9564 }
1354d172
AD
9565 return function(obj){
9566 return ((obj.item) ? slow : efficient).apply(this, arguments);
9567 };
9568 })() : efficient,
9569
9570 partial = function(/*Function|String*/method /*, ...*/){
9571 var arr = [ null ];
9572 return lang.hitch.apply(dojo, arr.concat(lang._toArray(arguments))); // Function
9573 },
9574
9575 clone = function(/*anything*/ src){
9576 if(!src || typeof src != "object" || lang.isFunction(src)){
9577 // null, undefined, any non-object, or function
9578 return src; // anything
9579 }
9580 if(src.nodeType && "cloneNode" in src){
9581 // DOM Node
9582 return src.cloneNode(true); // Node
9583 }
9584 if(src instanceof Date){
9585 // Date
9586 return new Date(src.getTime()); // Date
9587 }
9588 if(src instanceof RegExp){
9589 // RegExp
9590 return new RegExp(src); // RegExp
9591 }
9592 var r, i, l;
9593 if(lang.isArray(src)){
9594 // array
9595 r = [];
9596 for(i = 0, l = src.length; i < l; ++i){
9597 if(i in src){
9598 r.push(clone(src[i]));
2f01fe57 9599 }
2f01fe57 9600 }
1354d172
AD
9601 // we don't clone functions for performance reasons
9602 // }else if(d.isFunction(src)){
9603 // // function
9604 // r = function(){ return src.apply(this, arguments); };
9605 }else{
9606 // generic objects
9607 r = src.constructor ? new src.constructor() : {};
2f01fe57 9608 }
1354d172
AD
9609 return lang._mixin(r, src, clone);
9610 },
2f01fe57 9611
2f01fe57 9612
1354d172
AD
9613 trim = String.prototype.trim ?
9614 function(str){ return str.trim(); } :
9615 function(str){ return str.replace(/^\s\s*/, '').replace(/\s\s*$/, ''); },
2f01fe57 9616
2f01fe57 9617
1354d172 9618 _pattern = /\{([^\}]+)\}/g,
2f01fe57 9619
1354d172
AD
9620 replace = function(tmpl, map, pattern){
9621 return tmpl.replace(pattern || _pattern, lang.isFunction(map) ?
9622 map : function(_, k){ return getObject(k, false, map); });
9623 },
2f01fe57 9624
1354d172
AD
9625 lang = {
9626 _extraNames:_extraNames,
9627 _mixin:_mixin,
9628 mixin:mixin,
9629 setObject:setObject,
9630 getObject:getObject,
9631 exists:exists,
9632 isString:isString,
9633 isArray:isArray,
9634 isFunction:isFunction,
9635 isObject:isObject,
9636 isArrayLike:isArrayLike,
9637 isAlien:isAlien,
9638 extend:extend,
9639 _hitchArgs:_hitchArgs,
9640 hitch:hitch,
9641 delegate:delegate,
9642 _toArray:_toArray,
9643 partial:partial,
9644 clone:clone,
9645 trim:trim,
9646 replace:replace
9647 };
2f01fe57 9648
1354d172
AD
9649 1 && mixin(dojo, lang);
9650 return lang;
2f01fe57 9651
1354d172
AD
9652 /*=====
9653 dojo._extraNames
9654 // summary:
9655 // Array of strings. Lists property names that must be explicitly processed during for-in interation
9656 // in environments that have has("bug-for-in-skips-shadowed") true.
9657 =====*/
2f01fe57 9658
1354d172
AD
9659 /*=====
9660 dojo._mixin = function(dest, source, copyFunc){
9661 // summary:
9662 // Copies/adds all properties of source to dest; returns dest.
9663 // dest: Object:
9664 // The object to which to copy/add all properties contained in source.
9665 // source: Object:
9666 // The object from which to draw all properties to copy into dest.
9667 // copyFunc: Function?:
9668 // The process used to copy/add a property in source; defaults to the Javascript assignment operator.
9669 // returns:
9670 // dest, as modified
9671 // description:
9672 // All properties, including functions (sometimes termed "methods"), excluding any non-standard extensions
9673 // found in Object.prototype, are copied/added to dest. Copying/adding each particular property is
9674 // delegated to copyFunc (if any); copyFunc defaults to the Javascript assignment operator if not provided.
9675 // Notice that by default, _mixin executes a so-called "shallow copy" and aggregate types are copied/added by reference.
9676 }
9677 =====*/
2f01fe57 9678
1354d172
AD
9679 /*=====
9680 dojo.mixin = function(dest, sources){
9681 // summary:
9682 // Copies/adds all properties of one or more sources to dest; returns dest.
9683 // dest: Object
9684 // The object to which to copy/add all properties contained in source. If dest is falsy, then
9685 // a new object is manufactured before copying/adding properties begins.
9686 // sources: Object...
9687 // One of more objects from which to draw all properties to copy into dest. sources are processed
9688 // left-to-right and if more than one of these objects contain the same property name, the right-most
9689 // value "wins".
9690 // returns: Object
9691 // dest, as modified
9692 // description:
9693 // All properties, including functions (sometimes termed "methods"), excluding any non-standard extensions
9694 // found in Object.prototype, are copied/added from sources to dest. sources are processed left to right.
9695 // The Javascript assignment operator is used to copy/add each property; therefore, by default, mixin
9696 // executes a so-called "shallow copy" and aggregate types are copied/added by reference.
9697 // example:
9698 // make a shallow copy of an object
9699 // | var copy = lang.mixin({}, source);
9700 // example:
9701 // many class constructors often take an object which specifies
9702 // values to be configured on the object. In this case, it is
9703 // often simplest to call `lang.mixin` on the `this` object:
9704 // | dojo.declare("acme.Base", null, {
9705 // | constructor: function(properties){
9706 // | // property configuration:
9707 // | lang.mixin(this, properties);
9708 // |
9709 // | console.log(this.quip);
9710 // | // ...
9711 // | },
9712 // | quip: "I wasn't born yesterday, you know - I've seen movies.",
9713 // | // ...
9714 // | });
9715 // |
9716 // | // create an instance of the class and configure it
9717 // | var b = new acme.Base({quip: "That's what it does!" });
9718 // example:
9719 // copy in properties from multiple objects
9720 // | var flattened = lang.mixin(
9721 // | {
9722 // | name: "Frylock",
9723 // | braces: true
9724 // | },
9725 // | {
9726 // | name: "Carl Brutanananadilewski"
9727 // | }
9728 // | );
9729 // |
9730 // | // will print "Carl Brutanananadilewski"
9731 // | console.log(flattened.name);
9732 // | // will print "true"
9733 // | console.log(flattened.braces);
9734 }
9735 =====*/
2f01fe57 9736
1354d172
AD
9737 /*=====
9738 dojo.setObject = function(name, value, context){
9739 // summary:
9740 // Set a property from a dot-separated string, such as "A.B.C"
9741 // description:
9742 // Useful for longer api chains where you have to test each object in
9743 // the chain, or when you have an object reference in string format.
9744 // Objects are created as needed along `path`. Returns the passed
9745 // value if setting is successful or `undefined` if not.
9746 // name: String
9747 // Path to a property, in the form "A.B.C".
9748 // value: anything
9749 // value or object to place at location given by name
9750 // context: Object?
9751 // Optional. Object to use as root of path. Defaults to
9752 // `dojo.global`.
9753 // example:
9754 // set the value of `foo.bar.baz`, regardless of whether
9755 // intermediate objects already exist:
9756 // | lang.setObject("foo.bar.baz", value);
9757 // example:
9758 // without `lang.setObject`, we often see code like this:
9759 // | // ensure that intermediate objects are available
9760 // | if(!obj["parent"]){ obj.parent = {}; }
9761 // | if(!obj.parent["child"]){ obj.parent.child = {}; }
9762 // | // now we can safely set the property
9763 // | obj.parent.child.prop = "some value";
9764 // whereas with `lang.setObject`, we can shorten that to:
9765 // | lang.setObject("parent.child.prop", "some value", obj);
9766 }
9767 =====*/
2f01fe57 9768
1354d172
AD
9769 /*=====
9770 dojo.getObject = function(name, create, context){
9771 // summary:
9772 // Get a property from a dot-separated string, such as "A.B.C"
9773 // description:
9774 // Useful for longer api chains where you have to test each object in
9775 // the chain, or when you have an object reference in string format.
9776 // name: String
9777 // Path to an property, in the form "A.B.C".
9778 // create: Boolean?
9779 // Optional. Defaults to `false`. If `true`, Objects will be
9780 // created at any point along the 'path' that is undefined.
9781 // context: Object?
9782 // Optional. Object to use as root of path. Defaults to
9783 // 'dojo.global'. Null may be passed.
9784 }
9785 =====*/
2f01fe57 9786
1354d172
AD
9787 /*=====
9788 dojo.exists = function(name, obj){
9789 // summary:
9790 // determine if an object supports a given method
9791 // description:
9792 // useful for longer api chains where you have to test each object in
9793 // the chain. Useful for object and method detection.
9794 // name: String
9795 // Path to an object, in the form "A.B.C".
9796 // obj: Object?
9797 // Object to use as root of path. Defaults to
9798 // 'dojo.global'. Null may be passed.
9799 // example:
9800 // | // define an object
9801 // | var foo = {
9802 // | bar: { }
9803 // | };
9804 // |
9805 // | // search the global scope
9806 // | lang.exists("foo.bar"); // true
9807 // | lang.exists("foo.bar.baz"); // false
9808 // |
9809 // | // search from a particular scope
9810 // | lang.exists("bar", foo); // true
9811 // | lang.exists("bar.baz", foo); // false
9812 }
9813 =====*/
2f01fe57 9814
1354d172
AD
9815 /*=====
9816 dojo.isString = function(it){
9817 // summary:
9818 // Return true if it is a String
9819 // it: anything
9820 // Item to test.
9821 }
9822 =====*/
2f01fe57 9823
1354d172
AD
9824 /*=====
9825 dojo.isArray = function(it){
9826 // summary:
9827 // Return true if it is an Array.
9828 // Does not work on Arrays created in other windows.
9829 // it: anything
9830 // Item to test.
9831 }
9832 =====*/
2f01fe57 9833
1354d172
AD
9834 /*=====
9835 dojo.isFunction = function(it){
9836 // summary:
9837 // Return true if it is a Function
9838 // it: anything
9839 // Item to test.
9840 }
9841 =====*/
2f01fe57 9842
1354d172
AD
9843 /*=====
9844 dojo.isObject = function(it){
9845 // summary:
9846 // Returns true if it is a JavaScript object (or an Array, a Function
9847 // or null)
9848 // it: anything
9849 // Item to test.
9850 }
9851 =====*/
2f01fe57 9852
1354d172
AD
9853 /*=====
9854 dojo.isArrayLike = function(it){
9855 // summary:
9856 // similar to dojo.isArray() but more permissive
9857 // it: anything
9858 // Item to test.
9859 // returns:
9860 // If it walks like a duck and quacks like a duck, return `true`
9861 // description:
9862 // Doesn't strongly test for "arrayness". Instead, settles for "isn't
9863 // a string or number and has a length property". Arguments objects
9864 // and DOM collections will return true when passed to
9865 // dojo.isArrayLike(), but will return false when passed to
9866 // dojo.isArray().
9867 }
9868 =====*/
2f01fe57 9869
1354d172
AD
9870 /*=====
9871 dojo.isAlien = function(it){
9872 // summary:
9873 // Returns true if it is a built-in function or some other kind of
9874 // oddball that *should* report as a function but doesn't
9875 }
9876 =====*/
2f01fe57 9877
1354d172
AD
9878 /*=====
9879 dojo.extend = function(constructor, props){
9880 // summary:
9881 // Adds all properties and methods of props to constructor's
9882 // prototype, making them available to all instances created with
9883 // constructor.
9884 // constructor: Object
9885 // Target constructor to extend.
9886 // props: Object...
9887 // One or more objects to mix into constructor.prototype
9888 }
9889 =====*/
2f01fe57 9890
1354d172
AD
9891 /*=====
9892 dojo.hitch = function(scope, method){
9893 // summary:
9894 // Returns a function that will only ever execute in the a given scope.
9895 // This allows for easy use of object member functions
9896 // in callbacks and other places in which the "this" keyword may
9897 // otherwise not reference the expected scope.
9898 // Any number of default positional arguments may be passed as parameters
9899 // beyond "method".
9900 // Each of these values will be used to "placehold" (similar to curry)
9901 // for the hitched function.
9902 // scope: Object
9903 // The scope to use when method executes. If method is a string,
9904 // scope is also the object containing method.
9905 // method: Function|String...
9906 // A function to be hitched to scope, or the name of the method in
9907 // scope to be hitched.
9908 // example:
9909 // | dojo.hitch(foo, "bar")();
9910 // runs foo.bar() in the scope of foo
9911 // example:
9912 // | dojo.hitch(foo, myFunction);
9913 // returns a function that runs myFunction in the scope of foo
9914 // example:
9915 // Expansion on the default positional arguments passed along from
9916 // hitch. Passed args are mixed first, additional args after.
9917 // | var foo = { bar: function(a, b, c){ console.log(a, b, c); } };
9918 // | var fn = dojo.hitch(foo, "bar", 1, 2);
9919 // | fn(3); // logs "1, 2, 3"
9920 // example:
9921 // | var foo = { bar: 2 };
9922 // | dojo.hitch(foo, function(){ this.bar = 10; })();
9923 // execute an anonymous function in scope of foo
9924 }
9925 =====*/
2f01fe57 9926
1354d172
AD
9927 /*=====
9928 dojo.delegate = function(obj, props){
9929 // summary:
9930 // Returns a new object which "looks" to obj for properties which it
9931 // does not have a value for. Optionally takes a bag of properties to
9932 // seed the returned object with initially.
9933 // description:
9934 // This is a small implementaton of the Boodman/Crockford delegation
9935 // pattern in JavaScript. An intermediate object constructor mediates
9936 // the prototype chain for the returned object, using it to delegate
9937 // down to obj for property lookup when object-local lookup fails.
9938 // This can be thought of similarly to ES4's "wrap", save that it does
9939 // not act on types but rather on pure objects.
9940 // obj: Object
9941 // The object to delegate to for properties not found directly on the
9942 // return object or in props.
9943 // props: Object...
9944 // an object containing properties to assign to the returned object
9945 // returns:
9946 // an Object of anonymous type
9947 // example:
9948 // | var foo = { bar: "baz" };
9949 // | var thinger = dojo.delegate(foo, { thud: "xyzzy"});
9950 // | thinger.bar == "baz"; // delegated to foo
9951 // | foo.thud == undefined; // by definition
9952 // | thinger.thud == "xyzzy"; // mixed in from props
9953 // | foo.bar = "thonk";
9954 // | thinger.bar == "thonk"; // still delegated to foo's bar
9955 }
9956 =====*/
2f01fe57 9957
1354d172
AD
9958 /*=====
9959 dojo.partial = function(method){
9960 // summary:
9961 // similar to hitch() except that the scope object is left to be
9962 // whatever the execution context eventually becomes.
9963 // method: Function|String
9964 // description:
9965 // Calling dojo.partial is the functional equivalent of calling:
9966 // | dojo.hitch(null, funcName, ...);
9967 }
9968 =====*/
2f01fe57 9969
1354d172
AD
9970 /*=====
9971 dojo.trim = function(str){
9972 // summary:
9973 // Trims whitespace from both sides of the string
9974 // str: String
9975 // String to be trimmed
9976 // returns: String
9977 // Returns the trimmed string
9978 // description:
9979 // This version of trim() was selected for inclusion into the base due
9980 // to its compact size and relatively good performance
9981 // (see [Steven Levithan's blog](http://blog.stevenlevithan.com/archives/faster-trim-javascript)
9982 // Uses String.prototype.trim instead, if available.
9983 // The fastest but longest version of this function is located at
9984 // dojo.string.trim()
9985 }
9986 =====*/
9987
9988 /*=====
9989 dojo.clone = function(src){
9990 // summary:
9991 // Clones objects (including DOM nodes) and all children.
9992 // Warning: do not clone cyclic structures.
9993 // src:
9994 // The object to clone
9995 }
9996 =====*/
2f01fe57 9997
1354d172
AD
9998 /*=====
9999 dojo._toArray = function(obj, offset, startWith){
2f01fe57 10000 // summary:
1354d172
AD
10001 // Converts an array-like object (i.e. arguments, DOMCollection) to an
10002 // array. Returns a new Array with the elements of obj.
10003 // obj: Object
10004 // the object to "arrayify". We expect the object to have, at a
10005 // minimum, a length property which corresponds to integer-indexed
10006 // properties.
10007 // offset: Number?
10008 // the location in obj to start iterating from. Defaults to 0.
10009 // Optional.
10010 // startWith: Array?
10011 // An array to pack with the properties of obj. If provided,
10012 // properties in obj are appended at the end of startWith and
10013 // startWith is the returned array.
10014 }
10015 =====*/
10016
10017 /*=====
10018 dojo.replace = function(tmpl, map, pattern){
10019 // summary:
10020 // Performs parameterized substitutions on a string. Throws an
10021 // exception if any parameter is unmatched.
10022 // tmpl: String
10023 // String to be used as a template.
10024 // map: Object|Function
10025 // If an object, it is used as a dictionary to look up substitutions.
10026 // If a function, it is called for every substitution with following
10027 // parameters: a whole match, a name, an offset, and the whole template
10028 // string (see https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/String/replace
10029 // for more details).
10030 // pattern: RegEx?
10031 // Optional regular expression objects that overrides the default pattern.
10032 // Must be global and match one item. The default is: /\{([^\}]+)\}/g,
10033 // which matches patterns like that: "{xxx}", where "xxx" is any sequence
10034 // of characters, which doesn't include "}".
10035 // returns: String
10036 // Returns the substituted string.
2f01fe57 10037 // example:
1354d172
AD
10038 // | // uses a dictionary for substitutions:
10039 // | dojo.replace("Hello, {name.first} {name.last} AKA {nick}!",
10040 // | {
10041 // | nick: "Bob",
10042 // | name: {
10043 // | first: "Robert",
10044 // | middle: "X",
10045 // | last: "Cringely"
10046 // | }
10047 // | });
10048 // | // returns: Hello, Robert Cringely AKA Bob!
2f01fe57 10049 // example:
1354d172
AD
10050 // | // uses an array for substitutions:
10051 // | dojo.replace("Hello, {0} {2}!",
10052 // | ["Robert", "X", "Cringely"]);
10053 // | // returns: Hello, Robert Cringely!
2f01fe57 10054 // example:
1354d172
AD
10055 // | // uses a function for substitutions:
10056 // | function sum(a){
10057 // | var t = 0;
10058 // | dojo.forEach(a, function(x){ t += x; });
10059 // | return t;
10060 // | }
10061 // | dojo.replace(
10062 // | "{count} payments averaging {avg} USD per payment.",
10063 // | dojo.hitch(
10064 // | { payments: [11, 16, 12] },
10065 // | function(_, key){
10066 // | switch(key){
10067 // | case "count": return this.payments.length;
10068 // | case "min": return Math.min.apply(Math, this.payments);
10069 // | case "max": return Math.max.apply(Math, this.payments);
10070 // | case "sum": return sum(this.payments);
10071 // | case "avg": return sum(this.payments) / this.payments.length;
10072 // | }
2f01fe57 10073 // | }
1354d172
AD
10074 // | )
10075 // | );
10076 // | // prints: 3 payments averaging 13 USD per payment.
10077 // example:
10078 // | // uses an alternative PHP-like pattern for substitutions:
10079 // | dojo.replace("Hello, ${0} ${2}!",
10080 // | ["Robert", "X", "Cringely"], /\$\{([^\}]+)\}/g);
10081 // | // returns: Hello, Robert Cringely!
10082 return ""; // String
10083 }
10084 =====*/
10085});
2f01fe57 10086
2f01fe57 10087
1354d172
AD
10088},
10089'dojo/Evented':function(){
10090define(["./aspect", "./on"], function(aspect, on){
10091 // summary:
10092 // The export of this module is a class that can be used as a mixin or base class,
10093 // to add on() and emit() methods to a class
10094 // for listening for events and emiting events:
10095 // |define(["dojo/Evented"], function(Evented){
10096 // | var EventedWidget = dojo.declare([Evented, dijit._Widget], {...});
10097 // | widget = new EventedWidget();
10098 // | widget.on("open", function(event){
10099 // | ... do something with event
10100 // | });
10101 // |
10102 // | widget.emit("open", {name:"some event", ...});
10103
10104 "use strict";
10105 var after = aspect.after;
10106 function Evented(){
10107 }
10108 Evented.prototype = {
10109 on: function(type, listener){
10110 return on.parse(this, type, listener, function(target, type){
10111 return after(target, 'on' + type, listener, true);
10112 });
10113 },
10114 emit: function(type, event){
10115 var args = [this];
10116 args.push.apply(args, arguments);
10117 return on.emit.apply(on, args);
2f01fe57 10118 }
1354d172
AD
10119 };
10120 return Evented;
10121});
2f01fe57 10122
1354d172
AD
10123},
10124'dojo/mouse':function(){
10125define(["./_base/kernel", "./on", "./has", "./dom", "./_base/window"], function(dojo, on, has, dom, win){
2f01fe57 10126
1354d172
AD
10127 /*=====
10128 dojo.mouse = {
10129 // summary:
10130 // This module provide mouse event handling utility functions and exports
10131 // mouseenter and mouseleave event emulation.
10132 // enter: Synthetic Event
10133 // This is an extension event for the mouseenter that IE provides, emulating the
10134 // behavior on other browsers.
10135 // leave: Synthetic Event
10136 // This is an extension event for the mouseleave that IE provides, emulating the
10137 // behavior on other browsers.
10138 // isLeft: Function
10139 // Test an event object (from a mousedown event) to see if the left button was pressed.
10140 // isMiddle: Function
10141 // Test an event object (from a mousedown event) to see if the middle button was pressed.
10142 // isRight: Function
10143 // Test an event object (from a mousedown event) to see if the right button was pressed.
10144 // example:
10145 // To use these events, you register a mouseenter like this:
10146 // | define(["dojo/on", dojo/mouse"], function(on, mouse){
10147 // | on(targetNode, mouse.enter, function(event){
10148 // | dojo.addClass(targetNode, "highlighted");
10149 // | });
10150 // | on(targetNode, mouse.leave, function(event){
10151 // | dojo.removeClass(targetNode, "highlighted");
10152 // | });
10153 };
10154 ======*/
2f01fe57 10155
1354d172
AD
10156 has.add("dom-quirks", win.doc && win.doc.compatMode == "BackCompat");
10157 has.add("events-mouseenter", win.doc && "onmouseenter" in win.doc.createElement("div"));
2f01fe57 10158
1354d172
AD
10159 var mouseButtons;
10160 if(has("dom-quirks") || !has("dom-addeventlistener")){
10161 mouseButtons = {
10162 LEFT: 1,
10163 MIDDLE: 4,
10164 RIGHT: 2,
10165 // helper functions
10166 isButton: function(e, button){ return e.button & button; },
10167 isLeft: function(e){ return e.button & 1; },
10168 isMiddle: function(e){ return e.button & 4; },
10169 isRight: function(e){ return e.button & 2; }
10170 };
10171 }else{
10172 mouseButtons = {
10173 LEFT: 0,
10174 MIDDLE: 1,
10175 RIGHT: 2,
10176 // helper functions
10177 isButton: function(e, button){ return e.button == button; },
10178 isLeft: function(e){ return e.button == 0; },
10179 isMiddle: function(e){ return e.button == 1; },
10180 isRight: function(e){ return e.button == 2; }
10181 };
2f01fe57 10182 }
1354d172 10183 dojo.mouseButtons = mouseButtons;
2f01fe57 10184
1354d172
AD
10185/*=====
10186 dojo.mouseButtons = {
10187 // LEFT: Number
10188 // Numeric value of the left mouse button for the platform.
10189 LEFT: 0,
10190 // MIDDLE: Number
10191 // Numeric value of the middle mouse button for the platform.
10192 MIDDLE: 1,
10193 // RIGHT: Number
10194 // Numeric value of the right mouse button for the platform.
10195 RIGHT: 2,
81bea17a 10196
1354d172 10197 isButton: function(e, button){
81bea17a 10198 // summary:
1354d172
AD
10199 // Checks an event object for a pressed button
10200 // e: Event
10201 // Event object to examine
10202 // button: Number
10203 // The button value (example: dojo.mouseButton.LEFT)
10204 return e.button == button; // Boolean
81bea17a 10205 },
1354d172
AD
10206 isLeft: function(e){
10207 // summary:
10208 // Checks an event object for the pressed left button
10209 // e: Event
10210 // Event object to examine
10211 return e.button == 0; // Boolean
10212 },
10213 isMiddle: function(e){
10214 // summary:
10215 // Checks an event object for the pressed middle button
10216 // e: Event
10217 // Event object to examine
10218 return e.button == 1; // Boolean
81bea17a 10219 },
1354d172
AD
10220 isRight: function(e){
10221 // summary:
10222 // Checks an event object for the pressed right button
10223 // e: Event
10224 // Event object to examine
10225 return e.button == 2; // Boolean
10226 }
81bea17a 10227 };
1354d172 10228=====*/
81bea17a 10229
1354d172
AD
10230 function eventHandler(type, mustBubble){
10231 // emulation of mouseenter/leave with mouseover/out using descendant checking
10232 var handler = function(node, listener){
10233 return on(node, type, function(evt){
10234 if(!dom.isDescendant(evt.relatedTarget, mustBubble ? evt.target : node)){
10235 return listener.call(this, evt);
10236 }
10237 });
10238 };
10239 if(!mustBubble){
10240 handler.bubble = eventHandler(type, true);
81bea17a 10241 }
1354d172 10242 return handler;
81bea17a 10243 }
1354d172
AD
10244 return {
10245 enter: eventHandler("mouseover"),
10246 leave: eventHandler("mouseout"),
10247 isLeft: mouseButtons.isLeft,
10248 isMiddle: mouseButtons.isMiddle,
10249 isRight: mouseButtons.isRight
10250 };
10251});
10252
10253},
10254'dojo/topic':function(){
10255define(["./Evented"], function(Evented){
10256 // summary:
10257 // The export of this module is a pubsub hub
10258 // You can also use listen function itself as a pub/sub hub:
10259 // | topic.subscribe("some/topic", function(event){
10260 // | ... do something with event
10261 // | });
10262 // | topic.publish("some/topic", {name:"some event", ...});
2f01fe57 10263
1354d172
AD
10264 var hub = new Evented;
10265 return {
10266 publish: function(topic, event){
10267 // summary:
10268 // Publishes a message to a topic on the pub/sub hub. All arguments after
10269 // the first will be passed to the subscribers, so any number of arguments
10270 // can be provided (not just event).
10271 // topic: String
10272 // The name of the topic to publish to
10273 // event: Object
10274 // An event to distribute to the topic listeners
10275 return hub.emit.apply(hub, arguments);
10276 },
10277 subscribe: function(topic, listener){
10278 // summary:
10279 // Subcribes to a topic on the pub/sub hub
10280 // topic: String
10281 // The topic to subscribe to
10282 // listener: Function
10283 // A function to call when a message is published to the given topic
10284 return hub.on.apply(hub, arguments);
2f01fe57
AD
10285 }
10286 }
1354d172
AD
10287});
10288
10289},
10290'dojo/_base/xhr':function(){
10291define([
10292 "./kernel", "./sniff", "require", "../io-query", "../dom", "../dom-form", "./Deferred", "./json", "./lang", "./array", "../on"
10293], function(dojo, has, require, ioq, dom, domForm, deferred, json, lang, array, on){
10294 // module:
10295 // dojo/_base.xhr
10296 // summary:
10297 // This modules defines the dojo.xhr* API.
2f01fe57 10298
1354d172
AD
10299 has.add("native-xhr", function() {
10300 // if true, the environment has a native XHR implementation
10301 return typeof XMLHttpRequest !== 'undefined';
10302 });
2f01fe57 10303
1354d172
AD
10304 if(1 && require.getXhr){
10305 dojo._xhrObj = require.getXhr;
10306 }else if (has("native-xhr")){
10307 dojo._xhrObj = function(){
10308 // summary:
10309 // does the work of portably generating a new XMLHTTPRequest object.
10310 try{
10311 return new XMLHttpRequest();
10312 }catch(e){
10313 throw new Error("XMLHTTP not available: "+e);
2f01fe57 10314 }
1354d172
AD
10315 };
10316 }else{
10317 // PROGIDs are in order of decreasing likelihood; this will change in time.
10318 for(var XMLHTTP_PROGIDS = ['Msxml2.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.4.0'], progid, i = 0; i < 3;){
10319 try{
10320 progid = XMLHTTP_PROGIDS[i++];
10321 if (new ActiveXObject(progid)) {
10322 // this progid works; therefore, use it from now on
10323 break;
2f01fe57 10324 }
1354d172
AD
10325 }catch(e){
10326 // squelch; we're just trying to find a good ActiveX PROGID
10327 // if they all fail, then progid ends up as the last attempt and that will signal the error
10328 // the first time the client actually tries to exec an xhr
2f01fe57 10329 }
1354d172
AD
10330 }
10331 dojo._xhrObj= function() {
10332 return new ActiveXObject(progid);
10333 };
10334 }
10335
10336 var cfg = dojo.config;
10337
10338 // mix in io-query and dom-form
10339 dojo.objectToQuery = ioq.objectToQuery;
10340 dojo.queryToObject = ioq.queryToObject;
10341 dojo.fieldToObject = domForm.fieldToObject;
10342 dojo.formToObject = domForm.toObject;
10343 dojo.formToQuery = domForm.toQuery;
10344 dojo.formToJson = domForm.toJson;
2f01fe57
AD
10345
10346 // need to block async callbacks from snatching this thread as the result
10347 // of an async callback might call another sync XHR, this hangs khtml forever
10348 // must checked by watchInFlight()
10349
10350 dojo._blockAsync = false;
10351
10352 // MOW: remove dojo._contentHandlers alias in 2.0
1354d172 10353 var handlers = dojo._contentHandlers = dojo.contentHandlers = {
81bea17a 10354 // summary:
2f01fe57
AD
10355 // A map of availble XHR transport handle types. Name matches the
10356 // `handleAs` attribute passed to XHR calls.
10357 //
10358 // description:
10359 // A map of availble XHR transport handle types. Name matches the
10360 // `handleAs` attribute passed to XHR calls. Each contentHandler is
10361 // called, passing the xhr object for manipulation. The return value
81bea17a
AD
10362 // from the contentHandler will be passed to the `load` or `handle`
10363 // functions defined in the original xhr call.
10364 //
2f01fe57
AD
10365 // example:
10366 // Creating a custom content-handler:
10367 // | dojo.contentHandlers.makeCaps = function(xhr){
10368 // | return xhr.responseText.toUpperCase();
10369 // | }
10370 // | // and later:
81bea17a 10371 // | dojo.xhrGet({
2f01fe57
AD
10372 // | url:"foo.txt",
10373 // | handleAs:"makeCaps",
10374 // | load: function(data){ /* data is a toUpper version of foo.txt */ }
10375 // | });
10376
1354d172 10377 "text": function(xhr){
2f01fe57 10378 // summary: A contentHandler which simply returns the plaintext response data
81bea17a 10379 return xhr.responseText;
2f01fe57 10380 },
1354d172 10381 "json": function(xhr){
2f01fe57 10382 // summary: A contentHandler which returns a JavaScript object created from the response data
1354d172 10383 return json.fromJson(xhr.responseText || null);
2f01fe57 10384 },
81bea17a
AD
10385 "json-comment-filtered": function(xhr){
10386 // summary: A contentHandler which expects comment-filtered JSON.
10387 // description:
10388 // A contentHandler which expects comment-filtered JSON.
2f01fe57
AD
10389 // the json-comment-filtered option was implemented to prevent
10390 // "JavaScript Hijacking", but it is less secure than standard JSON. Use
10391 // standard JSON instead. JSON prefixing can be used to subvert hijacking.
81bea17a 10392 //
2f01fe57
AD
10393 // Will throw a notice suggesting to use application/json mimetype, as
10394 // json-commenting can introduce security issues. To decrease the chances of hijacking,
81bea17a
AD
10395 // use the standard `json` contentHandler, and prefix your "JSON" with: {}&&
10396 //
2f01fe57
AD
10397 // use djConfig.useCommentedJson = true to turn off the notice
10398 if(!dojo.config.useCommentedJson){
10399 console.warn("Consider using the standard mimetype:application/json."
10400 + " json-commenting can introduce security issues. To"
10401 + " decrease the chances of hijacking, use the standard the 'json' handler and"
10402 + " prefix your json with: {}&&\n"
10403 + "Use djConfig.useCommentedJson=true to turn off this message.");
10404 }
10405
10406 var value = xhr.responseText;
10407 var cStartIdx = value.indexOf("\/*");
10408 var cEndIdx = value.lastIndexOf("*\/");
10409 if(cStartIdx == -1 || cEndIdx == -1){
10410 throw new Error("JSON was not comment filtered");
10411 }
1354d172 10412 return json.fromJson(value.substring(cStartIdx+2, cEndIdx));
2f01fe57 10413 },
1354d172 10414 "javascript": function(xhr){
2f01fe57
AD
10415 // summary: A contentHandler which evaluates the response data, expecting it to be valid JavaScript
10416
10417 // FIXME: try Moz and IE specific eval variants?
1354d172 10418 return dojo.eval(xhr.responseText);
2f01fe57 10419 },
1354d172 10420 "xml": function(xhr){
2f01fe57
AD
10421 // summary: A contentHandler returning an XML Document parsed from the response data
10422 var result = xhr.responseXML;
1354d172
AD
10423
10424 if(has("ie")){
10425 if((!result || !result.documentElement)){
10426 //WARNING: this branch used by the xml handling in dojo.io.iframe,
10427 //so be sure to test dojo.io.iframe if making changes below.
10428 var ms = function(n){ return "MSXML" + n + ".DOMDocument"; };
10429 var dp = ["Microsoft.XMLDOM", ms(6), ms(4), ms(3), ms(2)];
10430 array.some(dp, function(p){
10431 try{
10432 var dom = new ActiveXObject(p);
10433 dom.async = false;
10434 dom.loadXML(xhr.responseText);
10435 result = dom;
10436 }catch(e){ return false; }
10437 return true;
10438 });
10439 }
10440 }
10441 return result; // DOMDocument
2f01fe57
AD
10442 },
10443 "json-comment-optional": function(xhr){
81bea17a 10444 // summary: A contentHandler which checks the presence of comment-filtered JSON and
2f01fe57
AD
10445 // alternates between the `json` and `json-comment-filtered` contentHandlers.
10446 if(xhr.responseText && /^[^{\[]*\/\*/.test(xhr.responseText)){
10447 return handlers["json-comment-filtered"](xhr);
10448 }else{
10449 return handlers["json"](xhr);
10450 }
10451 }
10452 };
10453
10454 /*=====
10455 dojo.__IoArgs = function(){
10456 // url: String
10457 // URL to server endpoint.
10458 // content: Object?
10459 // Contains properties with string values. These
10460 // properties will be serialized as name1=value2 and
10461 // passed in the request.
10462 // timeout: Integer?
10463 // Milliseconds to wait for the response. If this time
10464 // passes, the then error callbacks are called.
10465 // form: DOMNode?
10466 // DOM node for a form. Used to extract the form values
10467 // and send to the server.
10468 // preventCache: Boolean?
10469 // Default is false. If true, then a
10470 // "dojo.preventCache" parameter is sent in the request
10471 // with a value that changes with each request
10472 // (timestamp). Useful only with GET-type requests.
10473 // handleAs: String?
10474 // Acceptable values depend on the type of IO
10475 // transport (see specific IO calls for more information).
81bea17a 10476 // rawBody: String?
1354d172
AD
10477 // Sets the raw body for an HTTP request. If this is used, then the content
10478 // property is ignored. This is mostly useful for HTTP methods that have
10479 // a body to their requests, like PUT or POST. This property can be used instead
10480 // of postData and putData for dojo.rawXhrPost and dojo.rawXhrPut respectively.
2f01fe57
AD
10481 // ioPublish: Boolean?
10482 // Set this explicitly to false to prevent publishing of topics related to
1354d172
AD
10483 // IO operations. Otherwise, if djConfig.ioPublish is set to true, topics
10484 // will be published via dojo.publish for different phases of an IO operation.
10485 // See dojo.__IoPublish for a list of topics that are published.
2f01fe57
AD
10486 // load: Function?
10487 // This function will be
10488 // called on a successful HTTP response code.
10489 // error: Function?
10490 // This function will
10491 // be called when the request fails due to a network or server error, the url
10492 // is invalid, etc. It will also be called if the load or handle callback throws an
1354d172 10493 // exception, unless djConfig.debugAtAllCosts is true. This allows deployed applications
2f01fe57
AD
10494 // to continue to run even when a logic error happens in the callback, while making
10495 // it easier to troubleshoot while in debug mode.
10496 // handle: Function?
10497 // This function will
10498 // be called at the end of every request, whether or not an error occurs.
10499 this.url = url;
10500 this.content = content;
10501 this.timeout = timeout;
10502 this.form = form;
10503 this.preventCache = preventCache;
10504 this.handleAs = handleAs;
10505 this.ioPublish = ioPublish;
10506 this.load = function(response, ioArgs){
10507 // ioArgs: dojo.__IoCallbackArgs
10508 // Provides additional information about the request.
10509 // response: Object
10510 // The response in the format as defined with handleAs.
10511 }
10512 this.error = function(response, ioArgs){
10513 // ioArgs: dojo.__IoCallbackArgs
10514 // Provides additional information about the request.
10515 // response: Object
10516 // The response in the format as defined with handleAs.
10517 }
10518 this.handle = function(loadOrError, response, ioArgs){
10519 // loadOrError: String
10520 // Provides a string that tells you whether this function
10521 // was called because of success (load) or failure (error).
10522 // response: Object
10523 // The response in the format as defined with handleAs.
10524 // ioArgs: dojo.__IoCallbackArgs
10525 // Provides additional information about the request.
10526 }
10527 }
10528 =====*/
10529
10530 /*=====
10531 dojo.__IoCallbackArgs = function(args, xhr, url, query, handleAs, id, canDelete, json){
10532 // args: Object
10533 // the original object argument to the IO call.
10534 // xhr: XMLHttpRequest
10535 // For XMLHttpRequest calls only, the
10536 // XMLHttpRequest object that was used for the
10537 // request.
10538 // url: String
10539 // The final URL used for the call. Many times it
10540 // will be different than the original args.url
10541 // value.
10542 // query: String
10543 // For non-GET requests, the
10544 // name1=value1&name2=value2 parameters sent up in
10545 // the request.
10546 // handleAs: String
10547 // The final indicator on how the response will be
10548 // handled.
10549 // id: String
10550 // For dojo.io.script calls only, the internal
10551 // script ID used for the request.
10552 // canDelete: Boolean
10553 // For dojo.io.script calls only, indicates
10554 // whether the script tag that represents the
10555 // request can be deleted after callbacks have
10556 // been called. Used internally to know when
10557 // cleanup can happen on JSONP-type requests.
10558 // json: Object
10559 // For dojo.io.script calls only: holds the JSON
10560 // response for JSONP-type requests. Used
10561 // internally to hold on to the JSON responses.
10562 // You should not need to access it directly --
10563 // the same object should be passed to the success
10564 // callbacks directly.
10565 this.args = args;
10566 this.xhr = xhr;
10567 this.url = url;
10568 this.query = query;
10569 this.handleAs = handleAs;
10570 this.id = id;
10571 this.canDelete = canDelete;
10572 this.json = json;
10573 }
10574 =====*/
10575
10576
10577 /*=====
10578 dojo.__IoPublish = function(){
1354d172
AD
10579 // summary:
10580 // This is a list of IO topics that can be published
10581 // if djConfig.ioPublish is set to true. IO topics can be
10582 // published for any Input/Output, network operation. So,
10583 // dojo.xhr, dojo.io.script and dojo.io.iframe can all
10584 // trigger these topics to be published.
2f01fe57
AD
10585 // start: String
10586 // "/dojo/io/start" is sent when there are no outstanding IO
1354d172
AD
10587 // requests, and a new IO request is started. No arguments
10588 // are passed with this topic.
2f01fe57
AD
10589 // send: String
10590 // "/dojo/io/send" is sent whenever a new IO request is started.
1354d172 10591 // It passes the dojo.Deferred for the request with the topic.
2f01fe57
AD
10592 // load: String
10593 // "/dojo/io/load" is sent whenever an IO request has loaded
1354d172
AD
10594 // successfully. It passes the response and the dojo.Deferred
10595 // for the request with the topic.
2f01fe57
AD
10596 // error: String
10597 // "/dojo/io/error" is sent whenever an IO request has errored.
1354d172
AD
10598 // It passes the error and the dojo.Deferred
10599 // for the request with the topic.
2f01fe57
AD
10600 // done: String
10601 // "/dojo/io/done" is sent whenever an IO request has completed,
1354d172
AD
10602 // either by loading or by erroring. It passes the error and
10603 // the dojo.Deferred for the request with the topic.
2f01fe57
AD
10604 // stop: String
10605 // "/dojo/io/stop" is sent when all outstanding IO requests have
1354d172 10606 // finished. No arguments are passed with this topic.
2f01fe57
AD
10607 this.start = "/dojo/io/start";
10608 this.send = "/dojo/io/send";
10609 this.load = "/dojo/io/load";
10610 this.error = "/dojo/io/error";
10611 this.done = "/dojo/io/done";
10612 this.stop = "/dojo/io/stop";
10613 }
10614 =====*/
10615
10616
10617 dojo._ioSetArgs = function(/*dojo.__IoArgs*/args,
10618 /*Function*/canceller,
10619 /*Function*/okHandler,
10620 /*Function*/errHandler){
81bea17a 10621 // summary:
2f01fe57
AD
10622 // sets up the Deferred and ioArgs property on the Deferred so it
10623 // can be used in an io call.
10624 // args:
10625 // The args object passed into the public io call. Recognized properties on
10626 // the args object are:
10627 // canceller:
10628 // The canceller function used for the Deferred object. The function
10629 // will receive one argument, the Deferred object that is related to the
10630 // canceller.
10631 // okHandler:
10632 // The first OK callback to be registered with Deferred. It has the opportunity
10633 // to transform the OK response. It will receive one argument -- the Deferred
10634 // object returned from this function.
10635 // errHandler:
10636 // The first error callback to be registered with Deferred. It has the opportunity
81bea17a 10637 // to do cleanup on an error. It will receive two arguments: error (the
2f01fe57
AD
10638 // Error object) and dfd, the Deferred object returned from this function.
10639
10640 var ioArgs = {args: args, url: args.url};
10641
10642 //Get values from form if requestd.
10643 var formObject = null;
81bea17a 10644 if(args.form){
1354d172 10645 var form = dom.byId(args.form);
81bea17a 10646 //IE requires going through getAttributeNode instead of just getAttribute in some form cases,
1354d172 10647 //so use it for all. See #2844
2f01fe57 10648 var actnNode = form.getAttributeNode("action");
81bea17a 10649 ioArgs.url = ioArgs.url || (actnNode ? actnNode.value : null);
1354d172 10650 formObject = domForm.toObject(form);
2f01fe57
AD
10651 }
10652
10653 // set up the query params
10654 var miArgs = [{}];
1354d172 10655
2f01fe57
AD
10656 if(formObject){
10657 // potentially over-ride url-provided params w/ form values
10658 miArgs.push(formObject);
10659 }
10660 if(args.content){
10661 // stuff in content over-rides what's set by form
10662 miArgs.push(args.content);
10663 }
10664 if(args.preventCache){
10665 miArgs.push({"dojo.preventCache": new Date().valueOf()});
10666 }
1354d172
AD
10667 ioArgs.query = ioq.objectToQuery(lang.mixin.apply(null, miArgs));
10668
2f01fe57
AD
10669 // .. and the real work of getting the deferred in order, etc.
10670 ioArgs.handleAs = args.handleAs || "text";
1354d172 10671 var d = new deferred(canceller);
2f01fe57
AD
10672 d.addCallbacks(okHandler, function(error){
10673 return errHandler(error, d);
10674 });
10675
10676 //Support specifying load, error and handle callback functions from the args.
10677 //For those callbacks, the "this" object will be the args object.
10678 //The callbacks will get the deferred result value as the
10679 //first argument and the ioArgs object as the second argument.
10680 var ld = args.load;
1354d172 10681 if(ld && lang.isFunction(ld)){
2f01fe57
AD
10682 d.addCallback(function(value){
10683 return ld.call(args, value, ioArgs);
10684 });
10685 }
10686 var err = args.error;
1354d172 10687 if(err && lang.isFunction(err)){
2f01fe57
AD
10688 d.addErrback(function(value){
10689 return err.call(args, value, ioArgs);
10690 });
10691 }
10692 var handle = args.handle;
1354d172 10693 if(handle && lang.isFunction(handle)){
2f01fe57
AD
10694 d.addBoth(function(value){
10695 return handle.call(args, value, ioArgs);
10696 });
10697 }
10698
10699 //Plug in topic publishing, if dojo.publish is loaded.
1354d172 10700 if(cfg.ioPublish && dojo.publish && ioArgs.args.ioPublish !== false){
2f01fe57
AD
10701 d.addCallbacks(
10702 function(res){
1354d172 10703 dojo.publish("/dojo/io/load", [d, res]);
2f01fe57
AD
10704 return res;
10705 },
10706 function(res){
1354d172 10707 dojo.publish("/dojo/io/error", [d, res]);
2f01fe57
AD
10708 return res;
10709 }
10710 );
10711 d.addBoth(function(res){
1354d172 10712 dojo.publish("/dojo/io/done", [d, res]);
2f01fe57
AD
10713 return res;
10714 });
10715 }
10716
10717 d.ioArgs = ioArgs;
1354d172 10718
2f01fe57
AD
10719 // FIXME: need to wire up the xhr object's abort method to something
10720 // analagous in the Deferred
10721 return d;
81bea17a 10722 };
2f01fe57
AD
10723
10724 var _deferredCancel = function(/*Deferred*/dfd){
10725 // summary: canceller function for dojo._ioSetArgs call.
1354d172 10726
2f01fe57
AD
10727 dfd.canceled = true;
10728 var xhr = dfd.ioArgs.xhr;
10729 var _at = typeof xhr.abort;
10730 if(_at == "function" || _at == "object" || _at == "unknown"){
10731 xhr.abort();
10732 }
10733 var err = dfd.ioArgs.error;
10734 if(!err){
10735 err = new Error("xhr cancelled");
10736 err.dojoType="cancel";
10737 }
10738 return err;
81bea17a 10739 };
2f01fe57
AD
10740 var _deferredOk = function(/*Deferred*/dfd){
10741 // summary: okHandler function for dojo._ioSetArgs call.
10742
10743 var ret = handlers[dfd.ioArgs.handleAs](dfd.ioArgs.xhr);
10744 return ret === undefined ? null : ret;
81bea17a 10745 };
2f01fe57
AD
10746 var _deferError = function(/*Error*/error, /*Deferred*/dfd){
10747 // summary: errHandler function for dojo._ioSetArgs call.
10748
10749 if(!dfd.ioArgs.args.failOk){
10750 console.error(error);
10751 }
10752 return error;
81bea17a 10753 };
2f01fe57
AD
10754
10755 // avoid setting a timer per request. It degrades performance on IE
10756 // something fierece if we don't use unified loops.
10757 var _inFlightIntvl = null;
10758 var _inFlight = [];
1354d172
AD
10759
10760
2f01fe57
AD
10761 //Use a separate count for knowing if we are starting/stopping io calls.
10762 //Cannot use _inFlight.length since it can change at a different time than
10763 //when we want to do this kind of test. We only want to decrement the count
10764 //after a callback/errback has finished, since the callback/errback should be
10765 //considered as part of finishing a request.
10766 var _pubCount = 0;
10767 var _checkPubCount = function(dfd){
10768 if(_pubCount <= 0){
10769 _pubCount = 0;
1354d172
AD
10770 if(cfg.ioPublish && dojo.publish && (!dfd || dfd && dfd.ioArgs.args.ioPublish !== false)){
10771 dojo.publish("/dojo/io/stop");
2f01fe57
AD
10772 }
10773 }
10774 };
10775
10776 var _watchInFlight = function(){
81bea17a 10777 //summary:
2f01fe57
AD
10778 // internal method that checks each inflight XMLHttpRequest to see
10779 // if it has completed or if the timeout situation applies.
1354d172 10780
2f01fe57
AD
10781 var now = (new Date()).getTime();
10782 // make sure sync calls stay thread safe, if this callback is called
10783 // during a sync call and this results in another sync call before the
10784 // first sync call ends the browser hangs
1354d172 10785 if(!dojo._blockAsync){
2f01fe57
AD
10786 // we need manual loop because we often modify _inFlight (and therefore 'i') while iterating
10787 // note: the second clause is an assigment on purpose, lint may complain
10788 for(var i = 0, tif; i < _inFlight.length && (tif = _inFlight[i]); i++){
10789 var dfd = tif.dfd;
10790 var func = function(){
10791 if(!dfd || dfd.canceled || !tif.validCheck(dfd)){
81bea17a 10792 _inFlight.splice(i--, 1);
2f01fe57
AD
10793 _pubCount -= 1;
10794 }else if(tif.ioCheck(dfd)){
10795 _inFlight.splice(i--, 1);
10796 tif.resHandle(dfd);
10797 _pubCount -= 1;
10798 }else if(dfd.startTime){
10799 //did we timeout?
10800 if(dfd.startTime + (dfd.ioArgs.args.timeout || 0) < now){
10801 _inFlight.splice(i--, 1);
10802 var err = new Error("timeout exceeded");
10803 err.dojoType = "timeout";
10804 dfd.errback(err);
10805 //Cancel the request so the io module can do appropriate cleanup.
10806 dfd.cancel();
10807 _pubCount -= 1;
10808 }
10809 }
10810 };
10811 if(dojo.config.debugAtAllCosts){
10812 func.call(this);
10813 }else{
10814 try{
10815 func.call(this);
10816 }catch(e){
10817 dfd.errback(e);
10818 }
10819 }
10820 }
10821 }
10822
10823 _checkPubCount(dfd);
10824
10825 if(!_inFlight.length){
10826 clearInterval(_inFlightIntvl);
10827 _inFlightIntvl = null;
2f01fe57 10828 }
81bea17a 10829 };
2f01fe57
AD
10830
10831 dojo._ioCancelAll = function(){
10832 //summary: Cancels all pending IO requests, regardless of IO type
10833 //(xhr, script, iframe).
10834 try{
1354d172 10835 array.forEach(_inFlight, function(i){
2f01fe57
AD
10836 try{
10837 i.dfd.cancel();
10838 }catch(e){/*squelch*/}
10839 });
10840 }catch(e){/*squelch*/}
81bea17a 10841 };
2f01fe57
AD
10842
10843 //Automatically call cancel all io calls on unload
10844 //in IE for trac issue #2357.
1354d172
AD
10845 if(has("ie")){
10846 on(window, "unload", dojo._ioCancelAll);
2f01fe57 10847 }
1354d172
AD
10848
10849 dojo._ioNotifyStart = function(/*Deferred*/dfd){
2f01fe57 10850 // summary:
1354d172
AD
10851 // If dojo.publish is available, publish topics
10852 // about the start of a request queue and/or the
10853 // the beginning of request.
2f01fe57 10854 // description:
1354d172
AD
10855 // Used by IO transports. An IO transport should
10856 // call this method before making the network connection.
10857 if(cfg.ioPublish && dojo.publish && dfd.ioArgs.args.ioPublish !== false){
2f01fe57 10858 if(!_pubCount){
1354d172 10859 dojo.publish("/dojo/io/start");
2f01fe57
AD
10860 }
10861 _pubCount += 1;
1354d172 10862 dojo.publish("/dojo/io/send", [dfd]);
2f01fe57 10863 }
81bea17a 10864 };
2f01fe57 10865
1354d172 10866 dojo._ioWatch = function(dfd, validCheck, ioCheck, resHandle){
81bea17a 10867 // summary:
2f01fe57
AD
10868 // Watches the io request represented by dfd to see if it completes.
10869 // dfd: Deferred
10870 // The Deferred object to watch.
10871 // validCheck: Function
10872 // Function used to check if the IO request is still valid. Gets the dfd
10873 // object as its only argument.
10874 // ioCheck: Function
10875 // Function used to check if basic IO call worked. Gets the dfd
10876 // object as its only argument.
10877 // resHandle: Function
10878 // Function used to process response. Gets the dfd
10879 // object as its only argument.
10880 var args = dfd.ioArgs.args;
10881 if(args.timeout){
10882 dfd.startTime = (new Date()).getTime();
10883 }
1354d172 10884
2f01fe57
AD
10885 _inFlight.push({dfd: dfd, validCheck: validCheck, ioCheck: ioCheck, resHandle: resHandle});
10886 if(!_inFlightIntvl){
10887 _inFlightIntvl = setInterval(_watchInFlight, 50);
10888 }
10889 // handle sync requests
10890 //A weakness: async calls in flight
10891 //could have their handlers called as part of the
10892 //_watchInFlight call, before the sync's callbacks
10893 // are called.
10894 if(args.sync){
10895 _watchInFlight();
10896 }
81bea17a 10897 };
2f01fe57
AD
10898
10899 var _defaultContentType = "application/x-www-form-urlencoded";
10900
10901 var _validCheck = function(/*Deferred*/dfd){
10902 return dfd.ioArgs.xhr.readyState; //boolean
81bea17a 10903 };
2f01fe57
AD
10904 var _ioCheck = function(/*Deferred*/dfd){
10905 return 4 == dfd.ioArgs.xhr.readyState; //boolean
81bea17a 10906 };
2f01fe57
AD
10907 var _resHandle = function(/*Deferred*/dfd){
10908 var xhr = dfd.ioArgs.xhr;
1354d172 10909 if(dojo._isDocumentOk(xhr)){
2f01fe57
AD
10910 dfd.callback(dfd);
10911 }else{
10912 var err = new Error("Unable to load " + dfd.ioArgs.url + " status:" + xhr.status);
10913 err.status = xhr.status;
10914 err.responseText = xhr.responseText;
1354d172 10915 err.xhr = xhr;
2f01fe57
AD
10916 dfd.errback(err);
10917 }
81bea17a 10918 };
2f01fe57
AD
10919
10920 dojo._ioAddQueryToUrl = function(/*dojo.__IoCallbackArgs*/ioArgs){
10921 //summary: Adds query params discovered by the io deferred construction to the URL.
10922 //Only use this for operations which are fundamentally GET-type operations.
10923 if(ioArgs.query.length){
10924 ioArgs.url += (ioArgs.url.indexOf("?") == -1 ? "?" : "&") + ioArgs.query;
10925 ioArgs.query = null;
81bea17a
AD
10926 }
10927 };
2f01fe57
AD
10928
10929 /*=====
10930 dojo.declare("dojo.__XhrArgs", dojo.__IoArgs, {
10931 constructor: function(){
10932 // summary:
10933 // In addition to the properties listed for the dojo._IoArgs type,
10934 // the following properties are allowed for dojo.xhr* methods.
10935 // handleAs: String?
10936 // Acceptable values are: text (default), json, json-comment-optional,
10937 // json-comment-filtered, javascript, xml. See `dojo.contentHandlers`
10938 // sync: Boolean?
10939 // false is default. Indicates whether the request should
10940 // be a synchronous (blocking) request.
10941 // headers: Object?
10942 // Additional HTTP headers to send in the request.
10943 // failOk: Boolean?
10944 // false is default. Indicates whether a request should be
10945 // allowed to fail (and therefore no console error message in
10946 // the event of a failure)
1354d172
AD
10947 // contentType: String|Boolean
10948 // "application/x-www-form-urlencoded" is default. Set to false to
10949 // prevent a Content-Type header from being sent, or to a string
10950 // to send a different Content-Type.
2f01fe57
AD
10951 this.handleAs = handleAs;
10952 this.sync = sync;
10953 this.headers = headers;
10954 this.failOk = failOk;
10955 }
10956 });
10957 =====*/
10958
10959 dojo.xhr = function(/*String*/ method, /*dojo.__XhrArgs*/ args, /*Boolean?*/ hasBody){
10960 // summary:
10961 // Sends an HTTP request with the given method.
10962 // description:
10963 // Sends an HTTP request with the given method.
10964 // See also dojo.xhrGet(), xhrPost(), xhrPut() and dojo.xhrDelete() for shortcuts
10965 // for those HTTP methods. There are also methods for "raw" PUT and POST methods
10966 // via dojo.rawXhrPut() and dojo.rawXhrPost() respectively.
10967 // method:
1354d172 10968 // HTTP method to be used, such as GET, POST, PUT, DELETE. Should be uppercase.
2f01fe57
AD
10969 // hasBody:
10970 // If the request has an HTTP body, then pass true for hasBody.
10971
10972 //Make the Deferred object for this xhr request.
1354d172 10973 var dfd = dojo._ioSetArgs(args, _deferredCancel, _deferredOk, _deferError);
2f01fe57
AD
10974 var ioArgs = dfd.ioArgs;
10975
10976 //Pass the args to _xhrObj, to allow alternate XHR calls based specific calls, like
10977 //the one used for iframe proxies.
1354d172 10978 var xhr = ioArgs.xhr = dojo._xhrObj(ioArgs.args);
2f01fe57
AD
10979 //If XHR factory fails, cancel the deferred.
10980 if(!xhr){
10981 dfd.cancel();
10982 return dfd;
10983 }
10984
10985 //Allow for specifying the HTTP body completely.
10986 if("postData" in args){
10987 ioArgs.query = args.postData;
10988 }else if("putData" in args){
10989 ioArgs.query = args.putData;
10990 }else if("rawBody" in args){
10991 ioArgs.query = args.rawBody;
10992 }else if((arguments.length > 2 && !hasBody) || "POST|PUT".indexOf(method.toUpperCase()) == -1){
10993 //Check for hasBody being passed. If no hasBody,
10994 //then only append query string if not a POST or PUT request.
1354d172 10995 dojo._ioAddQueryToUrl(ioArgs);
2f01fe57
AD
10996 }
10997
10998 // IE 6 is a steaming pile. It won't let you call apply() on the native function (xhr.open).
10999 // workaround for IE6's apply() "issues"
11000 xhr.open(method, ioArgs.url, args.sync !== true, args.user || undefined, args.password || undefined);
11001 if(args.headers){
11002 for(var hdr in args.headers){
11003 if(hdr.toLowerCase() === "content-type" && !args.contentType){
11004 args.contentType = args.headers[hdr];
11005 }else if(args.headers[hdr]){
11006 //Only add header if it has a value. This allows for instnace, skipping
11007 //insertion of X-Requested-With by specifying empty value.
11008 xhr.setRequestHeader(hdr, args.headers[hdr]);
11009 }
11010 }
11011 }
11012 // FIXME: is this appropriate for all content types?
1354d172
AD
11013 if(args.contentType !== false){
11014 xhr.setRequestHeader("Content-Type", args.contentType || _defaultContentType);
11015 }
2f01fe57
AD
11016 if(!args.headers || !("X-Requested-With" in args.headers)){
11017 xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
11018 }
11019 // FIXME: set other headers here!
1354d172 11020 dojo._ioNotifyStart(dfd);
2f01fe57
AD
11021 if(dojo.config.debugAtAllCosts){
11022 xhr.send(ioArgs.query);
11023 }else{
11024 try{
11025 xhr.send(ioArgs.query);
11026 }catch(e){
11027 ioArgs.error = e;
11028 dfd.cancel();
11029 }
11030 }
1354d172
AD
11031 dojo._ioWatch(dfd, _validCheck, _ioCheck, _resHandle);
11032 xhr = null;
11033 return dfd; // dojo.Deferred
11034 };
11035
11036 dojo.xhrGet = function(/*dojo.__XhrArgs*/ args){
11037 // summary:
11038 // Sends an HTTP GET request to the server.
11039 return dojo.xhr("GET", args); // dojo.Deferred
11040 };
11041
11042 dojo.rawXhrPost = dojo.xhrPost = function(/*dojo.__XhrArgs*/ args){
11043 // summary:
11044 // Sends an HTTP POST request to the server. In addtion to the properties
11045 // listed for the dojo.__XhrArgs type, the following property is allowed:
11046 // postData:
11047 // String. Send raw data in the body of the POST request.
11048 return dojo.xhr("POST", args, true); // dojo.Deferred
11049 };
11050
11051 dojo.rawXhrPut = dojo.xhrPut = function(/*dojo.__XhrArgs*/ args){
11052 // summary:
11053 // Sends an HTTP PUT request to the server. In addtion to the properties
11054 // listed for the dojo.__XhrArgs type, the following property is allowed:
11055 // putData:
11056 // String. Send raw data in the body of the PUT request.
11057 return dojo.xhr("PUT", args, true); // dojo.Deferred
11058 };
11059
11060 dojo.xhrDelete = function(/*dojo.__XhrArgs*/ args){
11061 // summary:
11062 // Sends an HTTP DELETE request to the server.
11063 return dojo.xhr("DELETE", args); //dojo.Deferred
11064 };
11065
11066 /*
11067 dojo.wrapForm = function(formNode){
11068 //summary:
11069 // A replacement for FormBind, but not implemented yet.
11070
11071 // FIXME: need to think harder about what extensions to this we might
11072 // want. What should we allow folks to do w/ this? What events to
11073 // set/send?
11074 throw new Error("dojo.wrapForm not yet implemented");
11075 }
11076 */
11077
11078 dojo._isDocumentOk = function(http){
11079 var stat = http.status || 0;
11080 stat =
11081 (stat >= 200 && stat < 300) || // allow any 2XX response code
11082 stat == 304 || // or, get it out of the cache
11083 stat == 1223 || // or, Internet Explorer mangled the status code
11084 !stat; // or, we're Titanium/browser chrome/chrome extension requesting a local file
11085 return stat; // Boolean
11086 };
11087
11088 dojo._getText = function(url){
11089 var result;
11090 dojo.xhrGet({url:url, sync:true, load:function(text){
11091 result = text;
11092 }});
11093 return result;
11094 };
11095
11096 // Add aliases for static functions to dojo.xhr since dojo.xhr is what's returned from this module
11097 lang.mixin(dojo.xhr, {
11098 _xhrObj: dojo._xhrObj,
11099 fieldToObject: domForm.fieldToObject,
11100 formToObject: domForm.toObject,
11101 objectToQuery: ioq.objectToQuery,
11102 formToQuery: domForm.toQuery,
11103 formToJson: domForm.toJson,
11104 queryToObject: ioq.queryToObject,
11105 contentHandlers: handlers,
11106 _ioSetArgs: dojo._ioSetArgs,
11107 _ioCancelAll: dojo._ioCancelAll,
11108 _ioNotifyStart: dojo._ioNotifyStart,
11109 _ioWatch: dojo._ioWatch,
11110 _ioAddQueryToUrl: dojo._ioAddQueryToUrl,
11111 _isDocumentOk: dojo._isDocumentOk,
11112 _getText: dojo._getText,
11113 get: dojo.xhrGet,
11114 post: dojo.xhrPost,
11115 put: dojo.xhrPut,
11116 del: dojo.xhrDelete // because "delete" is a reserved word
11117 });
11118
11119 return dojo.xhr;
11120});
11121
11122},
11123'dojo/_base/unload':function(){
11124define(["./kernel", "./connect"], function(dojo, connect) {
11125 // module:
11126 // dojo/unload
11127 // summary:
11128 // This module contains the document and window unload detection API.
11129
11130 var win = window;
11131
11132 /*=====
11133 dojo.windowUnloaded = function(){
11134 // summary:
11135 // signal fired by impending window destruction. You may use
11136 // dojo.addOnWindowUnload() to register a listener for this
11137 // event. NOTE: if you wish to dojo.connect() to this method
11138 // to perform page/application cleanup, be aware that this
11139 // event WILL NOT fire if no handler has been registered with
11140 // dojo.addOnWindowUnload. This behavior started in Dojo 1.3.
11141 // Previous versions always triggered dojo.windowUnloaded. See
11142 // dojo.addOnWindowUnload for more info.
11143 };
11144 =====*/
11145
11146 dojo.addOnWindowUnload = function(/*Object?|Function?*/obj, /*String|Function?*/functionName){
11147 // summary:
11148 // registers a function to be triggered when window.onunload
11149 // fires.
11150 // description:
11151 // The first time that addOnWindowUnload is called Dojo
11152 // will register a page listener to trigger your unload
11153 // handler with. Note that registering these handlers may
11154 // destory "fastback" page caching in browsers that support
11155 // it. Be careful trying to modify the DOM or access
11156 // JavaScript properties during this phase of page unloading:
11157 // they may not always be available. Consider
11158 // dojo.addOnUnload() if you need to modify the DOM or do
11159 // heavy JavaScript work since it fires at the eqivalent of
11160 // the page's "onbeforeunload" event.
11161 // example:
11162 // | dojo.addOnWindowUnload(functionPointer)
11163 // | dojo.addOnWindowUnload(object, "functionName");
11164 // | dojo.addOnWindowUnload(object, function(){ /* ... */});
11165
11166 if (!dojo.windowUnloaded) {
11167 connect.connect(win, "unload", (dojo.windowUnloaded= function(){}));
11168 }
11169 connect.connect(win, "unload", obj, functionName);
11170 };
11171
11172 dojo.addOnUnload = function(/*Object?|Function?*/obj, /*String|Function?*/functionName){
11173 // summary:
11174 // registers a function to be triggered when the page unloads.
11175 // description:
11176 // The first time that addOnUnload is called Dojo will
11177 // register a page listener to trigger your unload handler
11178 // with.
11179 //
11180 // In a browser enviroment, the functions will be triggered
11181 // during the window.onbeforeunload event. Be careful of doing
11182 // too much work in an unload handler. onbeforeunload can be
11183 // triggered if a link to download a file is clicked, or if
11184 // the link is a javascript: link. In these cases, the
11185 // onbeforeunload event fires, but the document is not
11186 // actually destroyed. So be careful about doing destructive
11187 // operations in a dojo.addOnUnload callback.
11188 //
11189 // Further note that calling dojo.addOnUnload will prevent
11190 // browsers from using a "fast back" cache to make page
11191 // loading via back button instantaneous.
11192 // example:
11193 // | dojo.addOnUnload(functionPointer)
11194 // | dojo.addOnUnload(object, "functionName")
11195 // | dojo.addOnUnload(object, function(){ /* ... */});
11196
11197 connect.connect(win, "beforeunload", obj, functionName);
11198 };
11199
11200 return {
11201 addOnWindowUnload: dojo.addOnWindowUnload,
11202 addOnUnload: dojo.addOnUnload
11203 };
11204});
11205
11206},
11207'dojo/_base/NodeList':function(){
11208define(["./kernel", "../query", "./array", "./html", "../NodeList-dom"], function(dojo, query, array){
11209 // module:
11210 // dojo/_base/NodeList
11211 // summary:
11212 // This module defines dojo.NodeList.
11213
11214var NodeList = query.NodeList;
11215
11216 /*=====
11217 dojo.extend(dojo.NodeList, {
11218 connect: function(methodName, objOrFunc, funcName){
11219 // summary:
11220 // attach event handlers to every item of the NodeList. Uses dojo.connect()
11221 // so event properties are normalized
11222 // methodName: String
11223 // the name of the method to attach to. For DOM events, this should be
11224 // the lower-case name of the event
11225 // objOrFunc: Object|Function|String
11226 // if 2 arguments are passed (methodName, objOrFunc), objOrFunc should
11227 // reference a function or be the name of the function in the global
11228 // namespace to attach. If 3 arguments are provided
11229 // (methodName, objOrFunc, funcName), objOrFunc must be the scope to
11230 // locate the bound function in
11231 // funcName: String?
11232 // optional. A string naming the function in objOrFunc to bind to the
11233 // event. May also be a function reference.
11234 // example:
11235 // add an onclick handler to every button on the page
11236 // | dojo.query("div:nth-child(odd)").connect("onclick", function(e){
11237 // | console.log("clicked!");
11238 // | });
11239 // example:
11240 // attach foo.bar() to every odd div's onmouseover
11241 // | dojo.query("div:nth-child(odd)").connect("onmouseover", foo, "bar");
11242 },
11243 coords: function(){
11244 // summary:
11245 // Deprecated: Use position() for border-box x/y/w/h
11246 // or marginBox() for margin-box w/h/l/t.
11247 // Returns the box objects of all elements in a node list as
11248 // an Array (*not* a NodeList). Acts like `dojo.coords`, though assumes
11249 // the node passed is each node in this list.
11250
11251 return dojo.map(this, dojo.coords); // Array
11252 }
11253 });
11254
11255 var NodeList = dojo.NodeList;
11256 =====*/
11257 var nlp = NodeList.prototype;
11258
11259 // don't bind early to dojo.connect since we no longer explicitly depend on it
11260 nlp.connect = NodeList._adaptAsForEach(function(){
11261 return dojo.connect.apply(this, arguments);
11262 });
11263 nlp.coords = NodeList._adaptAsMap(dojo.coords);
11264
11265 NodeList.events = [
11266 // summary:
11267 // list of all DOM events used in NodeList
11268 "blur", "focus", "change", "click", "error", "keydown", "keypress",
11269 "keyup", "load", "mousedown", "mouseenter", "mouseleave", "mousemove",
11270 "mouseout", "mouseover", "mouseup", "submit"
11271 ];
11272
11273 // FIXME: pseudo-doc the above automatically generated on-event functions
11274
11275 // syntactic sugar for DOM events
11276 array.forEach(NodeList.events, function(evt){
11277 var _oe = "on" + evt;
11278 nlp[_oe] = function(a, b){
11279 return this.connect(_oe, a, b);
11280 };
11281 // FIXME: should these events trigger publishes?
11282 /*
11283 return (a ? this.connect(_oe, a, b) :
11284 this.forEach(function(n){
11285 // FIXME:
11286 // listeners get buried by
11287 // addEventListener and can't be dug back
11288 // out to be triggered externally.
11289 // see:
11290 // http://developer.mozilla.org/en/docs/DOM:element
11291
11292 console.log(n, evt, _oe);
11293
11294 // FIXME: need synthetic event support!
11295 var _e = { target: n, faux: true, type: evt };
11296 // dojo._event_listener._synthesizeEvent({}, { target: n, faux: true, type: evt });
11297 try{ n[evt](_e); }catch(e){ console.log(e); }
11298 try{ n[_oe](_e); }catch(e){ console.log(e); }
11299 })
11300 );
11301 */
11302 }
11303 );
11304
11305 dojo.NodeList = NodeList;
11306 return dojo.NodeList;
11307});
11308
11309},
11310'dojo/_base/Color':function(){
11311define(["./kernel", "./lang", "./array", "./config"], function(dojo, lang, ArrayUtil, config){
11312
11313 var Color = dojo.Color = function(/*Array|String|Object*/ color){
11314 // summary:
11315 // Takes a named string, hex string, array of rgb or rgba values,
11316 // an object with r, g, b, and a properties, or another `dojo.Color` object
11317 // and creates a new Color instance to work from.
11318 //
11319 // example:
11320 // Work with a Color instance:
11321 // | var c = new dojo.Color();
11322 // | c.setColor([0,0,0]); // black
11323 // | var hex = c.toHex(); // #000000
11324 //
11325 // example:
11326 // Work with a node's color:
11327 // | var color = dojo.style("someNode", "backgroundColor");
11328 // | var n = new dojo.Color(color);
11329 // | // adjust the color some
11330 // | n.r *= .5;
11331 // | console.log(n.toString()); // rgb(128, 255, 255);
11332 if(color){ this.setColor(color); }
11333 };
11334
11335 /*=====
11336 lang.mixin(dojo.Color,{
11337 named:{
11338 // summary: Dictionary list of all CSS named colors, by name. Values are 3-item arrays with corresponding RG and B values.
11339 }
11340 });
11341 =====*/
11342
11343 // FIXME:
11344 // there's got to be a more space-efficient way to encode or discover
11345 // these!! Use hex?
11346 Color.named = {
11347 "black": [0,0,0],
11348 "silver": [192,192,192],
11349 "gray": [128,128,128],
11350 "white": [255,255,255],
11351 "maroon": [128,0,0],
11352 "red": [255,0,0],
11353 "purple": [128,0,128],
11354 "fuchsia":[255,0,255],
11355 "green": [0,128,0],
11356 "lime": [0,255,0],
11357 "olive": [128,128,0],
11358 "yellow": [255,255,0],
11359 "navy": [0,0,128],
11360 "blue": [0,0,255],
11361 "teal": [0,128,128],
11362 "aqua": [0,255,255],
11363 "transparent": config.transparentColor || [0,0,0,0]
11364 };
11365
11366 lang.extend(Color, {
11367 r: 255, g: 255, b: 255, a: 1,
11368 _set: function(r, g, b, a){
11369 var t = this; t.r = r; t.g = g; t.b = b; t.a = a;
11370 },
11371 setColor: function(/*Array|String|Object*/ color){
11372 // summary:
11373 // Takes a named string, hex string, array of rgb or rgba values,
11374 // an object with r, g, b, and a properties, or another `dojo.Color` object
11375 // and sets this color instance to that value.
11376 //
11377 // example:
11378 // | var c = new dojo.Color(); // no color
11379 // | c.setColor("#ededed"); // greyish
11380 if(lang.isString(color)){
11381 Color.fromString(color, this);
11382 }else if(lang.isArray(color)){
11383 Color.fromArray(color, this);
11384 }else{
11385 this._set(color.r, color.g, color.b, color.a);
11386 if(!(color instanceof Color)){ this.sanitize(); }
11387 }
11388 return this; // dojo.Color
11389 },
11390 sanitize: function(){
11391 // summary:
11392 // Ensures the object has correct attributes
11393 // description:
11394 // the default implementation does nothing, include dojo.colors to
11395 // augment it with real checks
11396 return this; // dojo.Color
11397 },
11398 toRgb: function(){
11399 // summary:
11400 // Returns 3 component array of rgb values
11401 // example:
11402 // | var c = new dojo.Color("#000000");
11403 // | console.log(c.toRgb()); // [0,0,0]
11404 var t = this;
11405 return [t.r, t.g, t.b]; // Array
11406 },
11407 toRgba: function(){
11408 // summary:
11409 // Returns a 4 component array of rgba values from the color
11410 // represented by this object.
11411 var t = this;
11412 return [t.r, t.g, t.b, t.a]; // Array
11413 },
11414 toHex: function(){
11415 // summary:
11416 // Returns a CSS color string in hexadecimal representation
11417 // example:
11418 // | console.log(new dojo.Color([0,0,0]).toHex()); // #000000
11419 var arr = ArrayUtil.map(["r", "g", "b"], function(x){
11420 var s = this[x].toString(16);
11421 return s.length < 2 ? "0" + s : s;
11422 }, this);
11423 return "#" + arr.join(""); // String
11424 },
11425 toCss: function(/*Boolean?*/ includeAlpha){
11426 // summary:
11427 // Returns a css color string in rgb(a) representation
11428 // example:
11429 // | var c = new dojo.Color("#FFF").toCss();
11430 // | console.log(c); // rgb('255','255','255')
11431 var t = this, rgb = t.r + ", " + t.g + ", " + t.b;
11432 return (includeAlpha ? "rgba(" + rgb + ", " + t.a : "rgb(" + rgb) + ")"; // String
11433 },
11434 toString: function(){
11435 // summary:
11436 // Returns a visual representation of the color
11437 return this.toCss(true); // String
11438 }
11439 });
2f01fe57 11440
1354d172
AD
11441 Color.blendColors = dojo.blendColors = function(
11442 /*dojo.Color*/ start,
11443 /*dojo.Color*/ end,
11444 /*Number*/ weight,
11445 /*dojo.Color?*/ obj
11446 ){
11447 // summary:
11448 // Blend colors end and start with weight from 0 to 1, 0.5 being a 50/50 blend,
11449 // can reuse a previously allocated dojo.Color object for the result
11450 var t = obj || new Color();
11451 ArrayUtil.forEach(["r", "g", "b", "a"], function(x){
11452 t[x] = start[x] + (end[x] - start[x]) * weight;
11453 if(x != "a"){ t[x] = Math.round(t[x]); }
11454 });
11455 return t.sanitize(); // dojo.Color
81bea17a 11456 };
2f01fe57 11457
1354d172
AD
11458 Color.fromRgb = dojo.colorFromRgb = function(/*String*/ color, /*dojo.Color?*/ obj){
11459 // summary:
11460 // Returns a `dojo.Color` instance from a string of the form
11461 // "rgb(...)" or "rgba(...)". Optionally accepts a `dojo.Color`
11462 // object to update with the parsed value and return instead of
11463 // creating a new object.
11464 // returns:
11465 // A dojo.Color object. If obj is passed, it will be the return value.
11466 var m = color.toLowerCase().match(/^rgba?\(([\s\.,0-9]+)\)/);
11467 return m && Color.fromArray(m[1].split(/\s*,\s*/), obj); // dojo.Color
81bea17a 11468 };
2f01fe57 11469
1354d172
AD
11470 Color.fromHex = dojo.colorFromHex = function(/*String*/ color, /*dojo.Color?*/ obj){
11471 // summary:
11472 // Converts a hex string with a '#' prefix to a color object.
11473 // Supports 12-bit #rgb shorthand. Optionally accepts a
11474 // `dojo.Color` object to update with the parsed value.
11475 //
11476 // returns:
11477 // A dojo.Color object. If obj is passed, it will be the return value.
11478 //
11479 // example:
11480 // | var thing = dojo.colorFromHex("#ededed"); // grey, longhand
11481 //
11482 // example:
11483 // | var thing = dojo.colorFromHex("#000"); // black, shorthand
11484 var t = obj || new Color(),
11485 bits = (color.length == 4) ? 4 : 8,
11486 mask = (1 << bits) - 1;
11487 color = Number("0x" + color.substr(1));
11488 if(isNaN(color)){
11489 return null; // dojo.Color
11490 }
11491 ArrayUtil.forEach(["b", "g", "r"], function(x){
11492 var c = color & mask;
11493 color >>= bits;
11494 t[x] = bits == 4 ? 17 * c : c;
11495 });
11496 t.a = 1;
11497 return t; // dojo.Color
81bea17a 11498 };
2f01fe57 11499
1354d172
AD
11500 Color.fromArray = dojo.colorFromArray = function(/*Array*/ a, /*dojo.Color?*/ obj){
11501 // summary:
11502 // Builds a `dojo.Color` from a 3 or 4 element array, mapping each
11503 // element in sequence to the rgb(a) values of the color.
11504 // example:
11505 // | var myColor = dojo.colorFromArray([237,237,237,0.5]); // grey, 50% alpha
11506 // returns:
11507 // A dojo.Color object. If obj is passed, it will be the return value.
11508 var t = obj || new Color();
11509 t._set(Number(a[0]), Number(a[1]), Number(a[2]), Number(a[3]));
11510 if(isNaN(t.a)){ t.a = 1; }
11511 return t.sanitize(); // dojo.Color
81bea17a 11512 };
2f01fe57 11513
1354d172
AD
11514 Color.fromString = dojo.colorFromString = function(/*String*/ str, /*dojo.Color?*/ obj){
11515 // summary:
11516 // Parses `str` for a color value. Accepts hex, rgb, and rgba
11517 // style color values.
11518 // description:
11519 // Acceptable input values for str may include arrays of any form
11520 // accepted by dojo.colorFromArray, hex strings such as "#aaaaaa", or
11521 // rgb or rgba strings such as "rgb(133, 200, 16)" or "rgba(10, 10,
11522 // 10, 50)"
11523 // returns:
11524 // A dojo.Color object. If obj is passed, it will be the return value.
11525 var a = Color.named[str];
11526 return a && Color.fromArray(a, obj) || Color.fromRgb(str, obj) || Color.fromHex(str, obj); // dojo.Color
11527 };
11528
11529 return Color;
11530});
11531
11532},
11533'dojo/selector/_loader':function(){
11534define(["../has", "require"],
11535 function(has, require){
11536// summary:
11537// This module handles loading the appropriate selector engine for the given browser
11538"use strict";
11539var testDiv = document.createElement("div");
11540has.add("dom-qsa2.1", !!testDiv.querySelectorAll);
11541has.add("dom-qsa3", function(){
11542 // test to see if we have a reasonable native selector engine available
11543 try{
11544 testDiv.innerHTML = "<p class='TEST'></p>"; // test kind of from sizzle
11545 // Safari can't handle uppercase or unicode characters when
11546 // in quirks mode, IE8 can't handle pseudos like :empty
11547 return testDiv.querySelectorAll(".TEST:empty").length == 1;
11548 }catch(e){}
11549 });
11550var fullEngine;
11551var acme = "./acme", lite = "./lite";
11552return {
11553 load: function(id, parentRequire, loaded, config){
11554 var req = require;
11555 // here we implement the default logic for choosing a selector engine
11556 id = id == "default" ? has("config-selectorEngine") || "css3" : id;
11557 id = id == "css2" || id == "lite" ? lite :
11558 id == "css2.1" ? has("dom-qsa2.1") ? lite : acme :
11559 id == "css3" ? has("dom-qsa3") ? lite : acme :
11560 id == "acme" ? acme : (req = parentRequire) && id;
11561 if(id.charAt(id.length-1) == '?'){
11562 id = id.substring(0,id.length - 1);
11563 var optionalLoad = true;
11564 }
11565 // the query engine is optional, only load it if a native one is not available or existing one has not been loaded
11566 if(optionalLoad && (has("dom-compliant-qsa") || fullEngine)){
11567 return loaded(fullEngine);
11568 }
11569 // load the referenced selector engine
11570 req([id], function(engine){
11571 if(id != "./lite"){
11572 fullEngine = engine;
11573 }
11574 loaded(engine);
11575 });
2f01fe57 11576 }
1354d172
AD
11577};
11578});
2f01fe57 11579
1354d172
AD
11580},
11581'dojo/on':function(){
11582define(["./has!dom-addeventlistener?:./aspect", "./_base/kernel", "./has"], function(aspect, dojo, has){
11583 // summary:
11584 // The export of this module is a function that provides core event listening functionality. With this function
11585 // you can provide a target, event type, and listener to be notified of
11586 // future matching events that are fired.
11587 // target: Element|Object
11588 // This is the target object or DOM element that to receive events from
11589 // type: String|Function
11590 // This is the name of the event to listen for or an extension event type.
11591 // listener: Function
11592 // This is the function that should be called when the event fires.
11593 // returns: Object
11594 // An object with a remove() method that can be used to stop listening for this
11595 // event.
11596 // description:
11597 // To listen for "click" events on a button node, we can do:
11598 // | define(["dojo/on"], function(listen){
11599 // | on(button, "click", clickHandler);
11600 // | ...
11601 // Evented JavaScript objects can also have their own events.
11602 // | var obj = new Evented;
11603 // | on(obj, "foo", fooHandler);
11604 // And then we could publish a "foo" event:
11605 // | on.emit(obj, "foo", {key: "value"});
11606 // We can use extension events as well. For example, you could listen for a tap gesture:
11607 // | define(["dojo/on", "dojo/gesture/tap", function(listen, tap){
11608 // | on(button, tap, tapHandler);
11609 // | ...
11610 // which would trigger fooHandler. Note that for a simple object this is equivalent to calling:
11611 // | obj.onfoo({key:"value"});
11612 // If you use on.emit on a DOM node, it will use native event dispatching when possible.
11613
11614 "use strict";
11615 if(1){ // check to make sure we are in a browser, this module should work anywhere
11616 var major = window.ScriptEngineMajorVersion;
11617 has.add("jscript", major && (major() + ScriptEngineMinorVersion() / 10));
11618 has.add("event-orientationchange", has("touch") && !has("android")); // TODO: how do we detect this?
11619 }
11620 var on = function(target, type, listener, dontFix){
11621 if(target.on){
11622 // delegate to the target's on() method, so it can handle it's own listening if it wants
11623 return target.on(type, listener);
11624 }
11625 // delegate to main listener code
11626 return on.parse(target, type, listener, addListener, dontFix, this);
11627 };
11628 on.pausable = function(target, type, listener, dontFix){
11629 // summary:
11630 // This function acts the same as on(), but with pausable functionality. The
11631 // returned signal object has pause() and resume() functions. Calling the
11632 // pause() method will cause the listener to not be called for future events. Calling the
11633 // resume() method will cause the listener to again be called for future events.
11634 var paused;
11635 var signal = on(target, type, function(){
11636 if(!paused){
11637 return listener.apply(this, arguments);
11638 }
11639 }, dontFix);
11640 signal.pause = function(){
11641 paused = true;
11642 };
11643 signal.resume = function(){
11644 paused = false;
11645 };
11646 return signal;
2f01fe57 11647 };
1354d172
AD
11648 on.once = function(target, type, listener, dontFix){
11649 // summary:
11650 // This function acts the same as on(), but will only call the listener once. The
11651 // listener will be called for the first
11652 // event that takes place and then listener will automatically be removed.
11653 var signal = on(target, type, function(){
11654 // remove this listener
11655 signal.remove();
11656 // proceed to call the listener
11657 return listener.apply(this, arguments);
11658 });
11659 return signal;
11660 };
11661 on.parse = function(target, type, listener, addListener, dontFix, matchesTarget){
11662 if(type.call){
11663 // event handler function
11664 // on(node, dojo.touch.press, touchListener);
11665 return type.call(matchesTarget, target, listener);
11666 }
11667
11668 if(type.indexOf(",") > -1){
11669 // we allow comma delimited event names, so you can register for multiple events at once
11670 var events = type.split(/\s*,\s*/);
11671 var handles = [];
11672 var i = 0;
11673 var eventName;
11674 while(eventName = events[i++]){
11675 handles.push(addListener(target, eventName, listener, dontFix, matchesTarget));
11676 }
11677 handles.remove = function(){
11678 for(var i = 0; i < handles.length; i++){
11679 handles[i].remove();
11680 }
11681 };
11682 return handles;
11683 }
11684 return addListener(target, type, listener, dontFix, matchesTarget)
11685 };
11686 var touchEvents = /^touch/;
11687 function addListener(target, type, listener, dontFix, matchesTarget){
11688 // event delegation:
11689 var selector = type.match(/(.*):(.*)/);
11690 // if we have a selector:event, the last one is interpreted as an event, and we use event delegation
11691 if(selector){
11692 type = selector[2];
11693 selector = selector[1];
11694 // create the extension event for selectors and directly call it
11695 return on.selector(selector, type).call(matchesTarget, target, listener);
11696 }
11697 // test to see if it a touch event right now, so we don't have to do it every time it fires
11698 if(has("touch")){
11699 if(touchEvents.test(type)){
11700 // touch event, fix it
11701 listener = fixTouchListener(listener);
11702 }
11703 if(!has("event-orientationchange") && (type == "orientationchange")){
11704 //"orientationchange" not supported <= Android 2.1,
11705 //but works through "resize" on window
11706 type = "resize";
11707 target = window;
11708 listener = fixTouchListener(listener);
11709 }
11710 }
11711 // normal path, the target is |this|
11712 if(target.addEventListener){
11713 // 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)
11714 // check for capture conversions
11715 var capture = type in captures;
11716 target.addEventListener(capture ? captures[type] : type, listener, capture);
11717 // create and return the signal
11718 return {
11719 remove: function(){
11720 target.removeEventListener(type, listener, capture);
11721 }
11722 };
11723 }
11724 type = "on" + type;
11725 if(fixAttach && target.attachEvent){
11726 return fixAttach(target, type, listener);
11727 }
11728 throw new Error("Target must be an event emitter");
11729 }
2f01fe57 11730
1354d172
AD
11731 on.selector = function(selector, eventType, children){
11732 // summary:
11733 // Creates a new extension event with event delegation. This is based on
11734 // the provided event type (can be extension event) that
11735 // only calls the listener when the CSS selector matches the target of the event.
11736 // selector:
11737 // The CSS selector to use for filter events and determine the |this| of the event listener.
11738 // eventType:
11739 // The event to listen for
11740 // children:
11741 // Indicates if children elements of the selector should be allowed. This defaults to
11742 // true (except in the case of normally non-bubbling events like mouse.enter, in which case it defaults to false).
11743 // example:
11744 // define(["dojo/on", "dojo/mouse"], function(listen, mouse){
11745 // on(node, on.selector(".my-class", mouse.enter), handlerForMyHover);
11746 return function(target, listener){
11747 var matchesTarget = this;
11748 var bubble = eventType.bubble;
11749 if(bubble){
11750 // the event type doesn't naturally bubble, but has a bubbling form, use that
11751 eventType = bubble;
11752 }else if(children !== false){
11753 // for normal bubbling events we default to allowing children of the selector
11754 children = true;
11755 }
11756 return on(target, eventType, function(event){
11757 var eventTarget = event.target;
11758 // see if we have a valid matchesTarget or default to dojo.query
11759 matchesTarget = matchesTarget && matchesTarget.matches ? matchesTarget : dojo.query;
11760 // there is a selector, so make sure it matches
11761 while(!matchesTarget.matches(eventTarget, selector, target)){
11762 if(eventTarget == target || !children || !(eventTarget = eventTarget.parentNode)){ // intentional assignment
11763 return;
11764 }
11765 }
11766 return listener.call(eventTarget, event);
11767 });
11768 };
2f01fe57
AD
11769 };
11770
1354d172
AD
11771 function syntheticPreventDefault(){
11772 this.cancelable = false;
11773 }
11774 function syntheticStopPropagation(){
11775 this.bubbles = false;
11776 }
11777 var slice = [].slice,
11778 syntheticDispatch = on.emit = function(target, type, event){
11779 // summary:
11780 // Fires an event on the target object.
11781 // target:
11782 // The target object to fire the event on. This can be a DOM element or a plain
11783 // JS object. If the target is a DOM element, native event emiting mechanisms
11784 // are used when possible.
11785 // type:
11786 // The event type name. You can emulate standard native events like "click" and
11787 // "mouseover" or create custom events like "open" or "finish".
11788 // event:
11789 // An object that provides the properties for the event. See https://developer.mozilla.org/en/DOM/event.initEvent
11790 // for some of the properties. These properties are copied to the event object.
11791 // Of particular importance are the cancelable and bubbles properties. The
11792 // cancelable property indicates whether or not the event has a default action
11793 // that can be cancelled. The event is cancelled by calling preventDefault() on
11794 // the event object. The bubbles property indicates whether or not the
11795 // event will bubble up the DOM tree. If bubbles is true, the event will be called
11796 // on the target and then each parent successively until the top of the tree
11797 // is reached or stopPropagation() is called. Both bubbles and cancelable
11798 // default to false.
11799 // returns:
11800 // If the event is cancelable and the event is not cancelled,
11801 // emit will return true. If the event is cancelable and the event is cancelled,
11802 // emit will return false.
11803 // details:
11804 // Note that this is designed to emit events for listeners registered through
11805 // dojo/on. It should actually work with any event listener except those
11806 // added through IE's attachEvent (IE8 and below's non-W3C event emiting
11807 // doesn't support custom event types). It should work with all events registered
11808 // through dojo/on. Also note that the emit method does do any default
11809 // action, it only returns a value to indicate if the default action should take
11810 // place. For example, emiting a keypress event would not cause a character
11811 // to appear in a textbox.
11812 // example:
11813 // To fire our own click event
11814 // | on.emit(dojo.byId("button"), "click", {
11815 // | cancelable: true,
11816 // | bubbles: true,
11817 // | screenX: 33,
11818 // | screenY: 44
11819 // | });
11820 // We can also fire our own custom events:
11821 // | on.emit(dojo.byId("slider"), "slide", {
11822 // | cancelable: true,
11823 // | bubbles: true,
11824 // | direction: "left-to-right"
11825 // | });
11826 var args = slice.call(arguments, 2);
11827 var method = "on" + type;
11828 if("parentNode" in target){
11829 // node (or node-like), create event controller methods
11830 var newEvent = args[0] = {};
11831 for(var i in event){
11832 newEvent[i] = event[i];
11833 }
11834 newEvent.preventDefault = syntheticPreventDefault;
11835 newEvent.stopPropagation = syntheticStopPropagation;
11836 newEvent.target = target;
11837 newEvent.type = type;
11838 event = newEvent;
11839 }
11840 do{
11841 // 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)
11842 target[method] && target[method].apply(target, args);
11843 // and then continue up the parent node chain if it is still bubbling (if started as bubbles and stopPropagation hasn't been called)
11844 }while(event && event.bubbles && (target = target.parentNode));
11845 return event && event.cancelable && event; // if it is still true (was cancelable and was cancelled), return the event to indicate default action should happen
11846 };
11847 var captures = {};
11848 if(has("dom-addeventlistener")){
11849 // normalize focusin and focusout
11850 captures = {
11851 focusin: "focus",
11852 focusout: "blur"
11853 };
11854 if(has("opera")){
11855 captures.keydown = "keypress"; // this one needs to be transformed because Opera doesn't support repeating keys on keydown (and keypress works because it incorrectly fires on all keydown events)
11856 }
11857
11858 // emiter that works with native event handling
11859 on.emit = function(target, type, event){
11860 if(target.dispatchEvent && document.createEvent){
11861 // use the native event emiting mechanism if it is available on the target object
11862 // create a generic event
11863 // we could create branch into the different types of event constructors, but
11864 // that would be a lot of extra code, with little benefit that I can see, seems
11865 // best to use the generic constructor and copy properties over, making it
11866 // easy to have events look like the ones created with specific initializers
11867 var nativeEvent = document.createEvent("HTMLEvents");
11868 nativeEvent.initEvent(type, !!event.bubbles, !!event.cancelable);
11869 // and copy all our properties over
11870 for(var i in event){
11871 var value = event[i];
11872 if(!(i in nativeEvent)){
11873 nativeEvent[i] = event[i];
11874 }
11875 }
11876 return target.dispatchEvent(nativeEvent) && nativeEvent;
11877 }
11878 return syntheticDispatch.apply(on, arguments); // emit for a non-node
11879 };
11880 }else{
11881 // no addEventListener, basically old IE event normalization
11882 on._fixEvent = function(evt, sender){
11883 // summary:
11884 // normalizes properties on the event object including event
11885 // bubbling methods, keystroke normalization, and x/y positions
11886 // evt:
11887 // native event object
11888 // sender:
11889 // node to treat as "currentTarget"
11890 if(!evt){
11891 var w = sender && (sender.ownerDocument || sender.document || sender).parentWindow || window;
11892 evt = w.event;
11893 }
11894 if(!evt){return(evt);}
11895 if(!evt.target){ // check to see if it has been fixed yet
11896 evt.target = evt.srcElement;
11897 evt.currentTarget = (sender || evt.srcElement);
11898 if(evt.type == "mouseover"){
11899 evt.relatedTarget = evt.fromElement;
11900 }
11901 if(evt.type == "mouseout"){
11902 evt.relatedTarget = evt.toElement;
11903 }
11904 if(!evt.stopPropagation){
11905 evt.stopPropagation = stopPropagation;
11906 evt.preventDefault = preventDefault;
11907 }
11908 switch(evt.type){
11909 case "keypress":
11910 var c = ("charCode" in evt ? evt.charCode : evt.keyCode);
11911 if (c==10){
11912 // CTRL-ENTER is CTRL-ASCII(10) on IE, but CTRL-ENTER on Mozilla
11913 c=0;
11914 evt.keyCode = 13;
11915 }else if(c==13||c==27){
11916 c=0; // Mozilla considers ENTER and ESC non-printable
11917 }else if(c==3){
11918 c=99; // Mozilla maps CTRL-BREAK to CTRL-c
11919 }
11920 // Mozilla sets keyCode to 0 when there is a charCode
11921 // but that stops the event on IE.
11922 evt.charCode = c;
11923 _setKeyChar(evt);
11924 break;
11925 }
11926 }
11927 return evt;
11928 };
11929 var IESignal = function(handle){
11930 this.handle = handle;
11931 };
11932 IESignal.prototype.remove = function(){
11933 delete _dojoIEListeners_[this.handle];
11934 };
11935 var fixListener = function(listener){
11936 // this is a minimal function for closing on the previous listener with as few as variables as possible
11937 return function(evt){
11938 evt = on._fixEvent(evt, this);
11939 return listener.call(this, evt);
11940 }
11941 }
11942 var fixAttach = function(target, type, listener){
11943 listener = fixListener(listener);
11944 if(((target.ownerDocument ? target.ownerDocument.parentWindow : target.parentWindow || target.window || window) != top ||
11945 has("jscript") < 5.8) &&
11946 !has("config-_allow_leaks")){
11947 // IE will leak memory on certain handlers in frames (IE8 and earlier) and in unattached DOM nodes for JScript 5.7 and below.
11948 // Here we use global redirection to solve the memory leaks
11949 if(typeof _dojoIEListeners_ == "undefined"){
11950 _dojoIEListeners_ = [];
11951 }
11952 var emiter = target[type];
11953 if(!emiter || !emiter.listeners){
11954 var oldListener = emiter;
11955 target[type] = 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);}}');
11956 emiter.listeners = [];
11957 emiter.global = this;
11958 if(oldListener){
11959 emiter.listeners.push(_dojoIEListeners_.push(oldListener) - 1);
11960 }
11961 }
11962 var handle;
11963 emiter.listeners.push(handle = (emiter.global._dojoIEListeners_.push(listener) - 1));
11964 return new IESignal(handle);
11965 }
11966 return aspect.after(target, type, listener, true);
11967 };
11968
11969 var _setKeyChar = function(evt){
11970 evt.keyChar = evt.charCode ? String.fromCharCode(evt.charCode) : '';
11971 evt.charOrCode = evt.keyChar || evt.keyCode;
11972 };
11973 // Called in Event scope
11974 var stopPropagation = function(){
11975 this.cancelBubble = true;
11976 };
11977 var preventDefault = on._preventDefault = function(){
11978 // Setting keyCode to 0 is the only way to prevent certain keypresses (namely
11979 // ctrl-combinations that correspond to menu accelerator keys).
11980 // Otoh, it prevents upstream listeners from getting this information
11981 // Try to split the difference here by clobbering keyCode only for ctrl
11982 // combinations. If you still need to access the key upstream, bubbledKeyCode is
11983 // provided as a workaround.
11984 this.bubbledKeyCode = this.keyCode;
11985 if(this.ctrlKey){
11986 try{
11987 // squelch errors when keyCode is read-only
11988 // (e.g. if keyCode is ctrl or shift)
11989 this.keyCode = 0;
11990 }catch(e){
11991 }
11992 }
11993 this.returnValue = false;
11994 };
11995 }
11996 if(has("touch")){
11997 var Event = function (){};
11998 var windowOrientation = window.orientation;
11999 var fixTouchListener = function(listener){
12000 return function(originalEvent){
12001 //Event normalization(for ontouchxxx and resize):
12002 //1.incorrect e.pageX|pageY in iOS
12003 //2.there are no "e.rotation", "e.scale" and "onorientationchange" in Andriod
12004 //3.More TBD e.g. force | screenX | screenX | clientX | clientY | radiusX | radiusY
12005
12006 // see if it has already been corrected
12007 var event = originalEvent.corrected;
12008 if(!event){
12009 var type = originalEvent.type;
12010 try{
12011 delete originalEvent.type; // on some JS engines (android), deleting properties make them mutable
12012 }catch(e){}
12013 if(originalEvent.type){
12014 // deleting properties doesn't work (older iOS), have to use delegation
12015 Event.prototype = originalEvent;
12016 var event = new Event;
12017 // have to delegate methods to make them work
12018 event.preventDefault = function(){
12019 originalEvent.preventDefault();
12020 };
12021 event.stopPropagation = function(){
12022 originalEvent.stopPropagation();
12023 };
12024 }else{
12025 // deletion worked, use property as is
12026 event = originalEvent;
12027 event.type = type;
12028 }
12029 originalEvent.corrected = event;
12030 if(type == 'resize'){
12031 if(windowOrientation == window.orientation){
12032 return null;//double tap causes an unexpected 'resize' in Andriod
12033 }
12034 windowOrientation = window.orientation;
12035 event.type = "orientationchange";
12036 return listener.call(this, event);
12037 }
12038 // We use the original event and augment, rather than doing an expensive mixin operation
12039 if(!("rotation" in event)){ // test to see if it has rotation
12040 event.rotation = 0;
12041 event.scale = 1;
12042 }
12043 //use event.changedTouches[0].pageX|pageY|screenX|screenY|clientX|clientY|target
12044 var firstChangeTouch = event.changedTouches[0];
12045 for(var i in firstChangeTouch){ // use for-in, we don't need to have dependency on dojo/_base/lang here
12046 delete event[i]; // delete it first to make it mutable
12047 event[i] = firstChangeTouch[i];
12048 }
12049 }
12050 return listener.call(this, event);
12051 };
12052 };
12053 }
12054 return on;
12055});
12056
12057},
12058'dojo/_base/sniff':function(){
12059define(["./kernel", "../has"], function(dojo, has){
12060 // module:
12061 // dojo/sniff
12062 // summary:
12063 // This module populates the dojo browser version sniffing properties.
2f01fe57 12064
1354d172
AD
12065 if(!1){
12066 return has;
12067 }
2f01fe57 12068
1354d172
AD
12069 dojo.isBrowser = true,
12070 dojo._name = "browser";
12071
12072 var hasAdd = has.add,
12073 n = navigator,
12074 dua = n.userAgent,
12075 dav = n.appVersion,
12076 tv = parseFloat(dav),
12077 isOpera,
12078 isAIR,
12079 isKhtml,
12080 isWebKit,
12081 isChrome,
12082 isMac,
12083 isSafari,
12084 isMozilla ,
12085 isMoz,
12086 isIE,
12087 isFF,
12088 isQuirks,
12089 isIos,
12090 isAndroid,
12091 isWii;
12092
12093 /*=====
12094 dojo.isBrowser = {
12095 // example:
12096 // | if(dojo.isBrowser){ ... }
2f01fe57
AD
12097 };
12098
1354d172
AD
12099 dojo.isFF = {
12100 // example:
12101 // | if(dojo.isFF > 1){ ... }
12102 };
2f01fe57 12103
1354d172
AD
12104 dojo.isIE = {
12105 // example:
12106 // | if(dojo.isIE > 6){
12107 // | // we are IE7
12108 // | }
12109 };
2f01fe57 12110
1354d172
AD
12111 dojo.isSafari = {
12112 // example:
12113 // | if(dojo.isSafari){ ... }
12114 // example:
12115 // Detect iPhone:
12116 // | if(dojo.isSafari && navigator.userAgent.indexOf("iPhone") != -1){
12117 // | // we are iPhone. Note, iPod touch reports "iPod" above and fails this test.
12118 // | }
12119 };
2f01fe57 12120
1354d172
AD
12121 dojo.mixin(dojo, {
12122 // isBrowser: Boolean
12123 // True if the client is a web-browser
12124 isBrowser: true,
12125 // isFF: Number | undefined
12126 // Version as a Number if client is FireFox. undefined otherwise. Corresponds to
12127 // major detected FireFox version (1.5, 2, 3, etc.)
12128 isFF: 2,
12129 // isIE: Number | undefined
12130 // Version as a Number if client is MSIE(PC). undefined otherwise. Corresponds to
12131 // major detected IE version (6, 7, 8, etc.)
12132 isIE: 6,
12133 // isKhtml: Number | undefined
12134 // Version as a Number if client is a KHTML browser. undefined otherwise. Corresponds to major
12135 // detected version.
12136 isKhtml: 0,
12137 // isWebKit: Number | undefined
12138 // Version as a Number if client is a WebKit-derived browser (Konqueror,
12139 // Safari, Chrome, etc.). undefined otherwise.
12140 isWebKit: 0,
12141 // isMozilla: Number | undefined
12142 // Version as a Number if client is a Mozilla-based browser (Firefox,
12143 // SeaMonkey). undefined otherwise. Corresponds to major detected version.
12144 isMozilla: 0,
12145 // isOpera: Number | undefined
12146 // Version as a Number if client is Opera. undefined otherwise. Corresponds to
12147 // major detected version.
12148 isOpera: 0,
12149 // isSafari: Number | undefined
12150 // Version as a Number if client is Safari or iPhone. undefined otherwise.
12151 isSafari: 0,
12152 // isChrome: Number | undefined
12153 // Version as a Number if client is Chrome browser. undefined otherwise.
12154 isChrome: 0,
12155 // isMac: Boolean
12156 // True if the client runs on Mac
12157 isMac: 0,
12158 // isIos: Boolean
12159 // True if client is iPhone, iPod, or iPad
12160 isIos: 0,
12161 // isAndroid: Number | undefined
12162 // Version as a Number if client is android browser. undefined otherwise.
12163 isAndroid: 0,
12164 // isWii: Boolean
12165 // True if client is Wii
12166 isWii: 0
12167 });
2f01fe57
AD
12168 =====*/
12169
1354d172
AD
12170 // fill in the rendering support information in dojo.render.*
12171 if(dua.indexOf("AdobeAIR") >= 0){ isAIR = 1; }
12172 isKhtml = (dav.indexOf("Konqueror") >= 0) ? tv : 0;
12173 isWebKit = parseFloat(dua.split("WebKit/")[1]) || undefined;
12174 isChrome = parseFloat(dua.split("Chrome/")[1]) || undefined;
12175 isMac = dav.indexOf("Macintosh") >= 0;
12176 isIos = /iPhone|iPod|iPad/.test(dua);
12177 isAndroid = parseFloat(dua.split("Android ")[1]) || undefined;
12178 isWii = typeof opera != "undefined" && opera.wiiremote;
12179
12180 // safari detection derived from:
12181 // http://developer.apple.com/internet/safari/faq.html#anchor2
12182 // http://developer.apple.com/internet/safari/uamatrix.html
12183 var index = Math.max(dav.indexOf("WebKit"), dav.indexOf("Safari"), 0);
12184 if(index && !isChrome){
12185 // try to grab the explicit Safari version first. If we don't get
12186 // one, look for less than 419.3 as the indication that we're on something
12187 // "Safari 2-ish".
12188 isSafari = parseFloat(dav.split("Version/")[1]);
12189 if(!isSafari || parseFloat(dav.substr(index + 7)) <= 419.3){
12190 isSafari = 2;
12191 }
12192 }
2f01fe57 12193
1354d172
AD
12194 if (!has("dojo-webkit")) {
12195 if(dua.indexOf("Opera") >= 0){
12196 isOpera = tv;
12197 // see http://dev.opera.com/articles/view/opera-ua-string-changes and http://www.useragentstring.com/pages/Opera/
12198 // 9.8 has both styles; <9.8, 9.9 only old style
12199 if(isOpera >= 9.8){
12200 isOpera = parseFloat(dua.split("Version/")[1]) || tv;
12201 }
12202 }
12203
12204 if(dua.indexOf("Gecko") >= 0 && !isKhtml && !isWebKit){
12205 isMozilla = isMoz = tv;
12206 }
12207 if(isMoz){
12208 //We really need to get away from this. Consider a sane isGecko approach for the future.
12209 isFF = parseFloat(dua.split("Firefox/")[1] || dua.split("Minefield/")[1]) || undefined;
12210 }
12211 if(document.all && !isOpera){
12212 isIE = parseFloat(dav.split("MSIE ")[1]) || undefined;
12213 //In cases where the page has an HTTP header or META tag with
12214 //X-UA-Compatible, then it is in emulation mode.
12215 //Make sure isIE reflects the desired version.
12216 //document.documentMode of 5 means quirks mode.
12217 //Only switch the value if documentMode's major version
12218 //is different from isIE's major version.
12219 var mode = document.documentMode;
12220 if(mode && mode != 5 && Math.floor(isIE) != mode){
12221 isIE = mode;
12222 }
12223 }
12224 }
12225
12226 isQuirks = document.compatMode == "BackCompat";
12227
12228 hasAdd("opera", dojo.isOpera = isOpera);
12229 hasAdd("air", dojo.isAIR = isAIR);
12230 hasAdd("khtml", dojo.isKhtml = isKhtml);
12231 hasAdd("webkit", dojo.isWebKit = isWebKit);
12232 hasAdd("chrome", dojo.isChrome = isChrome);
12233 hasAdd("mac", dojo.isMac = isMac );
12234 hasAdd("safari", dojo.isSafari = isSafari);
12235 hasAdd("mozilla", dojo.isMozilla = dojo.isMoz = isMozilla );
12236 hasAdd("ie", dojo.isIE = isIE );
12237 hasAdd("ff", dojo.isFF = isFF);
12238 hasAdd("quirks", dojo.isQuirks = isQuirks);
12239 hasAdd("ios", dojo.isIos = isIos);
12240 hasAdd("android", dojo.isAndroid = isAndroid);
12241
12242 dojo.locale = dojo.locale || (isIE ? n.userLanguage : n.language).toLowerCase();
12243
12244 return has;
12245});
12246
12247},
12248'dojo/_base/array':function(){
12249define("dojo/_base/array", ["./kernel", "../has", "./lang"], function(dojo, has, lang){
12250 // module:
12251 // dojo/_base/array
12252 // summary:
12253 // This module defines the Javascript v1.6 array extensions.
2f01fe57
AD
12254
12255 /*=====
1354d172
AD
12256 dojo.indexOf = function(arr, value, fromIndex, findLast){
12257 // summary:
12258 // locates the first index of the provided value in the
12259 // passed array. If the value is not found, -1 is returned.
12260 // description:
12261 // This method corresponds to the JavaScript 1.6 Array.indexOf method, with one difference: when
12262 // run over sparse arrays, the Dojo function invokes the callback for every index whereas JavaScript
12263 // 1.6's indexOf skips the holes in the sparse array.
12264 // For details on this method, see:
12265 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/indexOf
12266 // arr: Array
12267 // value: Object
12268 // fromIndex: Integer?
12269 // findLast: Boolean?
12270 // returns: Number
12271 };
12272 dojo.lastIndexOf = function(arr, value, fromIndex){
12273 // summary:
12274 // locates the last index of the provided value in the passed
12275 // array. If the value is not found, -1 is returned.
12276 // description:
12277 // This method corresponds to the JavaScript 1.6 Array.lastIndexOf method, with one difference: when
12278 // run over sparse arrays, the Dojo function invokes the callback for every index whereas JavaScript
12279 // 1.6's lastIndexOf skips the holes in the sparse array.
12280 // For details on this method, see:
12281 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/lastIndexOf
12282 // arr: Array,
12283 // value: Object,
12284 // fromIndex: Integer?
12285 // returns: Number
12286 };
12287 dojo.forEach = function(arr, callback, thisObject){
12288 // summary:
12289 // for every item in arr, callback is invoked. Return values are ignored.
12290 // If you want to break out of the loop, consider using dojo.every() or dojo.some().
12291 // forEach does not allow breaking out of the loop over the items in arr.
12292 // arr:
12293 // the array to iterate over. If a string, operates on individual characters.
12294 // callback:
12295 // a function is invoked with three arguments: item, index, and array
12296 // thisObject:
12297 // may be used to scope the call to callback
12298 // description:
12299 // This function corresponds to the JavaScript 1.6 Array.forEach() method, with one difference: when
12300 // run over sparse arrays, this implementation passes the "holes" in the sparse array to
12301 // the callback function with a value of undefined. JavaScript 1.6's forEach skips the holes in the sparse array.
12302 // For more details, see:
12303 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/forEach
12304 // example:
12305 // | // log out all members of the array:
12306 // | dojo.forEach(
12307 // | [ "thinger", "blah", "howdy", 10 ],
12308 // | function(item){
12309 // | console.log(item);
12310 // | }
12311 // | );
12312 // example:
12313 // | // log out the members and their indexes
12314 // | dojo.forEach(
12315 // | [ "thinger", "blah", "howdy", 10 ],
12316 // | function(item, idx, arr){
12317 // | console.log(item, "at index:", idx);
12318 // | }
12319 // | );
12320 // example:
12321 // | // use a scoped object member as the callback
12322 // |
12323 // | var obj = {
12324 // | prefix: "logged via obj.callback:",
12325 // | callback: function(item){
12326 // | console.log(this.prefix, item);
12327 // | }
12328 // | };
12329 // |
12330 // | // specifying the scope function executes the callback in that scope
12331 // | dojo.forEach(
12332 // | [ "thinger", "blah", "howdy", 10 ],
12333 // | obj.callback,
12334 // | obj
12335 // | );
12336 // |
12337 // | // alternately, we can accomplish the same thing with dojo.hitch()
12338 // | dojo.forEach(
12339 // | [ "thinger", "blah", "howdy", 10 ],
12340 // | dojo.hitch(obj, "callback")
12341 // | );
12342 // arr: Array|String
12343 // callback: Function|String
12344 // thisObject: Object?
12345 };
12346 dojo.every = function(arr, callback, thisObject){
12347 // summary:
12348 // Determines whether or not every item in arr satisfies the
12349 // condition implemented by callback.
12350 // arr: Array|String
12351 // the array to iterate on. If a string, operates on individual characters.
12352 // callback: Function|String
12353 // a function is invoked with three arguments: item, index,
12354 // and array and returns true if the condition is met.
12355 // thisObject: Object?
12356 // may be used to scope the call to callback
12357 // returns: Boolean
12358 // description:
12359 // This function corresponds to the JavaScript 1.6 Array.every() method, with one difference: when
12360 // run over sparse arrays, this implementation passes the "holes" in the sparse array to
12361 // the callback function with a value of undefined. JavaScript 1.6's every skips the holes in the sparse array.
12362 // For more details, see:
12363 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/every
12364 // example:
12365 // | // returns false
12366 // | dojo.every([1, 2, 3, 4], function(item){ return item>1; });
12367 // example:
12368 // | // returns true
12369 // | dojo.every([1, 2, 3, 4], function(item){ return item>0; });
12370 };
12371 dojo.some = function(arr, callback, thisObject){
12372 // summary:
12373 // Determines whether or not any item in arr satisfies the
12374 // condition implemented by callback.
12375 // arr: Array|String
12376 // the array to iterate over. If a string, operates on individual characters.
12377 // callback: Function|String
12378 // a function is invoked with three arguments: item, index,
12379 // and array and returns true if the condition is met.
12380 // thisObject: Object?
12381 // may be used to scope the call to callback
12382 // returns: Boolean
12383 // description:
12384 // This function corresponds to the JavaScript 1.6 Array.some() method, with one difference: when
12385 // run over sparse arrays, this implementation passes the "holes" in the sparse array to
12386 // the callback function with a value of undefined. JavaScript 1.6's some skips the holes in the sparse array.
12387 // For more details, see:
12388 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/some
12389 // example:
12390 // | // is true
12391 // | dojo.some([1, 2, 3, 4], function(item){ return item>1; });
12392 // example:
12393 // | // is false
12394 // | dojo.some([1, 2, 3, 4], function(item){ return item<1; });
12395 };
12396 dojo.map = function(arr, callback, thisObject){
12397 // summary:
12398 // applies callback to each element of arr and returns
12399 // an Array with the results
12400 // arr: Array|String
12401 // the array to iterate on. If a string, operates on
12402 // individual characters.
12403 // callback: Function|String
12404 // a function is invoked with three arguments, (item, index,
12405 // array), and returns a value
12406 // thisObject: Object?
12407 // may be used to scope the call to callback
12408 // returns: Array
12409 // description:
12410 // This function corresponds to the JavaScript 1.6 Array.map() method, with one difference: when
12411 // run over sparse arrays, this implementation passes the "holes" in the sparse array to
12412 // the callback function with a value of undefined. JavaScript 1.6's map skips the holes in the sparse array.
12413 // For more details, see:
12414 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map
12415 // example:
12416 // | // returns [2, 3, 4, 5]
12417 // | dojo.map([1, 2, 3, 4], function(item){ return item+1 });
12418 };
12419 dojo.filter = function(arr, callback, thisObject){
12420 // summary:
12421 // Returns a new Array with those items from arr that match the
12422 // condition implemented by callback.
12423 // arr: Array
12424 // the array to iterate over.
12425 // callback: Function|String
12426 // a function that is invoked with three arguments (item,
12427 // index, array). The return of this function is expected to
12428 // be a boolean which determines whether the passed-in item
12429 // will be included in the returned array.
12430 // thisObject: Object?
12431 // may be used to scope the call to callback
12432 // returns: Array
12433 // description:
12434 // This function corresponds to the JavaScript 1.6 Array.filter() method, with one difference: when
12435 // run over sparse arrays, this implementation passes the "holes" in the sparse array to
12436 // the callback function with a value of undefined. JavaScript 1.6's filter skips the holes in the sparse array.
12437 // For more details, see:
12438 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/filter
12439 // example:
12440 // | // returns [2, 3, 4]
12441 // | dojo.filter([1, 2, 3, 4], function(item){ return item>1; });
12442 };
12443 =====*/
2f01fe57 12444
1354d172
AD
12445 // our old simple function builder stuff
12446 var cache = {}, u, array; // the export object
2f01fe57 12447
1354d172
AD
12448 function clearCache(){
12449 cache = {};
12450 }
2f01fe57 12451
1354d172
AD
12452 function buildFn(fn){
12453 return cache[fn] = new Function("item", "index", "array", fn); // Function
12454 }
12455 // magic snippet: if(typeof fn == "string") fn = cache[fn] || buildFn(fn);
2f01fe57 12456
1354d172 12457 // every & some
2f01fe57 12458
1354d172
AD
12459 function everyOrSome(some){
12460 var every = !some;
12461 return function(a, fn, o){
12462 var i = 0, l = a && a.length || 0, result;
12463 if(l && typeof a == "string") a = a.split("");
12464 if(typeof fn == "string") fn = cache[fn] || buildFn(fn);
12465 if(o){
12466 for(; i < l; ++i){
12467 result = !fn.call(o, a[i], i, a);
12468 if(some ^ result){
12469 return !result;
12470 }
12471 }
12472 }else{
12473 for(; i < l; ++i){
12474 result = !fn(a[i], i, a);
12475 if(some ^ result){
12476 return !result;
12477 }
12478 }
12479 }
12480 return every; // Boolean
12481 }
12482 }
12483 // var every = everyOrSome(false), some = everyOrSome(true);
2f01fe57 12484
1354d172 12485 // indexOf, lastIndexOf
2f01fe57 12486
1354d172
AD
12487 function index(up){
12488 var delta = 1, lOver = 0, uOver = 0;
12489 if(!up){
12490 delta = lOver = uOver = -1;
12491 }
12492 return function(a, x, from, last){
12493 if(last && delta > 0){
12494 // TODO: why do we use a non-standard signature? why do we need "last"?
12495 return array.lastIndexOf(a, x, from);
12496 }
12497 var l = a && a.length || 0, end = up ? l + uOver : lOver, i;
12498 if(from === u){
12499 i = up ? lOver : l + uOver;
12500 }else{
12501 if(from < 0){
12502 i = l + from;
12503 if(i < 0){
12504 i = lOver;
12505 }
12506 }else{
12507 i = from >= l ? l + uOver : from;
12508 }
12509 }
12510 if(l && typeof a == "string") a = a.split("");
12511 for(; i != end; i += delta){
12512 if(a[i] == x){
12513 return i; // Number
12514 }
12515 }
12516 return -1; // Number
12517 }
12518 }
12519 // var indexOf = index(true), lastIndexOf = index(false);
2f01fe57 12520
1354d172
AD
12521 function forEach(a, fn, o){
12522 var i = 0, l = a && a.length || 0;
12523 if(l && typeof a == "string") a = a.split("");
12524 if(typeof fn == "string") fn = cache[fn] || buildFn(fn);
12525 if(o){
12526 for(; i < l; ++i){
12527 fn.call(o, a[i], i, a);
12528 }
12529 }else{
12530 for(; i < l; ++i){
12531 fn(a[i], i, a);
12532 }
12533 }
12534 }
2f01fe57 12535
1354d172
AD
12536 function map(a, fn, o, Ctr){
12537 // TODO: why do we have a non-standard signature here? do we need "Ctr"?
12538 var i = 0, l = a && a.length || 0, out = new (Ctr || Array)(l);
12539 if(l && typeof a == "string") a = a.split("");
12540 if(typeof fn == "string") fn = cache[fn] || buildFn(fn);
12541 if(o){
12542 for(; i < l; ++i){
12543 out[i] = fn.call(o, a[i], i, a);
12544 }
12545 }else{
12546 for(; i < l; ++i){
12547 out[i] = fn(a[i], i, a);
12548 }
12549 }
12550 return out; // Array
12551 }
2f01fe57 12552
1354d172
AD
12553 function filter(a, fn, o){
12554 // TODO: do we need "Ctr" here like in map()?
12555 var i = 0, l = a && a.length || 0, out = [], value;
12556 if(l && typeof a == "string") a = a.split("");
12557 if(typeof fn == "string") fn = cache[fn] || buildFn(fn);
12558 if(o){
12559 for(; i < l; ++i){
12560 value = a[i];
12561 if(fn.call(o, value, i, a)){
12562 out.push(value);
2f01fe57
AD
12563 }
12564 }
1354d172
AD
12565 }else{
12566 for(; i < l; ++i){
12567 value = a[i];
12568 if(fn(value, i, a)){
12569 out.push(value);
12570 }
12571 }
12572 }
12573 return out; // Array
12574 }
2f01fe57 12575
1354d172
AD
12576 array = {
12577 every: everyOrSome(false),
12578 some: everyOrSome(true),
12579 indexOf: index(true),
12580 lastIndexOf: index(false),
12581 forEach: forEach,
12582 map: map,
12583 filter: filter,
12584 clearCache: clearCache
12585 };
2f01fe57 12586
1354d172
AD
12587 1 && lang.mixin(dojo, array);
12588
12589 /*===== return dojo.array; =====*/
12590 return array;
12591});
12592
12593},
12594'dojo/_base/json':function(){
12595define(["./kernel", "../json"], function(dojo, json){
12596 // module:
12597 // dojo/_base/json
12598 // summary:
12599 // This module defines the dojo JSON API.
12600
12601dojo.fromJson = function(/*String*/ js){
12602 // summary:
12603 // Parses a JavaScript expression and returns a JavaScript value.
12604 // description:
12605 // Throws for invalid JavaScript expressions. It does not use a strict JSON parser. It
12606 // always delegates to eval(). The content passed to this method must therefore come
12607 // from a trusted source.
12608 // It is recommend that you use dojo/json's parse function for an
12609 // implementation uses the (faster) native JSON parse when available.
12610 // js:
12611 // a string literal of a JavaScript expression, for instance:
12612 // `'{ "foo": [ "bar", 1, { "baz": "thud" } ] }'`
12613
12614 return eval("(" + js + ")"); // Object
12615};
12616
12617/*=====
12618dojo._escapeString = function(){
12619 // summary:
12620 // Adds escape sequences for non-visual characters, double quote and
12621 // backslash and surrounds with double quotes to form a valid string
12622 // literal.
12623};
12624=====*/
12625dojo._escapeString = json.stringify; // just delegate to json.stringify
12626
12627dojo.toJsonIndentStr = "\t";
12628dojo.toJson = function(/*Object*/ it, /*Boolean?*/ prettyPrint){
12629 // summary:
12630 // Returns a [JSON](http://json.org) serialization of an object.
12631 // description:
12632 // Returns a [JSON](http://json.org) serialization of an object.
12633 // Note that this doesn't check for infinite recursion, so don't do that!
12634 // It is recommend that you use dojo/json's stringify function for an lighter
12635 // and faster implementation that matches the native JSON API and uses the
12636 // native JSON serializer when available.
12637 // it:
12638 // an object to be serialized. Objects may define their own
12639 // serialization via a special "__json__" or "json" function
12640 // property. If a specialized serializer has been defined, it will
12641 // be used as a fallback.
12642 // Note that in 1.6, toJson would serialize undefined, but this no longer supported
12643 // since it is not supported by native JSON serializer.
12644 // prettyPrint:
12645 // if true, we indent objects and arrays to make the output prettier.
12646 // The variable `dojo.toJsonIndentStr` is used as the indent string --
12647 // to use something other than the default (tab), change that variable
12648 // before calling dojo.toJson().
12649 // Note that if native JSON support is available, it will be used for serialization,
12650 // and native implementations vary on the exact spacing used in pretty printing.
12651 // returns:
12652 // A JSON string serialization of the passed-in object.
12653 // example:
12654 // simple serialization of a trivial object
12655 // | var jsonStr = dojo.toJson({ howdy: "stranger!", isStrange: true });
12656 // | doh.is('{"howdy":"stranger!","isStrange":true}', jsonStr);
12657 // example:
12658 // a custom serializer for an objects of a particular class:
12659 // | dojo.declare("Furby", null, {
12660 // | furbies: "are strange",
12661 // | furbyCount: 10,
12662 // | __json__: function(){
12663 // | },
12664 // | });
12665
12666 // use dojo/json
12667 return json.stringify(it, function(key, value){
12668 if(value){
12669 var tf = value.__json__||value.json;
12670 if(typeof tf == "function"){
12671 return tf.call(value);
2f01fe57 12672 }
1354d172
AD
12673 }
12674 return value;
12675 }, prettyPrint && dojo.toJsonIndentStr); // String
12676};
2f01fe57 12677
1354d172
AD
12678return dojo;
12679});
2f01fe57 12680
1354d172
AD
12681},
12682'dojo/dom-class':function(){
12683define(["./_base/lang", "./_base/array", "./dom"], function(lang, array, dom){
12684 // module:
12685 // dojo/dom-class
12686 // summary:
12687 // This module defines the core dojo DOM class API.
2f01fe57 12688
1354d172 12689 var className = "className";
2f01fe57 12690
1354d172
AD
12691 /* Part I of classList-based implementation is preserved here for posterity
12692 var classList = "classList";
12693 has.add("dom-classList", function(){
12694 return classList in document.createElement("p");
12695 });
12696 */
2f01fe57 12697
1354d172
AD
12698 // =============================
12699 // (CSS) Class Functions
12700 // =============================
2f01fe57 12701
1354d172
AD
12702 /*=====
12703 dojo.hasClass = function(node, classStr){
12704 // summary:
12705 // Returns whether or not the specified classes are a portion of the
12706 // class list currently applied to the node.
12707 //
12708 // node: String|DOMNode
12709 // String ID or DomNode reference to check the class for.
12710 //
12711 // classStr: String
12712 // A string class name to look for.
12713 //
12714 // returns: Boolean
12715 //
12716 // example:
12717 // Do something if a node with id="someNode" has class="aSillyClassName" present
12718 // | if(dojo.hasClass("someNode","aSillyClassName")){ ... }
12719 };
12720 =====*/
2f01fe57 12721
1354d172
AD
12722 /*=====
12723 dojo.addClass = function(node, classStr){
12724 // summary:
12725 // Adds the specified classes to the end of the class list on the
12726 // passed node. Will not re-apply duplicate classes.
12727 //
12728 // node: String|DOMNode
12729 // String ID or DomNode reference to add a class string too
12730 //
12731 // classStr: String|Array
12732 // A String class name to add, or several space-separated class names,
12733 // or an array of class names.
12734 //
12735 // example:
12736 // Add a class to some node:
12737 // | dojo.addClass("someNode", "anewClass");
12738 //
12739 // example:
12740 // Add two classes at once:
12741 // | dojo.addClass("someNode", "firstClass secondClass");
12742 //
12743 // example:
12744 // Add two classes at once (using array):
12745 // | dojo.addClass("someNode", ["firstClass", "secondClass"]);
12746 //
12747 // example:
12748 // Available in `dojo.NodeList` for multiple additions
12749 // | dojo.query("ul > li").addClass("firstLevel");
12750 };
12751 =====*/
2f01fe57 12752
1354d172
AD
12753 /*=====
12754 dojo.removeClass = function(node, classStr){
12755 // summary:
12756 // Removes the specified classes from node. No `dojo.hasClass`
12757 // check is required.
12758 //
12759 // node: String|DOMNode
12760 // String ID or DomNode reference to remove the class from.
12761 //
12762 // classStr: String|Array
12763 // An optional String class name to remove, or several space-separated
12764 // class names, or an array of class names. If omitted, all class names
12765 // will be deleted.
12766 //
12767 // example:
12768 // Remove a class from some node:
12769 // | dojo.removeClass("someNode", "firstClass");
12770 //
12771 // example:
12772 // Remove two classes from some node:
12773 // | dojo.removeClass("someNode", "firstClass secondClass");
12774 //
12775 // example:
12776 // Remove two classes from some node (using array):
12777 // | dojo.removeClass("someNode", ["firstClass", "secondClass"]);
12778 //
12779 // example:
12780 // Remove all classes from some node:
12781 // | dojo.removeClass("someNode");
12782 //
12783 // example:
12784 // Available in `dojo.NodeList()` for multiple removal
12785 // | dojo.query(".foo").removeClass("foo");
12786 };
12787 =====*/
2f01fe57 12788
1354d172
AD
12789 /*=====
12790 dojo.replaceClass = function(node, addClassStr, removeClassStr){
12791 // summary:
12792 // Replaces one or more classes on a node if not present.
12793 // Operates more quickly than calling dojo.removeClass and dojo.addClass
12794 //
12795 // node: String|DOMNode
12796 // String ID or DomNode reference to remove the class from.
12797 //
12798 // addClassStr: String|Array
12799 // A String class name to add, or several space-separated class names,
12800 // or an array of class names.
12801 //
12802 // removeClassStr: String|Array?
12803 // A String class name to remove, or several space-separated class names,
12804 // or an array of class names.
12805 //
12806 // example:
12807 // | dojo.replaceClass("someNode", "add1 add2", "remove1 remove2");
12808 //
12809 // example:
12810 // Replace all classes with addMe
12811 // | dojo.replaceClass("someNode", "addMe");
12812 //
12813 // example:
12814 // Available in `dojo.NodeList()` for multiple toggles
12815 // | dojo.query(".findMe").replaceClass("addMe", "removeMe");
12816 };
12817 =====*/
2f01fe57 12818
1354d172
AD
12819 /*=====
12820 dojo.toggleClass = function(node, classStr, condition){
12821 // summary:
12822 // Adds a class to node if not present, or removes if present.
12823 // Pass a boolean condition if you want to explicitly add or remove.
12824 // Returns the condition that was specified directly or indirectly.
12825 //
12826 // node: String|DOMNode
12827 // String ID or DomNode reference to toggle a class string
12828 //
12829 // classStr: String|Array
12830 // A String class name to toggle, or several space-separated class names,
12831 // or an array of class names.
12832 //
12833 // condition:
12834 // If passed, true means to add the class, false means to remove.
12835 // Otherwise dojo.hasClass(node, classStr) is used to detect the class presence.
12836 //
12837 // example:
12838 // | dojo.toggleClass("someNode", "hovered");
12839 //
12840 // example:
12841 // Forcefully add a class
12842 // | dojo.toggleClass("someNode", "hovered", true);
12843 //
12844 // example:
12845 // Available in `dojo.NodeList()` for multiple toggles
12846 // | dojo.query(".toggleMe").toggleClass("toggleMe");
12847 };
12848 =====*/
2f01fe57 12849
1354d172
AD
12850 var cls, // exports object
12851 spaces = /\s+/, a1 = [""];
12852
12853 function str2array(s){
12854 if(typeof s == "string" || s instanceof String){
12855 if(s && !spaces.test(s)){
12856 a1[0] = s;
12857 return a1;
2f01fe57 12858 }
1354d172
AD
12859 var a = s.split(spaces);
12860 if(a.length && !a[0]){
12861 a.shift();
12862 }
12863 if(a.length && !a[a.length - 1]){
12864 a.pop();
12865 }
12866 return a;
12867 }
12868 // assumed to be an array
12869 if(!s){
12870 return [];
12871 }
12872 return array.filter(s, function(x){ return x; });
12873 }
2f01fe57 12874
1354d172
AD
12875 /* Part II of classList-based implementation is preserved here for posterity
12876 if(has("dom-classList")){
12877 // new classList version
12878 cls = {
12879 contains: function containsClass(node, classStr){
12880 var clslst = classStr && dom.byId(node)[classList];
12881 return clslst && clslst.contains(classStr); // Boolean
12882 },
2f01fe57 12883
1354d172
AD
12884 add: function addClass(node, classStr){
12885 node = dom.byId(node);
12886 classStr = str2array(classStr);
12887 for(var i = 0, len = classStr.length; i < len; ++i){
12888 node[classList].add(classStr[i]);
2f01fe57 12889 }
1354d172 12890 },
2f01fe57 12891
1354d172
AD
12892 remove: function removeClass(node, classStr){
12893 node = dom.byId(node);
12894 if(classStr === undefined){
12895 node[className] = "";
12896 }else{
12897 classStr = str2array(classStr);
12898 for(var i = 0, len = classStr.length; i < len; ++i){
12899 node[classList].remove(classStr[i]);
12900 }
2f01fe57 12901 }
1354d172 12902 },
2f01fe57 12903
1354d172
AD
12904 replace: function replaceClass(node, addClassStr, removeClassStr){
12905 node = dom.byId(node);
12906 if(removeClassStr === undefined){
12907 node[className] = "";
2f01fe57 12908 }else{
1354d172
AD
12909 removeClassStr = str2array(removeClassStr);
12910 for(var i = 0, len = removeClassStr.length; i < len; ++i){
12911 node[classList].remove(removeClassStr[i]);
12912 }
12913 }
12914 addClassStr = str2array(addClassStr);
12915 for(i = 0, len = addClassStr.length; i < len; ++i){
12916 node[classList].add(addClassStr[i]);
12917 }
12918 },
2f01fe57 12919
1354d172
AD
12920 toggle: function toggleClass(node, classStr, condition){
12921 node = dom.byId(node);
12922 if(condition === undefined){
12923 classStr = str2array(classStr);
12924 for(var i = 0, len = classStr.length; i < len; ++i){
12925 node[classList].toggle(classStr[i]);
2f01fe57 12926 }
1354d172
AD
12927 }else{
12928 cls[condition ? "add" : "remove"](node, classStr);
12929 }
12930 return condition; // Boolean
12931 }
12932 }
12933 }
12934 */
12935
12936 // regular DOM version
12937 var fakeNode = {}; // for effective replacement
12938 cls = {
12939 contains: function containsClass(/*DomNode|String*/node, /*String*/classStr){
12940 return ((" " + dom.byId(node)[className] + " ").indexOf(" " + classStr + " ") >= 0); // Boolean
12941 },
12942
12943 add: function addClass(/*DomNode|String*/node, /*String|Array*/classStr){
12944 node = dom.byId(node);
12945 classStr = str2array(classStr);
12946 var cls = node[className], oldLen;
12947 cls = cls ? " " + cls + " " : " ";
12948 oldLen = cls.length;
12949 for(var i = 0, len = classStr.length, c; i < len; ++i){
12950 c = classStr[i];
12951 if(c && cls.indexOf(" " + c + " ") < 0){
12952 cls += c + " ";
12953 }
12954 }
12955 if(oldLen < cls.length){
12956 node[className] = cls.substr(1, cls.length - 2);
12957 }
12958 },
12959
12960 remove: function removeClass(/*DomNode|String*/node, /*String|Array?*/classStr){
12961 node = dom.byId(node);
12962 var cls;
12963 if(classStr !== undefined){
12964 classStr = str2array(classStr);
12965 cls = " " + node[className] + " ";
12966 for(var i = 0, len = classStr.length; i < len; ++i){
12967 cls = cls.replace(" " + classStr[i] + " ", " ");
2f01fe57 12968 }
1354d172
AD
12969 cls = lang.trim(cls);
12970 }else{
12971 cls = "";
2f01fe57 12972 }
1354d172 12973 if(node[className] != cls){ node[className] = cls; }
2f01fe57
AD
12974 },
12975
1354d172
AD
12976 replace: function replaceClass(/*DomNode|String*/node, /*String|Array*/addClassStr, /*String|Array?*/removeClassStr){
12977 node = dom.byId(node);
12978 fakeNode[className] = node[className];
12979 cls.remove(fakeNode, removeClassStr);
12980 cls.add(fakeNode, addClassStr);
12981 if(node[className] !== fakeNode[className]){
12982 node[className] = fakeNode[className];
12983 }
12984 },
12985
12986 toggle: function toggleClass(/*DomNode|String*/node, /*String|Array*/classStr, /*Boolean?*/condition){
12987 node = dom.byId(node);
12988 if(condition === undefined){
12989 classStr = str2array(classStr);
12990 for(var i = 0, len = classStr.length, c; i < len; ++i){
12991 c = classStr[i];
12992 cls[cls.contains(node, c) ? "remove" : "add"](node, c);
12993 }
12994 }else{
12995 cls[condition ? "add" : "remove"](node, classStr);
12996 }
12997 return condition; // Boolean
2f01fe57 12998 }
1354d172 12999 };
2f01fe57 13000
1354d172
AD
13001 return cls;
13002});
2f01fe57 13003
1354d172
AD
13004},
13005'dojo/_base/window':function(){
13006define(["./kernel", "../has", "./sniff"], function(dojo, has){
13007 // module:
13008 // dojo/window
13009 // summary:
13010 // This module provides an API to save/set/restore the global/document scope.
2f01fe57 13011
1354d172
AD
13012/*=====
13013dojo.doc = {
13014 // summary:
13015 // Alias for the current document. 'dojo.doc' can be modified
13016 // for temporary context shifting. Also see dojo.withDoc().
13017 // description:
13018 // Refer to dojo.doc rather
13019 // than referring to 'window.document' to ensure your code runs
13020 // correctly in managed contexts.
13021 // example:
13022 // | n.appendChild(dojo.doc.createElement('div'));
13023}
13024=====*/
13025dojo.doc = this["document"] || null;
2f01fe57 13026
1354d172
AD
13027dojo.body = function(){
13028 // summary:
13029 // Return the body element of the document
13030 // return the body object associated with dojo.doc
13031 // example:
13032 // | dojo.body().appendChild(dojo.doc.createElement('div'));
2f01fe57 13033
1354d172
AD
13034 // Note: document.body is not defined for a strict xhtml document
13035 // Would like to memoize this, but dojo.doc can change vi dojo.withDoc().
13036 return dojo.doc.body || dojo.doc.getElementsByTagName("body")[0]; // Node
13037};
13038
13039dojo.setContext = function(/*Object*/globalObject, /*DocumentElement*/globalDocument){
13040 // summary:
13041 // changes the behavior of many core Dojo functions that deal with
13042 // namespace and DOM lookup, changing them to work in a new global
13043 // context (e.g., an iframe). The varibles dojo.global and dojo.doc
13044 // are modified as a result of calling this function and the result of
13045 // `dojo.body()` likewise differs.
13046 dojo.global = ret.global = globalObject;
13047 dojo.doc = ret.doc = globalDocument;
13048};
13049
13050dojo.withGlobal = function( /*Object*/globalObject,
13051 /*Function*/callback,
13052 /*Object?*/thisObject,
13053 /*Array?*/cbArguments){
13054 // summary:
13055 // Invoke callback with globalObject as dojo.global and
13056 // globalObject.document as dojo.doc.
13057 // description:
13058 // Invoke callback with globalObject as dojo.global and
13059 // globalObject.document as dojo.doc. If provided, globalObject
13060 // will be executed in the context of object thisObject
13061 // When callback() returns or throws an error, the dojo.global
13062 // and dojo.doc will be restored to its previous state.
13063
13064 var oldGlob = dojo.global;
13065 try{
13066 dojo.global = ret.global = globalObject;
13067 return dojo.withDoc.call(null, globalObject.document, callback, thisObject, cbArguments);
13068 }finally{
13069 dojo.global = ret.global = oldGlob;
13070 }
13071};
13072
13073dojo.withDoc = function( /*DocumentElement*/documentObject,
13074 /*Function*/callback,
13075 /*Object?*/thisObject,
13076 /*Array?*/cbArguments){
13077 // summary:
13078 // Invoke callback with documentObject as dojo.doc.
13079 // description:
13080 // Invoke callback with documentObject as dojo.doc. If provided,
13081 // callback will be executed in the context of object thisObject
13082 // When callback() returns or throws an error, the dojo.doc will
13083 // be restored to its previous state.
13084
13085 var oldDoc = dojo.doc,
13086 oldQ = dojo.isQuirks,
13087 oldIE = dojo.isIE, isIE, mode, pwin;
13088
13089 try{
13090 dojo.doc = ret.doc = documentObject;
13091 // update dojo.isQuirks and the value of the has feature "quirks"
13092 dojo.isQuirks = has.add("quirks", dojo.doc.compatMode == "BackCompat", true, true); // no need to check for QuirksMode which was Opera 7 only
13093
13094 if(has("ie")){
13095 if((pwin = documentObject.parentWindow) && pwin.navigator){
13096 // re-run IE detection logic and update dojo.isIE / has("ie")
13097 // (the only time parentWindow/navigator wouldn't exist is if we were not
13098 // passed an actual legitimate document object)
13099 isIE = parseFloat(pwin.navigator.appVersion.split("MSIE ")[1]) || undefined;
13100 mode = documentObject.documentMode;
13101 if(mode && mode != 5 && Math.floor(isIE) != mode){
13102 isIE = mode;
13103 }
13104 dojo.isIE = has.add("ie", isIE, true, true);
2f01fe57
AD
13105 }
13106 }
13107
1354d172
AD
13108 if(thisObject && typeof callback == "string"){
13109 callback = thisObject[callback];
13110 }
2f01fe57 13111
1354d172
AD
13112 return callback.apply(thisObject, cbArguments || []);
13113 }finally{
13114 dojo.doc = ret.doc = oldDoc;
13115 dojo.isQuirks = has.add("quirks", oldQ, true, true);
13116 dojo.isIE = has.add("ie", oldIE, true, true);
13117 }
13118};
2f01fe57 13119
1354d172
AD
13120var ret = {
13121 global: dojo.global,
13122 doc: dojo.doc,
13123 body: dojo.body,
13124 setContext: dojo.setContext,
13125 withGlobal: dojo.withGlobal,
13126 withDoc: dojo.withDoc
13127};
2f01fe57 13128
1354d172 13129return ret;
2f01fe57 13130
1354d172 13131});
2f01fe57 13132
1354d172
AD
13133},
13134'dojo/_base/config':function(){
13135define(["../has", "require"], function(has, require){
13136 // module:
13137 // dojo/_base/config
13138 // summary:
13139 // This module defines the user configuration during bootstrap.
13140 // description:
13141 // By defining user configuration as a module value, an entire configuration can be specified in a build,
13142 // thereby eliminating the need for sniffing and or explicitly setting in the global variable dojoConfig.
13143 // Also, when multiple instances of dojo exist in a single application, each will necessarily be located
13144 // at an unique absolute module identifier as given by the package configuration. Implementing configuration
13145 // as a module allows for specifying unique, per-instance configurations.
13146 // example:
13147 // Create a second instance of dojo with a different, instance-uniqe configuration (assume the loader and
13148 // dojo.js are already loaded).
13149 // | // specify a configuration that creates a new instance of dojo at the absolute module identifier "myDojo"
13150 // | require({
13151 // | packages:[{
13152 // | name:"myDojo",
13153 // | location:".", //assume baseUrl points to dojo.js
13154 // | }]
13155 // | });
13156 // |
13157 // | // specify a configuration for the myDojo instance
13158 // | define("myDojo/config", {
13159 // | // normal configuration variables go here, e.g.,
13160 // | locale:"fr-ca"
13161 // | });
13162 // |
13163 // | // load and use the new instance of dojo
13164 // | require(["myDojo"], function(dojo) {
13165 // | // dojo is the new instance of dojo
13166 // | // use as required
13167 // | });
2f01fe57 13168
1354d172
AD
13169 var result = {};
13170 if(1){
13171 // must be the dojo loader; take a shallow copy of require.rawConfig
13172 var src = require.rawConfig, p;
13173 for(p in src){
13174 result[p] = src[p];
13175 }
13176 }else{
13177 var adviseHas = function(featureSet, prefix, booting){
13178 for(p in featureSet){
13179 p!="has" && has.add(prefix + p, featureSet[p], 0, booting);
13180 }
13181 };
13182 result = 1 ?
13183 // must be a built version of the dojo loader; all config stuffed in require.rawConfig
13184 require.rawConfig :
13185 // a foreign loader
13186 this.dojoConfig || this.djConfig || {};
13187 adviseHas(result, "config", 1);
13188 adviseHas(result.has, "", 1);
13189 }
13190 return result;
2f01fe57 13191
1354d172
AD
13192/*=====
13193// note:
13194// 'dojoConfig' does not exist under 'dojo.*' so that it can be set before the
13195// 'dojo' variable exists.
13196// note:
13197// Setting any of these variables *after* the library has loaded does
13198// nothing at all.
13199
13200// FIXME: can we document these on dojo.config object and explain they must be set via djConfig/dojoConfig global prior to loading dojo.js
13201
13202dojoConfig = {
13203 // summary:
13204 // Application code can set the global 'dojoConfig' prior to loading
13205 // the library to control certain global settings for how dojo works.
13206 //
13207 // isDebug: Boolean
13208 // Defaults to `false`. If set to `true`, ensures that Dojo provides
13209 // extended debugging feedback via Firebug. If Firebug is not available
13210 // on your platform, setting `isDebug` to `true` will force Dojo to
13211 // pull in (and display) the version of Firebug Lite which is
13212 // integrated into the Dojo distribution, thereby always providing a
13213 // debugging/logging console when `isDebug` is enabled. Note that
13214 // Firebug's `console.*` methods are ALWAYS defined by Dojo. If
13215 // `isDebug` is false and you are on a platform without Firebug, these
13216 // methods will be defined as no-ops.
13217 isDebug: false,
13218 // locale: String
13219 // The locale to assume for loading localized resources in this page,
13220 // specified according to [RFC 3066](http://www.ietf.org/rfc/rfc3066.txt).
13221 // Must be specified entirely in lowercase, e.g. `en-us` and `zh-cn`.
13222 // See the documentation for `dojo.i18n` and `dojo.requireLocalization`
13223 // for details on loading localized resources. If no locale is specified,
13224 // Dojo assumes the locale of the user agent, according to `navigator.userLanguage`
13225 // or `navigator.language` properties.
13226 locale: undefined,
13227 // extraLocale: Array
13228 // No default value. Specifies additional locales whose
13229 // resources should also be loaded alongside the default locale when
13230 // calls to `dojo.requireLocalization()` are processed.
13231 extraLocale: undefined,
13232 // baseUrl: String
13233 // The directory in which `dojo.js` is located. Under normal
13234 // conditions, Dojo auto-detects the correct location from which it
13235 // was loaded. You may need to manually configure `baseUrl` in cases
13236 // where you have renamed `dojo.js` or in which `<base>` tags confuse
13237 // some browsers (e.g. IE 6). The variable `dojo.baseUrl` is assigned
13238 // either the value of `djConfig.baseUrl` if one is provided or the
13239 // auto-detected root if not. Other modules are located relative to
13240 // this path. The path should end in a slash.
13241 baseUrl: undefined,
13242 // modulePaths: Object
13243 // A map of module names to paths relative to `dojo.baseUrl`. The
13244 // key/value pairs correspond directly to the arguments which
13245 // `dojo.registerModulePath` accepts. Specifiying
13246 // `djConfig.modulePaths = { "foo": "../../bar" }` is the equivalent
13247 // of calling `dojo.registerModulePath("foo", "../../bar");`. Multiple
13248 // modules may be configured via `djConfig.modulePaths`.
13249 modulePaths: {},
13250 // afterOnLoad: Boolean
13251 // Indicates Dojo was added to the page after the page load. In this case
13252 // Dojo will not wait for the page DOMContentLoad/load events and fire
13253 // its dojo.addOnLoad callbacks after making sure all outstanding
13254 // dojo.required modules have loaded. Only works with a built dojo.js,
13255 // it does not work the dojo.js directly from source control.
13256 afterOnLoad: false,
13257 // addOnLoad: Function or Array
13258 // Adds a callback via dojo.addOnLoad. Useful when Dojo is added after
13259 // the page loads and djConfig.afterOnLoad is true. Supports the same
13260 // arguments as dojo.addOnLoad. When using a function reference, use
13261 // `djConfig.addOnLoad = function(){};`. For object with function name use
13262 // `djConfig.addOnLoad = [myObject, "functionName"];` and for object with
13263 // function reference use
13264 // `djConfig.addOnLoad = [myObject, function(){}];`
13265 addOnLoad: null,
13266 // require: Array
13267 // An array of module names to be loaded immediately after dojo.js has been included
13268 // in a page.
13269 require: [],
13270 // defaultDuration: Array
13271 // Default duration, in milliseconds, for wipe and fade animations within dijits.
13272 // Assigned to dijit.defaultDuration.
13273 defaultDuration: 200,
13274 // dojoBlankHtmlUrl: String
13275 // Used by some modules to configure an empty iframe. Used by dojo.io.iframe and
13276 // dojo.back, and dijit popup support in IE where an iframe is needed to make sure native
13277 // controls do not bleed through the popups. Normally this configuration variable
13278 // does not need to be set, except when using cross-domain/CDN Dojo builds.
13279 // Save dojo/resources/blank.html to your domain and set `djConfig.dojoBlankHtmlUrl`
13280 // to the path on your domain your copy of blank.html.
13281 dojoBlankHtmlUrl: undefined,
13282 // ioPublish: Boolean?
13283 // Set this to true to enable publishing of topics for the different phases of
13284 // IO operations. Publishing is done via dojo.publish. See dojo.__IoPublish for a list
13285 // of topics that are published.
13286 ioPublish: false,
13287 // useCustomLogger: Anything?
13288 // If set to a value that evaluates to true such as a string or array and
13289 // isDebug is true and Firebug is not available or running, then it bypasses
13290 // the creation of Firebug Lite allowing you to define your own console object.
13291 useCustomLogger: undefined,
13292 // transparentColor: Array
13293 // Array containing the r, g, b components used as transparent color in dojo.Color;
13294 // if undefined, [255,255,255] (white) will be used.
13295 transparentColor: undefined,
13296 // skipIeDomLoaded: Boolean
13297 // For IE only, skip the DOMContentLoaded hack used. Sometimes it can cause an Operation
13298 // Aborted error if the rest of the page triggers script defers before the DOM is ready.
13299 // If this is config value is set to true, then dojo.addOnLoad callbacks will not be
13300 // triggered until the page load event, which is after images and iframes load. If you
13301 // want to trigger the callbacks sooner, you can put a script block in the bottom of
13302 // your HTML that calls dojo._loadInit();. If you are using multiversion support, change
13303 // "dojo." to the appropriate scope name for dojo.
13304 skipIeDomLoaded: false
13305}
13306=====*/
13307});
13308
13309
13310},
13311'dojo/_base/event':function(){
13312define(["./kernel", "../on", "../has", "../dom-geometry"], function(dojo, on, has, dom){
13313 // module:
13314 // dojo/_base/event
13315 // summary:
13316 // This module defines dojo DOM event API.
13317 if(on._fixEvent){
13318 var fixEvent = on._fixEvent;
13319 on._fixEvent = function(evt, se){
13320 // add some additional normalization for back-compat, this isn't in on.js because it is somewhat more expensive
13321 evt = fixEvent(evt, se);
13322 if(evt){
13323 dom.normalizeEvent(evt);
13324 }
13325 return evt;
13326 };
2f01fe57 13327 }
1354d172 13328 dojo.fixEvent = function(/*Event*/ evt, /*DOMNode*/ sender){
2f01fe57 13329 // summary:
1354d172
AD
13330 // normalizes properties on the event object including event
13331 // bubbling methods, keystroke normalization, and x/y positions
13332 // evt: Event
13333 // native event object
13334 // sender: DOMNode
13335 // node to treat as "currentTarget"
13336 if(on._fixEvent){
13337 return on._fixEvent(evt, sender);
2f01fe57 13338 }
1354d172 13339 return evt; // Event
2f01fe57 13340 };
1354d172
AD
13341
13342 dojo.stopEvent = function(/*Event*/ evt){
13343 // summary:
13344 // prevents propagation and clobbers the default action of the
13345 // passed event
13346 // evt: Event
13347 // The event object. If omitted, window.event is used on IE.
13348 if(has("dom-addeventlistener") || (evt && evt.preventDefault)){
13349 evt.preventDefault();
13350 evt.stopPropagation();
13351 }else{
13352 evt = evt || window.event;
13353 evt.cancelBubble = true;
13354 on._preventDefault.call(evt);
13355 }
13356 };
13357
13358 return {
13359 fix: dojo.fixEvent,
13360 stop: dojo.stopEvent
13361 };
13362});
13363
13364},
13365'dojo/main':function(){
13366define([
13367 "./_base/kernel",
13368 "./has",
13369 "require",
13370 "./_base/sniff",
13371 "./_base/lang",
13372 "./_base/array",
13373 "./ready",
13374 "./_base/declare",
13375 "./_base/connect",
13376 "./_base/Deferred",
13377 "./_base/json",
13378 "./_base/Color",
13379 "./has!dojo-firebug?./_firebug/firebug",
13380 "./_base/browser",
13381 "./_base/loader"], function(dojo, has, require, sniff, lang, array, ready){
13382 // module:
13383 // dojo/main
13384 // summary:
13385 // This is the package main module for the dojo package; it loads dojo base appropriate for the execution environment.
13386
13387 // the preferred way to load the dojo firebug console is by setting has("dojo-firebug") true in dojoConfig
13388 // the isDebug config switch is for backcompat and will work fine in sync loading mode; it works in
13389 // async mode too, but there's no guarantee when the module is loaded; therefore, if you need a firebug
13390 // console guarnanteed at a particular spot in an app, either set config.has["dojo-firebug"] true before
13391 // loading dojo.js or explicitly include dojo/_firebug/firebug in a dependency list.
13392 if(dojo.config.isDebug){
13393 require(["./_firebug/firebug"]);
13394 }
2f01fe57 13395
1354d172
AD
13396 // dojoConfig.require is deprecated; use the loader configuration property deps
13397 true || has.add("dojo-config-require", 1);
13398 if(1){
13399 var deps= dojo.config.require;
13400 if(deps){
13401 // dojo.config.require may be dot notation
13402 deps= array.map(lang.isArray(deps) ? deps : [deps], function(item){ return item.replace(/\./g, "/"); });
13403 if(dojo.isAsync){
13404 require(deps);
13405 }else{
13406 // this is a bit janky; in 1.6- dojo is defined before these requires are applied; but in 1.7+
13407 // dojo isn't defined until returning from this module; this is only a problem in sync mode
13408 // since we're in sync mode, we know we've got our loader with its priority ready queue
13409 ready(1, function(){require(deps);});
2f01fe57
AD
13410 }
13411 }
1354d172 13412 }
2f01fe57 13413
1354d172
AD
13414 return dojo;
13415});
2f01fe57 13416
1354d172
AD
13417},
13418'dojo/ready':function(){
13419define(["./_base/kernel", "./has", "require", "./domReady", "./_base/lang"], function(dojo, has, require, domReady, lang) {
13420 // module:
13421 // dojo/ready
13422 // summary:
13423 // This module defines the dojo.ready API.
13424 //
13425 // note:
13426 // This module should be unnecessary in dojo 2.0
13427 var
13428 // truthy if DOMContentLoaded or better (e.g., window.onload fired) has been achieved
13429 isDomReady = 0,
2f01fe57 13430
1354d172
AD
13431 // a function to call to cause onLoad to be called when all requested modules have been loaded
13432 requestCompleteSignal,
2f01fe57 13433
1354d172
AD
13434 // The queue of functions waiting to execute as soon as dojo.ready conditions satisfied
13435 loadQ = [],
2f01fe57 13436
1354d172
AD
13437 // prevent recursion in onLoad
13438 onLoadRecursiveGuard = 0,
2f01fe57 13439
1354d172
AD
13440 handleDomReady = function(){
13441 isDomReady = 1;
13442 dojo._postLoad = dojo.config.afterOnLoad = true;
13443 if(loadQ.length){
13444 requestCompleteSignal(onLoad);
13445 }
13446 },
2f01fe57 13447
1354d172
AD
13448 // run the next function queued with dojo.ready
13449 onLoad = function(){
13450 if(isDomReady && !onLoadRecursiveGuard && loadQ.length){
13451 //guard against recursions into this function
13452 onLoadRecursiveGuard = 1;
13453 var f = loadQ.shift();
13454 try{
13455 f();
13456 }
13457 // FIXME: signal the error via require.on
13458 finally{
13459 onLoadRecursiveGuard = 0;
13460 }
13461 onLoadRecursiveGuard = 0;
13462 if(loadQ.length){
13463 requestCompleteSignal(onLoad);
2f01fe57
AD
13464 }
13465 }
1354d172 13466 };
2f01fe57 13467
1354d172
AD
13468 // define requireCompleteSignal; impl depends on loader
13469 if(1){
13470 require.on("idle", onLoad);
13471 requestCompleteSignal = function(){
13472 if(require.idle()){
13473 onLoad();
13474 } // else do nothing, onLoad will be called with the next idle signal
13475 };
13476 }else{
13477 // RequireJS or similar
13478 requestCompleteSignal = function(){
13479 // the next function call will fail if you don't have a loader with require.ready
13480 // in that case, either fix your loader, use dojo's loader, or don't call dojo.ready;
13481 require.ready(onLoad);
13482 };
13483 }
2f01fe57 13484
1354d172
AD
13485 var ready = dojo.ready = dojo.addOnLoad = function(priority, context, callback){
13486 // summary: Add a function to execute on DOM content loaded and all requested modules have arrived and been evaluated.
13487 // priority: Integer?
13488 // The order in which to exec this callback relative to other callbacks, defaults to 1000
13489 // context: Object?|Function
13490 // The context in which to run execute callback, or a callback if not using context
13491 // callback: Function?
13492 // The function to execute.
13493 //
13494 // example:
13495 // Simple DOM and Modules ready syntax
13496 // | dojo.ready(function(){ alert("Dom ready!"); });
13497 //
13498 // example:
13499 // Using a priority
13500 // | dojo.ready(2, function(){ alert("low priority ready!"); })
13501 //
13502 // example:
13503 // Using context
13504 // | dojo.ready(foo, function(){
13505 // | // in here, this == foo
13506 // | })
13507 //
13508 // example:
13509 // Using dojo.hitch style args:
13510 // | var foo = { dojoReady: function(){ console.warn(this, "dojo dom and modules ready."); } };
13511 // | dojo.ready(foo, "dojoReady");
13512
13513 var hitchArgs = lang._toArray(arguments);
13514 if(typeof priority != "number"){
13515 callback = context;
13516 context = priority;
13517 priority = 1000;
13518 }else{
13519 hitchArgs.shift();
13520 }
13521 callback = callback ?
13522 lang.hitch.apply(dojo, hitchArgs) :
13523 function(){
13524 context();
13525 };
13526 callback.priority = priority;
13527 for(var i = 0; i < loadQ.length && priority >= loadQ[i].priority; i++){}
13528 loadQ.splice(i, 0, callback);
13529 requestCompleteSignal();
13530 };
2f01fe57 13531
1354d172
AD
13532 true || has.add("dojo-config-addOnLoad", 1);
13533 if(1){
13534 var dca = dojo.config.addOnLoad;
13535 if(dca){
13536 ready[(lang.isArray(dca) ? "apply" : "call")](dojo, dca);
13537 }
13538 }
2f01fe57 13539
1354d172
AD
13540 if(1 && dojo.config.parseOnLoad && !dojo.isAsync){
13541 ready(99, function(){
13542 if(!dojo.parser){
13543 dojo.deprecated("Add explicit require(['dojo/parser']);", "", "2.0");
13544 require(["dojo/parser"]);
13545 }
13546 });
13547 }
2f01fe57 13548
1354d172
AD
13549 if(1){
13550 domReady(handleDomReady);
13551 }else{
13552 handleDomReady();
13553 }
2f01fe57 13554
1354d172
AD
13555 return ready;
13556});
2f01fe57 13557
1354d172
AD
13558},
13559'dojo/aspect':function(){
13560define([], function(){
2f01fe57 13561
1354d172
AD
13562// TODOC: after/before/around return object
13563// TODOC: after/before/around param types.
2f01fe57 13564
1354d172
AD
13565/*=====
13566 dojo.aspect = {
13567 // summary: provides aspect oriented programming functionality, allowing for
13568 // one to add before, around, or after advice on existing methods.
13569 //
13570 // example:
13571 // | define(["dojo/aspect"], function(aspect){
13572 // | var signal = aspect.after(targetObject, "methodName", function(someArgument){
13573 // | this will be called when targetObject.methodName() is called, after the original function is called
13574 // | });
13575 //
13576 // example:
13577 // The returned signal object can be used to cancel the advice.
13578 // | signal.remove(); // this will stop the advice from being executed anymore
13579 // | aspect.before(targetObject, "methodName", function(someArgument){
13580 // | // this will be called when targetObject.methodName() is called, before the original function is called
13581 // | });
13582
13583 after: function(target, methodName, advice, receiveArguments){
13584 // summary: The "after" export of the aspect module is a function that can be used to attach
13585 // "after" advice to a method. This function will be executed after the original method
13586 // is executed. By default the function will be called with a single argument, the return
13587 // value of the original method, or the the return value of the last executed advice (if a previous one exists).
13588 // The fourth (optional) argument can be set to true to so the function receives the original
13589 // arguments (from when the original method was called) rather than the return value.
13590 // If there are multiple "after" advisors, they are executed in the order they were registered.
13591 // target: Object
13592 // This is the target object
13593 // methodName: String
13594 // This is the name of the method to attach to.
13595 // advice: Function
13596 // This is function to be called after the original method
13597 // receiveArguments: Boolean?
13598 // If this is set to true, the advice function receives the original arguments (from when the original mehtod
13599 // was called) rather than the return value of the original/previous method.
13600 // returns:
13601 // A signal object that can be used to cancel the advice. If remove() is called on this signal object, it will
13602 // stop the advice function from being executed.
13603 },
13604
13605 before: function(target, methodName, advice){
13606 // summary: The "before" export of the aspect module is a function that can be used to attach
13607 // "before" advice to a method. This function will be executed before the original method
13608 // is executed. This function will be called with the arguments used to call the method.
13609 // This function may optionally return an array as the new arguments to use to call
13610 // the original method (or the previous, next-to-execute before advice, if one exists).
13611 // If the before method doesn't return anything (returns undefined) the original arguments
13612 // will be preserved.
13613 // If there are multiple "before" advisors, they are executed in the reverse order they were registered.
13614 //
13615 // target: Object
13616 // This is the target object
13617 // methodName: String
13618 // This is the name of the method to attach to.
13619 // advice: Function
13620 // This is function to be called before the original method
13621 },
2f01fe57 13622
1354d172
AD
13623 around: function(target, methodName, advice){
13624 // summary: The "around" export of the aspect module is a function that can be used to attach
13625 // "around" advice to a method. The advisor function is immediately executed when
13626 // the around() is called, is passed a single argument that is a function that can be
13627 // called to continue execution of the original method (or the next around advisor).
13628 // The advisor function should return a function, and this function will be called whenever
13629 // the method is called. It will be called with the arguments used to call the method.
13630 // Whatever this function returns will be returned as the result of the method call (unless after advise changes it).
13631 //
13632 // example:
13633 // If there are multiple "around" advisors, the most recent one is executed first,
13634 // which can then delegate to the next one and so on. For example:
13635 // | around(obj, "foo", function(originalFoo){
13636 // | return function(){
13637 // | var start = new Date().getTime();
13638 // | var results = originalFoo.apply(this, arguments); // call the original
13639 // | var end = new Date().getTime();
13640 // | console.log("foo execution took " + (end - start) + " ms");
13641 // | return results;
13642 // | };
13643 // | });
13644 //
13645 // target: Object
13646 // This is the target object
13647 // methodName: String
13648 // This is the name of the method to attach to.
13649 // advice: Function
13650 // This is function to be called around the original method
13651 }
2f01fe57 13652
1354d172
AD
13653 };
13654=====*/
2f01fe57 13655
1354d172
AD
13656 "use strict";
13657 var nextId = 0;
13658 function advise(dispatcher, type, advice, receiveArguments){
13659 var previous = dispatcher[type];
13660 var around = type == "around";
13661 var signal;
13662 if(around){
13663 var advised = advice(function(){
13664 return previous.advice(this, arguments);
13665 });
13666 signal = {
13667 remove: function(){
13668 signal.cancelled = true;
13669 },
13670 advice: function(target, args){
13671 return signal.cancelled ?
13672 previous.advice(target, args) : // cancelled, skip to next one
13673 advised.apply(target, args); // called the advised function
13674 }
13675 };
13676 }else{
13677 // create the remove handler
13678 signal = {
13679 remove: function(){
13680 var previous = signal.previous;
13681 var next = signal.next;
13682 if(!next && !previous){
13683 delete dispatcher[type];
13684 }else{
13685 if(previous){
13686 previous.next = next;
13687 }else{
13688 dispatcher[type] = next;
13689 }
13690 if(next){
13691 next.previous = previous;
13692 }
13693 }
13694 },
13695 id: nextId++,
13696 advice: advice,
13697 receiveArguments: receiveArguments
13698 };
13699 }
13700 if(previous && !around){
13701 if(type == "after"){
13702 // add the listener to the end of the list
13703 var next = previous;
13704 while(next){
13705 previous = next;
13706 next = next.next;
13707 }
13708 previous.next = signal;
13709 signal.previous = previous;
13710 }else if(type == "before"){
13711 // add to beginning
13712 dispatcher[type] = signal;
13713 signal.next = previous;
13714 previous.previous = signal;
13715 }
13716 }else{
13717 // around or first one just replaces
13718 dispatcher[type] = signal;
13719 }
13720 return signal;
13721 }
13722 function aspect(type){
13723 return function(target, methodName, advice, receiveArguments){
13724 var existing = target[methodName], dispatcher;
13725 if(!existing || existing.target != target){
13726 // no dispatcher in place
13727 target[methodName] = dispatcher = function(){
13728 var executionId = nextId;
13729 // before advice
13730 var args = arguments;
13731 var before = dispatcher.before;
13732 while(before){
13733 args = before.advice.apply(this, args) || args;
13734 before = before.next;
13735 }
13736 // around advice
13737 if(dispatcher.around){
13738 var results = dispatcher.around.advice(this, args);
13739 }
13740 // after advice
13741 var after = dispatcher.after;
13742 while(after && after.id < executionId){
13743 results = after.receiveArguments ? after.advice.apply(this, args) || results :
13744 after.advice.call(this, results);
13745 after = after.next;
13746 }
13747 return results;
13748 };
13749 if(existing){
13750 dispatcher.around = {advice: function(target, args){
13751 return existing.apply(target, args);
13752 }};
13753 }
13754 dispatcher.target = target;
13755 }
13756 var results = advise((dispatcher || existing), type, advice, receiveArguments);
13757 advice = null;
13758 return results;
13759 };
13760 }
13761 return {
13762 before: aspect("before"),
13763 around: aspect("around"),
13764 after: aspect("after")
13765 };
13766});
13767
13768},
13769'dojo/_base/connect':function(){
13770define(["./kernel", "../on", "../topic", "../aspect", "./event", "../mouse", "./sniff", "./lang", "../keys"], function(kernel, on, hub, aspect, eventModule, mouse, has, lang){
13771// module:
13772// dojo/_base/connect
13773// summary:
13774// This module defines the dojo.connect API.
13775// This modules also provides keyboard event handling helpers.
13776// This module exports an extension event for emulating Firefox's keypress handling.
13777// However, this extension event exists primarily for backwards compatibility and
13778// is not recommended. WebKit and IE uses an alternate keypress handling (only
13779// firing for printable characters, to distinguish from keydown events), and most
13780// consider the WebKit/IE behavior more desirable.
13781has.add("events-keypress-typed", function(){ // keypresses should only occur a printable character is hit
13782 var testKeyEvent = {charCode: 0};
13783 try{
13784 testKeyEvent = document.createEvent("KeyboardEvent");
13785 (testKeyEvent.initKeyboardEvent || testKeyEvent.initKeyEvent).call(testKeyEvent, "keypress", true, true, null, false, false, false, false, 9, 3);
13786 }catch(e){}
13787 return testKeyEvent.charCode == 0 && !has("opera");
13788});
13789
13790function connect_(obj, event, context, method, dontFix){
13791 method = lang.hitch(context, method);
13792 if(!obj || !(obj.addEventListener || obj.attachEvent)){
13793 // it is a not a DOM node and we are using the dojo.connect style of treating a
13794 // method like an event, must go right to aspect
13795 return aspect.after(obj || kernel.global, event, method, true);
13796 }
13797 if(typeof event == "string" && event.substring(0, 2) == "on"){
13798 event = event.substring(2);
13799 }
13800 if(!obj){
13801 obj = kernel.global;
13802 }
13803 if(!dontFix){
13804 switch(event){
13805 // dojo.connect has special handling for these event types
13806 case "keypress":
13807 event = keypress;
13808 break;
13809 case "mouseenter":
13810 event = mouse.enter;
13811 break;
13812 case "mouseleave":
13813 event = mouse.leave;
13814 break;
13815 }
13816 }
13817 return on(obj, event, method, dontFix);
13818}
81bea17a 13819
1354d172
AD
13820var _punctMap = {
13821 106:42,
13822 111:47,
13823 186:59,
13824 187:43,
13825 188:44,
13826 189:45,
13827 190:46,
13828 191:47,
13829 192:96,
13830 219:91,
13831 220:92,
13832 221:93,
13833 222:39,
13834 229:113
13835};
13836var evtCopyKey = has("mac") ? "metaKey" : "ctrlKey";
13837
13838
13839var _synthesizeEvent = function(evt, props){
13840 var faux = lang.mixin({}, evt, props);
13841 setKeyChar(faux);
13842 // FIXME: would prefer to use lang.hitch: lang.hitch(evt, evt.preventDefault);
13843 // but it throws an error when preventDefault is invoked on Safari
13844 // does Event.preventDefault not support "apply" on Safari?
13845 faux.preventDefault = function(){ evt.preventDefault(); };
13846 faux.stopPropagation = function(){ evt.stopPropagation(); };
13847 return faux;
13848};
13849function setKeyChar(evt){
13850 evt.keyChar = evt.charCode ? String.fromCharCode(evt.charCode) : '';
13851 evt.charOrCode = evt.keyChar || evt.keyCode;
13852}
13853var keypress;
13854if(has("events-keypress-typed")){
13855 // this emulates Firefox's keypress behavior where every keydown can correspond to a keypress
13856 var _trySetKeyCode = function(e, code){
13857 try{
13858 // squelch errors when keyCode is read-only
13859 // (e.g. if keyCode is ctrl or shift)
13860 return (e.keyCode = code);
13861 }catch(e){
13862 return 0;
13863 }
13864 };
13865 keypress = function(object, listener){
13866 var keydownSignal = on(object, "keydown", function(evt){
13867 // munge key/charCode
13868 var k=evt.keyCode;
13869 // These are Windows Virtual Key Codes
13870 // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/WinUI/WindowsUserInterface/UserInput/VirtualKeyCodes.asp
13871 var unprintable = (k!=13 || (has("ie") >= 9 && !has("quirks"))) && k!=32 && (k!=27||!has("ie")) && (k<48||k>90) && (k<96||k>111) && (k<186||k>192) && (k<219||k>222) && k!=229;
13872 // synthesize keypress for most unprintables and CTRL-keys
13873 if(unprintable||evt.ctrlKey){
13874 var c = unprintable ? 0 : k;
13875 if(evt.ctrlKey){
13876 if(k==3 || k==13){
13877 return listener.call(evt.currentTarget, evt); // IE will post CTRL-BREAK, CTRL-ENTER as keypress natively
13878 }else if(c>95 && c<106){
13879 c -= 48; // map CTRL-[numpad 0-9] to ASCII
13880 }else if((!evt.shiftKey)&&(c>=65&&c<=90)){
13881 c += 32; // map CTRL-[A-Z] to lowercase
13882 }else{
13883 c = _punctMap[c] || c; // map other problematic CTRL combinations to ASCII
13884 }
13885 }
13886 // simulate a keypress event
13887 var faux = _synthesizeEvent(evt, {type: 'keypress', faux: true, charCode: c});
13888 listener.call(evt.currentTarget, faux);
13889 if(has("ie")){
13890 _trySetKeyCode(evt, faux.keyCode);
13891 }
13892 }
13893 });
13894 var keypressSignal = on(object, "keypress", function(evt){
13895 var c = evt.charCode;
13896 c = c>=32 ? c : 0;
13897 evt = _synthesizeEvent(evt, {charCode: c, faux: true});
13898 return listener.call(this, evt);
13899 });
13900 return {
13901 remove: function(){
13902 keydownSignal.remove();
13903 keypressSignal.remove();
13904 }
13905 };
13906 };
13907}else{
13908 if(has("opera")){
13909 keypress = function(object, listener){
13910 return on(object, "keypress", function(evt){
13911 var c = evt.which;
13912 if(c==3){
13913 c=99; // Mozilla maps CTRL-BREAK to CTRL-c
13914 }
13915 // can't trap some keys at all, like INSERT and DELETE
13916 // there is no differentiating info between DELETE and ".", or INSERT and "-"
13917 c = c<32 && !evt.shiftKey ? 0 : c;
13918 if(evt.ctrlKey && !evt.shiftKey && c>=65 && c<=90){
13919 // lowercase CTRL-[A-Z] keys
13920 c += 32;
13921 }
13922 return listener.call(this, _synthesizeEvent(evt, { charCode: c }));
13923 });
13924 };
13925 }else{
13926 keypress = function(object, listener){
13927 return on(object, "keypress", function(evt){
13928 setKeyChar(evt);
13929 return listener.call(this, evt);
13930 });
13931 };
13932 }
81bea17a
AD
13933}
13934
1354d172
AD
13935var connect = {
13936 _keypress:keypress,
13937
13938 connect:function(obj, event, context, method, dontFix){
13939 // normalize arguments
13940 var a=arguments, args=[], i=0;
13941 // if a[0] is a String, obj was omitted
13942 args.push(typeof a[0] == "string" ? null : a[i++], a[i++]);
13943 // if the arg-after-next is a String or Function, context was NOT omitted
13944 var a1 = a[i+1];
13945 args.push(typeof a1 == "string" || typeof a1 == "function" ? a[i++] : null, a[i++]);
13946 // absorb any additional arguments
13947 for(var l=a.length; i<l; i++){ args.push(a[i]); }
13948 return connect_.apply(this, args);
13949 },
13950
13951 disconnect:function(handle){
13952 if(handle){
13953 handle.remove();
13954 }
13955 },
81bea17a 13956
1354d172
AD
13957 subscribe:function(topic, context, method){
13958 return hub.subscribe(topic, lang.hitch(context, method));
13959 },
13960
13961 publish:function(topic, args){
13962 return hub.publish.apply(hub, [topic].concat(args));
13963 },
81bea17a 13964
1354d172
AD
13965 connectPublisher:function(topic, obj, event){
13966 var pf = function(){ connect.publish(topic, arguments); };
13967 return event ? connect.connect(obj, event, pf) : connect.connect(obj, pf); //Handle
13968 },
81bea17a 13969
1354d172
AD
13970 isCopyKey: function(e){
13971 return e[evtCopyKey]; // Boolean
13972 }
13973};
13974connect.unsubscribe = connect.disconnect;
81bea17a 13975
1354d172
AD
139761 && lang.mixin(kernel, connect);
13977return connect;
81bea17a 13978
1354d172
AD
13979/*=====
13980dojo.connect = function(obj, event, context, method, dontFix){
13981 // summary:
13982 // `dojo.connect` is the core event handling and delegation method in
13983 // Dojo. It allows one function to "listen in" on the execution of
13984 // any other, triggering the second whenever the first is called. Many
13985 // listeners may be attached to a function, and source functions may
13986 // be either regular function calls or DOM events.
13987 //
13988 // description:
13989 // Connects listeners to actions, so that after event fires, a
13990 // listener is called with the same arguments passed to the original
13991 // function.
13992 //
13993 // Since `dojo.connect` allows the source of events to be either a
13994 // "regular" JavaScript function or a DOM event, it provides a uniform
13995 // interface for listening to all the types of events that an
13996 // application is likely to deal with though a single, unified
13997 // interface. DOM programmers may want to think of it as
13998 // "addEventListener for everything and anything".
13999 //
14000 // When setting up a connection, the `event` parameter must be a
14001 // string that is the name of the method/event to be listened for. If
14002 // `obj` is null, `kernel.global` is assumed, meaning that connections
14003 // to global methods are supported but also that you may inadvertently
14004 // connect to a global by passing an incorrect object name or invalid
14005 // reference.
14006 //
14007 // `dojo.connect` generally is forgiving. If you pass the name of a
14008 // function or method that does not yet exist on `obj`, connect will
14009 // not fail, but will instead set up a stub method. Similarly, null
14010 // arguments may simply be omitted such that fewer than 4 arguments
14011 // may be required to set up a connection See the examples for details.
14012 //
14013 // The return value is a handle that is needed to
14014 // remove this connection with `dojo.disconnect`.
14015 //
14016 // obj: Object|null:
14017 // The source object for the event function.
14018 // Defaults to `kernel.global` if null.
14019 // If obj is a DOM node, the connection is delegated
14020 // to the DOM event manager (unless dontFix is true).
14021 //
14022 // event: String:
14023 // String name of the event function in obj.
14024 // I.e. identifies a property `obj[event]`.
14025 //
14026 // context: Object|null
14027 // The object that method will receive as "this".
14028 //
14029 // If context is null and method is a function, then method
14030 // inherits the context of event.
14031 //
14032 // If method is a string then context must be the source
14033 // object object for method (context[method]). If context is null,
14034 // kernel.global is used.
14035 //
14036 // method: String|Function:
14037 // A function reference, or name of a function in context.
14038 // The function identified by method fires after event does.
14039 // method receives the same arguments as the event.
14040 // See context argument comments for information on method's scope.
14041 //
14042 // dontFix: Boolean?
14043 // If obj is a DOM node, set dontFix to true to prevent delegation
14044 // of this connection to the DOM event manager.
14045 //
14046 // example:
14047 // When obj.onchange(), do ui.update():
14048 // | dojo.connect(obj, "onchange", ui, "update");
14049 // | dojo.connect(obj, "onchange", ui, ui.update); // same
14050 //
14051 // example:
14052 // Using return value for disconnect:
14053 // | var link = dojo.connect(obj, "onchange", ui, "update");
14054 // | ...
14055 // | dojo.disconnect(link);
14056 //
14057 // example:
14058 // When onglobalevent executes, watcher.handler is invoked:
14059 // | dojo.connect(null, "onglobalevent", watcher, "handler");
14060 //
14061 // example:
14062 // When ob.onCustomEvent executes, customEventHandler is invoked:
14063 // | dojo.connect(ob, "onCustomEvent", null, "customEventHandler");
14064 // | dojo.connect(ob, "onCustomEvent", "customEventHandler"); // same
14065 //
14066 // example:
14067 // When ob.onCustomEvent executes, customEventHandler is invoked
14068 // with the same scope (this):
14069 // | dojo.connect(ob, "onCustomEvent", null, customEventHandler);
14070 // | dojo.connect(ob, "onCustomEvent", customEventHandler); // same
14071 //
14072 // example:
14073 // When globalEvent executes, globalHandler is invoked
14074 // with the same scope (this):
14075 // | dojo.connect(null, "globalEvent", null, globalHandler);
14076 // | dojo.connect("globalEvent", globalHandler); // same
14077}
14078=====*/
81bea17a 14079
1354d172
AD
14080/*=====
14081dojo.disconnect = function(handle){
14082 // summary:
14083 // Remove a link created by dojo.connect.
14084 // description:
14085 // Removes the connection between event and the method referenced by handle.
14086 // handle: Handle:
14087 // the return value of the dojo.connect call that created the connection.
14088}
14089=====*/
81bea17a 14090
1354d172
AD
14091/*=====
14092dojo.subscribe = function(topic, context, method){
14093 // summary:
14094 // Attach a listener to a named topic. The listener function is invoked whenever the
14095 // named topic is published (see: dojo.publish).
14096 // Returns a handle which is needed to unsubscribe this listener.
14097 // topic: String:
14098 // The topic to which to subscribe.
14099 // context: Object|null:
14100 // Scope in which method will be invoked, or null for default scope.
14101 // method: String|Function:
14102 // The name of a function in context, or a function reference. This is the function that
14103 // is invoked when topic is published.
14104 // example:
14105 // | dojo.subscribe("alerts", null, function(caption, message){ alert(caption + "\n" + message); });
14106 // | dojo.publish("alerts", [ "read this", "hello world" ]);
14107}
14108=====*/
81bea17a 14109
1354d172
AD
14110/*=====
14111dojo.unsubscribe = function(handle){
14112 // summary:
14113 // Remove a topic listener.
14114 // handle: Handle
14115 // The handle returned from a call to subscribe.
14116 // example:
14117 // | var alerter = dojo.subscribe("alerts", null, function(caption, message){ alert(caption + "\n" + message); };
14118 // | ...
14119 // | dojo.unsubscribe(alerter);
14120}
14121=====*/
81bea17a 14122
1354d172
AD
14123/*=====
14124dojo.publish = function(topic, args){
14125 // summary:
14126 // Invoke all listener method subscribed to topic.
14127 // topic: String:
14128 // The name of the topic to publish.
14129 // args: Array?
14130 // An array of arguments. The arguments will be applied
14131 // to each topic subscriber (as first class parameters, via apply).
14132 // example:
14133 // | dojo.subscribe("alerts", null, function(caption, message){ alert(caption + "\n" + message); };
14134 // | dojo.publish("alerts", [ "read this", "hello world" ]);
14135}
14136=====*/
2f01fe57 14137
1354d172
AD
14138/*=====
14139dojo.connectPublisher = function(topic, obj, event){
14140 // summary:
14141 // Ensure that every time obj.event() is called, a message is published
14142 // on the topic. Returns a handle which can be passed to
14143 // dojo.disconnect() to disable subsequent automatic publication on
14144 // the topic.
14145 // topic: String:
14146 // The name of the topic to publish.
14147 // obj: Object|null:
14148 // The source object for the event function. Defaults to kernel.global
14149 // if null.
14150 // event: String:
14151 // The name of the event function in obj.
14152 // I.e. identifies a property obj[event].
14153 // example:
14154 // | dojo.connectPublisher("/ajax/start", dojo, "xhrGet");
14155}
14156=====*/
2f01fe57 14157
1354d172
AD
14158/*=====
14159dojo.isCopyKey = function(e){
14160 // summary:
14161 // Checks an event for the copy key (meta on Mac, and ctrl anywhere else)
14162 // e: Event
14163 // Event object to examine
2f01fe57 14164}
1354d172
AD
14165=====*/
14166
14167});
2f01fe57 14168
2f01fe57 14169
2f01fe57 14170
1354d172
AD
14171}}});
14172(function(){
14173 // must use this.require to make this work in node.js
14174 var require = this.require;
14175 // consume the cached dojo layer
14176 require({cache:{}});
14177 !require.async && require(["dojo"]);
14178 require.boot && require.apply(null, require.boot);
14179})();