2 Copyright (c) 2004-2012, The Dojo Foundation All Rights Reserved.
3 Available via Academic Free License >= 2.1 OR the modified BSD license.
4 see: http://dojotoolkit.org/license for details
8 This is an optimized version of Dojo, built for deployment and not for
9 development. To get sources and documentation, please visit:
11 http://dojotoolkit.org
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.
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.
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.
31 // This loader includes sniffing machinery to determine the environment; the following environments are supported:
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.
40 // Design and Implementation Notes
42 // This is a dojo-specific adaption of bdLoad, donated to the dojo foundation by Altoviso LLC.
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.
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:
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.
68 // Language and Acronyms and Idioms
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.
78 // define a minimal library to help build the loader
79 var noop = function(){
82 isEmpty = function(it
){
89 toString
= {}.toString
,
91 isFunction = function(it
){
92 return toString
.call(it
) == "[object Function]";
95 isString = function(it
){
96 return toString
.call(it
) == "[object String]";
99 isArray = function(it
){
100 return toString
.call(it
) == "[object Array]";
103 forEach = function(vector
, callback
){
105 for(var i
= 0; i
< vector
.length
;){
106 callback(vector
[i
++]);
111 mix = function(dest
, src
){
118 makeError = function(error
, info
){
119 return mix(new Error(error
), {src
:"dojoLoader", info
:info
});
125 // Returns a unique indentifier (within the lifetime of the document) of the form /_d+/.
126 return "_" + uidSeed
++;
129 // FIXME: how to doc window.require() api
131 // this will be the global require function; define it immediately so we can start hanging things off of it
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
137 return contextRequire(config
, dependencies
, callback
, 0, req
);
140 // the loader uses the has.js API to control feature inclusion/exclusion; define then use throughout
143 doc
= global
.document
,
145 element
= doc
&& doc
.createElement("DiV"),
147 has
= req
.has = function(name
){
148 return isFunction(hasCache
[name
]) ? (hasCache
[name
] = hasCache
[name
](global
, doc
, element
)) : hasCache
[name
];
151 hasCache
= has
.cache
= defaultConfig
.hasCache
;
153 has
.add = function(name
, test
, now
, force
){
154 (hasCache
[name
]===undefined || force
) && (hasCache
[name
] = test
);
155 return now
&& has(name
);
158 0 && has
.add("host-node", userConfig
.has
&& "host-node" in userConfig
.has
?
159 userConfig
.has
["host-node"] :
160 (typeof process
== "object" && process
.versions
&& process
.versions
.node
&& process
.versions
.v8
));
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
;
168 0 && has
.add("host-rhino", userConfig
.has
&& "host-rhino" in userConfig
.has
?
169 userConfig
.has
["host-rhino"] :
170 (typeof load
== "function" && (typeof Packages
== "function" || typeof Packages
== "object")));
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"){
180 load(baseUrl
+ "/_base/configRhino.js");
181 rhinoDojoConfig(defaultConfig
, baseUrl
, rhinoArgs
);
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);
191 // define the loader data
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
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";
206 nonmodule
= "not-a-module";
207 executing
= "executing";
208 executed
= "executed";
215 dojoRequirePlugin
= 0,
216 checkDojoRequirePlugin
= noop
,
217 transformToAmd
= noop
,
222 req
.initSyncLoader = function(dojoRequirePlugin_
, checkDojoRequirePlugin_
, transformToAmd_
){
223 // the first dojo/_base/loader loaded gets to define these variables; they are designed to work
224 // in the presense of zero to many mapped dojo/_base/loaders
225 if(!dojoRequirePlugin
){
226 dojoRequirePlugin
= dojoRequirePlugin_
;
227 checkDojoRequirePlugin
= checkDojoRequirePlugin_
;
228 transformToAmd
= transformToAmd_
;
238 syncExecStack
:syncExecStack
,
242 injectModule
:injectModule
,
243 setArrived
:setArrived
,
245 finishExec
:finishExec
,
246 execModule
:execModule
,
247 dojoRequirePlugin
:dojoRequirePlugin
,
248 getLegacyMode:function(){return legacyMode
;},
249 guardCheckComplete
:guardCheckComplete
254 // in legacy sync mode, the loader needs a minimal XHR library
256 var locationProtocol
= location
.protocol
,
257 locationHost
= location
.host
;
258 req
.isXdUrl = function(url
){
260 // begins with a dot is always relative to page URL; therefore not xdomain
263 if(/^\/\//.test(url
)){
264 // for v1.6- backcompat, url starting with // indicates xdomain
267 // get protocol and host
268 // \/+ takes care of the typical file protocol that looks like file:///drive/path/to/file
269 // locationHost is falsy if file protocol => if locationProtocol matches and is "file:", || will return false
270 var match
= url
.match(/^([^\/\:]+\:)\/+([^\/]+)/);
271 return match
&& (match
[1] != locationProtocol
|| (locationHost
&& match
[2] != locationHost
));
275 // note: to get the file:// protocol to work in FF, you must set security.fileuri.strict_origin_policy to false in about:config
276 1 || has
.add("dojo-xhr-factory", 1);
277 has
.add("dojo-force-activex-xhr", 1 && !doc
.addEventListener
&& window
.location
.protocol
== "file:");
278 has
.add("native-xhr", typeof XMLHttpRequest
!= "undefined");
279 if(has("native-xhr") && !has("dojo-force-activex-xhr")){
281 return new XMLHttpRequest();
284 // if in the browser an old IE; find an xhr
285 for(var XMLHTTP_PROGIDS
= ['Msxml2.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.4.0'], progid
, i
= 0; i
< 3;){
287 progid
= XMLHTTP_PROGIDS
[i
++];
288 if(new ActiveXObject(progid
)){
289 // this progid works; therefore, use it from now on
293 // squelch; we're just trying to find a good ActiveX progid
294 // if they all fail, then progid ends up as the last attempt and that will signal the error
295 // the first time the client actually tries to exec an xhr
299 return new ActiveXObject(progid
);
304 has
.add("dojo-gettext-api", 1);
305 req
.getText = function(url
, async
, onLoad
){
307 xhr
.open('GET', fixupUrl(url
), false);
309 if(xhr
.status
== 200 || (!location
.host
&& !xhr
.status
)){
311 onLoad(xhr
.responseText
, async
);
314 throw makeError("xhrFailed", xhr
.status
);
316 return xhr
.responseText
;
327 // use the function constructor so our eval is scoped close to (but not in) in the global space with minimal pollution
328 new Function('return eval(arguments[0]);');
331 function(text
, hint
){
332 return eval_(text
+ "\r\n////@ sourceURL=" + hint
);
336 // loader micro events API
338 var listenerQueues
= {},
340 signal
= req
.signal = function(type
, args
){
341 var queue
= listenerQueues
[type
];
342 // notice we run a copy of the queue; this allows listeners to add/remove
343 // other listeners without affecting this particular signal
344 forEach(queue
&& queue
.slice(0), function(listener
){
345 listener
.apply(null, isArray(args
) ? args
: [args
]);
348 on
= req
.on = function(type
, listener
){
349 // notice a queue is not created until a client actually connects
350 var queue
= listenerQueues
[type
] || (listenerQueues
[type
] = []);
351 queue
.push(listener
);
354 for(var i
= 0; i
<queue
.length
; i
++){
355 if(queue
[i
]===listener
){
364 // configuration machinery; with an optimized/built defaultConfig, all configuration machinery can be discarded
365 // lexical variables hold key loader data structures to help with minification; these may be completely,
366 // one-time initialized by defaultConfig for optimized/built versions
369 // a vector of pairs of [regexs or string, replacement] => (alias, actual)
377 // list of (from-path, to-path, regex, length) derived from paths;
378 // a "program" to apply paths; see computeMapProg
382 // a map from packageId to package configuration object; see fixupPackageInfo
386 // AMD map config variable; dojo/_base/kernel needs req.map to figure out the scope map
390 // vector of quads as described by computeMapProg; map-key is AMD map key, map-value is AMD map value
394 // A hash:(mid) --> (module-object) the module namespace
396 // pid: the package identifier to which the module belongs (e.g., "dojo"); "" indicates the system or default package
397 // mid: the fully-resolved (i.e., mappings have been applied) module identifier without the package identifier (e.g., "dojo/io/script")
398 // url: the URL from which the module was retrieved
399 // pack: the package object of the package to which the module belongs
400 // executed: 0 => not executed; executing => in the process of tranversing deps and running factory; executed => factory has been executed
401 // deps: the dependency vector for this module (vector of modules objects)
402 // def: the factory for this module
403 // result: the result of the running the factory for this module
404 // injected: (0 | requested | arrived) the status of the module; nonmodule means the resource did not call define
405 // load: plugin load function; applicable only for plugins
407 // Modules go through several phases in creation:
409 // 1. Requested: some other module's definition or a require application contained the requested module in
410 // its dependency vector or executing code explicitly demands a module via req.require.
412 // 2. Injected: a script element has been appended to the insert-point element demanding the resource implied by the URL
414 // 3. Loaded: the resource injected in [2] has been evalated.
416 // 4. Defined: the resource contained a define statement that advised the loader about the module. Notice that some
417 // resources may just contain a bundle of code and never formally define a module via define
419 // 5. Evaluated: the module was defined via define and the loader has evaluated the factory and computed a result.
423 // query string to append to module URLs to bust browser cache
427 // hash:(mid | url)-->(function | string)
429 // A cache of resources. The resources arrive via a config.cache object, which is a hash from either mid --> function or
430 // url --> string. The url key is distinguished from the mid key by always containing the prefix "url:". url keys as provided
431 // by config.cache always have a string value that represents the contents of the resource at the given url. mid keys as provided
432 // by configl.cache always have a function value that causes the same code to execute as if the module was script injected.
434 // Both kinds of key-value pairs are entered into cache via the function consumePendingCache, which may relocate keys as given
435 // by any mappings *iff* the config.cache was received as part of a module resource request.
437 // Further, for mid keys, the implied url is computed and the value is entered into that key as well. This allows mapped modules
438 // to retrieve cached items that may have arrived consequent to another namespace.
443 // the prefix to prepend to a URL key in the cache.
447 // hash:(mid)-->(function)
449 // Gives a set of cache modules pending entry into cache. When cached modules are published to the loader, they are
450 // entered into pendingCacheInsert; modules are then pressed into cache upon (1) AMD define or (2) upon receiving another
451 // independent set of cached modules. (1) is the usual case, and this case allows normalizing mids given in the pending
452 // cache for the local configuration, possibly relocating modules.
456 // map of configuration variables
457 // give the data-dojo-config as sniffed from the document (if any)
461 var consumePendingCacheInsert = function(referenceModule
){
462 var p
, item
, match
, now
, m
;
463 for(p
in pendingCacheInsert
){
464 item
= pendingCacheInsert
[p
];
465 match
= p
.match(/^url\:(.+)/);
467 cache
[urlKeyPrefix
+ toUrl(match
[1], referenceModule
)] = item
;
470 }else if(p
!="*noref"){
471 m
= getModuleInfo(p
, referenceModule
);
472 cache
[m
.mid
] = cache
[urlKeyPrefix
+ m
.url
] = item
;
476 now(createRequire(referenceModule
));
478 pendingCacheInsert
= {};
481 escapeString = function(s
){
482 return s
.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, function(c
){ return "\\" + c
; });
485 computeMapProg = function(map
, dest
){
486 // This routine takes a map as represented by a JavaScript object and initializes dest, a vector of
487 // quads of (map-key, map-value, refex-for-map-key, length-of-map-key), sorted decreasing by length-
488 // of-map-key. The regex looks for the map-key followed by either "/" or end-of-string at the beginning
489 // of a the search source. Notice the map-value is irrelevent to the algorithm
490 dest
.splice(0, dest
.length
);
495 new RegExp("^" + escapeString(p
) + "(\/|$)"),
498 dest
.sort(function(lhs
, rhs
){ return rhs
[3] - lhs
[3]; });
502 fixupPackageInfo = function(packageInfo
){
503 // calculate the precise (name, location, main, mappings) for a package
504 var name
= packageInfo
.name
;
506 // packageInfo must be a string that gives the name
508 packageInfo
= {name
:name
};
510 packageInfo
= mix({main
:"main"}, packageInfo
);
511 packageInfo
.location
= packageInfo
.location
? packageInfo
.location
: name
;
513 // packageMap is depricated in favor of AMD map
514 if(packageInfo
.packageMap
){
515 map
[name
] = packageInfo
.packageMap
;
518 if(!packageInfo
.main
.indexOf("./")){
519 packageInfo
.main
= packageInfo
.main
.substring(2);
522 // now that we've got a fully-resolved package object, push it into the configuration
523 packs
[name
] = packageInfo
;
527 // module config cannot be consummed until the loader is completely initialized; therefore, all
528 // module config detected during booting is memorized and applied at the end of loader initialization
529 // TODO: this is a bit of a kludge; all config should be moved to end of loader initialization, but
530 // we'll delay this chore and do it with a final loader 1.x cleanup after the 2.x loader prototyping is complete
534 config = function(config
, booting
, referenceModule
){
535 for(var p
in config
){
536 if(p
=="waitSeconds"){
537 req
.waitms
= (config
[p
] || 0) * 1000;
540 cacheBust
= config
[p
] ? (isString(config
[p
]) ? config
[p
] : (new Date()).getTime() + "") : "";
542 if(p
=="baseUrl" || p
=="combo"){
545 if( 1 && p
=="async"){
546 // falsy or "sync" => legacy sync loader
547 // "xd" => sync but loading xdomain tree and therefore loading asynchronously (not configurable, set automatically by the loader)
548 // "legacyAsync" => permanently in "xd" by choice
549 // "debugAtAllCosts" => trying to load everything via script injection (not implemented)
550 // otherwise, must be truthy => AMD
551 // legacyMode: sync | legacyAsync | xd | false
552 var mode
= config
[p
];
553 req
.legacyMode
= legacyMode
= (isString(mode
) && /sync|legacyAsync/.test(mode
) ? mode
: (!mode
? sync
: false));
554 req
.async
= !legacyMode
;
556 if(config
[p
]!==hasCache
){
557 // accumulate raw config info for client apps which can use this to pass their own config
558 req
.rawConfig
[p
] = config
[p
];
559 p
!="has" && has
.add("config-"+p
, config
[p
], 0, booting
);
563 // make sure baseUrl exists
567 // make sure baseUrl ends with a slash
568 if(!/\/$/.test(req
.baseUrl
)){
572 // now do the special work for has, packages, packagePaths, paths, aliases, and cache
574 for(p
in config
.has
){
575 has
.add(p
, config
.has
[p
], 0, booting
);
578 // for each package found in any packages config item, augment the packs map owned by the loader
579 forEach(config
.packages
, fixupPackageInfo
);
581 // for each packagePath found in any packagePaths config item, augment the packageConfig
582 // packagePaths is depricated; remove in 2.0
583 for(baseUrl
in config
.packagePaths
){
584 forEach(config
.packagePaths
[baseUrl
], function(packageInfo
){
585 var location
= baseUrl
+ "/" + packageInfo
;
586 if(isString(packageInfo
)){
587 packageInfo
= {name
:packageInfo
};
589 packageInfo
.location
= location
;
590 fixupPackageInfo(packageInfo
);
594 // notice that computeMapProg treats the dest as a reference; therefore, if/when that variable
595 // is published (see dojo-publish-privates), the published variable will always hold a valid value.
597 // this must come after all package processing since package processing may mutate map
598 computeMapProg(mix(map
, config
.map
), mapProgs
);
599 forEach(mapProgs
, function(item
){
600 item
[1] = computeMapProg(item
[1], []);
602 mapProgs
.star
= item
;
606 // push in any paths and recompute the internal pathmap
607 computeMapProg(mix(paths
, config
.paths
), pathsMapProg
);
610 forEach(config
.aliases
, function(pair
){
611 if(isString(pair
[0])){
612 pair
[0] = new RegExp("^" + escapeString(pair
[0]) + "$");
618 delayedModuleConfig
.push({config
:config
.config
});
620 for(p
in config
.config
){
621 var module
= getModule(p
, referenceModule
);
622 module
.config
= mix(module
.config
|| {}, config
.config
[p
]);
626 // push in any new cache values
628 consumePendingCacheInsert();
629 pendingCacheInsert
= config
.cache
;
630 if(config
.cache
["*noref"]){
631 consumePendingCacheInsert();
635 signal("config", [config
, req
.rawConfig
]);
639 // execute the various sniffs; userConfig can override and value
642 if(has("dojo-cdn") || 1 ){
643 // the sniff regex looks for a src attribute ending in dojo.js, optionally preceeded with a path.
644 // match[3] returns the path to dojo.js (if any) without the trailing slash. This is used for the
645 // dojo location on CDN deployments and baseUrl when either/both of these are not provided
646 // explicitly in the config data; this is the 1.6- behavior.
648 var scripts
= doc
.getElementsByTagName("script"),
650 script
, dojoDir
, src
, match
;
651 while(i
< scripts
.length
){
652 script
= scripts
[i
++];
653 if((src
= script
.getAttribute("src")) && (match
= src
.match(/(((.*)\/)|^)dojo\.js(\W|$)/i))){
654 // sniff dojoDir and baseUrl
655 dojoDir
= match
[3] || "";
656 defaultConfig
.baseUrl
= defaultConfig
.baseUrl
|| dojoDir
;
658 // sniff configuration on attribute in script element
659 src
= (script
.getAttribute("data-dojo-config") || script
.getAttribute("djConfig"));
661 dojoSniffConfig
= req
.eval("({ " + src
+ " })", "data-dojo-config");
664 // sniff requirejs attribute
666 var dataMain
= script
.getAttribute("data-main");
668 dojoSniffConfig
.deps
= dojoSniffConfig
.deps
|| [dataMain
];
677 // pass down doh.testConfig from parent as if it were a data-dojo-config
679 if(window
.parent
!= window
&& window
.parent
.require
){
680 var doh
= window
.parent
.require("doh");
681 doh
&& mix(dojoSniffConfig
, doh
.testConfig
);
686 // configure the loader; let the user override defaults
688 config(defaultConfig
, 1);
690 // do this before setting userConfig/sniffConfig to allow userConfig/sniff overrides
692 packs
.dojo
.location
= dojoDir
;
696 packs
.dijit
.location
= dojoDir
+ "../dijit/";
697 packs
.dojox
.location
= dojoDir
+ "../dojox/";
700 config(userConfig
, 1);
701 config(dojoSniffConfig
, 1);
704 // no config API, assume defaultConfig has everything the loader needs...for the entire lifetime of the application
705 paths
= defaultConfig
.paths
;
706 pathsMapProg
= defaultConfig
.pathsMapProg
;
707 packs
= defaultConfig
.packs
;
708 aliases
= defaultConfig
.aliases
;
709 mapProgs
= defaultConfig
.mapProgs
;
710 modules
= defaultConfig
.modules
;
711 cache
= defaultConfig
.cache
;
712 cacheBust
= defaultConfig
.cacheBust
;
714 // remember the default config for other processes (e.g., dojo/config)
715 req
.rawConfig
= defaultConfig
;
720 req
.combo
= req
.combo
|| {add
:noop
};
721 var comboPending
= 0,
723 comboPendingTimer
= null;
727 // build the loader machinery iaw configuration, including has feature tests
728 var injectDependencies = function(module
){
729 // checkComplete!=0 holds the idle signal; we're not idle if we're injecting dependencies
730 guardCheckComplete(function(){
731 forEach(module
.deps
, injectModule
);
732 if( 0 && comboPending
&& !comboPendingTimer
){
733 comboPendingTimer
= setTimeout(function() {
735 comboPendingTimer
= null;
736 req
.combo
.done(function(mids
, url
) {
737 var onLoadCallback= function(){
738 // defQ is a vector of module definitions 1-to-1, onto mids
742 combosPending
.push(mids
);
743 injectingModule
= mids
;
744 req
.injectUrl(url
, onLoadCallback
, mids
);
752 contextRequire = function(a1
, a2
, a3
, referenceModule
, contextRequire
){
753 var module
, syntheticMid
;
755 // signature is (moduleId)
756 module
= getModule(a1
, referenceModule
, true);
757 if(module
&& module
.executed
){
758 return module
.result
;
760 throw makeError("undefinedModule", a1
);
763 // a1 is a configuration
764 config(a1
, 0, referenceModule
);
766 // juggle args; (a2, a3) may be (dependencies, callback)
771 // signature is (requestList [,callback])
775 syntheticMid
= "require*" + uid();
777 // resolve the request list with respect to the reference module
778 for(var mid
, deps
= [], i
= 0; i
< a1
.length
;){
780 deps
.push(getModule(mid
, referenceModule
));
783 // construct a synthetic module to control execution of the requestList, and, optionally, callback
784 module
= mix(makeModuleInfo("", syntheticMid
, 0, ""), {
788 require
: referenceModule
? referenceModule
.require
: req
,
789 gc
: 1 //garbage collect
791 modules
[module
.mid
] = module
;
793 // checkComplete!=0 holds the idle signal; we're not idle if we're injecting dependencies
794 injectDependencies(module
);
796 // try to immediately execute
797 // if already traversing a factory tree, then strict causes circular dependency to abort the execution; maybe
798 // it's possible to execute this require later after the current traversal completes and avoid the circular dependency.
799 // ...but *always* insist on immediate in synch mode
800 var strict
= checkCompleteGuard
&& legacyMode
!=sync
;
801 guardCheckComplete(function(){
802 execModule(module
, strict
);
804 if(!module
.executed
){
805 // some deps weren't on board or circular dependency detected and strict; therefore, push into the execQ
811 return contextRequire
;
814 createRequire = function(module
){
818 var result
= module
.require
;
820 result = function(a1
, a2
, a3
){
821 return contextRequire(a1
, a2
, a3
, module
, result
);
823 module
.require
= mix(result
, req
);
824 result
.module
= module
;
825 result
.toUrl = function(name
){
826 return toUrl(name
, module
);
828 result
.toAbsMid = function(mid
){
829 return toAbsMid(mid
, module
);
832 result
.undef = function(mid
){
833 req
.undef(mid
, module
);
837 result
.syncLoadNls = function(mid
){
838 var nlsModuleInfo
= getModuleInfo(mid
, module
),
839 nlsModule
= modules
[nlsModuleInfo
.mid
];
840 if(!nlsModule
|| !nlsModule
.executed
){
841 cached
= cache
[nlsModuleInfo
.mid
] || cache
[urlKeyPrefix
+ nlsModuleInfo
.url
];
843 evalModuleText(cached
);
844 nlsModule
= modules
[nlsModuleInfo
.mid
];
847 return nlsModule
&& nlsModule
.executed
&& nlsModule
.result
;
856 // The list of modules that need to be evaluated.
860 // The queue of define arguments sent to loader.
864 // The set of modules upon which the loader is waiting for definition to arrive
867 setRequested = function(module
){
868 module
.injected
= requested
;
869 waiting
[module
.mid
] = 1;
871 waiting
[module
.url
] = module
.pack
|| 1;
876 setArrived = function(module
){
877 module
.injected
= arrived
;
878 delete waiting
[module
.mid
];
880 delete waiting
[module
.url
];
882 if(isEmpty(waiting
)){
884 1 && legacyMode
==xd
&& (legacyMode
= sync
);
888 execComplete
= req
.idle
=
889 // says the loader has completed (or not) its work
891 return !defQ
.length
&& isEmpty(waiting
) && !execQ
.length
&& !checkCompleteGuard
;
894 runMapProg = function(targetMid
, map
){
895 // search for targetMid in map; return the map item if found; falsy otherwise
897 for(var i
= 0; i
< map
.length
; i
++){
898 if(map
[i
][2].test(targetMid
)){
906 compactPath = function(path
){
908 segment
, lastSegment
;
909 path
= path
.replace(/\\/g, '/').split('/');
911 segment = path.shift();
912 if(segment==".." && result.length && lastSegment!=".."){
914 lastSegment = result[result.length - 1];
915 }else if(segment!="."){
916 result.push(lastSegment= segment);
919 return result.join("/");
922 makeModuleInfo = function(pid, mid, pack, url){
924 var xd= req.isXdUrl(url);
925 return {pid:pid, mid:mid, pack:pack, url:url, executed:0, def:0, isXd:xd, isAmd:!!(xd || (packs[pid] && packs[pid].isAmd))};
927 return {pid:pid, mid:mid, pack:pack, url:url, executed:0, def:0};
931 getModuleInfo_ = function(mid, referenceModule, packs, modules, baseUrl, mapProgs, pathsMapProg, alwaysCreate){
932 // arguments are passed instead of using lexical variables so that this function my be used independent of the loader (e.g., the builder)
933 // alwaysCreate is useful in this case so that getModuleInfo never returns references to real modules owned by the loader
934 var pid, pack, midInPackage, mapProg, mapItem, url, result, isRelative, requestedMid;
936 isRelative = /^\./.test(mid);
937 if(/(^\/)|(\:)|(\.js$)/.test(mid) || (isRelative && !referenceModule)){
938 // absolute path or protocol of .js filetype, or relative path but no reference module and therefore relative to page
939 // whatever it is, it's not a module but just a URL
of some sort
940 // note: pid===0 indicates the routine is returning an unmodified mid
942 return makeModuleInfo(0, mid
, 0, mid
);
944 // relative module ids are relative to the referenceModule; get rid of any dots
945 mid
= compactPath(isRelative
? (referenceModule
.mid
+ "/../" + mid
) : mid
);
947 throw makeError("irrationalPath", mid
);
949 // at this point, mid is an absolute mid
953 mapItem
= runMapProg(referenceModule
.mid
, mapProgs
);
955 mapItem
= mapItem
|| mapProgs
.star
;
956 mapItem
= mapItem
&& runMapProg(mid
, mapItem
[1]);
959 mid
= mapItem
[1] + mid
.substring(mapItem
[3]);
962 match
= mid
.match(/^([^\/]+)(\/(.+))?$/);
963 pid
= match
? match
[1] : "";
964 if((pack
= packs
[pid
])){
965 mid
= pid
+ "/" + (midInPackage
= (match
[3] || pack
.main
));
971 var candidateLength
= 0,
973 forEach(aliases
, function(pair
){
974 var match
= mid
.match(pair
[0]);
975 if(match
&& match
.length
>candidateLength
){
976 candidate
= isFunction(pair
[1]) ? mid
.replace(pair
[0], pair
[1]) : pair
[1];
980 return getModuleInfo_(candidate
, 0, packs
, modules
, baseUrl
, mapProgs
, pathsMapProg
, alwaysCreate
);
983 result
= modules
[mid
];
985 return alwaysCreate
? makeModuleInfo(result
.pid
, result
.mid
, result
.pack
, result
.url
) : modules
[mid
];
988 // get here iff the sought-after module does not yet exist; therefore, we need to compute the URL given the
989 // fully resolved (i.e., all relative indicators and package mapping resolved) module id
991 // note: pid!==0 indicates the routine is returning a url that has .js appended unmodified mid
992 mapItem
= runMapProg(mid
, pathsMapProg
);
994 url
= mapItem
[1] + mid
.substring(mapItem
[3]);
996 url
= pack
.location
+ "/" + midInPackage
;
997 }else if(has("config-tlmSiblingOfDojo")){
1002 // if result is not absolute, add baseUrl
1003 if(!(/(^\/)|(\:)/.test(url
))){
1004 url
= baseUrl
+ url
;
1007 return makeModuleInfo(pid
, mid
, pack
, compactPath(url
));
1010 getModuleInfo = function(mid
, referenceModule
){
1011 return getModuleInfo_(mid
, referenceModule
, packs
, modules
, req
.baseUrl
, mapProgs
, pathsMapProg
);
1014 resolvePluginResourceId = function(plugin
, prid
, referenceModule
){
1015 return plugin
.normalize
? plugin
.normalize(prid
, function(mid
){return toAbsMid(mid
, referenceModule
);}) : toAbsMid(prid
, referenceModule
);
1018 dynamicPluginUidGenerator
= 0,
1020 getModule = function(mid
, referenceModule
, immediate
){
1021 // compute and optionally construct (if necessary) the module implied by the mid with respect to referenceModule
1022 var match
, plugin
, prid
, result
;
1023 match
= mid
.match(/^(.+?)\!(.*)$/);
1025 // name was <plugin-module>!<plugin-resource-id>
1026 plugin
= getModule(match
[1], referenceModule
, immediate
);
1028 if( 1 && legacyMode
== sync
&& !plugin
.executed
){
1029 injectModule(plugin
);
1030 if(plugin
.injected
===arrived
&& !plugin
.executed
){
1031 guardCheckComplete(function(){
1035 if(plugin
.executed
){
1036 promoteModuleToPlugin(plugin
);
1038 // we are in xdomain mode for some reason
1039 execQ
.unshift(plugin
);
1045 if(plugin
.executed
=== executed
&& !plugin
.load
){
1046 // executed the module not knowing it was a plugin
1047 promoteModuleToPlugin(plugin
);
1050 // if the plugin has not been loaded, then can't resolve the prid and must assume this plugin is dynamic until we find out otherwise
1052 prid
= resolvePluginResourceId(plugin
, match
[2], referenceModule
);
1053 mid
= (plugin
.mid
+ "!" + (plugin
.dynamic
? ++dynamicPluginUidGenerator
+ "!" : "") + prid
);
1056 mid
= plugin
.mid
+ "!" + (++dynamicPluginUidGenerator
) + "!waitingForPlugin";
1058 result
= {plugin
:plugin
, mid
:mid
, req
:createRequire(referenceModule
), prid
:prid
};
1060 result
= getModuleInfo(mid
, referenceModule
);
1062 return modules
[result
.mid
] || (!immediate
&& (modules
[result
.mid
] = result
));
1065 toAbsMid
= req
.toAbsMid = function(mid
, referenceModule
){
1066 return getModuleInfo(mid
, referenceModule
).mid
;
1069 toUrl
= req
.toUrl = function(name
, referenceModule
){
1070 var moduleInfo
= getModuleInfo(name
+"/x", referenceModule
),
1071 url
= moduleInfo
.url
;
1072 return fixupUrl(moduleInfo
.pid
===0 ?
1073 // if pid===0, then name had a protocol or absolute path; either way, toUrl is the identify function in such cases
1075 // "/x.js" since getModuleInfo automatically appends ".js" and we appended "/x" to make name look likde a module id
1076 url
.substring(0, url
.length
-5)
1087 makeCjs = function(mid
){
1088 return modules
[mid
] = mix({mid
:mid
}, nonModuleProps
);
1091 cjsRequireModule
= makeCjs("require"),
1092 cjsExportsModule
= makeCjs("exports"),
1093 cjsModuleModule
= makeCjs("module"),
1095 runFactory = function(module
, args
){
1096 req
.trace("loader-run-factory", [module
.mid
]);
1097 var factory
= module
.def
,
1099 1 && syncExecStack
.unshift(module
);
1100 if(has("config-dojo-loader-catches")){
1102 result
= isFunction(factory
) ? factory
.apply(null, args
) : factory
;
1104 signal(error
, module
.result
= makeError("factoryThrew", [module
, e
]));
1107 result
= isFunction(factory
) ? factory
.apply(null, args
) : factory
;
1109 module
.result
= result
===undefined && module
.cjs
? module
.cjs
.exports
: result
;
1110 1 && syncExecStack
.shift(module
);
1117 promoteModuleToPlugin = function(pluginModule
){
1118 var plugin
= pluginModule
.result
;
1119 pluginModule
.dynamic
= plugin
.dynamic
;
1120 pluginModule
.normalize
= plugin
.normalize
;
1121 pluginModule
.load
= plugin
.load
;
1122 return pluginModule
;
1125 resolvePluginLoadQ = function(plugin
){
1126 // plugins is a newly executed module that has a loadQ waiting to run
1128 // step 1: traverse the loadQ and fixup the mid and prid; remember the map from original mid to new mid
1129 // recall the original mid was created before the plugin was on board and therefore it was impossible to
1130 // compute the final mid; accordingly, prid may or may not change, but the mid will definitely change
1132 forEach(plugin
.loadQ
, function(pseudoPluginResource
){
1133 // manufacture and insert the real module in modules
1134 var prid
= resolvePluginResourceId(plugin
, pseudoPluginResource
.prid
, pseudoPluginResource
.req
.module
),
1135 mid
= plugin
.dynamic
? pseudoPluginResource
.mid
.replace(/waitingForPlugin$/, prid
) : (plugin
.mid
+ "!" + prid
),
1136 pluginResource
= mix(mix({}, pseudoPluginResource
), {mid
:mid
, prid
:prid
, injected
:0});
1138 // create a new (the real) plugin resource and inject it normally now that the plugin is on board
1139 injectPlugin(modules
[mid
] = pluginResource
);
1140 } // else this was a duplicate request for the same (plugin, rid) for a nondynamic plugin
1142 // pluginResource is really just a placeholder with the wrong mid (because we couldn't calculate it until the plugin was on board)
1143 // mark is as arrived and delete it from modules; the real module was requested above
1144 map
[pseudoPluginResource
.mid
] = modules
[mid
];
1145 setArrived(pseudoPluginResource
);
1146 delete modules
[pseudoPluginResource
.mid
];
1150 // step2: replace all references to any placeholder modules with real modules
1151 var substituteModules = function(module
){
1152 for(var replacement
, deps
= module
.deps
|| [], i
= 0; i
<deps
.length
; i
++){
1153 replacement
= map
[deps
[i
].mid
];
1155 deps
[i
] = replacement
;
1159 for(var p
in modules
){
1160 substituteModules(modules
[p
]);
1162 forEach(execQ
, substituteModules
);
1165 finishExec = function(module
){
1166 req
.trace("loader-finish-exec", [module
.mid
]);
1167 module
.executed
= executed
;
1168 module
.defOrder
= defOrder
++;
1169 1 && forEach(module
.provides
, function(cb
){ cb(); });
1171 // the module was a plugin
1172 promoteModuleToPlugin(module
);
1173 resolvePluginLoadQ(module
);
1175 // remove all occurences of this module from the execQ
1176 for(i
= 0; i
< execQ
.length
;){
1177 if(execQ
[i
] === module
){
1183 // delete references to synthetic modules
1184 if (/^require\*/.test(module
.mid
)) {
1185 delete modules
[module
.mid
];
1191 execModule = function(module
, strict
){
1192 // run the dependency vector, then run the factory for module
1193 if(module
.executed
=== executing
){
1194 req
.trace("loader-circular-dependency", [circleTrace
.concat(module
.mid
).join("->")]);
1195 return (!module
.def
|| strict
) ? abortExec
: (module
.cjs
&& module
.cjs
.exports
);
1197 // at this point the module is either not executed or fully executed
1200 if(!module
.executed
){
1204 var mid
= module
.mid
,
1205 deps
= module
.deps
|| [],
1211 circleTrace
.push(mid
);
1212 req
.trace("loader-exec-module", ["exec", circleTrace
.length
, mid
]);
1215 // for circular dependencies, assume the first module encountered was executed OK
1216 // modules that circularly depend on a module that has not run its factory will get
1217 // the premade cjs.exports===module.result. They can take a reference to this object and/or
1218 // add properties to it. When the module finally runs its factory, the factory can
1219 // read/write/replace this object. Notice that so long as the object isn't replaced, any
1220 // reference taken earlier while walking the deps list is still valid.
1221 module
.executed
= executing
;
1222 while(i
< deps
.length
){
1224 argResult
= ((arg
=== cjsRequireModule
) ? createRequire(module
) :
1225 ((arg
=== cjsExportsModule
) ? module
.cjs
.exports
:
1226 ((arg
=== cjsModuleModule
) ? module
.cjs
:
1227 execModule(arg
, strict
))));
1228 if(argResult
=== abortExec
){
1229 module
.executed
= 0;
1230 req
.trace("loader-exec-module", ["abort", mid
]);
1231 0 && circleTrace
.pop();
1234 args
.push(argResult
);
1236 runFactory(module
, args
);
1238 0 && circleTrace
.pop();
1240 // at this point the module is guaranteed fully executed
1242 return module
.result
;
1246 checkCompleteGuard
= 0,
1248 guardCheckComplete = function(proc
){
1250 checkCompleteGuard
++;
1253 checkCompleteGuard
--;
1260 checkComplete = function(){
1261 // keep going through the execQ as long as at least one factory is executed
1262 // plugins, recursion, cached modules all make for many execution path possibilities
1263 if(checkCompleteGuard
){
1266 guardCheckComplete(function(){
1267 checkDojoRequirePlugin();
1268 for(var currentDefOrder
, module
, i
= 0; i
< execQ
.length
;){
1269 currentDefOrder
= defOrder
;
1272 if(currentDefOrder
!=defOrder
){
1273 // defOrder was bumped one or more times indicating something was executed (note, this indicates
1274 // the execQ was modified, maybe a lot (for example a later module causes an earlier module to execute)
1275 checkDojoRequirePlugin();
1278 // nothing happened; check the next module in the exec queue
1287 req
.undef = function(moduleId
, referenceModule
){
1288 // In order to reload a module, it must be undefined (this routine) and then re-requested.
1289 // This is useful for testing frameworks (at least).
1290 var module
= getModule(moduleId
, referenceModule
);
1292 delete modules
[module
.mid
];
1297 if(has("dojo-loader-eval-hint-url")===undefined){
1298 has
.add("dojo-loader-eval-hint-url", 1);
1301 var fixupUrl= function(url
){
1302 url
+= ""; // make sure url is a Javascript string (some paths may be a Java string)
1303 return url
+ (cacheBust
? ((/\?/.test(url
) ? "&" : "?") + cacheBust
) : "");
1306 injectPlugin = function(
1309 // injects the plugin module given by module; may have to inject the plugin itself
1310 var plugin
= module
.plugin
;
1312 if(plugin
.executed
=== executed
&& !plugin
.load
){
1313 // executed the module not knowing it was a plugin
1314 promoteModuleToPlugin(plugin
);
1317 var onLoad = function(def
){
1318 module
.result
= def
;
1325 plugin
.load(module
.prid
, module
.req
, onLoad
);
1326 }else if(plugin
.loadQ
){
1327 plugin
.loadQ
.push(module
);
1329 // the unshift instead of push is important: we don't want plugins to execute as
1330 // dependencies of some other module because this may cause circles when the plugin
1331 // loadQ is run; also, generally, we want plugins to run early since they may load
1332 // several other modules and therefore can potentially unblock many modules
1333 plugin
.loadQ
= [module
];
1334 execQ
.unshift(plugin
);
1335 injectModule(plugin
);
1339 // for IE, injecting a module may result in a recursive execution if the module is in the cache
1343 injectingModule
= 0,
1345 injectingCachedModule
= 0,
1347 evalModuleText = function(text
, module
){
1348 // see def() for the injectingCachedModule bracket; it simply causes a short, safe curcuit
1349 if(has("config-stripStrict")){
1350 text
= text
.replace(/"use strict"/g, '');
1352 injectingCachedModule
= 1;
1353 if(has("config-dojo-loader-catches")){
1358 req
.eval(text
, has("dojo-loader-eval-hint-url") ? module
.url
: module
.mid
);
1361 signal(error
, makeError("evalModuleThrew", module
));
1367 req
.eval(text
, has("dojo-loader-eval-hint-url") ? module
.url
: module
.mid
);
1370 injectingCachedModule
= 0;
1373 injectModule = function(module
){
1374 // Inject the module. In the browser environment, this means appending a script element into
1375 // the document; in other environments, it means loading a file.
1377 // If in synchronous mode, then get the module synchronously if it's not xdomainLoading.
1379 var mid
= module
.mid
,
1381 if(module
.executed
|| module
.injected
|| waiting
[mid
] || (module
.url
&& ((module
.pack
&& waiting
[module
.url
]===module
.pack
) || waiting
[module
.url
]==1))){
1384 setRequested(module
);
1388 if(module
.plugin
&& module
.plugin
.isCombo
){
1389 // a combo plugin; therefore, must be handled by combo service
1390 // the prid should have already been converted to a URL (if required by the plugin) during
1391 // the normalze process; in any event, there is no way for the loader to know how to
1392 // to the conversion; therefore the third argument is zero
1393 req
.combo
.add(module
.plugin
.mid
, module
.prid
, 0, req
);
1395 }else if(!module
.plugin
){
1396 viaCombo
= req
.combo
.add(0, module
.mid
, module
.url
, req
);
1405 injectPlugin(module
);
1407 } // else a normal module (not a plugin)
1410 var onLoadCallback = function(){
1412 if(module
.injected
!== arrived
){
1413 // the script that contained the module arrived and has been executed yet
1414 // nothing was added to the defQ (so it wasn't an AMD module) and the module
1415 // wasn't marked as arrived by dojo.provide (so it wasn't a v1.6- module);
1416 // therefore, it must not have been a module; adjust state accordingly
1418 mix(module
, nonModuleProps
);
1419 req
.trace("loader-define-nonmodule", [module
.url
]);
1422 if( 1 && legacyMode
){
1423 // must call checkComplete even in for sync loader because we may be in xdomainLoading mode;
1424 // but, if xd loading, then don't call checkComplete until out of the current sync traversal
1425 // in order to preserve order of execution of the dojo.required modules
1426 !syncExecStack
.length
&& checkComplete();
1431 cached
= cache
[mid
] || cache
[urlKeyPrefix
+ module
.url
];
1433 req
.trace("loader-inject", ["cache", module
.mid
, url
]);
1434 evalModuleText(cached
, module
);
1438 if( 1 && legacyMode
){
1440 // switch to async mode temporarily; if current legacyMode!=sync, then is must be one of {legacyAsync, xd, false}
1441 legacyMode
==sync
&& (legacyMode
= xd
);
1442 // fall through and load via script injection
1443 }else if(module
.isAmd
&& legacyMode
!=sync
){
1444 // fall through and load via script injection
1446 // mode may be sync, xd/legacyAsync, or async; module may be AMD or legacy; but module is always located on the same domain
1447 var xhrCallback = function(text
){
1448 if(legacyMode
==sync
){
1449 // the top of syncExecStack gives the current synchronously executing module; the loader needs
1450 // to know this if it has to switch to async loading in the middle of evaluating a legacy module
1451 // this happens when a modules dojo.require's a module that must be loaded async because it's xdomain
1452 // (using unshift/shift because there is no back() methods for Javascript arrays)
1453 syncExecStack
.unshift(module
);
1454 evalModuleText(text
, module
);
1455 syncExecStack
.shift();
1457 // maybe the module was an AMD module
1460 // legacy modules never get to defineModule() => cjs and injected never set; also evaluation implies executing
1467 // while synchronously evaluating this module, dojo.require was applied referencing a module
1468 // that had to be loaded async; therefore, the loader stopped answering all dojo.require
1469 // requests so they could be answered completely in the correct sequence; module.finish gives
1470 // the list of dojo.requires that must be re-applied once all target modules are available;
1471 // make a synthetic module to execute the dojo.require's in the correct order
1473 // compute a guarnateed-unique mid for the synthetic finish module; remember the finish vector; remove it from the reference module
1474 // TODO: can we just leave the module.finish...what's it hurting?
1475 var finishMid
= mid
+ "*finish",
1476 finish
= module
.finish
;
1477 delete module
.finish
;
1479 def(finishMid
, ["dojo", ("dojo/require!" + finish
.join(",")).replace(/\./g, "/")], function(dojo){
1480 forEach(finish, function(mid){ dojo.require(mid); });
1482 // unshift, not push, which causes the current traversal to be reattempted from the top
1483 execQ.unshift(getModule(finishMid));
1487 text = transformToAmd(module, text);
1489 evalModuleText(text, module);
1492 // if transformToAmd returned falsy, then the module was already AMD and it can be script-injected
1493 // do so to improve debugability(even though it means another download...which probably won't happen with a good browser cache)
1494 injectingModule = module;
1495 req.injectUrl(fixupUrl(url), onLoadCallback, module);
1496 injectingModule = 0;
1501 req.trace("loader
-inject
", ["xhr
", module.mid, url, legacyMode!=sync]);
1502 if(has("config
-dojo
-loader
-catches
")){
1504 req.getText(url, legacyMode!=sync, xhrCallback);
1506 signal(error, makeError("xhrInjectFailed
", [module, e]));
1509 req.getText(url, legacyMode!=sync, xhrCallback);
1513 } // else async mode or fell through in xdomain loading mode; either way, load by script injection
1514 req.trace("loader
-inject
", ["script
", module.mid, url]);
1515 injectingModule = module;
1516 req.injectUrl(fixupUrl(url), onLoadCallback, module);
1517 injectingModule = 0;
1520 defineModule = function(module, deps, def){
1521 req.trace("loader
-define
-module
", [module.mid, deps]);
1523 if( 0 && module.plugin && module.plugin.isCombo){
1524 // the module is a plugin resource loaded by the combo service
1525 // note: check for module.plugin should be enough since normal plugin resources should
1526 // not follow this path; module.plugin.isCombo is future-proofing belt and suspenders
1527 module.result = isFunction(def) ? def() : def;
1533 var mid = module.mid;
1534 if(module.injected === arrived){
1535 signal(error, makeError("multipleDefine
", module));
1544 exports: (module.result = {}),
1545 setExports: function(exports){
1546 module.cjs.exports = exports;
1549 return module.config;
1554 // resolve deps with respect to this module
1555 for(var i = 0; i < deps.length; i++){
1556 deps[i] = getModule(deps[i], module);
1559 if( 1 && legacyMode && !waiting[mid]){
1560 // the module showed up without being asked for; it was probably in a <script> element
1561 injectDependencies(module);
1567 if(!isFunction(def) && !deps.length){
1568 module.result = def;
1575 runDefQ = function(referenceModule, mids){
1576 // defQ is an array of [id, dependencies, factory]
1577 // mids (if any) is a vector of mids given by a combo service
1578 var definedModules = [],
1581 args = defQ.shift();
1582 mids && (args[0]= mids.shift());
1583 // explicit define indicates possible multiple modules in a single file; delay injecting dependencies until defQ fully
1584 // processed since modules earlier in the queue depend on already-arrived modules that are later in the queue
1585 // TODO: what if no args[0] and no referenceModule
1586 module = (args[0] && getModule(args[0])) || referenceModule;
1587 definedModules.push([module, args[1], args[2]]);
1589 consumePendingCacheInsert(referenceModule);
1590 forEach(definedModules, function(args){
1591 injectDependencies(defineModule.apply(null, args));
1600 // Timer machinery that monitors how long the loader is waiting and signals an error when the timer runs out.
1601 clearTimer = function(){
1602 timerId && clearTimeout(timerId);
1606 startTimer = function(){
1609 timerId = window.setTimeout(function(){
1611 signal(error, makeError("timeout
", waiting));
1618 // the typically unnecessary !! in front of doc.attachEvent is due to an opera bug; see #15096
1619 has.add("ie
-event
-behavior
", !!doc.attachEvent && (typeof opera === "undefined" || opera.toString() != "[object Opera
]"));
1622 if( 1 && ( 1 || 1 )){
1623 var domOn = function(node, eventName, ieEventName, handler){
1624 // Add an event listener to a DOM node using the API appropriate for the current browser;
1625 // return a function that will disconnect the listener.
1626 if(!has("ie
-event
-behavior
")){
1627 node.addEventListener(eventName, handler, false);
1629 node.removeEventListener(eventName, handler, false);
1632 node.attachEvent(ieEventName, handler);
1634 node.detachEvent(ieEventName, handler);
1638 windowOnLoadListener = domOn(window, "load
", "onload
", function(){
1640 doc.readyState!="complete
" && (doc.readyState = "complete
");
1641 windowOnLoadListener();
1645 // if the loader is on the page, there must be at least one script element
1646 // getting its parent and then doing insertBefore solves the "Operation Aborted
"
1647 // error in IE from appending to a node that isn't properly closed; see
1648 // dojo/tests/_base/loader/requirejs/simple-badbase.html for an example
1649 var sibling = doc.getElementsByTagName("script
")[0],
1650 insertPoint= sibling.parentNode;
1651 req.injectUrl = function(url, callback, owner){
1652 // insert a script element to the insert-point element with src=url;
1653 // apply callback upon detecting the script has loaded.
1655 var node = owner.node = doc.createElement("script
"),
1656 onLoad = function(e){
1657 e = e || window.event;
1658 var node = e.target || e.srcElement;
1659 if(e.type === "load
" || /complete|loaded/.test(node.readyState)){
1661 errorDisconnector();
1662 callback && callback();
1665 loadDisconnector = domOn(node, "load
", "onreadystatechange
", onLoad),
1666 errorDisconnector = domOn(node, "error
", "onerror
", function(e){
1668 errorDisconnector();
1669 signal(error, makeError("scriptError
", [url, e]));
1672 node.type = "text
/javascript
";
1673 node.charset = "utf
-8";
1675 insertPoint.insertBefore(node, sibling);
1682 req.log = function(){
1684 for(var i = 0; i < arguments.length; i++){
1685 console.log(arguments[i]);
1694 var trace = req.trace = function(
1695 group, // the trace group to which this application belongs
1696 args // the contents of the trace
1699 // Tracing interface by group.
1701 // Sends the contents of args to the console iff (req.trace.on && req.trace[group])
1703 if(trace.on && trace.group[group]){
1704 signal("trace
", [group, args]);
1705 for(var arg, dump = [], text= "trace
:" + group + (args.length ? (":" + args[0]) : ""), i= 1; i<args.length;){
1714 dump.length && dump.push(".");
1715 req.log.apply(req, dump);
1721 set:function(group, value){
1722 if(isString(group)){
1723 trace.group[group]= value;
1725 mix(trace.group, group);
1729 trace.set(mix(mix(mix({}, defaultConfig.trace), userConfig.trace), dojoSniffConfig.trace));
1730 on("config
", function(config){
1731 config.trace && trace.set(config.trace);
1738 mid, //(commonjs.moduleId, optional) list of modules to be loaded before running factory
1739 dependencies, //(array of commonjs.moduleId, optional)
1743 // Advises the loader of a module factory. //Implements http://wiki.commonjs.org/wiki/Modules/AsynchronousDefinition.
1746 // CommonJS factory scan courtesy of http://requirejs.org
1748 var arity = arguments.length,
1749 defaultDeps = ["require
", "exports
", "module
"],
1750 // the predominate signature...
1751 args = [0, mid, dependencies];
1753 args = [0, (isFunction(mid) ? defaultDeps : []), mid];
1754 }else if(arity==2 && isString(mid)){
1755 args = [mid, (isFunction(dependencies) ? defaultDeps : []), dependencies];
1757 args = [mid, dependencies, factory];
1760 if( 0 && args[1]===defaultDeps){
1762 .replace(/(\/\*([\s\S]*?)\*\/|\/\/(.*)$)/mg, "")
1763 .replace(/require\(["']([\w\!\-_\.\/]+)["']\)/g
, function(match
, dep
){
1768 req
.trace("loader-define", args
.slice(0, 2));
1769 var targetModule
= args
[0] && getModule(args
[0]),
1771 if(targetModule
&& !waiting
[targetModule
.mid
]){
1772 // given a mid that hasn't been requested; therefore, defined through means other than injecting
1773 // consequent to a require() or define() application; examples include defining modules on-the-fly
1774 // due to some code path or including a module in a script element. In any case,
1775 // there is no callback waiting to finish processing and nothing to trigger the defQ and the
1776 // dependencies are never requested; therefore, do it here.
1777 injectDependencies(defineModule(targetModule
, args
[1], args
[2]));
1778 }else if(!has("ie-event-behavior") || ! 1 || injectingCachedModule
){
1779 // not IE path: anonymous module and therefore must have been injected; therefore, onLoad will fire immediately
1780 // after script finishes being evaluated and the defQ can be run from that callback to detect the module id
1783 // IE path: possibly anonymous module and therefore injected; therefore, cannot depend on 1-to-1,
1784 // in-order exec of onLoad with script eval (since it's IE) and must manually detect here
1785 targetModule
= targetModule
|| injectingModule
;
1787 for(mid
in waiting
){
1788 module
= modules
[mid
];
1789 if(module
&& module
.node
&& module
.node
.readyState
=== 'interactive'){
1790 targetModule
= module
;
1794 if( 0 && !targetModule
){
1795 for(var i
= 0; i
<combosPending
.length
; i
++){
1796 targetModule
= combosPending
[i
];
1797 if(targetModule
.node
&& targetModule
.node
.readyState
=== 'interactive'){
1804 if( 0 && isArray(targetModule
)){
1805 injectDependencies(defineModule(getModule(targetModule
.shift()), args
[1], args
[2]));
1806 if(!targetModule
.length
){
1807 combosPending
.splice(i
, 1);
1809 }else if(targetModule
){
1810 consumePendingCacheInsert(targetModule
);
1811 injectDependencies(defineModule(targetModule
, args
[1], args
[2]));
1813 signal(error
, makeError("ieDefineFailed", args
[0]));
1819 vendor
:"dojotoolkit.org"
1826 // allow config to override default implemention of named functions; this is useful for
1827 // non-browser environments, e.g., overriding injectUrl, getText, log, etc. in node.js, Rhino, etc.
1828 // also useful for testing and monkey patching loader
1829 mix(mix(req
, defaultConfig
.loaderPatch
), userConfig
.loaderPatch
);
1831 // now that req is fully initialized and won't change, we can hook it up to the error signal
1832 on(error
, function(arg
){
1835 if(arg
instanceof Error
){
1837 console
.log(p
+ ":", arg
[p
]);
1844 // always publish these
1854 // these may be interesting to look at when debugging
1858 legacyMode
:legacyMode
,
1863 // these are used for testing
1864 // TODO: move testing infrastructure to a different has feature
1867 pathsMapProg
:pathsMapProg
,
1868 listenerQueues
:listenerQueues
,
1870 // these are used by the builder (at least)
1871 computeMapProg
:computeMapProg
,
1872 runMapProg
:runMapProg
,
1873 compactPath
:compactPath
,
1874 getModuleInfo
:getModuleInfo_
1878 // the loader can be defined exactly once; look for global define which is the symbol AMD loaders are
1879 // *required* to define (as opposed to require, which is optional)
1882 signal(error
, makeError("defineAlreadyDefined", 0));
1886 global
.define
= def
;
1887 global
.require
= req
;
1893 if( 0 && req
.combo
&& req
.combo
.plugins
){
1894 var plugins
= req
.combo
.plugins
,
1896 for(pluginName
in plugins
){
1897 mix(mix(getModule(pluginName
), plugins
[pluginName
]), {isCombo
:1, executed
:"executed", load
:1});
1902 forEach(delayedModuleConfig
, function(c
){ config(c
); });
1903 var bootDeps
= dojoSniffConfig
.deps
|| userConfig
.deps
|| defaultConfig
.deps
,
1904 bootCallback
= dojoSniffConfig
.callback
|| userConfig
.callback
|| defaultConfig
.callback
;
1905 req
.boot
= (bootDeps
|| bootCallback
) ? [bootDeps
|| [], bootCallback
] : 0;
1908 !req
.async
&& req(["dojo"]);
1909 req
.boot
&& req
.apply(null, req
.boot
);
1912 (this.dojoConfig
|| this.djConfig
|| this.require
|| {}, {
1915 'config-selectorEngine':"acme",
1916 'config-tlmSiblingOfDojo':1,
1924 location
:"../dijit",
1933 'dojo/_base/fx':function(){
1934 define(["./kernel", "./config", /*===== "./declare", =====*/ "./lang", "../Evented", "./Color", "./connect", "./sniff", "../dom", "../dom-style"],
1935 function(dojo, config, /*===== declare, =====*/ lang
, Evented
, Color
, connect
, has
, dom
, style
){
1939 // Animation loosely package based on Dan Pupius' work, contributed under CLA; see
1940 // http://pupius.co.uk/js/Toolkit.Drawing.js
1942 var _mixin
= lang
.mixin
;
1947 // This module defines the base dojo/_base/fx implementation.
1950 var _Line
= basefx
._Line = function(/*int*/ start
, /*int*/ end
){
1952 // Object used to generate values from a start value to an end value
1954 // Beginning value for range
1956 // Ending value for range
1961 _Line
.prototype.getValue = function(/*float*/ n
){
1963 // Returns the point on the line
1965 // a floating point number greater than 0 and less than 1
1966 return ((this.end
- this.start
) * n
) + this.start
; // Decimal
1969 var Animation
= basefx
.Animation = function(args
){
1971 // A generic animation class that fires callbacks into its handlers
1972 // object at various states.
1974 // A generic animation class that fires callbacks into its handlers
1975 // object at various states. Nearly all dojo animation functions
1976 // return an instance of this method, usually without calling the
1977 // .play() method beforehand. Therefore, you will likely need to
1978 // call .play() on instances of `Animation` when one is
1981 // The 'magic argument', mixing all the properties into this
1982 // animation instance.
1985 if(lang
.isArray(this.curve
)){
1986 this.curve
= new _Line(this.curve
[0], this.curve
[1]);
1990 Animation
.prototype = new Evented();
1992 lang
.extend(Animation
, {
1993 // duration: Integer
1994 // The time in milliseconds the animation will take to run
1998 // curve: _Line|Array
1999 // A two element array of start and end values, or a `_Line` instance to be
2000 // used in the Animation.
2003 // easing: Function?
2004 // A Function to adjust the acceleration (or deceleration) of the progress
2010 // The number of times to loop the animation
2014 // the time in milliseconds to wait before advancing to next frame
2015 // (used as a fps timer: 1000/rate = fps)
2016 rate
: 20 /* 50 fps */,
2020 // The time in milliseconds to wait before starting animation after it
2021 // has been .play()'ed
2024 // beforeBegin: Event?
2025 // Synthetic event fired before a Animation begins playing (synchronous)
2029 // Synthetic event fired as a Animation begins playing (useful?)
2032 // onAnimate: Event?
2033 // Synthetic event fired at each interval of the Animation
2037 // Synthetic event fired after the final frame of the Animation
2041 // Synthetic event fired any time the Animation is play()'ed
2045 // Synthetic event fired when the Animation is paused
2049 // Synthetic event fires when the Animation is stopped
2055 _startRepeatCount
: 0,
2057 _getStep: function(){
2058 var _p
= this._percent
,
2061 return _e
? _e(_p
) : _p
;
2063 _fire: function(/*Event*/ evt
, /*Array?*/ args
){
2065 // Convenience function. Fire event "evt" and pass it the
2066 // arguments specified in "args".
2068 // Convenience function. Fire event "evt" and pass it the
2069 // arguments specified in "args".
2070 // Fires the callback in the scope of this Animation
2073 // The event to fire.
2075 // The arguments to pass to the event.
2078 if(config
.debugAtAllCosts
){
2079 this[evt
].apply(this, a
);
2082 this[evt
].apply(this, a
);
2084 // squelch and log because we shouldn't allow exceptions in
2085 // synthetic event handlers to cause the internal timer to run
2086 // amuck, potentially pegging the CPU. I'm not a fan of this
2087 // squelch, but hopefully logging will make it clear what's
2089 console
.error("exception in animation handler for:", evt
);
2094 return this; // Animation
2097 play: function(/*int?*/ delay
, /*Boolean?*/ gotoStart
){
2099 // Start the animation.
2101 // How many milliseconds to delay before starting.
2103 // If true, starts the animation from the beginning; otherwise,
2104 // starts it from its current position.
2105 // returns: Animation
2106 // The instance to allow chaining.
2109 if(_t
._delayTimer
){ _t
._clearTimer(); }
2112 _t
._active
= _t
._paused
= false;
2114 }else if(_t
._active
&& !_t
._paused
){
2118 _t
._fire("beforeBegin", [_t
.node
]);
2120 var de
= delay
|| _t
.delay
,
2121 _p
= lang
.hitch(_t
, "_play", gotoStart
);
2124 _t
._delayTimer
= setTimeout(_p
, de
);
2128 return _t
; // Animation
2131 _play: function(gotoStart
){
2133 if(_t
._delayTimer
){ _t
._clearTimer(); }
2134 _t
._startTime
= new Date().valueOf();
2136 _t
._startTime
-= _t
.duration
* _t
._percent
;
2141 var value
= _t
.curve
.getValue(_t
._getStep());
2143 if(!_t
._startRepeatCount
){
2144 _t
._startRepeatCount
= _t
.repeat
;
2146 _t
._fire("onBegin", [value
]);
2149 _t
._fire("onPlay", [value
]);
2152 return _t
; // Animation
2157 // Pauses a running animation.
2159 if(_t
._delayTimer
){ _t
._clearTimer(); }
2161 if(!_t
._active
){ return _t
; /*Animation*/ }
2163 _t
._fire("onPause", [_t
.curve
.getValue(_t
._getStep())]);
2164 return _t
; // Animation
2167 gotoPercent: function(/*Decimal*/ percent
, /*Boolean?*/ andPlay
){
2169 // Sets the progress of the animation.
2171 // A percentage in decimal notation (between and including 0.0 and 1.0).
2173 // If true, play the animation after setting the progress.
2176 _t
._active
= _t
._paused
= true;
2177 _t
._percent
= percent
;
2178 if(andPlay
){ _t
.play(); }
2179 return _t
; // Animation
2182 stop: function(/*boolean?*/ gotoEnd
){
2184 // Stops a running animation.
2186 // If true, the animation will end.
2188 if(_t
._delayTimer
){ _t
._clearTimer(); }
2189 if(!_t
._timer
){ return _t
; /* Animation */ }
2194 _t
._fire("onStop", [_t
.curve
.getValue(_t
._getStep())]);
2195 _t
._active
= _t
._paused
= false;
2196 return _t
; // Animation
2201 // Returns a string token representation of the status of
2202 // the animation, one of: "paused", "playing", "stopped"
2204 return this._paused
? "paused" : "playing"; // String
2206 return "stopped"; // String
2212 var curr
= new Date().valueOf();
2213 // Allow durations of 0 (instant) by setting step to 1 - see #13798
2214 var step
= _t
.duration
=== 0 ? 1 : (curr
- _t
._startTime
) / (_t
.duration
);
2223 step
= _t
.easing(step
);
2226 _t
._fire("onAnimate", [_t
.curve
.getValue(step
)]);
2228 if(_t
._percent
< 1){
2235 _t
.play(null, true);
2236 }else if(_t
.repeat
== -1){
2237 _t
.play(null, true);
2239 if(_t
._startRepeatCount
){
2240 _t
.repeat
= _t
._startRepeatCount
;
2241 _t
._startRepeatCount
= 0;
2245 _t
._fire("onEnd", [_t
.node
]);
2246 !_t
.repeat
&& _t
._stopTimer();
2249 return _t
; // Animation
2252 _clearTimer: function(){
2254 // Clear the play delay timer
2255 clearTimeout(this._delayTimer
);
2256 delete this._delayTimer
;
2261 // the local timer, stubbed into all Animation instances
2268 lang
.extend(Animation
, {
2270 _startTimer: function(){
2272 this._timer
= connect
.connect(runner
, "run", this, "_cycle");
2276 timer
= setInterval(lang
.hitch(runner
, "run"), this.rate
);
2280 _stopTimer: function(){
2282 connect
.disconnect(this._timer
);
2287 clearInterval(timer
);
2296 has("ie") ? function(node
){
2297 // only set the zoom if the "tickle" value would be the same as the
2299 var ns
= node
.style
;
2300 // don't set the width to auto if it didn't already cascade that way.
2301 // We don't want to f anyones designs
2302 if(!ns
.width
.length
&& style
.get(node
, "width") == "auto"){
2308 basefx
._fade = function(/*Object*/ args
){
2310 // Returns an animation that will fade the node defined by
2311 // args.node from the start to end values passed (args.start
2312 // args.end) (end is mandatory, start is optional)
2314 args
.node
= dom
.byId(args
.node
);
2315 var fArgs
= _mixin({ properties
: {} }, args
),
2316 props
= (fArgs
.properties
.opacity
= {});
2318 props
.start
= !("start" in fArgs
) ?
2320 return +style
.get(fArgs
.node
, "opacity")||0;
2322 props
.end
= fArgs
.end
;
2324 var anim
= basefx
.animateProperty(fArgs
);
2325 connect
.connect(anim
, "beforeBegin", lang
.partial(_makeFadeable
, fArgs
.node
));
2327 return anim
; // Animation
2331 var __FadeArgs = declare(null, {
2332 // node: DOMNode|String
2333 // The node referenced in the animation
2334 // duration: Integer?
2335 // Duration of the animation in milliseconds.
2336 // easing: Function?
2337 // An easing function.
2341 basefx
.fadeIn = function(/*__FadeArgs*/ args
){
2343 // Returns an animation that will fade node defined in 'args' from
2344 // its current opacity to fully opaque.
2345 return basefx
._fade(_mixin({ end
: 1 }, args
)); // Animation
2348 basefx
.fadeOut = function(/*__FadeArgs*/ args
){
2350 // Returns an animation that will fade node defined in 'args'
2351 // from its current opacity to fully transparent.
2352 return basefx
._fade(_mixin({ end
: 0 }, args
)); // Animation
2355 basefx
._defaultEasing = function(/*Decimal?*/ n
){
2357 // The default easing function for Animation(s)
2358 return 0.5 + ((Math
.sin((n
+ 1.5) * Math
.PI
)) / 2); // Decimal
2361 var PropLine = function(properties
){
2362 // PropLine is an internal class which is used to model the values of
2363 // an a group of CSS properties across an animation lifecycle. In
2364 // particular, the "getValue" function handles getting interpolated
2365 // values between start and end for a particular CSS value.
2366 this._properties
= properties
;
2367 for(var p
in properties
){
2368 var prop
= properties
[p
];
2369 if(prop
.start
instanceof Color
){
2370 // create a reusable temp color object to keep intermediate results
2371 prop
.tempColor
= new Color();
2376 PropLine
.prototype.getValue = function(r
){
2378 for(var p
in this._properties
){
2379 var prop
= this._properties
[p
],
2381 if(start
instanceof Color
){
2382 ret
[p
] = Color
.blendColors(start
, prop
.end
, r
, prop
.tempColor
).toCss();
2383 }else if(!lang
.isArray(start
)){
2384 ret
[p
] = ((prop
.end
- start
) * r
) + start
+ (p
!= "opacity" ? prop
.units
|| "px" : 0);
2391 var __AnimArgs = declare(__FadeArgs, {
2392 // properties: Object?
2393 // A hash map of style properties to Objects describing the transition,
2394 // such as the properties of _Line with an additional 'units' property
2397 //TODOC: add event callbacks
2401 basefx
.animateProperty = function(/*__AnimArgs*/ args
){
2403 // Returns an animation that will transition the properties of
2404 // node defined in `args` depending how they are defined in
2405 // `args.properties`
2408 // Foundation of most `dojo/_base/fx`
2409 // animations. It takes an object of "properties" corresponding to
2410 // style properties, and animates them in parallel over a set
2414 // A simple animation that changes the width of the specified node.
2415 // | basefx.animateProperty({
2416 // | node: "nodeId",
2417 // | properties: { width: 400 },
2419 // Dojo figures out the start value for the width and converts the
2420 // integer specified for the width to the more expressive but
2421 // verbose form `{ width: { end: '400', units: 'px' } }` which you
2422 // can also specify directly. Defaults to 'px' if omitted.
2425 // Animate width, height, and padding over 2 seconds... the
2427 // | basefx.animateProperty({ node: node, duration:2000,
2429 // | width: { start: '200', end: '400', units:"px" },
2430 // | height: { start:'200', end: '400', units:"px" },
2431 // | paddingTop: { start:'5', end:'50', units:"px" }
2434 // Note 'paddingTop' is used over 'padding-top'. Multi-name CSS properties
2435 // are written using "mixed case", as the hyphen is illegal as an object key.
2438 // Plug in a different easing function and register a callback for
2439 // when the animation ends. Easing functions accept values between
2440 // zero and one and return a value on that basis. In this case, an
2441 // exponential-in curve.
2442 // | basefx.animateProperty({
2443 // | node: "nodeId",
2444 // | // dojo figures out the start value
2445 // | properties: { width: { end: 400 } },
2446 // | easing: function(n){
2447 // | return (n==0) ? 0 : Math.pow(2, 10 * (n - 1));
2449 // | onEnd: function(node){
2450 // | // called when the animation finishes. The animation
2451 // | // target is passed to this function
2453 // | }).play(500); // delay playing half a second
2456 // Like all `Animation`s, animateProperty returns a handle to the
2457 // Animation instance, which fires the events common to Dojo FX. Use `aspect.after`
2458 // to access these events outside of the Animation definition:
2459 // | var anim = basefx.animateProperty({
2462 // | width:400, height:500
2465 // | aspect.after(anim, "onEnd", function(){
2466 // | console.log("animation ended");
2468 // | // play the animation now:
2472 // Each property can be a function whose return value is substituted along.
2473 // Additionally, each measurement (eg: start, end) can be a function. The node
2474 // reference is passed directly to callbacks.
2475 // | basefx.animateProperty({
2478 // | height:function(node){
2479 // | // shrink this node by 50%
2480 // | return domGeom.position(node).h / 2
2483 // | start:function(node){ return 100; },
2484 // | end:function(node){ return 200; }
2490 var n
= args
.node
= dom
.byId(args
.node
);
2491 if(!args
.easing
){ args
.easing
= dojo
._defaultEasing
; }
2493 var anim
= new Animation(args
);
2494 connect
.connect(anim
, "beforeBegin", anim
, function(){
2496 for(var p
in this.properties
){
2497 // Make shallow copy of properties into pm because we overwrite
2498 // some values below. In particular if start/end are functions
2499 // we don't want to overwrite them or the functions won't be
2500 // called if the animation is reused.
2501 if(p
== "width" || p
== "height"){
2502 this.node
.display
= "block";
2504 var prop
= this.properties
[p
];
2505 if(lang
.isFunction(prop
)){
2508 prop
= pm
[p
] = _mixin({}, (lang
.isObject(prop
) ? prop
: { end
: prop
}));
2510 if(lang
.isFunction(prop
.start
)){
2511 prop
.start
= prop
.start(n
);
2513 if(lang
.isFunction(prop
.end
)){
2514 prop
.end
= prop
.end(n
);
2516 var isColor
= (p
.toLowerCase().indexOf("color") >= 0);
2517 function getStyle(node
, p
){
2518 // domStyle.get(node, "height") can return "auto" or "" on IE; this is more reliable:
2519 var v
= { height
: node
.offsetHeight
, width
: node
.offsetWidth
}[p
];
2520 if(v
!== undefined){ return v
; }
2521 v
= style
.get(node
, p
);
2522 return (p
== "opacity") ? +v
: (isColor
? v
: parseFloat(v
));
2524 if(!("end" in prop
)){
2525 prop
.end
= getStyle(n
, p
);
2526 }else if(!("start" in prop
)){
2527 prop
.start
= getStyle(n
, p
);
2531 prop
.start
= new Color(prop
.start
);
2532 prop
.end
= new Color(prop
.end
);
2534 prop
.start
= (p
== "opacity") ? +prop
.start
: parseFloat(prop
.start
);
2537 this.curve
= new PropLine(pm
);
2539 connect
.connect(anim
, "onAnimate", lang
.hitch(style
, "set", anim
.node
));
2540 return anim
; // Animation
2543 basefx
.anim = function( /*DOMNode|String*/ node
,
2544 /*Object*/ properties
,
2545 /*Integer?*/ duration
,
2546 /*Function?*/ easing
,
2547 /*Function?*/ onEnd
,
2548 /*Integer?*/ delay
){
2550 // A simpler interface to `animateProperty()`, also returns
2551 // an instance of `Animation` but begins the animation
2552 // immediately, unlike nearly every other Dojo animation API.
2554 // Simpler (but somewhat less powerful) version
2555 // of `animateProperty`. It uses defaults for many basic properties
2556 // and allows for positional parameters to be used in place of the
2557 // packed "property bag" which is used for other Dojo animation
2560 // The `Animation` object returned will be already playing, so
2561 // calling play() on it again is (usually) a no-op.
2563 // a DOM node or the id of a node to animate CSS properties on
2565 // The number of milliseconds over which the animation
2566 // should run. Defaults to the global animation default duration
2569 // An easing function over which to calculate acceleration
2570 // and deceleration of the animation through its duration.
2571 // A default easing algorithm is provided, but you may
2572 // plug in any you wish. A large selection of easing algorithms
2573 // are available in `dojo/fx/easing`.
2575 // A function to be called when the animation finishes
2578 // The number of milliseconds to delay beginning the
2579 // animation by. The default is 0.
2582 // | basefx.anim("id", { opacity: 0 });
2584 // Fade out a node over a full second
2585 // | basefx.anim("id", { opacity: 0 }, 1000);
2586 return basefx
.animateProperty({ // Animation
2588 duration
: duration
|| Animation
.prototype.duration
,
2589 properties
: properties
,
2592 }).play(delay
|| 0);
2597 _mixin(dojo
, basefx
);
2598 // Alias to drop come 2.0:
2599 dojo
._Animation
= Animation
;
2606 'dojo/dom-form':function(){
2607 define(["./_base/lang", "./dom", "./io-query", "./json"], function(lang
, dom
, ioq
, json
){
2611 function setValue(/*Object*/ obj
, /*String*/ name
, /*String*/ value
){
2613 // For the named property in object, set the value. If a value
2614 // already exists and it is a string, convert the value to be an
2617 // Skip it if there is no value
2622 var val
= obj
[name
];
2623 if(typeof val
== "string"){ // inline'd type check
2624 obj
[name
] = [val
, value
];
2625 }else if(lang
.isArray(val
)){
2632 var exclude
= "file|submit|image|reset|button";
2636 // This module defines form-processing functions.
2638 fieldToObject
: function fieldToObject(/*DOMNode|String*/ inputNode
){
2640 // Serialize a form field to a JavaScript object.
2642 // Returns the value encoded in a form field as
2643 // as a string or an array of strings. Disabled form elements
2644 // and unchecked radio and checkboxes are skipped. Multi-select
2645 // elements are returned as an array of string values.
2646 // inputNode: DOMNode|String
2650 inputNode
= dom
.byId(inputNode
);
2652 var _in
= inputNode
.name
, type
= (inputNode
.type
|| "").toLowerCase();
2653 if(_in
&& type
&& !inputNode
.disabled
){
2654 if(type
== "radio" || type
== "checkbox"){
2655 if(inputNode
.checked
){
2656 ret
= inputNode
.value
;
2658 }else if(inputNode
.multiple
){
2660 var nodes
= [inputNode
.firstChild
];
2661 while(nodes
.length
){
2662 for(var node
= nodes
.pop(); node
; node
= node
.nextSibling
){
2663 if(node
.nodeType
== 1 && node
.tagName
.toLowerCase() == "option"){
2665 ret
.push(node
.value
);
2668 if(node
.nextSibling
){
2669 nodes
.push(node
.nextSibling
);
2671 if(node
.firstChild
){
2672 nodes
.push(node
.firstChild
);
2679 ret
= inputNode
.value
;
2683 return ret
; // Object
2686 toObject
: function formToObject(/*DOMNode|String*/ formNode
){
2688 // Serialize a form node to a JavaScript object.
2690 // Returns the values encoded in an HTML form as
2691 // string properties in an object which it then returns. Disabled form
2692 // elements, buttons, and other non-value form elements are skipped.
2693 // Multi-select elements are returned as an array of string values.
2694 // formNode: DOMNode|String
2697 // | <form id="test_form">
2698 // | <input type="text" name="blah" value="blah">
2699 // | <input type="text" name="no_value" value="blah" disabled>
2700 // | <input type="button" name="no_value2" value="blah">
2701 // | <select type="select" multiple name="multi" size="5">
2702 // | <option value="blah">blah</option>
2703 // | <option value="thud" selected>thud</option>
2704 // | <option value="thonk" selected>thonk</option>
2708 // yields this object structure as the result of a call to
2719 var ret
= {}, elems
= dom
.byId(formNode
).elements
;
2720 for(var i
= 0, l
= elems
.length
; i
< l
; ++i
){
2721 var item
= elems
[i
], _in
= item
.name
, type
= (item
.type
|| "").toLowerCase();
2722 if(_in
&& type
&& exclude
.indexOf(type
) < 0 && !item
.disabled
){
2723 setValue(ret
, _in
, form
.fieldToObject(item
));
2724 if(type
== "image"){
2725 ret
[_in
+ ".x"] = ret
[_in
+ ".y"] = ret
[_in
].x
= ret
[_in
].y
= 0;
2729 return ret
; // Object
2732 toQuery
: function formToQuery(/*DOMNode|String*/ formNode
){
2734 // Returns a URL-encoded string representing the form passed as either a
2735 // node or string ID identifying the form to serialize
2736 // formNode: DOMNode|String
2739 return ioq
.objectToQuery(form
.toObject(formNode
)); // String
2742 toJson
: function formToJson(/*DOMNode|String*/ formNode
, /*Boolean?*/ prettyPrint
){
2744 // Create a serialized JSON string from a form node or string
2745 // ID identifying the form to serialize
2746 // formNode: DOMNode|String
2747 // prettyPrint: Boolean?
2750 return json
.stringify(form
.toObject(formNode
), null, prettyPrint
? 4 : 0); // String
2758 'dojo/promise/tracer':function(){
2763 ], function(lang
, Promise
, Evented
){
2767 // dojo/promise/tracer
2772 // Trace promise fulfillment.
2774 // Trace promise fulfillment. Calling `.trace()` or `.traceError()` on a
2775 // promise enables tracing. Will emit `resolved`, `rejected` or `progress`
2778 on: function(type, listener){
2780 // Subscribe to traces.
2782 // See `dojo/Evented#on()`.
2784 // `resolved`, `rejected`, or `progress`
2785 // listener: Function
2786 // The listener is passed the traced value and any arguments
2787 // that were used with the `.trace()` call.
2792 var evented
= new Evented
;
2793 var emit
= evented
.emit
;
2794 evented
.emit
= null;
2795 // Emit events asynchronously since they should not change the promise state.
2796 function emitAsync(args
){
2797 setTimeout(function(){
2798 emit
.apply(evented
, args
);
2802 Promise
.prototype.trace = function(){
2804 // Trace the promise.
2806 // Tracing allows you to transparently log progress,
2807 // resolution and rejection of promises, without affecting the
2808 // promise itself. Any arguments passed to `trace()` are
2809 // emitted in trace events. See `dojo/promise/tracer` on how
2810 // to handle traces.
2811 // returns: dojo/promise/Promise
2812 // The promise instance `trace()` is called on.
2814 var args
= lang
._toArray(arguments
);
2816 function(value
){ emitAsync(["resolved", value
].concat(args
)); },
2817 function(error
){ emitAsync(["rejected", error
].concat(args
)); },
2818 function(update
){ emitAsync(["progress", update
].concat(args
)); }
2823 Promise
.prototype.traceRejected = function(){
2825 // Trace rejection of the promise.
2827 // Tracing allows you to transparently log progress,
2828 // resolution and rejection of promises, without affecting the
2829 // promise itself. Any arguments passed to `trace()` are
2830 // emitted in trace events. See `dojo/promise/tracer` on how
2831 // to handle traces.
2832 // returns: dojo/promise/Promise
2833 // The promise instance `traceRejected()` is called on.
2835 var args
= lang
._toArray(arguments
);
2836 this.otherwise(function(error
){
2837 emitAsync(["rejected", error
].concat(args
));
2846 'dojo/errors/RequestError':function(){
2847 define(['./create'], function(create
){
2849 // dojo/errors/RequestError
2858 return create("RequestError", function(message
, response
){
2859 this.response
= response
;
2864 'dojo/_base/html':function(){
2865 define("dojo/_base/html", ["./kernel", "../dom", "../dom-style", "../dom-attr", "../dom-prop", "../dom-class", "../dom-construct", "../dom-geometry"], function(dojo
, dom
, style
, attr
, prop
, cls
, ctr
, geom
){
2872 // This module is a stub for the core dojo DOM API.
2877 dojo
.byId
= dom
.byId
;
2878 dojo
.isDescendant
= dom
.isDescendant
;
2879 dojo
.setSelectable
= dom
.setSelectable
;
2882 dojo
.getAttr
= attr
.get;
2883 dojo
.setAttr
= attr
.set;
2884 dojo
.hasAttr
= attr
.has
;
2885 dojo
.removeAttr
= attr
.remove
;
2886 dojo
.getNodeProp
= attr
.getNodeProp
;
2888 dojo
.attr = function(node
, name
, value
){
2890 // Gets or sets an attribute on an HTML element.
2892 // Handles normalized getting and setting of attributes on DOM
2893 // Nodes. If 2 arguments are passed, and a the second argument is a
2894 // string, acts as a getter.
2896 // If a third argument is passed, or if the second argument is a
2897 // map of attributes, acts as a setter.
2899 // When passing functions as values, note that they will not be
2900 // directly assigned to slots on the node, but rather the default
2901 // behavior will be removed and the new behavior will be added
2902 // using `dojo.connect()`, meaning that event handler properties
2903 // will be normalized and that some caveats with regards to
2904 // non-standard behaviors for onsubmit apply. Namely that you
2905 // should cancel form submission using `dojo.stopEvent()` on the
2906 // passed event object instead of returning a boolean value from
2907 // the handler itself.
2908 // node: DOMNode|String
2909 // id or reference to the element to get or set the attribute on
2910 // name: String|Object
2911 // the name of the attribute to get or set.
2913 // The value to set for the attribute
2915 // when used as a getter, the value of the requested attribute
2916 // or null if that attribute does not have a specified or
2919 // when used as a setter, the DOM node
2922 // | // get the current value of the "foo" attribute on a node
2923 // | dojo.attr(dojo.byId("nodeId"), "foo");
2924 // | // or we can just pass the id:
2925 // | dojo.attr("nodeId", "foo");
2928 // | // use attr() to set the tab index
2929 // | dojo.attr("nodeId", "tabIndex", 3);
2933 // Set multiple values at once, including event handlers:
2934 // | dojo.attr("formId", {
2936 // | "tabIndex": -1,
2937 // | "method": "POST",
2938 // | "onsubmit": function(e){
2939 // | // stop submitting the form. Note that the IE behavior
2940 // | // of returning true or false will have no effect here
2941 // | // since our handler is connect()ed to the built-in
2942 // | // onsubmit behavior and so we need to use
2943 // | // dojo.stopEvent() to ensure that the submission
2944 // | // doesn't proceed.
2945 // | dojo.stopEvent(e);
2947 // | // submit the form with Ajax
2948 // | dojo.xhrPost({ form: "formId" });
2953 // Style is s special case: Only set with an object hash of styles
2954 // | dojo.attr("someNode",{
2957 // | width:"200px", height:"100px", color:"#000"
2962 // Again, only set style as an object hash of styles:
2963 // | var obj = { color:"#fff", backgroundColor:"#000" };
2964 // | dojo.attr("someNode", "style", obj);
2966 // | // though shorter to use `dojo.style()` in this case:
2967 // | dojo.style("someNode", obj);
2969 if(arguments
.length
== 2){
2970 return attr
[typeof name
== "string" ? "get" : "set"](node
, name
);
2972 return attr
.set(node
, name
, value
);
2976 dojo
.hasClass
= cls
.contains
;
2977 dojo
.addClass
= cls
.add
;
2978 dojo
.removeClass
= cls
.remove
;
2979 dojo
.toggleClass
= cls
.toggle
;
2980 dojo
.replaceClass
= cls
.replace
;
2982 // mix-in dom-construct
2983 dojo
._toDom
= dojo
.toDom
= ctr
.toDom
;
2984 dojo
.place
= ctr
.place
;
2985 dojo
.create
= ctr
.create
;
2986 dojo
.empty = function(node
){ ctr
.empty(node
); };
2987 dojo
._destroyElement
= dojo
.destroy = function(node
){ ctr
.destroy(node
); };
2989 // mix-in dom-geometry
2990 dojo
._getPadExtents
= dojo
.getPadExtents
= geom
.getPadExtents
;
2991 dojo
._getBorderExtents
= dojo
.getBorderExtents
= geom
.getBorderExtents
;
2992 dojo
._getPadBorderExtents
= dojo
.getPadBorderExtents
= geom
.getPadBorderExtents
;
2993 dojo
._getMarginExtents
= dojo
.getMarginExtents
= geom
.getMarginExtents
;
2994 dojo
._getMarginSize
= dojo
.getMarginSize
= geom
.getMarginSize
;
2995 dojo
._getMarginBox
= dojo
.getMarginBox
= geom
.getMarginBox
;
2996 dojo
.setMarginBox
= geom
.setMarginBox
;
2997 dojo
._getContentBox
= dojo
.getContentBox
= geom
.getContentBox
;
2998 dojo
.setContentSize
= geom
.setContentSize
;
2999 dojo
._isBodyLtr
= dojo
.isBodyLtr
= geom
.isBodyLtr
;
3000 dojo
._docScroll
= dojo
.docScroll
= geom
.docScroll
;
3001 dojo
._getIeDocumentElementOffset
= dojo
.getIeDocumentElementOffset
= geom
.getIeDocumentElementOffset
;
3002 dojo
._fixIeBiDiScrollLeft
= dojo
.fixIeBiDiScrollLeft
= geom
.fixIeBiDiScrollLeft
;
3003 dojo
.position
= geom
.position
;
3005 dojo
.marginBox
= function marginBox(/*DomNode|String*/node
, /*Object?*/box
){
3007 // Getter/setter for the margin-box of node.
3009 // Getter/setter for the margin-box of node.
3010 // Returns an object in the expected format of box (regardless
3011 // if box is passed). The object might look like:
3012 // `{ l: 50, t: 200, w: 300: h: 150 }`
3013 // for a node offset from its parent 50px to the left, 200px from
3014 // the top with a margin width of 300px and a margin-height of
3017 // id or reference to DOM Node to get/set box for
3019 // If passed, denotes that dojo.marginBox() should
3020 // update/set the margin box for node. Box is an object in the
3021 // above format. All properties are optional if passed.
3023 // Retrieve the margin box of a passed node
3024 // | var box = dojo.marginBox("someNodeId");
3025 // | console.dir(box);
3028 // Set a node's margin box to the size of another node
3029 // | var box = dojo.marginBox("someNodeId");
3030 // | dojo.marginBox("someOtherNode", box);
3031 return box
? geom
.setMarginBox(node
, box
) : geom
.getMarginBox(node
); // Object
3034 dojo
.contentBox
= function contentBox(/*DomNode|String*/node
, /*Object?*/box
){
3036 // Getter/setter for the content-box of node.
3038 // Returns an object in the expected format of box (regardless if box is passed).
3039 // The object might look like:
3040 // `{ l: 50, t: 200, w: 300: h: 150 }`
3041 // for a node offset from its parent 50px to the left, 200px from
3042 // the top with a content width of 300px and a content-height of
3043 // 150px. Note that the content box may have a much larger border
3044 // or margin box, depending on the box model currently in use and
3045 // CSS values set/inherited for node.
3046 // While the getter will return top and left values, the
3047 // setter only accepts setting the width and height.
3049 // id or reference to DOM Node to get/set box for
3051 // If passed, denotes that dojo.contentBox() should
3052 // update/set the content box for node. Box is an object in the
3053 // above format, but only w (width) and h (height) are supported.
3054 // All properties are optional if passed.
3055 return box
? geom
.setContentSize(node
, box
) : geom
.getContentBox(node
); // Object
3058 dojo
.coords = function(/*DomNode|String*/node
, /*Boolean?*/includeScroll
){
3060 // Deprecated: Use position() for border-box x/y/w/h
3061 // or marginBox() for margin-box w/h/l/t.
3063 // Returns an object that measures margin-box (w)idth/(h)eight
3064 // and absolute position x/y of the border-box. Also returned
3065 // is computed (l)eft and (t)op values in pixels from the
3066 // node's offsetParent as returned from marginBox().
3067 // Return value will be in the form:
3068 //| { l: 50, t: 200, w: 300: h: 150, x: 100, y: 300 }
3069 // Does not act as a setter. If includeScroll is passed, the x and
3070 // y params are affected as one would expect in dojo.position().
3071 dojo
.deprecated("dojo.coords()", "Use dojo.position() or dojo.marginBox().");
3072 node
= dom
.byId(node
);
3073 var s
= style
.getComputedStyle(node
), mb
= geom
.getMarginBox(node
, s
);
3074 var abs
= geom
.position(node
, includeScroll
);
3077 return mb
; // Object
3081 dojo
.getProp
= prop
.get;
3082 dojo
.setProp
= prop
.set;
3084 dojo
.prop = function(/*DomNode|String*/node
, /*String|Object*/name
, /*String?*/value
){
3086 // Gets or sets a property on an HTML element.
3088 // Handles normalized getting and setting of properties on DOM
3089 // Nodes. If 2 arguments are passed, and a the second argument is a
3090 // string, acts as a getter.
3092 // If a third argument is passed, or if the second argument is a
3093 // map of attributes, acts as a setter.
3095 // When passing functions as values, note that they will not be
3096 // directly assigned to slots on the node, but rather the default
3097 // behavior will be removed and the new behavior will be added
3098 // using `dojo.connect()`, meaning that event handler properties
3099 // will be normalized and that some caveats with regards to
3100 // non-standard behaviors for onsubmit apply. Namely that you
3101 // should cancel form submission using `dojo.stopEvent()` on the
3102 // passed event object instead of returning a boolean value from
3103 // the handler itself.
3105 // id or reference to the element to get or set the property on
3107 // the name of the property to get or set.
3109 // The value to set for the property
3111 // when used as a getter, the value of the requested property
3112 // or null if that attribute does not have a specified or
3115 // when used as a setter, the DOM node
3118 // | // get the current value of the "foo" property on a node
3119 // | dojo.prop(dojo.byId("nodeId"), "foo");
3120 // | // or we can just pass the id:
3121 // | dojo.prop("nodeId", "foo");
3124 // | // use prop() to set the tab index
3125 // | dojo.prop("nodeId", "tabIndex", 3);
3129 // Set multiple values at once, including event handlers:
3130 // | dojo.prop("formId", {
3132 // | "tabIndex": -1,
3133 // | "method": "POST",
3134 // | "onsubmit": function(e){
3135 // | // stop submitting the form. Note that the IE behavior
3136 // | // of returning true or false will have no effect here
3137 // | // since our handler is connect()ed to the built-in
3138 // | // onsubmit behavior and so we need to use
3139 // | // dojo.stopEvent() to ensure that the submission
3140 // | // doesn't proceed.
3141 // | dojo.stopEvent(e);
3143 // | // submit the form with Ajax
3144 // | dojo.xhrPost({ form: "formId" });
3149 // Style is s special case: Only set with an object hash of styles
3150 // | dojo.prop("someNode",{
3153 // | width:"200px", height:"100px", color:"#000"
3158 // Again, only set style as an object hash of styles:
3159 // | var obj = { color:"#fff", backgroundColor:"#000" };
3160 // | dojo.prop("someNode", "style", obj);
3162 // | // though shorter to use `dojo.style()` in this case:
3163 // | dojo.style("someNode", obj);
3165 if(arguments
.length
== 2){
3166 return prop
[typeof name
== "string" ? "get" : "set"](node
, name
);
3169 return prop
.set(node
, name
, value
);
3173 dojo
.getStyle
= style
.get;
3174 dojo
.setStyle
= style
.set;
3175 dojo
.getComputedStyle
= style
.getComputedStyle
;
3176 dojo
.__toPixelValue
= dojo
.toPixelValue
= style
.toPixelValue
;
3178 dojo
.style = function(node
, name
, value
){
3180 // Accesses styles on a node. If 2 arguments are
3181 // passed, acts as a getter. If 3 arguments are passed, acts
3184 // Getting the style value uses the computed style for the node, so the value
3185 // will be a calculated value, not just the immediate node.style value.
3186 // Also when getting values, use specific style names,
3187 // like "borderBottomWidth" instead of "border" since compound values like
3188 // "border" are not necessarily reflected as expected.
3189 // If you want to get node dimensions, use `dojo.marginBox()`,
3190 // `dojo.contentBox()` or `dojo.position()`.
3191 // node: DOMNode|String
3192 // id or reference to node to get/set style for
3193 // name: String|Object?
3194 // the style property to set in DOM-accessor format
3195 // ("borderWidth", not "border-width") or an object with key/value
3196 // pairs suitable for setting each property.
3198 // If passed, sets value on the node for style, handling
3199 // cross-browser concerns. When setting a pixel value,
3200 // be sure to include "px" in the value. For instance, top: "200px".
3201 // Otherwise, in some cases, some browsers will not apply the style.
3203 // when used as a getter, return the computed style of the node if passing in an ID or node,
3204 // or return the normalized, computed value for the property when passing in a node and a style property
3206 // Passing only an ID or node returns the computed style object of
3208 // | dojo.style("thinger");
3210 // Passing a node and a style property returns the current
3211 // normalized, computed value for that property:
3212 // | dojo.style("thinger", "opacity"); // 1 by default
3215 // Passing a node, a style property, and a value changes the
3216 // current display of the node and returns the new computed value
3217 // | dojo.style("thinger", "opacity", 0.5); // == 0.5
3220 // Passing a node, an object-style style property sets each of the values in turn and returns the computed style object of the node:
3221 // | dojo.style("thinger", {
3222 // | "opacity": 0.5,
3223 // | "border": "3px solid black",
3224 // | "height": "300px"
3228 // When the CSS style property is hyphenated, the JavaScript property is camelCased.
3229 // font-size becomes fontSize, and so on.
3230 // | dojo.style("thinger",{
3231 // | fontSize:"14pt",
3232 // | letterSpacing:"1.2em"
3236 // dojo/NodeList implements .style() using the same syntax, omitting the "node" parameter, calling
3237 // dojo.style() on every element of the list. See: `dojo/query` and `dojo/NodeList`
3238 // | dojo.query(".someClassName").style("visibility","hidden");
3240 // | dojo.query("#baz > div").style({
3242 // | fontSize:"13pt"
3245 switch(arguments
.length
){
3247 return style
.get(node
);
3249 return style
[typeof name
== "string" ? "get" : "set"](node
, name
);
3252 return style
.set(node
, name
, value
);
3259 'dojo/_base/kernel':function(){
3260 define(["../has", "./config", "require", "module"], function(has
, config
, require
, module
){
3262 // dojo/_base/kernel
3264 // This module is the foundational module of the dojo boot sequence; it defines the dojo object.
3267 // loop variables for this module
3270 // create dojo, dijit, and dojox
3271 // FIXME: in 2.0 remove dijit, dojox being created by dojo
3276 // This module is the foundational module of the dojo boot sequence; it defines the dojo object.
3278 // notice dojo takes ownership of the value of the config module
3286 // Configure the scope map. For a 100% AMD application, the scope map is not needed other than to provide
3287 // a _scopeName property for the dojo, dijit, and dojox root object so those packages can create
3288 // unique names in the global space.
3290 // Built, legacy modules use the scope map to allow those modules to be expressed as if dojo, dijit, and dojox,
3291 // where global when in fact they are either global under different names or not global at all. In v1.6-, the
3292 // config variable "scopeMap" was used to map names as used within a module to global names. This has been
3293 // subsumed by the AMD map configuration variable which can relocate packages to different names. For backcompat,
3294 // only the "*" mapping is supported. See http://livedocs.dojotoolkit.org/developer/design/loader#legacy-cross-domain-mode for details.
3296 // The following computations contort the packageMap for this dojo instance into a scopeMap.
3298 // a map from a name used in a legacy module to the (global variable name, object addressed by that name)
3299 // always map dojo, dijit, and dojox
3301 dojo
:["dojo", dojo
],
3302 dijit
:["dijit", dijit
],
3303 dojox
:["dojox", dojox
]
3307 // the package map for this dojo instance; note, a foreign loader or no pacakgeMap results in the above default config
3308 (require
.map
&& require
.map
[module
.id
.match(/[^\/]+/)[0]]),
3313 // process all mapped top-level names for this instance of dojo
3314 for(p
in packageMap
){
3316 // mapped dojo, dijit, or dojox
3317 scopeMap
[p
][0] = packageMap
[p
];
3319 // some other top-level name
3320 scopeMap
[p
] = [packageMap
[p
], {}];
3324 // publish those names to _scopeName and, optionally, the global namespace
3327 item
[1]._scopeName
= item
[0];
3328 if(!config
.noGlobals
){
3329 this[item
[0]] = item
[1];
3332 dojo
.scopeMap
= scopeMap
;
3334 /*===== dojo.__docParserConfigureScopeMap(scopeMap); =====*/
3336 // FIXME: dojo.baseUrl and dojo.config.baseUrl should be deprecated
3337 dojo
.baseUrl
= dojo
.config
.baseUrl
= require
.baseUrl
;
3338 dojo
.isAsync
= ! 1 || require
.async
;
3339 dojo
.locale
= config
.locale
;
3341 var rev
= "$Rev: 30226 $".match(/\d+/);
3344 // Version number of the Dojo Toolkit
3346 // Hash about the version, including
3348 // - major: Integer: Major version. If total version is "1.2.0beta1", will be 1
3349 // - minor: Integer: Minor version. If total version is "1.2.0beta1", will be 2
3350 // - patch: Integer: Patch version. If total version is "1.2.0beta1", will be 0
3351 // - flag: String: Descriptor flag. If total version is "1.2.0beta1", will be "beta1"
3352 // - revision: Number: The SVN rev from which dojo was pulled
3354 major
: 1, minor
: 8, patch
: 3, flag
: "",
3355 revision
: rev
? +rev
[0] : NaN
,
3356 toString: function(){
3357 var v
= dojo
.version
;
3358 return v
.major
+ "." + v
.minor
+ "." + v
.patch
+ v
.flag
+ " (" + v
.revision
+ ")"; // String
3362 // If 1 is truthy, then as a dojo module is defined it should push it's definitions
3363 // into the dojo object, and conversely. In 2.0, it will likely be unusual to augment another object
3364 // as a result of defining a module. This has feature gives a way to force 2.0 behavior as the code
3365 // is migrated. Absent specific advice otherwise, set extend-dojo to truthy.
3366 1 || has
.add("extend-dojo", 1);
3369 (Function("d", "d.eval = function(){return d.global.eval ? d.global.eval(arguments[0]) : eval(arguments[0]);}"))(dojo
);
3371 dojo.eval = function(scriptText){
3373 // A legacy method created for use exclusively by internal Dojo methods. Do not use this method
3374 // directly unless you understand its possibly-different implications on the platforms your are targeting.
3376 // Makes an attempt to evaluate scriptText in the global scope. The function works correctly for browsers
3377 // that support indirect eval.
3379 // As usual, IE does not. On IE, the only way to implement global eval is to
3380 // use execScript. Unfortunately, execScript does not return a value and breaks some current usages of dojo.eval.
3381 // This implementation uses the technique of executing eval in the scope of a function that is a single scope
3382 // frame below the global scope; thereby coming close to the global scope. Note carefully that
3384 // dojo.eval("var pi = 3.14;");
3386 // will define global pi in non-IE environments, but define pi only in a temporary local scope for IE. If you want
3387 // to define a global variable using dojo.eval, write something like
3389 // dojo.eval("window.pi = 3.14;")
3391 // The text to evaluation.
3393 // The result of the evaluation. Often `undefined`
3399 dojo
.exit = function(exitcode
){
3403 dojo
.exit = function(){
3407 1 || has
.add("dojo-guarantee-console",
3408 // ensure that console.log, console.warn, etc. are defined
3412 typeof console
!= "undefined" || (console
= {});
3413 // Be careful to leave 'log' always at the end
3415 "assert", "count", "debug", "dir", "dirxml", "error", "group",
3416 "groupEnd", "info", "profile", "profileEnd", "time", "timeEnd",
3417 "trace", "warn", "log"
3421 while((tn
= cn
[i
++])){
3425 console
[tcn
] = ('log' in console
) ? function(){
3426 var a
= Array
.apply({}, arguments
);
3427 a
.unshift(tcn
+ ":");
3428 console
["log"](a
.join(" "));
3430 console
[tcn
]._fake
= true;
3436 has
.add("dojo-debug-messages",
3437 // include dojo.deprecated/dojo.experimental implementations
3440 dojo
.deprecated
= dojo
.experimental = function(){};
3441 if(has("dojo-debug-messages")){
3442 dojo
.deprecated = function(/*String*/ behaviour
, /*String?*/ extra
, /*String?*/ removal
){
3444 // Log a debug message to indicate that a behavior has been
3446 // behaviour: String
3447 // The API or behavior being deprecated. Usually in the form
3448 // of "myApp.someFunction()".
3450 // Text to append to the message. Often provides advice on a
3451 // new function or facility to achieve the same goal during
3452 // the deprecation period.
3454 // Text to indicate when in the future the behavior will be
3455 // removed. Usually a version number.
3457 // | dojo.deprecated("myApp.getTemp()", "use myApp.getLocaleTemp() instead", "1.0");
3459 var message
= "DEPRECATED: " + behaviour
;
3460 if(extra
){ message
+= " " + extra
; }
3461 if(removal
){ message
+= " -- will be removed in version: " + removal
; }
3462 console
.warn(message
);
3465 dojo
.experimental = function(/* String */ moduleName
, /* String? */ extra
){
3467 // Marks code as experimental.
3469 // This can be used to mark a function, file, or module as
3470 // experimental. Experimental code is not ready to be used, and the
3471 // APIs are subject to change without notice. Experimental code may be
3472 // completed deleted without going through the normal deprecation
3474 // moduleName: String
3475 // The name of a module, or the name of a module file or a specific
3478 // some additional message for the user
3480 // | dojo.experimental("dojo.data.Result");
3482 // | dojo.experimental("dojo.weather.toKelvin()", "PENDING approval from NOAA");
3484 var message
= "EXPERIMENTAL: " + moduleName
+ " -- APIs subject to change without notice.";
3485 if(extra
){ message
+= " " + extra
; }
3486 console
.warn(message
);
3490 1 || has
.add("dojo-modulePaths",
3491 // consume dojo.modulePaths processing
3495 // notice that modulePaths won't be applied to any require's before the dojo/_base/kernel factory is run;
3496 // this is the v1.6- behavior.
3497 if(config
.modulePaths
){
3498 dojo
.deprecated("dojo.modulePaths", "use paths configuration");
3500 for(p
in config
.modulePaths
){
3501 paths
[p
.replace(/\./g, "/")] = config
.modulePaths
[p
];
3503 require({paths
:paths
});
3507 1 || has
.add("dojo-moduleUrl",
3508 // include dojo.moduleUrl
3512 dojo
.moduleUrl = function(/*String*/module
, /*String?*/url
){
3514 // Returns a URL relative to a module.
3516 // | var pngPath = dojo.moduleUrl("acme","images/small.png");
3517 // | console.dir(pngPath); // list the object properties
3518 // | // create an image and set it's source to pngPath's value:
3519 // | var img = document.createElement("img");
3520 // | img.src = pngPath;
3521 // | // add our image to the document
3522 // | dojo.body().appendChild(img);
3524 // you may de-reference as far as you like down the package
3525 // hierarchy. This is sometimes handy to avoid lenghty relative
3526 // urls or for building portable sub-packages. In this example,
3527 // the `acme.widget` and `acme.util` directories may be located
3528 // under different roots (see `dojo.registerModulePath`) but the
3529 // the modules which reference them can be unaware of their
3530 // relative locations on the filesystem:
3531 // | // somewhere in a configuration block
3532 // | dojo.registerModulePath("acme.widget", "../../acme/widget");
3533 // | dojo.registerModulePath("acme.util", "../../util");
3537 // | // code in a module using acme resources
3538 // | var tmpltPath = dojo.moduleUrl("acme.widget","templates/template.html");
3539 // | var dataPath = dojo.moduleUrl("acme.util","resources/data.json");
3541 dojo
.deprecated("dojo.moduleUrl()", "use require.toUrl", "2.0");
3543 // require.toUrl requires a filetype; therefore, just append the suffix "/*.*" to guarantee a filetype, then
3544 // remove the suffix from the result. This way clients can request a url w/out a filetype. This should be
3545 // rare, but it maintains backcompat for the v1.x line (note: dojo.moduleUrl will be removed in v2.0).
3546 // Notice * is an illegal filename so it won't conflict with any real path map that may exist the paths config.
3549 result
= require
.toUrl(module
.replace(/\./g, "/") + (url
? ("/" + url
) : "") + "/*.*").replace(/\/\*\.\*/, "") + (url
? "" : "/");
3555 dojo
._hasResource
= {}; // for backward compatibility with layers built with 1.6 tooling
3561 'dojo/io-query':function(){
3562 define(["./_base/lang"], function(lang
){
3571 // This module defines query string processing functions.
3573 objectToQuery
: function objectToQuery(/*Object*/ map
){
3575 // takes a name/value mapping object and returns a string representing
3576 // a URL-encoded version of that object.
3588 // yields the following query string:
3590 // | "blah=blah&multi=thud&multi=thonk"
3592 // FIXME: need to implement encodeAscii!!
3593 var enc
= encodeURIComponent
, pairs
= [];
3594 for(var name
in map
){
3595 var value
= map
[name
];
3596 if(value
!= backstop
[name
]){
3597 var assign
= enc(name
) + "=";
3598 if(lang
.isArray(value
)){
3599 for(var i
= 0, l
= value
.length
; i
< l
; ++i
){
3600 pairs
.push(assign
+ enc(value
[i
]));
3603 pairs
.push(assign
+ enc(value
));
3607 return pairs
.join("&"); // String
3610 queryToObject
: function queryToObject(/*String*/ str
){
3612 // Create an object representing a de-serialized query section of a
3613 // URL. Query keys with multiple values are returned in an array.
3618 // | "foo=bar&foo=baz&thinger=%20spaces%20=blah&zonk=blarg&"
3620 // results in this object structure:
3623 // | foo: [ "bar", "baz" ],
3624 // | thinger: " spaces =blah",
3628 // Note that spaces and other urlencoded entities are correctly
3631 // FIXME: should we grab the URL string if we're not passed one?
3632 var dec
= decodeURIComponent
, qp
= str
.split("&"), ret
= {}, name
, val
;
3633 for(var i
= 0, l
= qp
.length
, item
; i
< l
; ++i
){
3636 var s
= item
.indexOf("=");
3641 name
= dec(item
.slice(0, s
));
3642 val
= dec(item
.slice(s
+ 1));
3644 if(typeof ret
[name
] == "string"){ // inline'd type check
3645 ret
[name
] = [ret
[name
]];
3648 if(lang
.isArray(ret
[name
])){
3649 ret
[name
].push(val
);
3655 return ret
; // Object
3660 'dojo/_base/Deferred':function(){
3664 "../promise/Promise",
3665 "../errors/CancelError",
3669 ], function(dojo
, NewDeferred
, Promise
, CancelError
, has
, lang
, when
){
3671 // dojo/_base/Deferred
3673 var mutator = function(){};
3674 var freeze
= Object
.freeze
|| function(){};
3675 // A deferred provides an API for creating and resolving a promise.
3676 var Deferred
= dojo
.Deferred = function(/*Function?*/ canceller
){
3678 // Deprecated. This module defines the legacy dojo/_base/Deferred API.
3679 // New code should use dojo/Deferred instead.
3681 // The Deferred API is based on the concept of promises that provide a
3682 // generic interface into the eventual completion of an asynchronous action.
3683 // The motivation for promises fundamentally is about creating a
3684 // separation of concerns that allows one to achieve the same type of
3685 // call patterns and logical data flow in asynchronous code as can be
3686 // achieved in synchronous code. Promises allows one
3687 // to be able to call a function purely with arguments needed for
3688 // execution, without conflating the call with concerns of whether it is
3689 // sync or async. One shouldn't need to alter a call's arguments if the
3690 // implementation switches from sync to async (or vice versa). By having
3691 // async functions return promises, the concerns of making the call are
3692 // separated from the concerns of asynchronous interaction (which are
3693 // handled by the promise).
3695 // The Deferred is a type of promise that provides methods for fulfilling the
3696 // promise with a successful result or an error. The most important method for
3697 // working with Dojo's promises is the then() method, which follows the
3698 // CommonJS proposed promise API. An example of using a Dojo promise:
3700 // | var resultingPromise = someAsyncOperation.then(function(result){
3701 // | ... handle result ...
3703 // | function(error){
3704 // | ... handle error ...
3707 // The .then() call returns a new promise that represents the result of the
3708 // execution of the callback. The callbacks will never affect the original promises value.
3710 // The Deferred instances also provide the following functions for backwards compatibility:
3712 // - addCallback(handler)
3713 // - addErrback(handler)
3714 // - callback(result)
3715 // - errback(result)
3717 // Callbacks are allowed to return promises themselves, so
3718 // you can build complicated sequences of events with ease.
3720 // The creator of the Deferred may specify a canceller. The canceller
3721 // is a function that will be called if Deferred.cancel is called
3722 // before the Deferred fires. You can use this to implement clean
3723 // aborting of an XMLHttpRequest, etc. Note that cancel will fire the
3724 // deferred with a CancelledError (unless your canceller returns
3725 // another kind of error), so the errbacks should be prepared to
3726 // handle that error for cancellable Deferreds.
3728 // | var deferred = new Deferred();
3729 // | setTimeout(function(){ deferred.callback({success: true}); }, 1000);
3730 // | return deferred;
3732 // Deferred objects are often used when making code asynchronous. It
3733 // may be easiest to write functions in a synchronous manner and then
3734 // split code using a deferred to trigger a response to a long-lived
3735 // operation. For example, instead of register a callback function to
3736 // denote when a rendering operation completes, the function can
3737 // simply return a deferred:
3739 // | // callback style:
3740 // | function renderLotsOfData(data, callback){
3741 // | var success = false
3743 // | for(var x in data){
3744 // | renderDataitem(data[x]);
3746 // | success = true;
3749 // | callback(success);
3753 // | // using callback style
3754 // | renderLotsOfData(someDataObj, function(success){
3755 // | // handles success or failure
3757 // | promptUserToRecover();
3760 // | // NOTE: no way to add another callback here!!
3762 // Using a Deferred doesn't simplify the sending code any, but it
3763 // provides a standard interface for callers and senders alike,
3764 // providing both with a simple way to service multiple callbacks for
3765 // an operation and freeing both sides from worrying about details
3766 // such as "did this get called already?". With Deferreds, new
3767 // callbacks can be added at any time.
3769 // | // Deferred style:
3770 // | function renderLotsOfData(data){
3771 // | var d = new Deferred();
3773 // | for(var x in data){
3774 // | renderDataitem(data[x]);
3776 // | d.callback(true);
3778 // | d.errback(new Error("rendering failed"));
3783 // | // using Deferred style
3784 // | renderLotsOfData(someDataObj).then(null, function(){
3785 // | promptUserToRecover();
3787 // | // NOTE: addErrback and addCallback both return the Deferred
3788 // | // again, so we could chain adding callbacks or save the
3789 // | // deferred for later should we need to be notified again.
3791 // In this example, renderLotsOfData is synchronous and so both
3792 // versions are pretty artificial. Putting the data display on a
3793 // timeout helps show why Deferreds rock:
3795 // | // Deferred style and async func
3796 // | function renderLotsOfData(data){
3797 // | var d = new Deferred();
3798 // | setTimeout(function(){
3800 // | for(var x in data){
3801 // | renderDataitem(data[x]);
3803 // | d.callback(true);
3805 // | d.errback(new Error("rendering failed"));
3811 // | // using Deferred style
3812 // | renderLotsOfData(someDataObj).then(null, function(){
3813 // | promptUserToRecover();
3816 // Note that the caller doesn't have to change his code at all to
3817 // handle the asynchronous case.
3819 var result
, finished
, isError
, head
, nextListener
;
3820 var promise
= (this.promise
= new Promise());
3822 function complete(value
){
3824 throw new Error("This deferred has already been resolved");
3832 while(!mutated
&& nextListener
){
3833 var listener
= nextListener
;
3834 nextListener
= nextListener
.next
;
3835 if((mutated
= (listener
.progress
== mutator
))){ // assignment and check
3839 var func
= (isError
? listener
.error
: listener
.resolved
);
3840 if(has("config-useDeferredInstrumentation")){
3841 if(isError
&& NewDeferred
.instrumentRejected
){
3842 NewDeferred
.instrumentRejected(result
, !!func
);
3847 var newResult
= func(result
);
3848 if (newResult
&& typeof newResult
.then
=== "function"){
3849 newResult
.then(lang
.hitch(listener
.deferred
, "resolve"), lang
.hitch(listener
.deferred
, "reject"), lang
.hitch(listener
.deferred
, "progress"));
3852 var unchanged
= mutated
&& newResult
=== undefined;
3853 if(mutated
&& !unchanged
){
3854 isError
= newResult
instanceof Error
;
3856 listener
.deferred
[unchanged
&& isError
? "reject" : "resolve"](unchanged
? result
: newResult
);
3858 listener
.deferred
.reject(e
);
3862 listener
.deferred
.reject(result
);
3864 listener
.deferred
.resolve(result
);
3869 // calling resolve will resolve the promise
3870 this.resolve
= this.callback = function(value
){
3872 // Fulfills the Deferred instance successfully with the provide value
3874 this.results
= [value
, null];
3879 // calling error will indicate that the promise failed
3880 this.reject
= this.errback = function(error
){
3882 // Fulfills the Deferred instance as an error with the provided error
3885 if(has("config-useDeferredInstrumentation")){
3886 if(NewDeferred
.instrumentRejected
){
3887 NewDeferred
.instrumentRejected(error
, !!nextListener
);
3891 this.results
= [null, error
];
3893 // call progress to provide updates on the progress on the completion of the promise
3894 this.progress = function(update
){
3896 // Send progress events to all listeners
3897 var listener
= nextListener
;
3899 var progress
= listener
.progress
;
3900 progress
&& progress(update
);
3901 listener
= listener
.next
;
3904 this.addCallbacks = function(callback
, errback
){
3906 // Adds callback and error callback for this deferred instance.
3907 // callback: Function?
3908 // The callback attached to this deferred object.
3909 // errback: Function?
3910 // The error callback attached to this deferred object.
3912 // Returns this deferred object.
3913 this.then(callback
, errback
, mutator
);
3914 return this; // Deferred
3916 // provide the implementation of the promise
3917 promise
.then
= this.then = function(/*Function?*/resolvedCallback
, /*Function?*/errorCallback
, /*Function?*/progressCallback
){
3919 // Adds a fulfilledHandler, errorHandler, and progressHandler to be called for
3920 // completion of a promise. The fulfilledHandler is called when the promise
3921 // is fulfilled. The errorHandler is called when a promise fails. The
3922 // progressHandler is called for progress events. All arguments are optional
3923 // and non-function values are ignored. The progressHandler is not only an
3924 // optional argument, but progress events are purely optional. Promise
3925 // providers are not required to ever create progress events.
3927 // This function will return a new promise that is fulfilled when the given
3928 // fulfilledHandler or errorHandler callback is finished. This allows promise
3929 // operations to be chained together. The value returned from the callback
3930 // handler is the fulfillment value for the returned promise. If the callback
3931 // throws an error, the returned promise will be moved to failed state.
3934 // Returns a new promise that represents the result of the
3935 // execution of the callback. The callbacks will never affect the original promises value.
3937 // An example of using a CommonJS compliant promise:
3938 // | asyncComputeTheAnswerToEverything().
3940 // | then(printResult, onError);
3943 var returnDeferred
= progressCallback
== mutator
? this : new Deferred(promise
.cancel
);
3945 resolved
: resolvedCallback
,
3946 error
: errorCallback
,
3947 progress
: progressCallback
,
3948 deferred
: returnDeferred
3951 head
= head
.next
= listener
;
3954 nextListener
= head
= listener
;
3959 return returnDeferred
.promise
; // Promise
3961 var deferred
= this;
3962 promise
.cancel
= this.cancel = function(){
3964 // Cancels the asynchronous operation
3966 var error
= canceller
&& canceller(deferred
);
3968 if (!(error
instanceof Error
)){
3969 error
= new CancelError(error
);
3972 deferred
.reject(error
);
3978 lang
.extend(Deferred
, {
3979 addCallback: function(/*Function*/ callback
){
3981 // Adds successful callback for this deferred instance.
3983 // Returns this deferred object.
3984 return this.addCallbacks(lang
.hitch
.apply(dojo
, arguments
)); // Deferred
3987 addErrback: function(/*Function*/ errback
){
3989 // Adds error callback for this deferred instance.
3991 // Returns this deferred object.
3992 return this.addCallbacks(null, lang
.hitch
.apply(dojo
, arguments
)); // Deferred
3995 addBoth: function(/*Function*/ callback
){
3997 // Add handler as both successful callback and error callback for this deferred instance.
3999 // Returns this deferred object.
4000 var enclosed
= lang
.hitch
.apply(dojo
, arguments
);
4001 return this.addCallbacks(enclosed
, enclosed
); // Deferred
4006 Deferred
.when
= dojo
.when
= when
;
4012 'dojo/NodeList-dom':function(){
4013 define(["./_base/kernel", "./query", "./_base/array", "./_base/lang", "./dom-class", "./dom-construct", "./dom-geometry", "./dom-attr", "./dom-style"], function(dojo
, query
, array
, lang
, domCls
, domCtr
, domGeom
, domAttr
, domStyle
){
4016 // dojo/NodeList-dom.js
4021 // Adds DOM related methods to NodeList, and returns NodeList constructor.
4025 var magicGuard = function(a
){
4027 // the guard function for dojo.attr() and dojo.style()
4028 return a
.length
== 1 && (typeof a
[0] == "string"); // inline'd type check
4031 var orphan = function(node
){
4033 // function to orphan nodes
4034 var p
= node
.parentNode
;
4036 p
.removeChild(node
);
4039 // FIXME: should we move orphan() to dojo.html?
4041 var NodeList
= query
.NodeList
,
4042 awc
= NodeList
._adaptWithCondition
,
4043 aafe
= NodeList
._adaptAsForEach
,
4044 aam
= NodeList
._adaptAsMap
;
4046 function getSet(module
){
4047 return function(node
, name
, value
){
4048 if(arguments
.length
== 2){
4049 return module
[typeof name
== "string" ? "get" : "set"](node
, name
);
4052 return module
.set(node
, name
, value
);
4056 lang
.extend(NodeList
, {
4057 _normalize: function(/*String||Element||Object||NodeList*/content
, /*DOMNode?*/refNode
){
4059 // normalizes data to an array of items to insert.
4061 // If content is an object, it can have special properties "template" and
4062 // "parse". If "template" is defined, then the template value is run through
4063 // dojo.string.substitute (if dojo/string.substitute() has been dojo.required elsewhere),
4064 // or if templateFunc is a function on the content, that function will be used to
4065 // transform the template into a final string to be used for for passing to dojo/dom-construct.toDom().
4066 // If content.parse is true, then it is remembered for later, for when the content
4067 // nodes are inserted into the DOM. At that point, the nodes will be parsed for widgets
4068 // (if dojo.parser has been dojo.required elsewhere).
4070 //Wanted to just use a DocumentFragment, but for the array/NodeList
4071 //case that meant using cloneNode, but we may not want that.
4072 //Cloning should only happen if the node operations span
4073 //multiple refNodes. Also, need a real array, not a NodeList from the
4074 //DOM since the node movements could change those NodeLists.
4076 var parse
= content
.parse
=== true;
4078 //Do we have an object that needs to be run through a template?
4079 if(typeof content
.template
== "string"){
4080 var templateFunc
= content
.templateFunc
|| (dojo
.string
&& dojo
.string
.substitute
);
4081 content
= templateFunc
? templateFunc(content
.template
, content
) : content
;
4084 var type
= (typeof content
);
4085 if(type
== "string" || type
== "number"){
4086 content
= domCtr
.toDom(content
, (refNode
&& refNode
.ownerDocument
));
4087 if(content
.nodeType
== 11){
4088 //DocumentFragment. It cannot handle cloneNode calls, so pull out the children.
4089 content
= lang
._toArray(content
.childNodes
);
4091 content
= [content
];
4093 }else if(!lang
.isArrayLike(content
)){
4094 content
= [content
];
4095 }else if(!lang
.isArray(content
)){
4096 //To get to this point, content is array-like, but
4097 //not an array, which likely means a DOM NodeList. Convert it now.
4098 content
= lang
._toArray(content
);
4101 //Pass around the parse info
4103 content
._runParse
= true;
4105 return content
; //Array
4108 _cloneNode: function(/*DOMNode*/ node
){
4110 // private utility to clone a node. Not very interesting in the vanilla
4111 // dojo/NodeList case, but delegates could do interesting things like
4112 // clone event handlers if that is derivable from the node.
4113 return node
.cloneNode(true);
4116 _place: function(/*Array*/ary
, /*DOMNode*/refNode
, /*String*/position
, /*Boolean*/useClone
){
4118 // private utility to handle placing an array of nodes relative to another node.
4120 // Allows for cloning the nodes in the array, and for
4121 // optionally parsing widgets, if ary._runParse is true.
4123 //Avoid a disallowed operation if trying to do an innerHTML on a non-element node.
4124 if(refNode
.nodeType
!= 1 && position
== "only"){
4127 var rNode
= refNode
, tempNode
;
4129 //Always cycle backwards in case the array is really a
4130 //DOM NodeList and the DOM operations take it out of the live collection.
4131 var length
= ary
.length
;
4132 for(var i
= length
- 1; i
>= 0; i
--){
4133 var node
= (useClone
? this._cloneNode(ary
[i
]) : ary
[i
]);
4135 //If need widget parsing, use a temp node, instead of waiting after inserting into
4136 //real DOM because we need to start widget parsing at one node up from current node,
4137 //which could cause some already parsed widgets to be parsed again.
4138 if(ary
._runParse
&& dojo
.parser
&& dojo
.parser
.parse
){
4140 tempNode
= rNode
.ownerDocument
.createElement("div");
4142 tempNode
.appendChild(node
);
4143 dojo
.parser
.parse(tempNode
);
4144 node
= tempNode
.firstChild
;
4145 while(tempNode
.firstChild
){
4146 tempNode
.removeChild(tempNode
.firstChild
);
4150 if(i
== length
- 1){
4151 domCtr
.place(node
, rNode
, position
);
4153 rNode
.parentNode
.insertBefore(node
, rNode
);
4160 position
: aam(domGeom
.position
),
4162 position: function(){
4164 // Returns border-box objects (x/y/w/h) of all elements in a node list
4165 // as an Array (*not* a NodeList). Acts like `dojo.position`, though
4166 // assumes the node passed is each node in this list.
4168 return dojo.map(this, dojo.position); // Array
4172 attr
: awc(getSet(domAttr
), magicGuard
),
4174 attr: function(property, value){
4176 // gets or sets the DOM attribute for every element in the
4177 // NodeList. See also `dojo.attr`
4179 // the attribute to get/set
4181 // optional. The value to set the property to
4183 // if no value is passed, the result is an array of attribute values
4184 // If a value is passed, the return is this NodeList
4186 // Make all nodes with a particular class focusable:
4187 // | dojo.query(".focusable").attr("tabIndex", -1);
4189 // Disable a group of buttons:
4190 // | dojo.query("button.group").attr("disabled", true);
4192 // innerHTML can be assigned or retrieved as well:
4193 // | // get the innerHTML (as an array) for each list item
4194 // | var ih = dojo.query("li.replaceable").attr("innerHTML");
4195 return; // dojo/NodeList|Array
4199 style
: awc(getSet(domStyle
), magicGuard
),
4201 style: function(property, value){
4203 // gets or sets the CSS property for every element in the NodeList
4205 // the CSS property to get/set, in JavaScript notation
4206 // ("lineHieght" instead of "line-height")
4208 // optional. The value to set the property to
4210 // if no value is passed, the result is an array of strings.
4211 // If a value is passed, the return is this NodeList
4212 return; // dojo/NodeList
4217 addClass
: aafe(domCls
.add
),
4219 addClass: function(className){
4221 // adds the specified class to every node in the list
4222 // className: String|Array
4223 // A String class name to add, or several space-separated class names,
4224 // or an array of class names.
4225 return; // dojo/NodeList
4229 removeClass
: aafe(domCls
.remove
),
4231 removeClass: function(className){
4233 // removes the specified class from every node in the list
4234 // className: String|Array?
4235 // An optional String class name to remove, or several space-separated
4236 // class names, or an array of class names. If omitted, all class names
4240 return; // dojo/NodeList
4244 toggleClass
: aafe(domCls
.toggle
),
4246 toggleClass: function(className, condition){
4248 // Adds a class to node if not present, or removes if present.
4249 // Pass a boolean condition if you want to explicitly add or remove.
4250 // condition: Boolean?
4251 // If passed, true means to add the class, false means to remove.
4252 // className: String
4253 // the CSS class to add
4254 return; // dojo/NodeList
4258 replaceClass
: aafe(domCls
.replace
),
4260 replaceClass: function(addClassStr, removeClassStr){
4262 // Replaces one or more classes on a node if not present.
4263 // Operates more quickly than calling `removeClass()` and `addClass()`
4264 // addClassStr: String|Array
4265 // A String class name to add, or several space-separated class names,
4266 // or an array of class names.
4267 // removeClassStr: String|Array?
4268 // A String class name to remove, or several space-separated class names,
4269 // or an array of class names.
4270 return; // dojo/NodeList
4274 empty
: aafe(domCtr
.empty
),
4278 // clears all content from each node in the list. Effectively
4279 // equivalent to removing all child nodes from every item in
4281 return this.forEach("item.innerHTML='';"); // dojo/NodeList
4282 // FIXME: should we be checking for and/or disposing of widgets below these nodes?
4286 removeAttr
: aafe(domAttr
.remove
),
4288 removeAttr: function(name){
4290 // Removes an attribute from each node in the list.
4292 // the name of the attribute to remove
4293 return; // dojo/NodeList
4297 marginBox
: aam(domGeom
.getMarginBox
),
4299 marginBox: function(){
4301 // Returns margin-box size of nodes
4302 return; // dojo/NodeList
4306 // FIXME: connectPublisher()? connectRunOnce()?
4309 destroy: function(){
4311 // destroys every item in the list.
4312 this.forEach(d.destroy);
4313 // FIXME: should we be checking for and/or disposing of widgets below these nodes?
4317 place: function(/*String||Node*/ queryOrNode
, /*String*/ position
){
4319 // places elements of this node list relative to the first element matched
4320 // by queryOrNode. Returns the original NodeList. See: `dojo.place`
4322 // may be a string representing any valid CSS3 selector or a DOM node.
4323 // In the selector case, only the first matching element will be used
4324 // for relative positioning.
4328 // - "last" (default)
4335 // or an offset in the childNodes property
4336 var item
= query(queryOrNode
)[0];
4337 return this.forEach(function(node
){ domCtr
.place(node
, item
, position
); }); // dojo/NodeList
4340 orphan: function(/*String?*/ filter
){
4342 // removes elements in this list that match the filter
4343 // from their parents and returns them as a new NodeList.
4345 // CSS selector like ".foo" or "div > span"
4347 // NodeList containing the orphaned elements
4348 return (filter
? query
._filterResult(this, filter
) : this).forEach(orphan
); // dojo/NodeList
4351 adopt: function(/*String||Array||DomNode*/ queryOrListOrNode
, /*String?*/ position
){
4353 // places any/all elements in queryOrListOrNode at a
4354 // position relative to the first element in this list.
4355 // Returns a dojo/NodeList of the adopted elements.
4356 // queryOrListOrNode:
4357 // a DOM node or a query string or a query result.
4358 // Represents the nodes to be adopted relative to the
4359 // first element of this NodeList.
4363 // - "last" (default)
4370 // or an offset in the childNodes property
4371 return query(queryOrListOrNode
).place(this[0], position
)._stash(this); // dojo/NodeList
4374 // FIXME: do we need this?
4375 query: function(/*String*/ queryStr
){
4377 // Returns a new list whose members match the passed query,
4378 // assuming elements of the current NodeList as the root for
4381 // assume a DOM created by this markup:
4384 // | bacon is tasty, <span>dontcha think?</span>
4388 // | <p>great comedians may not be funny <span>in person</span></p>
4390 // If we are presented with the following definition for a NodeList:
4391 // | var l = new NodeList(dojo.byId("foo"), dojo.byId("bar"));
4392 // it's possible to find all span elements under paragraphs
4393 // contained by these elements with this sub-query:
4394 // | var spans = l.query("p span");
4396 // FIXME: probably slow
4397 if(!queryStr
){ return this; }
4398 var ret
= new NodeList
;
4399 this.map(function(node
){
4400 // FIXME: why would we ever get undefined here?
4401 query(queryStr
, node
).forEach(function(subNode
){
4402 if(subNode
!== undefined){
4407 return ret
._stash(this); // dojo/NodeList
4410 filter: function(/*String|Function*/ filter
){
4412 // "masks" the built-in javascript filter() method (supported
4413 // in Dojo via `dojo.filter`) to support passing a simple
4414 // string filter in addition to supporting filtering function
4417 // If a string, a CSS rule like ".thinger" or "div > span".
4419 // "regular" JS filter syntax as exposed in dojo.filter:
4420 // | dojo.query("*").filter(function(item){
4421 // | // highlight every paragraph
4422 // | return (item.nodeName == "p");
4423 // | }).style("backgroundColor", "yellow");
4425 // the same filtering using a CSS selector
4426 // | dojo.query("*").filter("p").styles("backgroundColor", "yellow");
4428 var a
= arguments
, items
= this, start
= 0;
4429 if(typeof filter
== "string"){ // inline'd type check
4430 items
= query
._filterResult(this, a
[0]);
4432 // if we only got a string query, pass back the filtered results
4433 return items
._stash(this); // dojo/NodeList
4435 // if we got a callback, run it over the filtered items
4438 return this._wrap(array
.filter(items
, a
[start
], a
[start
+ 1]), this); // dojo/NodeList
4442 // FIXME: should this be "copyTo" and include parenting info?
4445 // creates node clones of each element of this list
4446 // and returns a new list containing the clones
4450 addContent: function(/*String||DomNode||Object||dojo/NodeList*/ content, /*String||Integer?*/ position
){
4452 // add a node, NodeList or some HTML as a string to every item in the
4453 // list. Returns the original list.
4455 // a copy of the HTML content is added to each item in the
4456 // list, with an optional position argument. If no position
4457 // argument is provided, the content is appended to the end of
4460 // DOM node, HTML in string format, a NodeList or an Object. If a DOM node or
4461 // NodeList, the content will be cloned if the current NodeList has more than one
4462 // element. Only the DOM nodes are cloned, no event handlers. If it is an Object,
4463 // it should be an object with at "template" String property that has the HTML string
4464 // to insert. If dojo.string has already been dojo.required, then dojo.string.substitute
4465 // will be used on the "template" to generate the final HTML string. Other allowed
4466 // properties on the object are: "parse" if the HTML
4467 // string should be parsed for widgets (dojo.require("dojo.parser") to get that
4468 // option to work), and "templateFunc" if a template function besides dojo.string.substitute
4469 // should be used to transform the "template".
4473 // - "last"||"end" (default)
4474 // - "first||"start"
4477 // - "replace" (replaces nodes in this NodeList with new content)
4478 // - "only" (removes other children of the nodes so new content is the only child)
4480 // or an offset in the childNodes property
4482 // appends content to the end if the position is omitted
4483 // | dojo.query("h3 > p").addContent("hey there!");
4485 // add something to the front of each element that has a
4486 // "thinger" property:
4487 // | dojo.query("[thinger]").addContent("...", "first");
4489 // adds a header before each element of the list
4490 // | dojo.query(".note").addContent("<h4>NOTE:</h4>", "before");
4492 // add a clone of a DOM node to the end of every element in
4493 // the list, removing it from its existing parent.
4494 // | dojo.query(".note").addContent(dojo.byId("foo"));
4496 // Append nodes from a templatized string.
4497 // | dojo.require("dojo.string");
4498 // | dojo.query(".note").addContent({
4499 // | template: '<b>${id}: </b><span>${name}</span>',
4501 // | name: "Mr. Anderson"
4504 // Append nodes from a templatized string that also has widgets parsed.
4505 // | dojo.require("dojo.string");
4506 // | dojo.require("dojo.parser");
4507 // | var notes = dojo.query(".note").addContent({
4508 // | template: '<button dojoType="dijit/form/Button">${text}</button>',
4512 content
= this._normalize(content
, this[0]);
4513 for(var i
= 0, node
; (node
= this[i
]); i
++){
4514 this._place(content
, node
, position
, i
> 0);
4516 return this; // dojo/NodeList
4524 'dojo/query':function(){
4525 define(["./_base/kernel", "./has", "./dom", "./on", "./_base/array", "./_base/lang", "./selector/_loader", "./selector/_loader!default"],
4526 function(dojo
, has
, dom
, on
, array
, lang
, loader
, defaultEngine
){
4530 has
.add("array-extensible", function(){
4531 // test to see if we can extend an array (not supported in old IE)
4532 return lang
.delegate([], {length
: 1}).length
== 1 && !has("bug-for-in-skips-shadowed");
4535 var ap
= Array
.prototype, aps
= ap
.slice
, apc
= ap
.concat
, forEach
= array
.forEach
;
4537 var tnl = function(/*Array*/ a
, /*dojo/NodeList?*/ parent, /*Function?*/ NodeListCtor
){
4539 // decorate an array to make it look like a `dojo/NodeList`.
4541 // Array of nodes to decorate.
4543 // An optional parent NodeList that generated the current
4544 // list of nodes. Used to call _stash() so the parent NodeList
4545 // can be accessed via end() later.
4547 // An optional constructor function to use for any
4548 // new NodeList calls. This allows a certain chain of
4549 // NodeList calls to use a different object than dojo/NodeList.
4550 var nodeList
= new (NodeListCtor
|| this._NodeListCtor
|| nl
)(a
);
4551 return parent
? nodeList
._stash(parent
) : nodeList
;
4554 var loopBody = function(f
, a
, o
){
4555 a
= [0].concat(aps
.call(a
, 0));
4556 o
= o
|| dojo
.global
;
4557 return function(node
){
4559 return f
.apply(o
, a
);
4565 var adaptAsForEach = function(f
, o
){
4567 // adapts a single node function to be used in the forEach-type
4568 // actions. The initial object is returned from the specialized
4571 // a function to adapt
4573 // an optional context for f
4575 this.forEach(loopBody(f
, arguments
, o
));
4576 return this; // Object
4580 var adaptAsMap = function(f
, o
){
4582 // adapts a single node function to be used in the map-type
4583 // actions. The return is a new array of values, as via `dojo.map`
4585 // a function to adapt
4587 // an optional context for f
4589 return this.map(loopBody(f
, arguments
, o
));
4593 var adaptAsFilter = function(f
, o
){
4595 // adapts a single node function to be used in the filter-type actions
4597 // a function to adapt
4599 // an optional context for f
4601 return this.filter(loopBody(f
, arguments
, o
));
4605 var adaptWithCondition = function(f
, g
, o
){
4607 // adapts a single node function to be used in the map-type
4608 // actions, behaves like forEach() or map() depending on arguments
4610 // a function to adapt
4612 // a condition function, if true runs as map(), otherwise runs as forEach()
4614 // an optional context for f and g
4616 var a
= arguments
, body
= loopBody(f
, a
, o
);
4617 if(g
.call(o
|| dojo
.global
, a
)){
4618 return this.map(body
); // self
4621 return this; // self
4625 var NodeList = function(array
){
4627 // Array-like object which adds syntactic
4628 // sugar for chaining, common iteration operations, animation, and
4629 // node manipulation. NodeLists are most often returned as the
4630 // result of dojo.query() calls.
4632 // NodeList instances provide many utilities that reflect
4633 // core Dojo APIs for Array iteration and manipulation, DOM
4634 // manipulation, and event handling. Instead of needing to dig up
4635 // functions in the dojo.* namespace, NodeLists generally make the
4636 // full power of Dojo available for DOM manipulation tasks in a
4637 // simple, chainable way.
4639 // create a node list from a node
4640 // | new query.NodeList(dojo.byId("foo"));
4642 // get a NodeList from a CSS query and iterate on it
4643 // | var l = dojo.query(".thinger");
4644 // | l.forEach(function(node, index, nodeList){
4645 // | console.log(index, node.innerHTML);
4648 // use native and Dojo-provided array methods to manipulate a
4649 // NodeList without needing to use dojo.* functions explicitly:
4650 // | var l = dojo.query(".thinger");
4651 // | // since NodeLists are real arrays, they have a length
4652 // | // property that is both readable and writable and
4653 // | // push/pop/shift/unshift methods
4654 // | console.log(l.length);
4655 // | l.push(dojo.create("span"));
4657 // | // dojo's normalized array methods work too:
4658 // | console.log( l.indexOf(dojo.byId("foo")) );
4659 // | // ...including the special "function as string" shorthand
4660 // | console.log( l.every("item.nodeType == 1") );
4662 // | // NodeLists can be [..] indexed, or you can use the at()
4663 // | // function to get specific items wrapped in a new NodeList:
4664 // | var node = l[3]; // the 4th element
4665 // | var newList = l.at(1, 3); // the 2nd and 4th elements
4667 // the style functions you expect are all there too:
4668 // | // style() as a getter...
4669 // | var borders = dojo.query(".thinger").style("border");
4670 // | // ...and as a setter:
4671 // | dojo.query(".thinger").style("border", "1px solid black");
4672 // | // class manipulation
4673 // | dojo.query("li:nth-child(even)").addClass("even");
4674 // | // even getting the coordinates of all the items
4675 // | var coords = dojo.query(".thinger").coords();
4677 // DOM manipulation functions from the dojo.* namespace area also available:
4678 // | // remove all of the elements in the list from their
4679 // | // parents (akin to "deleting" them from the document)
4680 // | dojo.query(".thinger").orphan();
4681 // | // place all elements in the list at the front of #foo
4682 // | dojo.query(".thinger").place("foo", "first");
4684 // Event handling couldn't be easier. `dojo.connect` is mapped in,
4685 // and shortcut handlers are provided for most DOM events:
4686 // | // like dojo.connect(), but with implicit scope
4687 // | dojo.query("li").connect("onclick", console, "log");
4689 // | // many common event handlers are already available directly:
4690 // | dojo.query("li").onclick(console, "log");
4691 // | var toggleHovered = dojo.hitch(dojo, "toggleClass", "hovered");
4692 // | dojo.query("p")
4693 // | .onmouseenter(toggleHovered)
4694 // | .onmouseleave(toggleHovered);
4696 // chainability is a key advantage of NodeLists:
4697 // | dojo.query(".thinger")
4698 // | .onclick(function(e){ /* ... */ })
4699 // | .at(1, 3, 8) // get a subset
4700 // | .style("padding", "5px")
4701 // | .forEach(console.log);
4702 var isNew
= this instanceof nl
&& has("array-extensible");
4703 if(typeof array
== "number"){
4704 array
= Array(array
);
4706 var nodeArray
= (array
&& "length" in array
) ? array
: arguments
;
4707 if(isNew
|| !nodeArray
.sort
){
4708 // make sure it's a real array before we pass it on to be wrapped
4709 var target
= isNew
? this : [],
4710 l
= target
.length
= nodeArray
.length
;
4711 for(var i
= 0; i
< l
; i
++){
4712 target
[i
] = nodeArray
[i
];
4715 // called with new operator, this means we are going to use this instance and push
4716 // the nodes on to it. This is usually much faster since the NodeList properties
4717 // don't need to be copied (unless the list of nodes is extremely large).
4722 // called without new operator, use a real array and copy prototype properties,
4723 // this is slower and exists for back-compat. Should be removed in 2.0.
4724 lang
._mixin(nodeArray
, nlp
);
4725 nodeArray
._NodeListCtor = function(array
){
4726 // call without new operator to preserve back-compat behavior
4732 var nl
= NodeList
, nlp
= nl
.prototype =
4733 has("array-extensible") ? [] : {};// extend an array if it is extensible
4735 // expose adapters and the wrapper as private functions
4737 nl
._wrap
= nlp
._wrap
= tnl
;
4738 nl
._adaptAsMap
= adaptAsMap
;
4739 nl
._adaptAsForEach
= adaptAsForEach
;
4740 nl
._adaptAsFilter
= adaptAsFilter
;
4741 nl
._adaptWithCondition
= adaptWithCondition
;
4745 // add array redirectors
4746 forEach(["slice", "splice"], function(name
){
4748 //Use a copy of the this array via this.slice() to allow .end() to work right in the splice case.
4749 // CANNOT apply ._stash()/end() to splice since it currently modifies
4750 // the existing this array -- it would break backward compatibility if we copy the array before
4751 // the splice so that we can use .end(). So only doing the stash option to this._wrap for slice.
4752 nlp
[name
] = function(){ return this._wrap(f
.apply(this, arguments
), name
== "slice" ? this : null); };
4754 // concat should be here but some browsers with native NodeList have problems with it
4756 // add array.js redirectors
4757 forEach(["indexOf", "lastIndexOf", "every", "some"], function(name
){
4758 var f
= array
[name
];
4759 nlp
[name
] = function(){ return f
.apply(dojo
, [this].concat(aps
.call(arguments
, 0))); };
4762 lang
.extend(NodeList
, {
4763 // copy the constructors
4766 toString: function(){
4767 // Array.prototype.toString can't be applied to objects, so we use join
4768 return this.join(",");
4770 _stash: function(parent
){
4772 // private function to hold to a parent NodeList. end() to return the parent NodeList.
4775 // How to make a `dojo/NodeList` method that only returns the third node in
4776 // the dojo/NodeList but allows access to the original NodeList by using this._stash:
4777 // | dojo.extend(NodeList, {
4778 // | third: function(){
4779 // | var newNodeList = NodeList(this[2]);
4780 // | return newNodeList._stash(this);
4783 // | // then see how _stash applies a sub-list, to be .end()'ed out of
4784 // | dojo.query(".foo")
4786 // | .addClass("thirdFoo")
4788 // | // access to the orig .foo list
4789 // | .removeClass("foo")
4792 this._parent
= parent
;
4793 return this; // dojo/NodeList
4796 on: function(eventName
, listener
){
4798 // Listen for events on the nodes in the NodeList. Basic usage is:
4799 // | query(".my-class").on("click", listener);
4800 // This supports event delegation by using selectors as the first argument with the event names as
4801 // pseudo selectors. For example:
4802 // | dojo.query("#my-list").on("li:click", listener);
4803 // This will listen for click events within `<li>` elements that are inside the `#my-list` element.
4804 // Because on supports CSS selector syntax, we can use comma-delimited events as well:
4805 // | dojo.query("#my-list").on("li button:mouseover, li:click", listener);
4806 var handles
= this.map(function(node
){
4807 return on(node
, eventName
, listener
); // TODO: apply to the NodeList so the same selector engine is used for matches
4809 handles
.remove = function(){
4810 for(var i
= 0; i
< handles
.length
; i
++){
4811 handles
[i
].remove();
4819 // Ends use of the current `NodeList` by returning the previous NodeList
4820 // that generated the current NodeList.
4822 // Returns the `NodeList` that generated the current `NodeList`. If there
4823 // is no parent NodeList, an empty NodeList is returned.
4825 // | dojo.query("a")
4826 // | .filter(".disabled")
4827 // | // operate on the anchors that only have a disabled class
4828 // | .style("color", "grey")
4830 // | // jump back to the list of anchors
4834 return this._parent
;
4836 //Just return empty list.
4837 return new this._NodeListCtor(0);
4841 // http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array#Methods
4843 // FIXME: handle return values for #3244
4844 // http://trac.dojotoolkit.org/ticket/3244
4847 // need to wrap or implement:
4848 // join (perhaps w/ innerHTML/outerHTML overload for toString() of items?)
4853 slice: function(begin, end){
4855 // Returns a new NodeList, maintaining this one in place
4857 // This method behaves exactly like the Array.slice method
4858 // with the caveat that it returns a dojo/NodeList and not a
4859 // raw Array. For more details, see Mozilla's [slice
4860 // documentation](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/slice)
4862 // Can be a positive or negative integer, with positive
4863 // integers noting the offset to begin at, and negative
4864 // integers denoting an offset from the end (i.e., to the left
4867 // Optional parameter to describe what position relative to
4868 // the NodeList's zero index to end the slice at. Like begin,
4869 // can be positive or negative.
4870 return this._wrap(a.slice.apply(this, arguments));
4873 splice: function(index, howmany, item){
4875 // Returns a new NodeList, manipulating this NodeList based on
4876 // the arguments passed, potentially splicing in new elements
4877 // at an offset, optionally deleting elements
4879 // This method behaves exactly like the Array.splice method
4880 // with the caveat that it returns a dojo/NodeList and not a
4881 // raw Array. For more details, see Mozilla's [splice
4882 // documentation](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/splice)
4883 // For backwards compatibility, calling .end() on the spliced NodeList
4884 // does not return the original NodeList -- splice alters the NodeList in place.
4886 // begin can be a positive or negative integer, with positive
4887 // integers noting the offset to begin at, and negative
4888 // integers denoting an offset from the end (i.e., to the left
4890 // howmany: Integer?
4891 // Optional parameter to describe what position relative to
4892 // the NodeList's zero index to end the slice at. Like begin,
4893 // can be positive or negative.
4895 // Any number of optional parameters may be passed in to be
4896 // spliced into the NodeList
4897 return this._wrap(a.splice.apply(this, arguments)); // dojo/NodeList
4900 indexOf: function(value, fromIndex){
4902 // see dojo.indexOf(). The primary difference is that the acted-on
4903 // array is implicitly this NodeList
4905 // The value to search for.
4906 // fromIndex: Integer?
4907 // The location to start searching from. Optional. Defaults to 0.
4909 // For more details on the behavior of indexOf, see Mozilla's
4911 // docs](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf)
4913 // Positive Integer or 0 for a match, -1 of not found.
4914 return d.indexOf(this, value, fromIndex); // Integer
4917 lastIndexOf: function(value, fromIndex){
4919 // see dojo.lastIndexOf(). The primary difference is that the
4920 // acted-on array is implicitly this NodeList
4922 // For more details on the behavior of lastIndexOf, see
4923 // Mozilla's [lastIndexOf
4924 // docs](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/lastIndexOf)
4926 // The value to search for.
4927 // fromIndex: Integer?
4928 // The location to start searching from. Optional. Defaults to 0.
4930 // Positive Integer or 0 for a match, -1 of not found.
4931 return d.lastIndexOf(this, value, fromIndex); // Integer
4934 every: function(callback, thisObject){
4936 // see `dojo.every()` and the [Array.every
4937 // docs](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/every).
4938 // Takes the same structure of arguments and returns as
4939 // dojo.every() with the caveat that the passed array is
4940 // implicitly this NodeList
4941 // callback: Function
4943 // thisObject: Object?
4945 return d.every(this, callback, thisObject); // Boolean
4948 some: function(callback, thisObject){
4950 // Takes the same structure of arguments and returns as
4951 // `dojo.some()` with the caveat that the passed array is
4952 // implicitly this NodeList. See `dojo.some()` and Mozilla's
4954 // documentation](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/some).
4955 // callback: Function
4957 // thisObject: Object?
4959 return d.some(this, callback, thisObject); // Boolean
4963 concat: function(item
){
4965 // Returns a new NodeList comprised of items in this NodeList
4966 // as well as items passed in as parameters
4968 // This method behaves exactly like the Array.concat method
4969 // with the caveat that it returns a `NodeList` and not a
4970 // raw Array. For more details, see the [Array.concat
4971 // docs](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/concat)
4973 // Any number of optional parameters may be passed in to be
4974 // spliced into the NodeList
4976 //return this._wrap(apc.apply(this, arguments));
4977 // the line above won't work for the native NodeList, or for Dojo NodeLists either :-(
4979 // implementation notes:
4980 // Array.concat() doesn't recognize native NodeLists or Dojo NodeLists
4981 // as arrays, and so does not inline them into a unioned array, but
4982 // appends them as single entities. Both the original NodeList and the
4983 // items passed in as parameters must be converted to raw Arrays
4984 // and then the concatenation result may be re-_wrap()ed as a Dojo NodeList.
4986 var t
= aps
.call(this, 0),
4987 m
= array
.map(arguments
, function(a
){
4988 return aps
.call(a
, 0);
4990 return this._wrap(apc
.apply(t
, m
), this); // dojo/NodeList
4993 map: function(/*Function*/ func
, /*Function?*/ obj
){
4995 // see dojo.map(). The primary difference is that the acted-on
4996 // array is implicitly this NodeList and the return is a
4997 // NodeList (a subclass of Array)
4998 return this._wrap(array
.map(this, func
, obj
), this); // dojo/NodeList
5001 forEach: function(callback
, thisObj
){
5003 // see `dojo.forEach()`. The primary difference is that the acted-on
5004 // array is implicitly this NodeList. If you want the option to break out
5005 // of the forEach loop, use every() or some() instead.
5006 forEach(this, callback
, thisObj
);
5007 // non-standard return to allow easier chaining
5008 return this; // dojo/NodeList
5010 filter: function(/*String|Function*/ filter
){
5012 // "masks" the built-in javascript filter() method (supported
5013 // in Dojo via `dojo.filter`) to support passing a simple
5014 // string filter in addition to supporting filtering function
5017 // If a string, a CSS rule like ".thinger" or "div > span".
5019 // "regular" JS filter syntax as exposed in dojo.filter:
5020 // | dojo.query("*").filter(function(item){
5021 // | // highlight every paragraph
5022 // | return (item.nodeName == "p");
5023 // | }).style("backgroundColor", "yellow");
5025 // the same filtering using a CSS selector
5026 // | dojo.query("*").filter("p").styles("backgroundColor", "yellow");
5028 var a
= arguments
, items
= this, start
= 0;
5029 if(typeof filter
== "string"){ // inline'd type check
5030 items
= query
._filterResult(this, a
[0]);
5032 // if we only got a string query, pass back the filtered results
5033 return items
._stash(this); // dojo/NodeList
5035 // if we got a callback, run it over the filtered items
5038 return this._wrap(array
.filter(items
, a
[start
], a
[start
+ 1]), this); // dojo/NodeList
5040 instantiate: function(/*String|Object*/ declaredClass
, /*Object?*/ properties
){
5042 // Create a new instance of a specified class, using the
5043 // specified properties and each node in the NodeList as a
5046 // Grabs all buttons in the page and converts them to dijit/form/Button's.
5047 // | var buttons = query("button").instantiate(Button, {showLabel: true});
5048 var c
= lang
.isFunction(declaredClass
) ? declaredClass
: lang
.getObject(declaredClass
);
5049 properties
= properties
|| {};
5050 return this.forEach(function(node
){
5051 new c(properties
, node
);
5052 }); // dojo/NodeList
5054 at: function(/*===== index =====*/){
5056 // Returns a new NodeList comprised of items in this NodeList
5057 // at the given index or indices.
5059 // index: Integer...
5060 // One or more 0-based indices of items in the current
5061 // NodeList. A negative index will start at the end of the
5062 // list and go backwards.
5065 // Shorten the list to the first, second, and third elements
5066 // | query("a").at(0, 1, 2).forEach(fn);
5069 // Retrieve the first and last elements of a unordered list:
5070 // | query("ul > li").at(0, -1).forEach(cb);
5073 // Do something for the first element only, but end() out back to
5074 // the original list and continue chaining:
5075 // | query("a").at(0).onclick(fn).end().forEach(function(n){
5076 // | console.log(n); // all anchors on the page.
5079 var t
= new this._NodeListCtor(0);
5080 forEach(arguments
, function(i
){
5081 if(i
< 0){ i
= this.length
+ i
; }
5082 if(this[i
]){ t
.push(this[i
]); }
5084 return t
._stash(this); // dojo/NodeList
5088 function queryForEngine(engine
, NodeList
){
5089 var query = function(/*String*/ query
, /*String|DOMNode?*/ root
){
5091 // Returns nodes which match the given CSS selector, searching the
5092 // entire document by default but optionally taking a node to scope
5093 // the search by. Returns an instance of NodeList.
5094 if(typeof root
== "string"){
5095 root
= dom
.byId(root
);
5097 return new NodeList([]);
5100 var results
= typeof query
== "string" ? engine(query
, root
) : query
? query
.orphan
? query
: [query
] : [];
5105 return new NodeList(results
);
5107 query
.matches
= engine
.match
|| function(node
, selector
, root
){
5109 // Test to see if a node matches a selector
5110 return query
.filter([node
], selector
, root
).length
> 0;
5112 // the engine provides a filtering function, use it to for matching
5113 query
.filter
= engine
.filter
|| function(nodes
, selector
, root
){
5115 // Filters an array of nodes. Note that this does not guarantee to return a NodeList, just an array.
5116 return query(selector
, root
).filter(function(node
){
5117 return array
.indexOf(nodes
, node
) > -1;
5120 if(typeof engine
!= "function"){
5121 var search
= engine
.search
;
5122 engine = function(selector
, root
){
5123 // Slick does it backwards (or everyone else does it backwards, probably the latter)
5124 return search(root
|| document
, selector
);
5129 var query
= queryForEngine(defaultEngine
, NodeList
);
5131 query = function(selector, context){
5133 // This modules provides DOM querying functionality. The module export is a function
5134 // that can be used to query for DOM nodes by CSS selector and returns a NodeList
5135 // representing the matching nodes.
5137 // A CSS selector to search for.
5138 // context: String|DomNode?
5139 // An optional context to limit the searching scope. Only nodes under `context` will be
5142 // add an onclick handler to every submit button in the document
5143 // which causes the form to be sent via Ajax instead:
5144 // | require(["dojo/query"], function(query){
5145 // | query("input[type='submit']").on("click", function(e){
5146 // | dojo.stopEvent(e); // prevent sending the form
5147 // | var btn = e.target;
5149 // | form: btn.form,
5150 // | load: function(data){
5151 // | // replace the form with the response
5152 // | var div = dojo.doc.createElement("div");
5153 // | dojo.place(div, btn.form, "after");
5154 // | div.innerHTML = data;
5155 // | dojo.style(btn.form, "display", "none");
5162 // dojo/query is responsible for loading the appropriate query engine and wrapping
5163 // its results with a `NodeList`. You can use dojo/query with a specific selector engine
5164 // by using it as a plugin. For example, if you installed the sizzle package, you could
5165 // use it as the selector engine with:
5166 // | require(["dojo/query!sizzle"], function(query){
5167 // | query("div")...
5169 // The id after the ! can be a module id of the selector engine or one of the following values:
5171 // - acme: This is the default engine used by Dojo base, and will ensure that the full
5172 // Acme engine is always loaded.
5174 // - css2: If the browser has a native selector engine, this will be used, otherwise a
5175 // very minimal lightweight selector engine will be loaded that can do simple CSS2 selectors
5176 // (by #id, .class, tag, and [name=value] attributes, with standard child or descendant (>)
5177 // operators) and nothing more.
5179 // - css2.1: If the browser has a native selector engine, this will be used, otherwise the
5180 // full Acme engine will be loaded.
5182 // - css3: If the browser has a native selector engine with support for CSS3 pseudo
5183 // selectors (most modern browsers except IE8), this will be used, otherwise the
5184 // full Acme engine will be loaded.
5186 // - Or the module id of a selector engine can be used to explicitly choose the selector engine
5188 // For example, if you are using CSS3 pseudo selectors in module, you can specify that
5189 // you will need support them with:
5190 // | require(["dojo/query!css3"], function(query){
5191 // | query('#t > h3:nth-child(odd)')...
5193 // You can also choose the selector engine/load configuration by setting the query-selector:
5195 // | <script data-dojo-config="query-selector:'css3'" src="dojo.js"></script>
5197 return new NodeList(); // dojo/NodeList
5201 // the query that is returned from this module is slightly different than dojo.query,
5202 // because dojo.query has to maintain backwards compatibility with returning a
5203 // true array which has performance problems. The query returned from the module
5204 // does not use true arrays, but rather inherits from Array, making it much faster to
5206 dojo
.query
= queryForEngine(defaultEngine
, function(array
){
5207 // call it without the new operator to invoke the back-compat behavior that returns a true array
5208 return NodeList(array
); // dojo/NodeList
5211 query
.load = function(id
, parentRequire
, loaded
){
5213 // can be used as AMD plugin to conditionally load new query engine
5215 // | require(["dojo/query!custom"], function(qsa){
5216 // | // loaded selector/custom.js as engine
5217 // | qsa("#foobar").forEach(...);
5219 loader
.load(id
, parentRequire
, function(engine
){
5220 loaded(queryForEngine(engine
, NodeList
));
5224 dojo
._filterQueryResult
= query
._filterResult = function(nodes
, selector
, root
){
5225 return new NodeList(query
.filter(nodes
, selector
, root
));
5227 dojo
.NodeList
= query
.NodeList
= NodeList
;
5232 'dojo/has':function(){
5233 define(["require", "module"], function(require
, module
){
5237 // Defines the has.js API and several feature tests used by dojo.
5239 // This module defines the has API as described by the project has.js with the following additional features:
5241 // - the has test cache is exposed at has.cache.
5242 // - the method has.add includes a forth parameter that controls whether or not existing tests are replaced
5243 // - the loader's has cache may be optionally copied into this module's has cahce.
5245 // This module adopted from https://github.com/phiggins42/has.js; thanks has.js team!
5247 // try to pull the has implementation from the loader; both the dojo loader and bdLoad provide one
5248 // if using a foreign loader, then the has cache may be initialized via the config object for this module
5249 // WARNING: if a foreign loader defines require.has to be something other than the has.js API, then this implementation fail
5250 var has
= require
.has
|| function(){};
5254 // the most fundamental decision: are we in the browser?
5255 typeof window
!= "undefined" &&
5256 typeof location
!= "undefined" &&
5257 typeof document
!= "undefined" &&
5258 window
.location
== location
&& window
.document
== document
,
5260 // has API variables
5262 doc
= isBrowser
&& document
,
5263 element
= doc
&& doc
.createElement("DiV"),
5264 cache
= (module
.config
&& module
.config()) || {};
5266 has = function(name
){
5268 // Return the current value of the named feature.
5270 // name: String|Integer
5271 // The name (if a string) or identifier (if an integer) of the feature to test.
5274 // Returns the value of the feature named by name. The feature must have been
5275 // previously added to the cache by has.add.
5277 return typeof cache
[name
] == "function" ? (cache
[name
] = cache
[name
](global
, doc
, element
)) : cache
[name
]; // Boolean
5282 has
.add = function(name
, test
, now
, force
){
5284 // Register a new feature test for some named feature.
5285 // name: String|Integer
5286 // The name (if a string) or identifier (if an integer) of the feature to test.
5288 // A test function to register. If a function, queued for testing until actually
5289 // needed. The test function should return a boolean indicating
5290 // the presence of a feature or bug.
5292 // Optional. Omit if `test` is not a function. Provides a way to immediately
5293 // run the test and cache the result.
5295 // Optional. If the test already exists and force is truthy, then the existing
5296 // test will be replaced; otherwise, add does not replace an existing test (that
5297 // is, by default, the first test advice wins).
5299 // A redundant test, testFn with immediate execution:
5300 // | has.add("javascript", function(){ return true; }, true);
5303 // Again with the redundantness. You can do this in your tests, but we should
5304 // not be doing this in any internal has.js tests
5305 // | has.add("javascript", true);
5308 // Three things are passed to the testFunction. `global`, `document`, and a generic element
5309 // from which to work your test should the need arise.
5310 // | has.add("bug-byid", function(g, d, el){
5311 // | // g == global, typically window, yadda yadda
5312 // | // d == document object
5313 // | // el == the generic element. a `has` element.
5314 // | return false; // fake test, byid-when-form-has-name-matching-an-id is slightly longer
5317 (typeof cache
[name
]=="undefined" || force
) && (cache
[name
]= test
);
5318 return now
&& has(name
);
5321 // since we're operating under a loader that doesn't provide a has API, we must explicitly initialize
5322 // has as it would have otherwise been initialized by the dojo loader; use has.add to the builder
5323 // can optimize these away iff desired
5324 1 || has
.add("host-browser", isBrowser
);
5325 1 || has
.add("dom", isBrowser
);
5326 1 || has
.add("dojo-dom-ready-api", 1);
5327 1 || has
.add("dojo-sniff", 1);
5331 // Common application level tests
5332 has
.add("dom-addeventlistener", !!document
.addEventListener
);
5333 has
.add("touch", "ontouchstart" in document
);
5334 // I don't know if any of these tests are really correct, just a rough guess
5335 has
.add("device-width", screen
.availWidth
|| innerWidth
);
5337 // Tests for DOMNode.attributes[] behavior:
5338 // - dom-attributes-explicit - attributes[] only lists explicitly user specified attributes
5339 // - dom-attributes-specified-flag (IE8) - need to check attr.specified flag to skip attributes user didn't specify
5340 // - Otherwise, in IE6-7. attributes[] will list hundreds of values, so need to do outerHTML to get attrs instead.
5341 var form
= document
.createElement("form");
5342 has
.add("dom-attributes-explicit", form
.attributes
.length
== 0); // W3C
5343 has
.add("dom-attributes-specified-flag", form
.attributes
.length
> 0 && form
.attributes
.length
< 40); // IE8
5346 has
.clearElement = function(element
){
5348 // Deletes the contents of the element passed to test functions.
5349 element
.innerHTML
= "";
5353 has
.normalize = function(id
, toAbsMid
){
5355 // Resolves id into a module id based on possibly-nested tenary expression that branches on has feature test value(s).
5357 // toAbsMid: Function
5358 // Resolves a relative module id into an absolute module id
5360 tokens
= id
.match(/[\?:]|[^:\?]*/g), i
= 0,
5361 get = function(skip
){
5362 var term
= tokens
[i
++];
5364 // empty string module name, resolves to 0
5367 // postfixed with a ? means it is a feature to branch on, the term is the name of the feature
5368 if(tokens
[i
++] == "?"){
5369 if(!skip
&& has(term
)){
5370 // matched the feature, get the first value from the options
5373 // did not match, get the second value, passing over the first
5383 return id
&& toAbsMid(id
);
5386 has
.load = function(id
, parentRequire
, loaded
){
5388 // Conditional loading of AMD modules based on a has feature test value.
5390 // Gives the resolved module id to load.
5391 // parentRequire: Function
5392 // The loader require function with respect to the module that contained the plugin resource in it's
5395 // Callback to loader that consumes result of plugin demand.
5398 parentRequire([id
], loaded
);
5408 'dojo/_base/loader':function(){
5409 define(["./kernel", "../has", "require", "module", "./json", "./lang", "./array"], function(dojo
, has
, require
, thisModule
, json
, lang
, array
) {
5411 // dojo/_base/loader
5413 // This module defines the v1.x synchronous loader API.
5415 // signal the loader in sync mode...
5419 console
.error("cannot load the Dojo v1.x loader with a foreign loader");
5423 1 || has
.add("dojo-fast-sync-require", 1);
5426 var makeErrorToken = function(id
){
5427 return {src
:thisModule
.id
, id
:id
};
5430 slashName = function(name
){
5431 return name
.replace(/\./g, "/");
5434 buildDetectRe
= /\/\/>>built/,
5436 dojoRequireCallbacks
= [],
5437 dojoRequireModuleStack
= [],
5439 dojoRequirePlugin = function(mid
, require
, loaded
){
5440 dojoRequireCallbacks
.push(loaded
);
5441 array
.forEach(mid
.split(","), function(mid
){
5442 var module
= getModule(mid
, require
.module
);
5443 dojoRequireModuleStack
.push(module
);
5444 injectModule(module
);
5446 checkDojoRequirePlugin();
5449 checkDojoRequirePlugin
= ( 1 ?
5450 // This version of checkDojoRequirePlugin makes the observation that all dojoRequireCallbacks can be released
5451 // when all *non-dojo/require!, dojo/loadInit!* modules are either executed, not requested, or arrived. This is
5452 // the case since there are no more modules the loader is waiting for, therefore, dojo/require! must have
5453 // everything it needs on board.
5455 // The potential weakness of this algorithm is that dojo/require will not execute callbacks until *all* dependency
5456 // trees are ready. It is possible that some trees may be ready earlier than others, and this extra wait is non-optimal.
5457 // Still, for big projects, this seems better than the original algorithm below that proved slow in some cases.
5458 // Note, however, the original algorithm had the potential to execute partial trees, but that potential was never enabled.
5459 // There are also other optimization available with the original algorithm that have not been explored.
5462 for(mid
in modules
){
5463 module
= modules
[mid
];
5464 if(module
.noReqPluginCheck
===undefined){
5465 // tag the module as either a loadInit or require plugin or not for future reference
5466 module
.noReqPluginCheck
= /loadInit\!/.test(mid
) || /require\!/.test(mid
) ? 1 : 0;
5468 if(!module
.executed
&& !module
.noReqPluginCheck
&& module
.injected
==requested
){
5473 guardCheckComplete(function(){
5474 var oldCallbacks
= dojoRequireCallbacks
;
5475 dojoRequireCallbacks
= [];
5476 array
.forEach(oldCallbacks
, function(cb
){cb(1);});
5479 // Note: this is the original checkDojoRequirePlugin that is much slower than the algorithm above. However, we know it
5480 // works, so we leave it here in case the algorithm above fails in some corner case.
5482 // checkDojoRequirePlugin inspects all of the modules demanded by a dojo/require!<module-list> dependency
5483 // to see if they have arrived. The loader does not release *any* of these modules to be instantiated
5484 // until *all* of these modules are on board, thereby preventing the evaluation of a module with dojo.require's
5485 // that reference modules that are not available.
5487 // The algorithm works by traversing the dependency graphs (remember, there can be cycles so they are not trees)
5488 // of each module in the dojoRequireModuleStack array (which contains the list of modules demanded by dojo/require!).
5489 // The moment a single module is discovered that is missing, the algorithm gives up and indicates that not all
5490 // modules are on board. dojo/loadInit! and dojo/require! are ignored because there dependencies are inserted
5491 // directly in dojoRequireModuleStack. For example, if "your/module" module depends on "dojo/require!my/module", then
5492 // *both* "dojo/require!my/module" and "my/module" will be in dojoRequireModuleStack. Obviously, if "my/module"
5493 // is on board, then "dojo/require!my/module" is also satisfied, so the algorithm doesn't check for "dojo/require!my/module".
5495 // Note: inserting a dojo/require!<some-module-list> dependency in the dojoRequireModuleStack achieves nothing
5496 // with the current algorithm; however, having such modules present makes it possible to optimize the algorithm
5498 // Note: prior versions of this algorithm had an optimization that signaled loaded on dojo/require! dependencies
5499 // individually (rather than waiting for them all to be resolved). The implementation proved problematic with cycles
5500 // and plugins. However, it is possible to reattach that strategy in the future.
5502 // a set from module-id to {undefined | 1 | 0}, where...
5503 // undefined => the module has not been inspected
5504 // 0 => the module or at least one of its dependencies has not arrived
5505 // 1 => the module is a loadInit! or require! plugin resource, or is currently being traversed (therefore, assume
5506 // OK until proven otherwise), or has been completely traversed and all dependencies have arrived
5509 traverse = function(m
){
5511 for(var t
, module
, deps
= m
.deps
|| [], i
= 0; i
<deps
.length
; i
++){
5513 if(!(t
= touched
[module
.mid
])){
5514 if(t
===0 || !traverse(module
)){
5524 // initialize the touched hash with easy-to-compute values that help short circuit recursive algorithm;
5525 // recall loadInit/require plugin modules are dependencies of modules in dojoRequireModuleStack...
5526 // which would cause a circular dependency chain that would never be resolved if checked here
5527 // notice all dependencies of any particular loadInit/require plugin module will already
5528 // be checked since those are pushed into dojoRequireModuleStack explicitly by the
5529 // plugin...so if a particular loadInitPlugin module's dependencies are not really
5530 // on board, that *will* be detected elsewhere in the traversal.
5533 for(mid
in modules
){
5534 module
= modules
[mid
];
5535 if(module
.executed
|| module
.noReqPluginCheck
){
5538 if(module
.noReqPluginCheck
!==0){
5539 // tag the module as either a loadInit or require plugin or not for future reference
5540 module
.noReqPluginCheck
= /loadInit\!/.test(mid
) || /require\!/.test(mid
) ? 1 : 0;
5542 if(module
.noReqPluginCheck
){
5544 }else if(module
.injected
!==arrived
){
5545 // not executed, has not arrived, and is not a loadInit or require plugin resource
5547 }// else, leave undefined and we'll traverse the dependencies
5550 for(var t
, i
= 0, end
= dojoRequireModuleStack
.length
; i
<end
; i
++){
5551 module
= dojoRequireModuleStack
[i
];
5552 if(!(t
= touched
[module
.mid
])){
5553 if(t
===0 || !traverse(module
)){
5558 guardCheckComplete(function(){
5559 var oldCallbacks
= dojoRequireCallbacks
;
5560 dojoRequireCallbacks
= [];
5561 array
.forEach(oldCallbacks
, function(cb
){cb(1);});
5566 dojoLoadInitPlugin = function(mid
, require
, loaded
){
5567 // mid names a module that defines a "dojo load init" bundle, an object with two properties:
5569 // * names: a vector of module ids that give top-level names to define in the lexical scope of def
5570 // * def: a function that contains some some legacy loader API applications
5572 // The point of def is to possibly cause some modules to be loaded (but not executed) by dojo/require! where the module
5573 // ids are possibly-determined at runtime. For example, here is dojox.gfx from v1.6 expressed as an AMD module using the dojo/loadInit
5574 // and dojo/require plugins.
5578 // define("*loadInit_12, {
5579 // names:["dojo", "dijit", "dojox"],
5581 // dojo.loadInit(function(){
5582 // var gfx = lang.getObject("dojox.gfx", true);
5585 // // code required to set gfx properties ommitted...
5588 // // now use the calculations to include the runtime-dependent module
5589 // dojo.require("dojox.gfx." + gfx.renderer);
5594 // define(["dojo", "dojo/loadInit!" + id].concat("dojo/require!dojox/gfx/matric,dojox/gfx/_base"), function(dojo){
5595 // // when this AMD factory function is executed, the following modules are guaranteed downloaded but not executed:
5596 // // "dojox.gfx." + gfx.renderer
5597 // // dojox.gfx.matrix
5598 // // dojox.gfx._base
5599 // dojo.provide("dojo.gfx");
5600 // dojo.require("dojox.gfx.matrix");
5601 // dojo.require("dojox.gfx._base");
5602 // dojo.require("dojox.gfx." + gfx.renderer);
5603 // return lang.getObject("dojo.gfx");
5607 // The idea is to run the legacy loader API with global variables shadowed, which allows these variables to
5608 // be relocated. For example, dojox and dojo could be relocated to different names by giving a map and the code above will
5609 // execute properly (because the plugin below resolves the load init bundle.names module with respect to the module that demanded
5610 // the plugin resource).
5612 // Note that the relocation is specified in the runtime configuration; relocated names need not be set at build-time.
5614 // Warning: this is not the best way to express dojox.gfx as and AMD module. In fact, the module has been properly converted in
5615 // v1.7. However, this technique allows the builder to convert legacy modules into AMD modules and guarantee the codepath is the
5616 // same in the converted AMD module.
5617 require([mid
], function(bundle
){
5618 // notice how names is resolved with respect to the module that demanded the plugin resource
5619 require(bundle
.names
, function(){
5620 // bring the bundle names into scope
5621 for(var scopeText
= "", args
= [], i
= 0; i
<arguments
.length
; i
++){
5622 scopeText
+= "var " + bundle
.names
[i
] + "= arguments[" + i
+ "]; ";
5623 args
.push(arguments
[i
]);
5627 var callingModule
= require
.module
,
5628 // the list of modules that need to be downloaded but not executed before the callingModule can be executed
5631 // the list of i18n bundles that are xdomain; undefined if none
5635 provide:function(moduleName
){
5636 // mark modules that arrive consequent to multiple provides in this module as arrived since they can't be injected
5637 moduleName
= slashName(moduleName
);
5638 var providedModule
= getModule(moduleName
, callingModule
);
5639 if(providedModule
!==callingModule
){
5640 setArrived(providedModule
);
5643 require:function(moduleName
, omitModuleCheck
){
5644 moduleName
= slashName(moduleName
);
5645 omitModuleCheck
&& (getModule(moduleName
, callingModule
).result
= nonmodule
);
5646 requireList
.push(moduleName
);
5648 requireLocalization:function(moduleName
, bundleName
, locale
){
5649 // since we're going to need dojo/i8n, add it to i18nDeps if not already there
5651 // don't have to map since that will occur when the dependency is resolved
5652 i18nDeps
= ["dojo/i18n"];
5655 // figure out if the bundle is xdomain; if so, add it to the i18nDepsSet
5656 locale
= (locale
|| dojo
.locale
).toLowerCase();
5657 moduleName
= slashName(moduleName
) + "/nls/" + (/root/i.test(locale
) ? "" : locale
+ "/") + slashName(bundleName
);
5658 if(getModule(moduleName
, callingModule
).isXd
){
5659 // don't have to map since that will occur when the dependency is resolved
5660 i18nDeps
.push("dojo/i18n!" + moduleName
);
5661 }// else the bundle will be loaded synchronously when the module is evaluated
5663 loadInit:function(f
){
5671 // hijack the correct dojo and apply bundle.def
5673 for(p
in syncLoaderApi
){
5675 dojo
[p
] = syncLoaderApi
[p
];
5677 bundle
.def
.apply(null, args
);
5679 signal("error", [makeErrorToken("failedDojoLoadInit"), e
]);
5681 for(p
in syncLoaderApi
){
5687 requireList
= requireList
.concat(i18nDeps
);
5690 if(requireList
.length
){
5691 dojoRequirePlugin(requireList
.join(","), require
, loaded
);
5699 extractApplication = function(
5700 text
, // the text to search
5701 startSearch
, // the position in text to start looking for the closing paren
5702 startApplication
// the position in text where the function application expression starts
5704 // find end of the call by finding the matching end paren
5705 // Warning: as usual, this will fail in the presense of unmatched right parans contained in strings, regexs, or unremoved comments
5706 var parenRe
= /\(|\)/g,
5709 parenRe
.lastIndex
= startSearch
;
5710 while((match
= parenRe
.exec(text
))){
5711 if(match
[0] == ")"){
5716 if(matchCount
== 0){
5721 if(matchCount
!= 0){
5722 throw "unmatched paren around character " + parenRe
.lastIndex
+ " in: " + text
;
5725 //Put the master matching string in the results.
5726 return [dojo
.trim(text
.substring(startApplication
, parenRe
.lastIndex
))+";\n", parenRe
.lastIndex
];
5729 // the following regex is taken from 1.6. It is a very poor technique to remove comments and
5730 // will fail in some cases; for example, consider the code...
5732 // var message = "Category-1 */* Category-2";
5734 // The regex that follows will see a /* comment and trash the code accordingly. In fact, there are all
5735 // kinds of cases like this with strings and regexs that will cause this design to fail miserably.
5737 // Alternative regex designs exist that will result in less-likely failures, but will still fail in many cases.
5738 // The only solution guaranteed 100% correct is to parse the code and that seems overkill for this
5739 // backcompat/unbuilt-xdomain layer. In the end, since it's been this way for a while, we won't change it.
5740 // See the opening paragraphs of Chapter 7 or ECME-262 which describes the lexical abiguity further.
5741 removeCommentRe
= /(\/\*([\s\S]*?)\*\/|\/\/(.*)$)/mg,
5743 syncLoaderApiRe
= /(^|\s)dojo\.(loadInit|require|provide|requireLocalization|requireIf|requireAfterIf|platformRequire)\s*\(/mg,
5745 amdLoaderApiRe
= /(^|\s)(require|define)\s*\(/m,
5747 extractLegacyApiApplications = function(text
, noCommentText
){
5748 // scan the noCommentText for any legacy loader API applications. Copy such applications into result (this is
5749 // used by the builder). Move dojo.loadInit applications to loadInitApplications string. Copy all other applications
5750 // to otherApplications string. If no applications were found, return 0, signalling an AMD module. Otherwise, return
5751 // loadInitApplications + otherApplications. Fixup text by replacing
5753 // dojo.loadInit(// etc...
5757 // \n 0 && dojo.loadInit(// etc...
5759 // Which results in the dojo.loadInit from *not* being applied. This design goes a long way towards protecting the
5760 // code from an over-agressive removeCommentRe. However...
5762 // WARNING: the removeCommentRe will cause an error if a detected comment removes all or part of a legacy-loader application
5763 // that is not in a comment.
5765 var match
, startSearch
, startApplication
, application
,
5766 loadInitApplications
= [],
5767 otherApplications
= [],
5768 allApplications
= [];
5770 // noCommentText may be provided by a build app with comments extracted by a better method than regex (hopefully)
5771 noCommentText
= noCommentText
|| text
.replace(removeCommentRe
, function(match
){
5772 // remove iff the detected comment has text that looks like a sync loader API application; this helps by
5773 // removing as little as possible, minimizing the changes the janky regex will kill the module
5774 syncLoaderApiRe
.lastIndex
= amdLoaderApiRe
.lastIndex
= 0;
5775 return (syncLoaderApiRe
.test(match
) || amdLoaderApiRe
.test(match
)) ? "" : match
;
5778 // find and extract all dojo.loadInit applications
5779 while((match
= syncLoaderApiRe
.exec(noCommentText
))){
5780 startSearch
= syncLoaderApiRe
.lastIndex
;
5781 startApplication
= startSearch
- match
[0].length
;
5782 application
= extractApplication(noCommentText
, startSearch
, startApplication
);
5783 if(match
[2]=="loadInit"){
5784 loadInitApplications
.push(application
[0]);
5786 otherApplications
.push(application
[0]);
5788 syncLoaderApiRe
.lastIndex
= application
[1];
5790 allApplications
= loadInitApplications
.concat(otherApplications
);
5791 if(allApplications
.length
|| !amdLoaderApiRe
.test(noCommentText
)){
5792 // either there were some legacy loader API applications or there were no AMD API applications
5793 return [text
.replace(/(^|\s)dojo\.loadInit\s*\(/g, "\n0 && dojo.loadInit("), allApplications
.join(""), allApplications
];
5795 // legacy loader API *was not* detected and AMD API *was* detected; therefore, assume it's an AMD module
5800 transformToAmd = function(module
, text
){
5801 // This is roughly the equivalent of dojo._xdCreateResource in 1.6-; however, it expresses a v1.6- dojo
5802 // module in terms of AMD define instead of creating the dojo proprietary xdomain module expression.
5803 // The module could have originated from several sources:
5805 // * amd require() a module, e.g., require(["my/module"])
5806 // * amd require() a nonmodule, e.g., require(["my/resource.js"')
5807 // * amd define() deps vector (always a module)
5808 // * dojo.require() a module, e.g. dojo.require("my.module")
5809 // * dojo.require() a nonmodule, e.g., dojo.require("my.module", true)
5810 // * dojo.requireIf/requireAfterIf/platformRequire a module
5812 // The module is scanned for legacy loader API applications; if none are found, then assume the module is an
5813 // AMD module and return 0. Otherwise, a synthetic dojo/loadInit plugin resource is created and the module text
5814 // is rewritten as an AMD module with the single dependency of this synthetic resource. When the dojo/loadInit
5815 // plugin loaded the synthetic resource, it will cause all dojo.loadInit's to be executed, find all dojo.require's
5816 // (either directly consequent to dojo.require or indirectly consequent to dojo.require[After]If or
5817 // dojo.platformRequire, and finally cause loading of all dojo.required modules with the dojo/require plugin. Thus,
5818 // when the dojo/loadInit plugin reports it has been loaded, all modules required by the given module are guaranteed
5819 // loaded (but not executed). This then allows the module to execute it's code path without interupts, thereby
5820 // following the synchronous code path.
5822 // Notice that this function behaves the same whether or not it happens to be in a mapped dojo/loader module.
5824 var extractResult
, id
, names
= [], namesAsStrings
= [];
5825 if(buildDetectRe
.test(text
) || !(extractResult
= extractLegacyApiApplications(text
))){
5826 // buildDetectRe.test(text) => a built module, always AMD
5827 // extractResult==0 => no sync API
5831 // manufacture a synthetic module id that can never be a real mdule id (just like require does)
5832 id
= module
.mid
+ "-*loadInit";
5834 // construct the dojo/loadInit names vector which causes any relocated names to be defined as lexical variables under their not-relocated name
5835 // the dojo/loadInit plugin assumes the first name in names is "dojo"
5837 for(var p
in getModule("dojo", module
).result
.scopeMap
){
5839 namesAsStrings
.push('"' + p
+ '"');
5842 // rewrite the module as a synthetic dojo/loadInit plugin resource + the module expressed as an AMD module that depends on this synthetic resource
5843 // don't have to map dojo/init since that will occur when the dependency is resolved
5844 return "// xdomain rewrite of " + module
.mid
+ "\n" +
5845 "define('" + id
+ "',{\n" +
5846 "\tnames:" + dojo
.toJson(names
) + ",\n" +
5847 "\tdef:function(" + names
.join(",") + "){" + extractResult
[1] + "}" +
5849 "define(" + dojo
.toJson(names
.concat(["dojo/loadInit!"+id
])) + ", function(" + names
.join(",") + "){\n" + extractResult
[0] + "});";
5852 loaderVars
= require
.initSyncLoader(dojoRequirePlugin
, checkDojoRequirePlugin
, transformToAmd
),
5858 loaderVars
.requested
,
5864 loaderVars
.nonmodule
,
5867 loaderVars
.executing
,
5870 loaderVars
.executed
,
5873 loaderVars
.syncExecStack
,
5882 loaderVars
.getModule
,
5885 loaderVars
.injectModule
,
5888 loaderVars
.setArrived
,
5894 loaderVars
.finishExec
,
5897 loaderVars
.execModule
,
5900 loaderVars
.getLegacyMode
,
5902 guardCheckComplete
=
5903 loaderVars
.guardCheckComplete
;
5905 // there is exactly one dojoRequirePlugin among possibly-many dojo/_base/loader's (owing to mapping)
5906 dojoRequirePlugin
= loaderVars
.dojoRequirePlugin
;
5908 dojo
.provide = function(mid
){
5909 var executingModule
= syncExecStack
[0],
5910 module
= lang
.mixin(getModule(slashName(mid
), require
.module
), {
5912 result
:lang
.getObject(mid
, true)
5915 if(executingModule
){
5916 (executingModule
.provides
|| (executingModule
.provides
= [])).push(function(){
5917 module
.result
= lang
.getObject(mid
);
5918 delete module
.provides
;
5919 module
.executed
!==executed
&& finishExec(module
);
5921 }// else dojo.provide called not consequent to loading; therefore, give up trying to publish module value to loader namespace
5922 return module
.result
;
5925 has
.add("config-publishRequireResult", 1, 0, 0);
5927 dojo
.require = function(moduleName
, omitModuleCheck
) {
5929 // loads a Javascript module from the appropriate URI
5931 // moduleName: String
5932 // module name to load, using periods for separators,
5933 // e.g. "dojo.date.locale". Module paths are de-referenced by dojo's
5934 // internal mapping of locations to names and are disambiguated by
5935 // longest prefix. See `dojo.registerModulePath()` for details on
5936 // registering new modules.
5938 // omitModuleCheck: Boolean?
5939 // if `true`, omitModuleCheck skips the step of ensuring that the
5940 // loaded file actually defines the symbol it is referenced by.
5941 // For example if it called as `dojo.require("a.b.c")` and the
5942 // file located at `a/b/c.js` does not define an object `a.b.c`,
5943 // and exception will be throws whereas no exception is raised
5944 // when called as `dojo.require("a.b.c", true)`
5947 // Modules are loaded via dojo.require by using one of two loaders: the normal loader
5948 // and the xdomain loader. The xdomain loader is used when dojo was built with a
5949 // custom build that specified loader=xdomain and the module lives on a modulePath
5950 // that is a whole URL, with protocol and a domain. The versions of Dojo that are on
5951 // the Google and AOL CDNs use the xdomain loader.
5953 // If the module is loaded via the xdomain loader, it is an asynchronous load, since
5954 // the module is added via a dynamically created script tag. This
5955 // means that dojo.require() can return before the module has loaded. However, this
5956 // should only happen in the case where you do dojo.require calls in the top-level
5957 // HTML page, or if you purposely avoid the loader checking for dojo.require
5958 // dependencies in your module by using a syntax like dojo["require"] to load the module.
5960 // Sometimes it is useful to not have the loader detect the dojo.require calls in the
5961 // module so that you can dynamically load the modules as a result of an action on the
5962 // page, instead of right at module load time.
5964 // Also, for script blocks in an HTML page, the loader does not pre-process them, so
5965 // it does not know to download the modules before the dojo.require calls occur.
5967 // So, in those two cases, when you want on-the-fly module loading or for script blocks
5968 // in the HTML page, special care must be taken if the dojo.required code is loaded
5969 // asynchronously. To make sure you can execute code that depends on the dojo.required
5970 // modules, be sure to add the code that depends on the modules in a dojo.addOnLoad()
5971 // callback. dojo.addOnLoad waits for all outstanding modules to finish loading before
5974 // This type of syntax works with both xdomain and normal loaders, so it is good
5975 // practice to always use this idiom for on-the-fly code loading and in HTML script
5976 // blocks. If at some point you change loaders and where the code is loaded from,
5977 // it will all still work.
5979 // More on how dojo.require
5980 // `dojo.require("A.B")` first checks to see if symbol A.B is
5981 // defined. If it is, it is simply returned (nothing to do).
5983 // If it is not defined, it will look for `A/B.js` in the script root
5986 // `dojo.require` throws an exception if it cannot find a file
5987 // to load, or if the symbol `A.B` is not defined after loading.
5989 // It returns the object `A.B`, but note the caveats above about on-the-fly loading and
5990 // HTML script blocks when the xdomain loader is loading a module.
5992 // `dojo.require()` does nothing about importing symbols into
5993 // the current namespace. It is presumed that the caller will
5994 // take care of that.
5997 // To use dojo.require in conjunction with dojo.ready:
5999 // | dojo.require("foo");
6000 // | dojo.require("bar");
6001 // | dojo.addOnLoad(function(){
6002 // | //you can now safely do something with foo and bar
6006 // For example, to import all symbols into a local block, you might write:
6008 // | with (dojo.require("A.B")) {
6012 // And to import just the leaf symbol to a local variable:
6014 // | var B = dojo.require("A.B");
6018 // the required namespace object
6019 function doRequire(mid
, omitModuleCheck
){
6020 var module
= getModule(slashName(mid
), require
.module
);
6021 if(syncExecStack
.length
&& syncExecStack
[0].finish
){
6022 // switched to async loading in the middle of evaluating a legacy module; stop
6023 // applying dojo.require so the remaining dojo.requires are applied in order
6024 syncExecStack
[0].finish
.push(mid
);
6028 // recall module.executed has values {0, executing, executed}; therefore, truthy indicates executing or executed
6029 if(module
.executed
){
6030 return module
.result
;
6032 omitModuleCheck
&& (module
.result
= nonmodule
);
6034 // rcg...why here and in two lines??
6035 var currentMode
= getLegacyMode();
6037 // recall, in sync mode to inject is to *eval* the module text
6038 // if the module is a legacy module, this is the same as executing
6039 // but if the module is an AMD module, this means defining, not executing
6040 injectModule(module
);
6041 // the inject may have changed the mode
6042 currentMode
= getLegacyMode();
6044 // in sync mode to dojo.require is to execute
6045 if(module
.executed
!==executed
&& module
.injected
===arrived
){
6046 // the module was already here before injectModule was called probably finishing up a xdomain
6047 // load, but maybe a module given to the loader directly rather than having the loader retrieve it
6049 loaderVars
.guardCheckComplete(function(){
6053 if(module
.executed
){
6054 return module
.result
;
6057 if(currentMode
==sync
){
6058 // the only way to get here is in sync mode and dojo.required a module that
6059 // * was loaded async in the injectModule application a few lines up
6060 // * was an AMD module that had deps that are being loaded async and therefore couldn't execute
6062 // the module was an AMD module; unshift, not push, which causes the current traversal to be reattempted from the top
6063 execQ
.unshift(module
);
6065 // the module was a legacy module
6066 syncExecStack
.length
&& (syncExecStack
[0].finish
= [mid
]);
6069 // the loader wasn't in sync mode on entry; probably async mode; therefore, no expectation of getting
6070 // the module value synchronously; make sure it gets executed though
6077 var result
= doRequire(moduleName
, omitModuleCheck
);
6078 if(has("config-publishRequireResult") && !lang
.exists(moduleName
) && result
!==undefined){
6079 lang
.setObject(moduleName
, result
);
6084 dojo
.loadInit = function(f
) {
6088 dojo
.registerModulePath = function(/*String*/moduleName
, /*String*/prefix
){
6090 // Maps a module name to a path
6092 // An unregistered module is given the default path of ../[module],
6093 // relative to Dojo root. For example, module acme is mapped to
6094 // ../acme. If you want to use a different module name, use
6095 // dojo.registerModulePath.
6097 // If your dojo.js is located at this location in the web root:
6098 // | /myapp/js/dojo/dojo/dojo.js
6099 // and your modules are located at:
6100 // | /myapp/js/foo/bar.js
6101 // | /myapp/js/foo/baz.js
6102 // | /myapp/js/foo/thud/xyzzy.js
6103 // Your application can tell Dojo to locate the "foo" namespace by calling:
6104 // | dojo.registerModulePath("foo", "../../foo");
6105 // At which point you can then use dojo.require() to load the
6106 // modules (assuming they provide() the same things which are
6107 // required). The full code might be:
6108 // | <script type="text/javascript"
6109 // | src="/myapp/js/dojo/dojo/dojo.js"></script>
6110 // | <script type="text/javascript">
6111 // | dojo.registerModulePath("foo", "../../foo");
6112 // | dojo.require("foo.bar");
6113 // | dojo.require("foo.baz");
6114 // | dojo.require("foo.thud.xyzzy");
6118 paths
[moduleName
.replace(/\./g, "/")] = prefix
;
6119 require({paths
:paths
});
6122 dojo
.platformRequire = function(/*Object*/modMap
){
6124 // require one or more modules based on which host environment
6125 // Dojo is currently operating in
6127 // This method takes a "map" of arrays which one can use to
6128 // optionally load dojo modules. The map is indexed by the
6129 // possible dojo.name_ values, with two additional values:
6130 // "default" and "common". The items in the "default" array will
6131 // be loaded if none of the other items have been choosen based on
6132 // dojo.name_, set by your host environment. The items in the
6133 // "common" array will *always* be loaded, regardless of which
6136 // | dojo.platformRequire({
6138 // | "foo.sample", // simple module
6140 // | ["foo.bar.baz", true] // skip object check in _loadModule (dojo.require)
6142 // | default: [ "foo.sample._base" ],
6143 // | common: [ "important.module.common" ]
6146 var result
= (modMap
.common
|| []).concat(modMap
[dojo
._name
] || modMap
["default"] || []),
6148 while(result
.length
){
6149 if(lang
.isArray(temp
= result
.shift())){
6150 dojo
.require
.apply(dojo
, temp
);
6157 dojo
.requireIf
= dojo
.requireAfterIf = function(/*Boolean*/ condition
, /*String*/ moduleName
, /*Boolean?*/omitModuleCheck
){
6159 // If the condition is true then call `dojo.require()` for the specified
6163 // | dojo.requireIf(dojo.isBrowser, "my.special.Module");
6166 dojo
.require(moduleName
, omitModuleCheck
);
6170 dojo
.requireLocalization = function(/*String*/moduleName
, /*String*/bundleName
, /*String?*/locale
){
6171 require(["../i18n"], function(i18n
){
6172 i18n
.getLocalization(moduleName
, bundleName
, locale
);
6178 // This module defines the v1.x synchronous loader API.
6180 extractLegacyApiApplications
:extractLegacyApiApplications
,
6181 require
:dojoRequirePlugin
,
6182 loadInit
:dojoLoadInitPlugin
6187 'dojo/json':function(){
6188 define(["./has"], function(has
){
6190 var hasJSON
= typeof JSON
!= "undefined";
6191 has
.add("json-parse", hasJSON
); // all the parsers work fine
6192 // Firefox 3.5/Gecko 1.9 fails to use replacer in stringify properly https://bugzilla.mozilla.org/show_bug.cgi?id=509184
6193 has
.add("json-stringify", hasJSON
&& JSON
.stringify({a
:0}, function(k
,v
){return v
||1;}) == '{"a":1}');
6198 // Functions to parse and serialize JSON
6200 parse: function(str, strict){
6202 // Parses a [JSON](http://json.org) string to return a JavaScript object.
6204 // This function follows [native JSON API](https://developer.mozilla.org/en/JSON)
6205 // Throws for invalid JSON strings. This delegates to eval() if native JSON
6206 // support is not available. By default this will evaluate any valid JS expression.
6207 // With the strict parameter set to true, the parser will ensure that only
6208 // valid JSON strings are parsed (otherwise throwing an error). Without the strict
6209 // parameter, the content passed to this method must come
6210 // from a trusted source.
6212 // a string literal of a JSON item, for instance:
6213 // `'{ "foo": [ "bar", 1, { "baz": "thud" } ] }'`
6215 // When set to true, this will ensure that only valid, secure JSON is ever parsed.
6216 // Make sure this is set to true for untrusted content. Note that on browsers/engines
6217 // without native JSON support, setting this to true will run slower.
6219 stringify: function(value, replacer, spacer){
6221 // Returns a [JSON](http://json.org) serialization of an object.
6223 // Returns a [JSON](http://json.org) serialization of an object.
6224 // This function follows [native JSON API](https://developer.mozilla.org/en/JSON)
6225 // Note that this doesn't check for infinite recursion, so don't do that!
6227 // A value to be serialized.
6229 // A replacer function that is called for each value and can return a replacement
6231 // A spacer string to be used for pretty printing of JSON
6233 // simple serialization of a trivial object
6234 // | define(["dojo/json"], function(JSON){
6235 // | var jsonStr = JSON.stringify({ howdy: "stranger!", isStrange: true });
6236 // | doh.is('{"howdy":"stranger!","isStrange":true}', jsonStr);
6241 if(has("json-stringify")){
6244 var escapeString = function(/*String*/str
){
6246 // Adds escape sequences for non-visual characters, double quote and
6247 // backslash and surrounds with double quotes to form a valid string
6249 return ('"' + str
.replace(/(["\\])/g, '\\$1') + '"').
6250 replace(/[\f]/g, "\\f").replace(/[\b]/g, "\\b").replace(/[\n]/g, "\\n").
6251 replace(/[\t]/g, "\\t").replace(/[\r]/g, "\\r"); // string
6254 parse
: has("json-parse") ? JSON
.parse : function(str
, strict
){
6255 if(strict
&& !/^([\s\[\{]*(?:"(?:\\.|[^"])+"|-?\d[\d\.]*(?:[Ee][+-]?\d+)?|null|true|false|)[\s\]\}]*(?:,|:|$))+$/.test(str
)){
6256 throw new SyntaxError("Invalid characters in JSON");
6258 return eval('(' + str
+ ')');
6260 stringify: function(value
, replacer
, spacer
){
6262 if(typeof replacer
== "string"){
6266 function stringify(it
, indent
, key
){
6268 it
= replacer(key
, it
);
6270 var val
, objtype
= typeof it
;
6271 if(objtype
== "number"){
6272 return isFinite(it
) ? it
+ "" : "null";
6274 if(objtype
== "boolean"){
6280 if(typeof it
== "string"){
6281 return escapeString(it
);
6283 if(objtype
== "function" || objtype
== "undefined"){
6284 return undef
; // undefined
6286 // short-circuit for objects that support "json" serialization
6287 // if they return "self" then just pass-through...
6288 if(typeof it
.toJSON
== "function"){
6289 return stringify(it
.toJSON(key
), indent
, key
);
6291 if(it
instanceof Date
){
6292 return '"{FullYear}-{Month+}-{Date}T{Hours}:{Minutes}:{Seconds}Z"'.replace(/\{(\w+)(\+)?\}/g, function(t
, prop
, plus
){
6293 var num
= it
["getUTC" + prop
]() + (plus
? 1 : 0);
6294 return num
< 10 ? "0" + num
: num
;
6297 if(it
.valueOf() !== it
){
6298 // primitive wrapper, try again unwrapped:
6299 return stringify(it
.valueOf(), indent
, key
);
6301 var nextIndent
= spacer
? (indent
+ spacer
) : "";
6302 /* we used to test for DOM nodes and throw, but FF serializes them as {}, so cross-browser consistency is probably not efficiently attainable */
6304 var sep
= spacer
? " " : "";
6305 var newLine
= spacer
? "\n" : "";
6308 if(it
instanceof Array
){
6309 var itl
= it
.length
, res
= [];
6310 for(key
= 0; key
< itl
; key
++){
6312 val
= stringify(obj
, nextIndent
, key
);
6313 if(typeof val
!= "string"){
6316 res
.push(newLine
+ nextIndent
+ val
);
6318 return "[" + res
.join(",") + newLine
+ indent
+ "]";
6320 // generic object code path
6324 if(it
.hasOwnProperty(key
)){
6325 if(typeof key
== "number"){
6326 keyStr
= '"' + key
+ '"';
6327 }else if(typeof key
== "string"){
6328 keyStr
= escapeString(key
);
6330 // skip non-string or number keys
6333 val
= stringify(it
[key
], nextIndent
, key
);
6334 if(typeof val
!= "string"){
6335 // skip non-serializable values
6338 // At this point, the most non-IE browsers don't get in this branch
6339 // (they have native JSON), so push is definitely the way to
6340 output
.push(newLine
+ nextIndent
+ keyStr
+ ":" + sep
+ val
);
6343 return "{" + output
.join(",") + newLine
+ indent
+ "}"; // String
6345 return stringify(value
, "", "");
6352 'dojo/_base/declare':function(){
6353 define(["./kernel", "../has", "./lang"], function(dojo
, has
, lang
){
6355 // dojo/_base/declare
6357 var mix
= lang
.mixin
, op
= Object
.prototype, opts
= op
.toString
,
6358 xtor
= new Function
, counter
= 0, cname
= "constructor";
6360 function err(msg
, cls
){ throw new Error("declare" + (cls
? " " + cls
: "") + ": " + msg
); }
6362 // C3 Method Resolution Order (see http://www.python.org/download/releases/2.3/mro/)
6363 function c3mro(bases
, className
){
6364 var result
= [], roots
= [{cls
: 0, refs
: []}], nameMap
= {}, clsCount
= 1,
6365 l
= bases
.length
, i
= 0, j
, lin
, base
, top
, proto
, rec
, name
, refs
;
6367 // build a list of bases naming them if needed
6371 err("mixin #" + i
+ " is unknown. Did you use dojo.require to pull it in?", className
);
6372 }else if(opts
.call(base
) != "[object Function]"){
6373 err("mixin #" + i
+ " is not a callable constructor.", className
);
6375 lin
= base
._meta
? base
._meta
.bases
: [base
];
6377 // add bases to the name map
6378 for(j
= lin
.length
- 1; j
>= 0; --j
){
6379 proto
= lin
[j
].prototype;
6380 if(!proto
.hasOwnProperty("declaredClass")){
6381 proto
.declaredClass
= "uniqName_" + (counter
++);
6383 name
= proto
.declaredClass
;
6384 if(!nameMap
.hasOwnProperty(name
)){
6385 nameMap
[name
] = {count
: 0, refs
: [], cls
: lin
[j
]};
6388 rec
= nameMap
[name
];
6389 if(top
&& top
!== rec
){
6396 roots
[0].refs
.push(top
);
6399 // remove classes without external references recursively
6400 while(roots
.length
){
6402 result
.push(top
.cls
);
6404 // optimization: follow a single-linked chain
6405 while(refs
= top
.refs
, refs
.length
== 1){
6407 if(!top
|| --top
.count
){
6408 // branch or end of chain => do not end to roots
6412 result
.push(top
.cls
);
6417 for(i
= 0, l
= refs
.length
; i
< l
; ++i
){
6426 err("can't build consistent linearization", className
);
6429 // calculate the superclass offset
6432 base
._meta
&& base
=== result
[result
.length
- base
._meta
.bases
.length
] ?
6433 base
._meta
.bases
.length
: 1 : 0;
6438 function inherited(args
, a
, f
){
6439 var name
, chains
, bases
, caller
, meta
, base
, proto
, opf
, pos
,
6440 cache
= this._inherited
= this._inherited
|| {};
6443 if(typeof args
== "string"){
6450 caller
= args
.callee
;
6451 name
= name
|| caller
.nom
;
6453 err("can't deduce a name to call inherited()", this.declaredClass
);
6456 meta
= this.constructor._meta
;
6462 if(cache
.c
!== caller
){
6467 if(meta
.hidden
[name
] !== caller
){
6469 chains
= meta
.chains
;
6470 if(chains
&& typeof chains
[name
] == "string"){
6471 err("calling chained method with inherited: " + name
, this.declaredClass
);
6476 proto
= base
.prototype;
6477 if(meta
&& (proto
[name
] === caller
&& proto
.hasOwnProperty(name
) || meta
.hidden
[name
] === caller
)){
6480 }while(base
= bases
[++pos
]); // intentional assignment
6481 pos
= base
? pos
: -1;
6485 base
= bases
[++pos
];
6487 proto
= base
.prototype;
6488 if(base
._meta
&& proto
.hasOwnProperty(name
)){
6493 proto
= base
.prototype;
6495 if(f
&& (base
._meta
? proto
.hasOwnProperty(name
) : f
!== opf
)){
6498 }while(base
= bases
[++pos
]); // intentional assignment
6501 f
= base
&& f
|| op
[name
];
6504 if(cache
.c
!== caller
){
6507 meta
= bases
[0]._meta
;
6508 if(meta
&& meta
.ctor
!== caller
){
6510 chains
= meta
.chains
;
6511 if(!chains
|| chains
.constructor !== "manual"){
6512 err("calling chained constructor with inherited", this.declaredClass
);
6515 while(base
= bases
[++pos
]){ // intentional assignment
6517 if(meta
&& meta
.ctor
=== caller
){
6521 pos
= base
? pos
: -1;
6525 while(base
= bases
[++pos
]){ // intentional assignment
6527 f
= meta
? meta
.ctor
: base
;
6535 // cache the found super method
6539 // now we have the result
6541 return a
=== true ? f
: f
.apply(this, a
|| args
);
6543 // intentionally no return if a super method was not found
6546 function getInherited(name
, args
){
6547 if(typeof name
== "string"){
6548 return this.__inherited(name
, args
, true);
6550 return this.__inherited(name
, true);
6553 function inherited__debug(args
, a1
, a2
){
6554 var f
= this.getInherited(args
, a1
);
6555 if(f
){ return f
.apply(this, a2
|| a1
|| args
); }
6556 // intentionally no return if a super method was not found
6559 var inheritedImpl
= dojo
.config
.isDebug
? inherited__debug
: inherited
;
6561 // emulation of "instanceof"
6562 function isInstanceOf(cls
){
6563 var bases
= this.constructor._meta
.bases
;
6564 for(var i
= 0, l
= bases
.length
; i
< l
; ++i
){
6565 if(bases
[i
] === cls
){
6569 return this instanceof cls
;
6572 function mixOwn(target
, source
){
6573 // add props adding metadata for incoming functions skipping a constructor
6574 for(var name
in source
){
6575 if(name
!= cname
&& source
.hasOwnProperty(name
)){
6576 target
[name
] = source
[name
];
6579 if(has("bug-for-in-skips-shadowed")){
6580 for(var extraNames
= lang
._extraNames
, i
= extraNames
.length
; i
;){
6581 name
= extraNames
[--i
];
6582 if(name
!= cname
&& source
.hasOwnProperty(name
)){
6583 target
[name
] = source
[name
];
6589 // implementation of safe mixin function
6590 function safeMixin(target
, source
){
6592 // Mix in properties skipping a constructor and decorating functions
6593 // like it is done by declare().
6595 // Target object to accept new properties.
6597 // Source object for new properties.
6599 // This function is used to mix in properties like lang.mixin does,
6600 // but it skips a constructor property and decorates functions like
6603 // It is meant to be used with classes and objects produced with
6604 // declare. Functions mixed in with dojo.safeMixin can use
6605 // this.inherited() like normal methods.
6607 // This function is used to implement extend() method of a constructor
6608 // produced with declare().
6611 // | var A = declare(null, {
6612 // | m1: function(){
6613 // | console.log("A.m1");
6615 // | m2: function(){
6616 // | console.log("A.m2");
6619 // | var B = declare(A, {
6620 // | m1: function(){
6621 // | this.inherited(arguments);
6622 // | console.log("B.m1");
6626 // | m2: function(){
6627 // | this.inherited(arguments);
6628 // | console.log("B.m2");
6631 // | var x = new B();
6632 // | dojo.safeMixin(x, {
6633 // | m1: function(){
6634 // | this.inherited(arguments);
6635 // | console.log("X.m1");
6637 // | m2: function(){
6638 // | this.inherited(arguments);
6639 // | console.log("X.m2");
6649 // add props adding metadata for incoming functions skipping a constructor
6650 for(name
in source
){
6652 if((t
!== op
[name
] || !(name
in op
)) && name
!= cname
){
6653 if(opts
.call(t
) == "[object Function]"){
6654 // non-trivial function method => attach its name
6660 if(has("bug-for-in-skips-shadowed")){
6661 for(var extraNames
= lang
._extraNames
, i
= extraNames
.length
; i
;){
6662 name
= extraNames
[--i
];
6664 if((t
!== op
[name
] || !(name
in op
)) && name
!= cname
){
6665 if(opts
.call(t
) == "[object Function]"){
6666 // non-trivial function method => attach its name
6676 function extend(source
){
6677 declare
.safeMixin(this.prototype, source
);
6681 function createSubclass(mixins
){
6682 return declare([this].concat(mixins
));
6685 // chained constructor compatible with the legacy declare()
6686 function chainedConstructor(bases
, ctorSpecial
){
6688 var a
= arguments
, args
= a
, a0
= a
[0], f
, i
, m
,
6689 l
= bases
.length
, preArgs
;
6691 if(!(this instanceof a
.callee
)){
6692 // not called via new, so force it
6696 //this._inherited = {};
6697 // perform the shaman's rituals of the original declare()
6698 // 1) call two types of the preamble
6699 if(ctorSpecial
&& (a0
&& a0
.preamble
|| this.preamble
)){
6700 // full blown ritual
6701 preArgs
= new Array(bases
.length
);
6702 // prepare parameters
6705 // process the preamble of the 1st argument
6710 a
= f
.apply(this, a
) || a
;
6713 // process the preamble of this class
6714 f
= bases
[i
].prototype;
6715 f
= f
.hasOwnProperty("preamble") && f
.preamble
;
6717 a
= f
.apply(this, a
) || a
;
6719 // one peculiarity of the preamble:
6720 // it is called if it is not needed,
6721 // e.g., there is no constructor to call
6722 // let's watch for the last constructor
6723 // (see ticket #9795)
6730 // 2) call all non-trivial constructors using prepared arguments
6731 for(i
= l
- 1; i
>= 0; --i
){
6736 f
.apply(this, preArgs
? preArgs
[i
] : a
);
6739 // 3) continue the original ritual: call the postscript
6740 f
= this.postscript
;
6742 f
.apply(this, args
);
6748 // chained constructor compatible with the legacy declare()
6749 function singleConstructor(ctor
, ctorSpecial
){
6751 var a
= arguments
, t
= a
, a0
= a
[0], f
;
6753 if(!(this instanceof a
.callee
)){
6754 // not called via new, so force it
6758 //this._inherited = {};
6759 // perform the shaman's rituals of the original declare()
6760 // 1) call two types of the preamble
6762 // full blown ritual
6764 // process the preamble of the 1st argument
6767 t
= f
.apply(this, t
) || t
;
6772 // process the preamble of this class
6774 // one peculiarity of the preamble:
6775 // it is called even if it is not needed,
6776 // e.g., there is no constructor to call
6777 // let's watch for the last constructor
6778 // (see ticket #9795)
6781 // 2) call a constructor
6783 ctor
.apply(this, a
);
6785 // 3) continue the original ritual: call the postscript
6786 f
= this.postscript
;
6793 // plain vanilla constructor (can use inherited() to call its base constructor)
6794 function simpleConstructor(bases
){
6796 var a
= arguments
, i
= 0, f
, m
;
6798 if(!(this instanceof a
.callee
)){
6799 // not called via new, so force it
6803 //this._inherited = {};
6804 // perform the shaman's rituals of the original declare()
6805 // 1) do not call the preamble
6806 // 2) call the top constructor (it can use this.inherited())
6807 for(; f
= bases
[i
]; ++i
){ // intentional assignment
6815 // 3) call the postscript
6816 f
= this.postscript
;
6823 function chain(name
, bases
, reversed
){
6825 var b
, m
, f
, i
= 0, step
= 1;
6827 i
= bases
.length
- 1;
6830 for(; b
= bases
[i
]; i
+= step
){ // intentional assignment
6832 f
= (m
? m
.hidden
: b
.prototype)[name
];
6834 f
.apply(this, arguments
);
6841 // return a new object that inherits from ctor.prototype but
6842 // without actually running ctor on the object.
6843 function forceNew(ctor
){
6844 // create object with correct prototype using a do-nothing
6846 xtor
.prototype = ctor
.prototype;
6848 xtor
.prototype = null; // clean up
6853 // just like 'new ctor()' except that the constructor and its arguments come
6854 // from args, which must be an array or an arguments object
6855 function applyNew(args
){
6856 // create an object with ctor's prototype but without
6857 // calling ctor on it.
6858 var ctor
= args
.callee
, t
= forceNew(ctor
);
6859 // execute the real constructor on the new object
6860 ctor
.apply(t
, args
);
6864 function declare(className
, superclass
, props
){
6866 // Create a feature-rich constructor from compact notation.
6867 // className: String?
6868 // The optional name of the constructor (loosely, a "class")
6869 // stored in the "declaredClass" property in the created prototype.
6870 // It will be used as a global name for a created constructor.
6871 // superclass: Function|Function[]
6872 // May be null, a Function, or an Array of Functions. This argument
6873 // specifies a list of bases (the left-most one is the most deepest
6876 // An object whose properties are copied to the created prototype.
6877 // Add an instance-initialization function by making it a property
6878 // named "constructor".
6879 // returns: dojo/_base/declare.__DeclareCreatedObject
6880 // New constructor function.
6882 // Create a constructor using a compact notation for inheritance and
6883 // prototype extension.
6885 // Mixin ancestors provide a type of multiple inheritance.
6886 // Prototypes of mixin ancestors are copied to the new class:
6887 // changes to mixin prototypes will not affect classes to which
6888 // they have been mixed in.
6890 // Ancestors can be compound classes created by this version of
6891 // declare(). In complex cases all base classes are going to be
6892 // linearized according to C3 MRO algorithm
6893 // (see http://www.python.org/download/releases/2.3/mro/ for more
6896 // "className" is cached in "declaredClass" property of the new class,
6897 // if it was supplied. The immediate super class will be cached in
6898 // "superclass" property of the new class.
6900 // Methods in "props" will be copied and modified: "nom" property
6901 // (the declared name of the method) will be added to all copied
6902 // functions to help identify them for the internal machinery. Be
6903 // very careful, while reusing methods: if you use the same
6904 // function under different names, it can produce errors in some
6907 // It is possible to use constructors created "manually" (without
6908 // declare()) as bases. They will be called as usual during the
6909 // creation of an instance, their methods will be chained, and even
6910 // called by "this.inherited()".
6912 // Special property "-chains-" governs how to chain methods. It is
6913 // a dictionary, which uses method names as keys, and hint strings
6914 // as values. If a hint string is "after", this method will be
6915 // called after methods of its base classes. If a hint string is
6916 // "before", this method will be called before methods of its base
6919 // If "constructor" is not mentioned in "-chains-" property, it will
6920 // be chained using the legacy mode: using "after" chaining,
6921 // calling preamble() method before each constructor, if available,
6922 // and calling postscript() after all constructors were executed.
6923 // If the hint is "after", it is chained as a regular method, but
6924 // postscript() will be called after the chain of constructors.
6925 // "constructor" cannot be chained "before", but it allows
6926 // a special hint string: "manual", which means that constructors
6927 // are not going to be chained in any way, and programmer will call
6928 // them manually using this.inherited(). In the latter case
6929 // postscript() will be called after the construction.
6931 // All chaining hints are "inherited" from base classes and
6932 // potentially can be overridden. Be very careful when overriding
6933 // hints! Make sure that all chained methods can work in a proposed
6934 // manner of chaining.
6936 // Once a method was chained, it is impossible to unchain it. The
6937 // only exception is "constructor". You don't need to define a
6938 // method in order to supply a chaining hint.
6940 // If a method is chained, it cannot use this.inherited() because
6941 // all other methods in the hierarchy will be called automatically.
6943 // Usually constructors and initializers of any kind are chained
6944 // using "after" and destructors of any kind are chained as
6945 // "before". Note that chaining assumes that chained methods do not
6946 // return any value: any returned value will be discarded.
6949 // | declare("my.classes.bar", my.classes.foo, {
6950 // | // properties to be added to the class prototype
6952 // | // initialization function
6953 // | constructor: function(){
6954 // | this.myComplicatedObject = new ReallyComplicatedObject();
6956 // | // other functions
6957 // | someMethod: function(){
6963 // | var MyBase = declare(null, {
6964 // | // constructor, properties, and methods go here
6967 // | var MyClass1 = declare(MyBase, {
6968 // | // constructor, properties, and methods go here
6971 // | var MyClass2 = declare(MyBase, {
6972 // | // constructor, properties, and methods go here
6975 // | var MyDiamond = declare([MyClass1, MyClass2], {
6976 // | // constructor, properties, and methods go here
6981 // | var F = function(){ console.log("raw constructor"); };
6982 // | F.prototype.method = function(){
6983 // | console.log("raw method");
6985 // | var A = declare(F, {
6986 // | constructor: function(){
6987 // | console.log("A.constructor");
6989 // | method: function(){
6990 // | console.log("before calling F.method...");
6991 // | this.inherited(arguments);
6992 // | console.log("...back in A");
6995 // | new A().method();
6997 // | // raw constructor
6998 // | // A.constructor
6999 // | // before calling F.method...
7001 // | // ...back in A
7004 // | var A = declare(null, {
7006 // | destroy: "before"
7009 // | var B = declare(A, {
7010 // | constructor: function(){
7011 // | console.log("B.constructor");
7013 // | destroy: function(){
7014 // | console.log("B.destroy");
7017 // | var C = declare(B, {
7018 // | constructor: function(){
7019 // | console.log("C.constructor");
7021 // | destroy: function(){
7022 // | console.log("C.destroy");
7025 // | new C().destroy();
7027 // | // B.constructor
7028 // | // C.constructor
7033 // | var A = declare(null, {
7035 // | constructor: "manual"
7038 // | var B = declare(A, {
7039 // | constructor: function(){
7041 // | // call the base constructor with new parameters
7042 // | this.inherited(arguments, [1, 2, 3]);
7048 // | var A = declare(null, {
7052 // | m1: function(){
7053 // | console.log("A.m1");
7055 // | m2: function(){
7056 // | console.log("A.m2");
7059 // | var B = declare(A, {
7063 // | m1: function(){
7064 // | console.log("B.m1");
7066 // | m2: function(){
7067 // | console.log("B.m2");
7070 // | var x = new B();
7081 if(typeof className
!= "string"){
7083 superclass
= className
;
7086 props
= props
|| {};
7088 var proto
, i
, t
, ctor
, name
, bases
, chains
, mixins
= 1, parents
= superclass
;
7090 // build a prototype
7091 if(opts
.call(superclass
) == "[object Array]"){
7093 bases
= c3mro(superclass
, className
);
7095 mixins
= bases
.length
- t
;
7096 superclass
= bases
[mixins
];
7100 if(opts
.call(superclass
) == "[object Function]"){
7101 t
= superclass
._meta
;
7102 bases
= bases
.concat(t
? t
.bases
: superclass
);
7104 err("base class is not a callable constructor.", className
);
7106 }else if(superclass
!== null){
7107 err("unknown base class. Did you use dojo.require to pull it in?", className
);
7111 for(i
= mixins
- 1;; --i
){
7112 proto
= forceNew(superclass
);
7114 // stop if nothing to add (the last base)
7117 // mix in properties
7119 (t
._meta
? mixOwn
: mix
)(proto
, t
.prototype);
7120 // chain in new constructor
7121 ctor
= new Function
;
7122 ctor
.superclass
= superclass
;
7123 ctor
.prototype = proto
;
7124 superclass
= proto
.constructor = ctor
;
7129 // add all properties
7130 declare
.safeMixin(proto
, props
);
7132 t
= props
.constructor;
7133 if(t
!== op
.constructor){
7135 proto
.constructor = t
;
7138 // collect chains and flags
7139 for(i
= mixins
- 1; i
; --i
){ // intentional assignment
7142 chains
= mix(chains
|| {}, t
.chains
);
7145 if(proto
["-chains-"]){
7146 chains
= mix(chains
|| {}, proto
["-chains-"]);
7150 t
= !chains
|| !chains
.hasOwnProperty(cname
);
7151 bases
[0] = ctor
= (chains
&& chains
.constructor === "manual") ? simpleConstructor(bases
) :
7152 (bases
.length
== 1 ? singleConstructor(props
.constructor, t
) : chainedConstructor(bases
, t
));
7154 // add meta information to the constructor
7155 ctor
._meta
= {bases
: bases
, hidden
: props
, chains
: chains
,
7156 parents
: parents
, ctor
: props
.constructor};
7157 ctor
.superclass
= superclass
&& superclass
.prototype;
7158 ctor
.extend
= extend
;
7159 ctor
.createSubclass
= createSubclass
;
7160 ctor
.prototype = proto
;
7161 proto
.constructor = ctor
;
7163 // add "standard" methods to the prototype
7164 proto
.getInherited
= getInherited
;
7165 proto
.isInstanceOf
= isInstanceOf
;
7166 proto
.inherited
= inheritedImpl
;
7167 proto
.__inherited
= inherited
;
7169 // add name if specified
7171 proto
.declaredClass
= className
;
7172 lang
.setObject(className
, ctor
);
7175 // build chains and add them to the prototype
7177 for(name
in chains
){
7178 if(proto
[name
] && typeof chains
[name
] == "string" && name
!= cname
){
7179 t
= proto
[name
] = chain(name
, bases
, chains
[name
] === "after");
7184 // chained methods do not return values
7185 // no need to chain "invisible" functions
7187 return ctor
; // Function
7191 declare.__DeclareCreatedObject = {
7193 // dojo/_base/declare() returns a constructor `C`. `new C()` returns an Object with the following
7194 // methods, in addition to the methods and properties specified via the arguments passed to declare().
7196 inherited: function(name, args, newArgs){
7198 // Calls a super method.
7200 // The optional method name. Should be the same as the caller's
7201 // name. Usually "name" is specified in complex dynamic cases, when
7202 // the calling method was dynamically added, undecorated by
7203 // declare(), and it cannot be determined.
7205 // The caller supply this argument, which should be the original
7208 // If "true", the found function will be returned without
7210 // If Array, it will be used to call a super method. Otherwise
7211 // "args" will be used.
7213 // Whatever is returned by a super method, or a super method itself,
7214 // if "true" was specified as newArgs.
7216 // This method is used inside method of classes produced with
7217 // declare() to call a super method (next in the chain). It is
7218 // used for manually controlled chaining. Consider using the regular
7219 // chaining, because it is faster. Use "this.inherited()" only in
7222 // This method cannot me called from automatically chained
7223 // constructors including the case of a special (legacy)
7224 // constructor chaining. It cannot be called from chained methods.
7226 // If "this.inherited()" cannot find the next-in-chain method, it
7227 // does nothing and returns "undefined". The last method in chain
7228 // can be a default method implemented in Object, which will be
7231 // If "name" is specified, it is assumed that the method that
7232 // received "args" is the parent method for this call. It is looked
7233 // up in the chain list and if it is found the next-in-chain method
7234 // is called. If it is not found, the first-in-chain method is
7237 // If "name" is not specified, it will be derived from the calling
7238 // method (using a methoid property "nom").
7241 // | var B = declare(A, {
7242 // | method1: function(a, b, c){
7243 // | this.inherited(arguments);
7245 // | method2: function(a, b){
7246 // | return this.inherited(arguments, [a + b]);
7249 // | // next method is not in the chain list because it is added
7250 // | // manually after the class was created.
7251 // | B.prototype.method3 = function(){
7252 // | console.log("This is a dynamically-added method.");
7253 // | this.inherited("method3", arguments);
7256 // | var B = declare(A, {
7257 // | method: function(a, b){
7258 // | var super = this.inherited(arguments, true);
7261 // | console.log("there is no super method");
7264 // | return super.apply(this, arguments);
7267 return {}; // Object
7270 getInherited: function(name, args){
7272 // Returns a super method.
7274 // The optional method name. Should be the same as the caller's
7275 // name. Usually "name" is specified in complex dynamic cases, when
7276 // the calling method was dynamically added, undecorated by
7277 // declare(), and it cannot be determined.
7279 // The caller supply this argument, which should be the original
7282 // Returns a super method (Function) or "undefined".
7284 // This method is a convenience method for "this.inherited()".
7285 // It uses the same algorithm but instead of executing a super
7286 // method, it returns it, or "undefined" if not found.
7289 // | var B = declare(A, {
7290 // | method: function(a, b){
7291 // | var super = this.getInherited(arguments);
7294 // | console.log("there is no super method");
7297 // | return super.apply(this, arguments);
7300 return {}; // Object
7303 isInstanceOf: function(cls){
7305 // Checks the inheritance chain to see if it is inherited from this
7308 // Class constructor.
7310 // "true", if this object is inherited from this class, "false"
7313 // This method is used with instances of classes produced with
7314 // declare() to determine of they support a certain interface or
7315 // not. It models "instanceof" operator.
7318 // | var A = declare(null, {
7319 // | // constructor, properties, and methods go here
7322 // | var B = declare(null, {
7323 // | // constructor, properties, and methods go here
7326 // | var C = declare([A, B], {
7327 // | // constructor, properties, and methods go here
7330 // | var D = declare(A, {
7331 // | // constructor, properties, and methods go here
7335 // | var a = new A(), b = new B(), c = new C(), d = new D();
7337 // | console.log(a.isInstanceOf(A)); // true
7338 // | console.log(b.isInstanceOf(A)); // false
7339 // | console.log(c.isInstanceOf(A)); // true
7340 // | console.log(d.isInstanceOf(A)); // true
7342 // | console.log(a.isInstanceOf(B)); // false
7343 // | console.log(b.isInstanceOf(B)); // true
7344 // | console.log(c.isInstanceOf(B)); // true
7345 // | console.log(d.isInstanceOf(B)); // false
7347 // | console.log(a.isInstanceOf(C)); // false
7348 // | console.log(b.isInstanceOf(C)); // false
7349 // | console.log(c.isInstanceOf(C)); // true
7350 // | console.log(d.isInstanceOf(C)); // false
7352 // | console.log(a.isInstanceOf(D)); // false
7353 // | console.log(b.isInstanceOf(D)); // false
7354 // | console.log(c.isInstanceOf(D)); // false
7355 // | console.log(d.isInstanceOf(D)); // true
7356 return {}; // Object
7359 extend: function(source){
7361 // Adds all properties and methods of source to constructor's
7362 // prototype, making them available to all instances created with
7363 // constructor. This method is specific to constructors created with
7366 // Source object which properties are going to be copied to the
7367 // constructor's prototype.
7369 // Adds source properties to the constructor's prototype. It can
7370 // override existing properties.
7372 // This method is similar to dojo.extend function, but it is specific
7373 // to constructors produced by declare(). It is implemented
7374 // using dojo.safeMixin, and it skips a constructor property,
7375 // and properly decorates copied functions.
7378 // | var A = declare(null, {
7379 // | m1: function(){},
7380 // | s1: "Popokatepetl"
7383 // | m1: function(){},
7384 // | m2: function(){},
7392 // For back-compat, remove for 2.0
7393 dojo
.safeMixin
= declare
.safeMixin
= safeMixin
;
7394 dojo
.declare
= declare
;
7400 'dojo/dom':function(){
7401 define(["./sniff", "./_base/window"],
7406 // FIXME: need to add unit tests for all the semi-public methods
7410 document
.execCommand("BackgroundImageCache", false, true);
7412 // sane browsers don't have cache "issues"
7416 // =============================
7418 // =============================
7420 // the result object
7423 // This module defines the core dojo DOM API.
7427 dom
.byId = function(id
, doc
){
7428 if(typeof id
!= "string"){
7431 var _d
= doc
|| win
.doc
, te
= id
&& _d
.getElementById(id
);
7432 // attributes.id.value is better than just id in case the
7433 // user has a name=id inside a form
7434 if(te
&& (te
.attributes
.id
.value
== id
|| te
.id
== id
)){
7437 var eles
= _d
.all
[id
];
7438 if(!eles
|| eles
.nodeName
){
7441 // if more than 1, choose first with the correct id
7443 while((te
= eles
[i
++])){
7444 if((te
.attributes
&& te
.attributes
.id
&& te
.attributes
.id
.value
== id
) || te
.id
== id
){
7451 dom
.byId = function(id
, doc
){
7452 // inline'd type check.
7453 // be sure to return null per documentation, to match IE branch.
7454 return ((typeof id
== "string") ? (doc
|| win
.doc
).getElementById(id
) : id
) || null; // DOMNode
7458 dom.byId = function(id, doc){
7460 // Returns DOM node with matching `id` attribute or falsy value (ex: null or undefined)
7461 // if not found. If `id` is a DomNode, this function is a no-op.
7463 // id: String|DOMNode
7464 // A string to match an HTML id attribute or a reference to a DOM Node
7467 // Document to work in. Defaults to the current value of
7468 // dojo.doc. Can be used to retrieve
7469 // node references from other documents.
7472 // Look up a node by ID:
7473 // | var n = dojo.byId("foo");
7476 // Check if a node exists, and use it.
7477 // | var n = dojo.byId("bar");
7478 // | if(n){ doStuff() ... }
7481 // Allow string or DomNode references to be passed to a custom function:
7482 // | var foo = function(nodeOrId){
7483 // | nodeOrId = dojo.byId(nodeOrId);
7484 // | // ... more stuff
7489 dom
.isDescendant = function(/*DOMNode|String*/ node
, /*DOMNode|String*/ ancestor
){
7491 // Returns true if node is a descendant of ancestor
7492 // node: DOMNode|String
7493 // string id or node reference to test
7494 // ancestor: DOMNode|String
7495 // string id or node reference of potential parent to test against
7498 // Test is node id="bar" is a descendant of node id="foo"
7499 // | if(dojo.isDescendant("bar", "foo")){ ... }
7502 node
= dom
.byId(node
);
7503 ancestor
= dom
.byId(ancestor
);
7505 if(node
== ancestor
){
7506 return true; // Boolean
7508 node
= node
.parentNode
;
7510 }catch(e
){ /* squelch, return false */ }
7511 return false; // Boolean
7515 // TODO: do we need setSelectable in the base?
7517 // Add feature test for user-select CSS property
7518 // (currently known to work in all but IE < 10 and Opera)
7519 has
.add("css-user-select", function(global
, doc
, element
){
7520 // Avoid exception when dom.js is loaded in non-browser environments
7521 if(!element
){ return false; }
7523 var style
= element
.style
;
7524 var prefixes
= ["Khtml", "O", "ms", "Moz", "Webkit"],
7525 i
= prefixes
.length
,
7526 name
= "userSelect",
7529 // Iterate prefixes from most to least likely
7531 if(typeof style
[name
] !== "undefined"){
7532 // Supported; return property name
7535 }while(i
-- && (name
= prefixes
[i
] + "UserSelect"));
7537 // Not supported if we didn't return before now
7542 dom.setSelectable = function(node, selectable){
7544 // Enable or disable selection on a node
7545 // node: DOMNode|String
7546 // id or reference to node
7547 // selectable: Boolean
7548 // state to put the node in. false indicates unselectable, true
7549 // allows selection.
7551 // Make the node id="bar" unselectable
7552 // | dojo.setSelectable("bar");
7554 // Make the node id="bar" selectable
7555 // | dojo.setSelectable("bar", true);
7559 var cssUserSelect
= has("css-user-select");
7560 dom
.setSelectable
= cssUserSelect
? function(node
, selectable
){
7561 // css-user-select returns a (possibly vendor-prefixed) CSS property name
7562 dom
.byId(node
).style
[cssUserSelect
] = selectable
? "" : "none";
7563 } : function(node
, selectable
){
7564 node
= dom
.byId(node
);
7566 // (IE < 10 / Opera) Fall back to setting/removing the
7567 // unselectable attribute on the element and all its children
7568 var nodes
= node
.getElementsByTagName("*"),
7572 node
.removeAttribute("unselectable");
7574 nodes
[i
].removeAttribute("unselectable");
7577 node
.setAttribute("unselectable", "on");
7579 nodes
[i
].setAttribute("unselectable", "on");
7588 'dojo/_base/browser':function(){
7590 require
.has
.add("config-selectorEngine", "acme");
7595 "./connect", // until we decide if connect is going back into non-browser environments
7603 "./fx"], function(dojo
){
7606 // dojo/_base/browser
7611 // This module causes the browser-only base modules to be loaded.
7619 'dojo/errors/RequestTimeoutError':function(){
7620 define("dojo/errors/RequestTimeoutError", ['./create', './RequestError'], function(create
, RequestError
){
7622 // dojo/errors/RequestTimeoutError
7631 return create("RequestTimeoutError", null, RequestError
, {
7637 'dojo/dom-style':function(){
7638 define("dojo/dom-style", ["./sniff", "./dom"], function(has
, dom
){
7642 // =============================
7644 // =============================
7646 // getComputedStyle drives most of the style code.
7647 // Wherever possible, reuse the returned object.
7649 // API functions below that need to access computed styles accept an
7650 // optional computedStyle parameter.
7651 // If this parameter is omitted, the functions will call getComputedStyle themselves.
7652 // This way, calling code can access computedStyle once, and then pass the reference to
7653 // multiple API functions.
7655 // Although we normally eschew argument validation at this
7656 // level, here we test argument 'node' for (duck)type,
7657 // by testing nodeType, ecause 'document' is the 'parentNode' of 'body'
7658 // it is frequently sent to this function even
7659 // though it is not Element.
7660 var getComputedStyle
, style
= {
7662 // This module defines the core dojo DOM style API.
7665 getComputedStyle = function(/*DomNode*/ node
){
7667 if(node
.nodeType
== 1){
7668 var dv
= node
.ownerDocument
.defaultView
;
7669 s
= dv
.getComputedStyle(node
, null);
7670 if(!s
&& node
.style
){
7671 node
.style
.display
= "";
7672 s
= dv
.getComputedStyle(node
, null);
7677 }else if(has("ie") && (has("ie") < 9 || has("quirks"))){
7678 getComputedStyle = function(node
){
7679 // IE (as of 7) doesn't expose Element like sane browsers
7680 // currentStyle can be null on IE8!
7681 return node
.nodeType
== 1 /* ELEMENT_NODE*/ && node
.currentStyle
? node
.currentStyle
: {};
7684 getComputedStyle = function(node
){
7685 return node
.nodeType
== 1 /* ELEMENT_NODE*/ ?
7686 node
.ownerDocument
.defaultView
.getComputedStyle(node
, null) : {};
7689 style
.getComputedStyle
= getComputedStyle
;
7691 style.getComputedStyle = function(node){
7693 // Returns a "computed style" object.
7696 // Gets a "computed style" object which can be used to gather
7697 // information about the current state of the rendered node.
7699 // Note that this may behave differently on different browsers.
7700 // Values may have different formats and value encodings across
7703 // Note also that this method is expensive. Wherever possible,
7704 // reuse the returned object.
7706 // Use the dojo.style() method for more consistent (pixelized)
7710 // A reference to a DOM node. Does NOT support taking an
7711 // ID string for speed reasons.
7713 // | dojo.getComputedStyle(dojo.byId('foo')).borderWidth;
7716 // Reusing the returned object, avoiding multiple lookups:
7717 // | var cs = dojo.getComputedStyle(dojo.byId("someNode"));
7718 // | var w = cs.width, h = cs.height;
7719 return; // CSS2Properties
7725 toPixel = function(element
, value
){
7726 // style values can be floats, client code may want
7727 // to round for integer pixels.
7728 return parseFloat(value
) || 0;
7731 toPixel = function(element
, avalue
){
7732 if(!avalue
){ return 0; }
7733 // on IE7, medium is usually 4 pixels
7734 if(avalue
== "medium"){ return 4; }
7735 // style values can be floats, client code may
7736 // want to round this value for integer pixels.
7737 if(avalue
.slice
&& avalue
.slice(-2) == 'px'){ return parseFloat(avalue
); }
7738 var s
= element
.style
, rs
= element
.runtimeStyle
, cs
= element
.currentStyle
,
7739 sLeft
= s
.left
, rsLeft
= rs
.left
;
7742 // 'avalue' may be incompatible with style.left, which can cause IE to throw
7743 // this has been observed for border widths using "thin", "medium", "thick" constants
7744 // those particular constants could be trapped by a lookup
7745 // but perhaps there are more
7747 avalue
= s
.pixelLeft
;
7756 style
.toPixelValue
= toPixel
;
7758 style.toPixelValue = function(node, value){
7760 // converts style value to pixels on IE or return a numeric value.
7767 // FIXME: there opacity quirks on FF that we haven't ported over. Hrm.
7769 var astr
= "DXImageTransform.Microsoft.Alpha";
7770 var af = function(n
, f
){
7772 return n
.filters
.item(astr
);
7774 return f
? {} : null;
7779 has("ie") < 9 || (has("ie") < 10 && has("quirks")) ? function(node
){
7781 return af(node
).Opacity
/ 100; // Number
7787 return getComputedStyle(node
).opacity
;
7791 has("ie") < 9 || (has("ie") < 10 && has("quirks")) ? function(/*DomNode*/ node
, /*Number*/ opacity
){
7792 var ov
= opacity
* 100, opaque
= opacity
== 1;
7793 node
.style
.zoom
= opaque
? "" : 1;
7799 node
.style
.filter
+= " progid:" + astr
+ "(Opacity=" + ov
+ ")";
7801 af(node
, 1).Opacity
= ov
;
7804 // on IE7 Alpha(Filter opacity=100) makes text look fuzzy so disable it altogether (bug #2661),
7805 //but still update the opacity value so we can get a correct reading if it is read later.
7806 af(node
, 1).Enabled
= !opaque
;
7808 if(node
.tagName
.toLowerCase() == "tr"){
7809 for(var td
= node
.firstChild
; td
; td
= td
.nextSibling
){
7810 if(td
.tagName
.toLowerCase() == "td"){
7811 _setOpacity(td
, opacity
);
7817 function(node
, opacity
){
7818 return node
.style
.opacity
= opacity
;
7821 var _pixelNamesCache
= {
7822 left
: true, top
: true
7824 var _pixelRegExp
= /margin|padding|width|height|max|min|offset/; // |border
7825 function _toStyleValue(node
, type
, value
){
7826 //TODO: should we really be doing string case conversion here? Should we cache it? Need to profile!
7827 type
= type
.toLowerCase();
7829 if(value
== "auto"){
7830 if(type
== "height"){ return node
.offsetHeight
; }
7831 if(type
== "width"){ return node
.offsetWidth
; }
7833 if(type
== "fontweight"){
7835 case 700: return "bold";
7837 default: return "normal";
7841 if(!(type
in _pixelNamesCache
)){
7842 _pixelNamesCache
[type
] = _pixelRegExp
.test(type
);
7844 return _pixelNamesCache
[type
] ? toPixel(node
, value
) : value
;
7847 var _floatStyle
= has("ie") ? "styleFloat" : "cssFloat",
7848 _floatAliases
= {"cssFloat": _floatStyle
, "styleFloat": _floatStyle
, "float": _floatStyle
};
7852 style
.get = function getStyle(/*DOMNode|String*/ node
, /*String?*/ name
){
7854 // Accesses styles on a node.
7856 // Getting the style value uses the computed style for the node, so the value
7857 // will be a calculated value, not just the immediate node.style value.
7858 // Also when getting values, use specific style names,
7859 // like "borderBottomWidth" instead of "border" since compound values like
7860 // "border" are not necessarily reflected as expected.
7861 // If you want to get node dimensions, use `dojo.marginBox()`,
7862 // `dojo.contentBox()` or `dojo.position()`.
7863 // node: DOMNode|String
7864 // id or reference to node to get style for
7866 // the style property to get
7868 // Passing only an ID or node returns the computed style object of
7870 // | dojo.getStyle("thinger");
7872 // Passing a node and a style property returns the current
7873 // normalized, computed value for that property:
7874 // | dojo.getStyle("thinger", "opacity"); // 1 by default
7876 var n
= dom
.byId(node
), l
= arguments
.length
, op
= (name
== "opacity");
7878 return _getOpacity(n
);
7880 name
= _floatAliases
[name
] || name
;
7881 var s
= style
.getComputedStyle(n
);
7882 return (l
== 1) ? s
: _toStyleValue(n
, name
, s
[name
] || n
.style
[name
]); /* CSS2Properties||String||Number */
7885 style
.set = function setStyle(/*DOMNode|String*/ node
, /*String|Object*/ name
, /*String?*/ value
){
7887 // Sets styles on a node.
7888 // node: DOMNode|String
7889 // id or reference to node to set style for
7890 // name: String|Object
7891 // the style property to set in DOM-accessor format
7892 // ("borderWidth", not "border-width") or an object with key/value
7893 // pairs suitable for setting each property.
7895 // If passed, sets value on the node for style, handling
7896 // cross-browser concerns. When setting a pixel value,
7897 // be sure to include "px" in the value. For instance, top: "200px".
7898 // Otherwise, in some cases, some browsers will not apply the style.
7901 // Passing a node, a style property, and a value changes the
7902 // current display of the node and returns the new computed value
7903 // | dojo.setStyle("thinger", "opacity", 0.5); // == 0.5
7906 // Passing a node, an object-style style property sets each of the values in turn and returns the computed style object of the node:
7907 // | dojo.setStyle("thinger", {
7908 // | "opacity": 0.5,
7909 // | "border": "3px solid black",
7910 // | "height": "300px"
7914 // When the CSS style property is hyphenated, the JavaScript property is camelCased.
7915 // font-size becomes fontSize, and so on.
7916 // | dojo.setStyle("thinger",{
7917 // | fontSize:"14pt",
7918 // | letterSpacing:"1.2em"
7922 // dojo/NodeList implements .style() using the same syntax, omitting the "node" parameter, calling
7923 // dojo.style() on every element of the list. See: `dojo.query()` and `dojo/NodeList`
7924 // | dojo.query(".someClassName").style("visibility","hidden");
7926 // | dojo.query("#baz > div").style({
7928 // | fontSize:"13pt"
7931 var n
= dom
.byId(node
), l
= arguments
.length
, op
= (name
== "opacity");
7932 name
= _floatAliases
[name
] || name
;
7934 return op
? _setOpacity(n
, value
) : n
.style
[name
] = value
; // Number
7937 style
.set(node
, x
, name
[x
]);
7939 return style
.getComputedStyle(n
);
7946 'dojo/dom-geometry':function(){
7947 define(["./sniff", "./_base/window","./dom", "./dom-style"],
7948 function(has
, win
, dom
, style
){
7950 // dojo/dom-geometry
7952 // the result object
7955 // This module defines the core dojo DOM geometry API.
7958 // Box functions will assume this model.
7959 // On IE/Opera, BORDER_BOX will be set if the primary document is in quirks mode.
7960 // Can be set to change behavior of box setters.
7964 // "content-box" (default)
7965 geom
.boxModel
= "content-box";
7967 // We punt per-node box mode testing completely.
7968 // If anybody cares, we can provide an additional (optional) unit
7969 // that overrides existing code to include per-node box sensitivity.
7971 // Opera documentation claims that Opera 9 uses border-box in BackCompat mode.
7972 // but experiments (Opera 9.10.8679 on Windows Vista) indicate that it actually continues to use content-box.
7973 // IIRC, earlier versions of Opera did in fact use border-box.
7974 // Opera guys, this is really confusing. Opera being broken in quirks mode is not our fault.
7976 if(has("ie") /*|| has("opera")*/){
7977 // client code may have to adjust if compatMode varies across iframes
7978 geom
.boxModel
= document
.compatMode
== "BackCompat" ? "border-box" : "content-box";
7981 geom
.getPadExtents
= function getPadExtents(/*DomNode*/ node
, /*Object*/ computedStyle
){
7983 // Returns object with special values specifically useful for node
7986 // Returns an object with `w`, `h`, `l`, `t` properties:
7987 // | l/t/r/b = left/top/right/bottom padding (respectively)
7988 // | w = the total of the left and right padding
7989 // | h = the total of the top and bottom padding
7990 // If 'node' has position, l/t forms the origin for child nodes.
7991 // The w/h are used for calculating boxes.
7992 // Normally application code will not need to invoke this
7993 // directly, and will use the ...box... functions instead.
7995 // computedStyle: Object?
7996 // This parameter accepts computed styles object.
7997 // If this parameter is omitted, the functions will call
7998 // dojo.getComputedStyle to get one. It is a better way, calling
7999 // dojo.computedStyle once, and then pass the reference to this
8000 // computedStyle parameter. Wherever possible, reuse the returned
8001 // object of dojo/dom-style.getComputedStyle().
8003 node
= dom
.byId(node
);
8004 var s
= computedStyle
|| style
.getComputedStyle(node
), px
= style
.toPixelValue
,
8005 l
= px(node
, s
.paddingLeft
), t
= px(node
, s
.paddingTop
), r
= px(node
, s
.paddingRight
), b
= px(node
, s
.paddingBottom
);
8006 return {l
: l
, t
: t
, r
: r
, b
: b
, w
: l
+ r
, h
: t
+ b
};
8011 geom
.getBorderExtents
= function getBorderExtents(/*DomNode*/ node
, /*Object*/ computedStyle
){
8013 // returns an object with properties useful for noting the border
8016 // - l/t/r/b = the sum of left/top/right/bottom border (respectively)
8017 // - w = the sum of the left and right border
8018 // - h = the sum of the top and bottom border
8020 // The w/h are used for calculating boxes.
8021 // Normally application code will not need to invoke this
8022 // directly, and will use the ...box... functions instead.
8024 // computedStyle: Object?
8025 // This parameter accepts computed styles object.
8026 // If this parameter is omitted, the functions will call
8027 // dojo.getComputedStyle to get one. It is a better way, calling
8028 // dojo.computedStyle once, and then pass the reference to this
8029 // computedStyle parameter. Wherever possible, reuse the returned
8030 // object of dojo/dom-style.getComputedStyle().
8032 node
= dom
.byId(node
);
8033 var px
= style
.toPixelValue
, s
= computedStyle
|| style
.getComputedStyle(node
),
8034 l
= s
.borderLeftStyle
!= none
? px(node
, s
.borderLeftWidth
) : 0,
8035 t
= s
.borderTopStyle
!= none
? px(node
, s
.borderTopWidth
) : 0,
8036 r
= s
.borderRightStyle
!= none
? px(node
, s
.borderRightWidth
) : 0,
8037 b
= s
.borderBottomStyle
!= none
? px(node
, s
.borderBottomWidth
) : 0;
8038 return {l
: l
, t
: t
, r
: r
, b
: b
, w
: l
+ r
, h
: t
+ b
};
8041 geom
.getPadBorderExtents
= function getPadBorderExtents(/*DomNode*/ node
, /*Object*/ computedStyle
){
8043 // Returns object with properties useful for box fitting with
8044 // regards to padding.
8046 // - l/t/r/b = the sum of left/top/right/bottom padding and left/top/right/bottom border (respectively)
8047 // - w = the sum of the left and right padding and border
8048 // - h = the sum of the top and bottom padding and border
8050 // The w/h are used for calculating boxes.
8051 // Normally application code will not need to invoke this
8052 // directly, and will use the ...box... functions instead.
8054 // computedStyle: Object?
8055 // This parameter accepts computed styles object.
8056 // If this parameter is omitted, the functions will call
8057 // dojo.getComputedStyle to get one. It is a better way, calling
8058 // dojo.computedStyle once, and then pass the reference to this
8059 // computedStyle parameter. Wherever possible, reuse the returned
8060 // object of dojo/dom-style.getComputedStyle().
8062 node
= dom
.byId(node
);
8063 var s
= computedStyle
|| style
.getComputedStyle(node
),
8064 p
= geom
.getPadExtents(node
, s
),
8065 b
= geom
.getBorderExtents(node
, s
);
8076 geom
.getMarginExtents
= function getMarginExtents(node
, computedStyle
){
8078 // returns object with properties useful for box fitting with
8079 // regards to box margins (i.e., the outer-box).
8081 // - l/t = marginLeft, marginTop, respectively
8082 // - w = total width, margin inclusive
8083 // - h = total height, margin inclusive
8085 // The w/h are used for calculating boxes.
8086 // Normally application code will not need to invoke this
8087 // directly, and will use the ...box... functions instead.
8089 // computedStyle: Object?
8090 // This parameter accepts computed styles object.
8091 // If this parameter is omitted, the functions will call
8092 // dojo.getComputedStyle to get one. It is a better way, calling
8093 // dojo.computedStyle once, and then pass the reference to this
8094 // computedStyle parameter. Wherever possible, reuse the returned
8095 // object of dojo/dom-style.getComputedStyle().
8097 node
= dom
.byId(node
);
8098 var s
= computedStyle
|| style
.getComputedStyle(node
), px
= style
.toPixelValue
,
8099 l
= px(node
, s
.marginLeft
), t
= px(node
, s
.marginTop
), r
= px(node
, s
.marginRight
), b
= px(node
, s
.marginBottom
);
8100 return {l
: l
, t
: t
, r
: r
, b
: b
, w
: l
+ r
, h
: t
+ b
};
8103 // Box getters work in any box context because offsetWidth/clientWidth
8104 // are invariant wrt box context
8106 // They do *not* work for display: inline objects that have padding styles
8107 // because the user agent ignores padding (it's bogus styling in any case)
8109 // Be careful with IMGs because they are inline or block depending on
8110 // browser and browser mode.
8112 // Although it would be easier to read, there are not separate versions of
8113 // _getMarginBox for each browser because:
8114 // 1. the branching is not expensive
8115 // 2. factoring the shared code wastes cycles (function call overhead)
8116 // 3. duplicating the shared code wastes bytes
8118 geom
.getMarginBox
= function getMarginBox(/*DomNode*/ node
, /*Object*/ computedStyle
){
8120 // returns an object that encodes the width, height, left and top
8121 // positions of the node's margin box.
8123 // computedStyle: Object?
8124 // This parameter accepts computed styles object.
8125 // If this parameter is omitted, the functions will call
8126 // dojo.getComputedStyle to get one. It is a better way, calling
8127 // dojo.computedStyle once, and then pass the reference to this
8128 // computedStyle parameter. Wherever possible, reuse the returned
8129 // object of dojo/dom-style.getComputedStyle().
8131 node
= dom
.byId(node
);
8132 var s
= computedStyle
|| style
.getComputedStyle(node
), me
= geom
.getMarginExtents(node
, s
),
8133 l
= node
.offsetLeft
- me
.l
, t
= node
.offsetTop
- me
.t
, p
= node
.parentNode
, px
= style
.toPixelValue
, pcs
;
8136 // If offsetParent has a computed overflow != visible, the offsetLeft is decreased
8137 // by the parent's border.
8138 // We don't want to compute the parent's style, so instead we examine node's
8139 // computed left/top which is more stable.
8140 var sl
= parseFloat(s
.left
), st
= parseFloat(s
.top
);
8141 if(!isNaN(sl
) && !isNaN(st
)){
8145 // If child's computed left/top are not parseable as a number (e.g. "auto"), we
8146 // have no choice but to examine the parent's computed style.
8148 pcs
= style
.getComputedStyle(p
);
8149 if(pcs
.overflow
!= "visible"){
8150 l
+= pcs
.borderLeftStyle
!= none
? px(node
, pcs
.borderLeftWidth
) : 0;
8151 t
+= pcs
.borderTopStyle
!= none
? px(node
, pcs
.borderTopWidth
) : 0;
8155 }else if(has("opera") || (has("ie") == 8 && !has("quirks"))){
8156 // On Opera and IE 8, offsetLeft/Top includes the parent's border
8158 pcs
= style
.getComputedStyle(p
);
8159 l
-= pcs
.borderLeftStyle
!= none
? px(node
, pcs
.borderLeftWidth
) : 0;
8160 t
-= pcs
.borderTopStyle
!= none
? px(node
, pcs
.borderTopWidth
) : 0;
8163 return {l
: l
, t
: t
, w
: node
.offsetWidth
+ me
.w
, h
: node
.offsetHeight
+ me
.h
};
8166 geom
.getContentBox
= function getContentBox(node
, computedStyle
){
8168 // Returns an object that encodes the width, height, left and top
8169 // positions of the node's content box, irrespective of the
8170 // current box model.
8172 // computedStyle: Object?
8173 // This parameter accepts computed styles object.
8174 // If this parameter is omitted, the functions will call
8175 // dojo.getComputedStyle to get one. It is a better way, calling
8176 // dojo.computedStyle once, and then pass the reference to this
8177 // computedStyle parameter. Wherever possible, reuse the returned
8178 // object of dojo/dom-style.getComputedStyle().
8180 // clientWidth/Height are important since the automatically account for scrollbars
8181 // fallback to offsetWidth/Height for special cases (see #3378)
8182 node
= dom
.byId(node
);
8183 var s
= computedStyle
|| style
.getComputedStyle(node
), w
= node
.clientWidth
, h
,
8184 pe
= geom
.getPadExtents(node
, s
), be
= geom
.getBorderExtents(node
, s
);
8186 w
= node
.offsetWidth
;
8187 h
= node
.offsetHeight
;
8189 h
= node
.clientHeight
;
8192 // On Opera, offsetLeft includes the parent's border
8197 return {l
: pe
.l
, t
: pe
.t
, w
: w
- pe
.w
- be
.w
, h
: h
- pe
.h
- be
.h
};
8200 // Box setters depend on box context because interpretation of width/height styles
8201 // vary wrt box context.
8203 // The value of boxModel is used to determine box context.
8204 // boxModel can be set directly to change behavior.
8206 // Beware of display: inline objects that have padding styles
8207 // because the user agent ignores padding (it's a bogus setup anyway)
8209 // Be careful with IMGs because they are inline or block depending on
8210 // browser and browser mode.
8212 // Elements other than DIV may have special quirks, like built-in
8213 // margins or padding, or values not detectable via computedStyle.
8214 // In particular, margins on TABLE do not seems to appear
8215 // at all in computedStyle on Mozilla.
8217 function setBox(/*DomNode*/ node
, /*Number?*/ l
, /*Number?*/ t
, /*Number?*/ w
, /*Number?*/ h
, /*String?*/ u
){
8219 // sets width/height/left/top in the current (native) box-model
8220 // dimensions. Uses the unit passed in u.
8222 // DOM Node reference. Id string not supported for performance
8225 // left offset from parent.
8227 // top offset from parent.
8229 // width in current box model.
8231 // width in current box model.
8233 // unit measure to use for other measures. Defaults to "px".
8250 function isButtonTag(/*DomNode*/ node
){
8252 // True if the node is BUTTON or INPUT.type="button".
8253 return node
.tagName
.toLowerCase() == "button" ||
8254 node
.tagName
.toLowerCase() == "input" && (node
.getAttribute("type") || "").toLowerCase() == "button"; // boolean
8257 function usesBorderBox(/*DomNode*/ node
){
8259 // True if the node uses border-box layout.
8261 // We could test the computed style of node to see if a particular box
8262 // has been specified, but there are details and we choose not to bother.
8264 // TABLE and BUTTON (and INPUT type=button) are always border-box by default.
8265 // If you have assigned a different box to either one via CSS then
8266 // box functions will break.
8268 return geom
.boxModel
== "border-box" || node
.tagName
.toLowerCase() == "table" || isButtonTag(node
); // boolean
8271 geom
.setContentSize
= function setContentSize(/*DomNode*/ node
, /*Object*/ box
, /*Object*/ computedStyle
){
8273 // Sets the size of the node's contents, irrespective of margins,
8274 // padding, or borders.
8277 // hash with optional "w", and "h" properties for "width", and "height"
8278 // respectively. All specified properties should have numeric values in whole pixels.
8279 // computedStyle: Object?
8280 // This parameter accepts computed styles object.
8281 // If this parameter is omitted, the functions will call
8282 // dojo.getComputedStyle to get one. It is a better way, calling
8283 // dojo.computedStyle once, and then pass the reference to this
8284 // computedStyle parameter. Wherever possible, reuse the returned
8285 // object of dojo/dom-style.getComputedStyle().
8287 node
= dom
.byId(node
);
8288 var w
= box
.w
, h
= box
.h
;
8289 if(usesBorderBox(node
)){
8290 var pb
= geom
.getPadBorderExtents(node
, computedStyle
);
8298 setBox(node
, NaN
, NaN
, w
, h
);
8301 var nilExtents
= {l
: 0, t
: 0, w
: 0, h
: 0};
8303 geom
.setMarginBox
= function setMarginBox(/*DomNode*/ node
, /*Object*/ box
, /*Object*/ computedStyle
){
8305 // sets the size of the node's margin box and placement
8306 // (left/top), irrespective of box model. Think of it as a
8307 // passthrough to setBox that handles box-model vagaries for
8311 // hash with optional "l", "t", "w", and "h" properties for "left", "right", "width", and "height"
8312 // respectively. All specified properties should have numeric values in whole pixels.
8313 // computedStyle: Object?
8314 // This parameter accepts computed styles object.
8315 // If this parameter is omitted, the functions will call
8316 // dojo.getComputedStyle to get one. It is a better way, calling
8317 // dojo.computedStyle once, and then pass the reference to this
8318 // computedStyle parameter. Wherever possible, reuse the returned
8319 // object of dojo/dom-style.getComputedStyle().
8321 node
= dom
.byId(node
);
8322 var s
= computedStyle
|| style
.getComputedStyle(node
), w
= box
.w
, h
= box
.h
,
8323 // Some elements have special padding, margin, and box-model settings.
8324 // To use box functions you may need to set padding, margin explicitly.
8325 // Controlling box-model is harder, in a pinch you might set dojo/dom-geometry.boxModel.
8326 pb
= usesBorderBox(node
) ? nilExtents
: geom
.getPadBorderExtents(node
, s
),
8327 mb
= geom
.getMarginExtents(node
, s
);
8329 // on Safari (3.1.2), button nodes with no explicit size have a default margin
8330 // setting an explicit size eliminates the margin.
8331 // We have to swizzle the width to get correct margin reading.
8332 if(isButtonTag(node
)){
8333 var ns
= node
.style
;
8334 if(w
>= 0 && !ns
.width
){
8337 if(h
>= 0 && !ns
.height
){
8343 w
= Math
.max(w
- pb
.w
- mb
.w
, 0);
8346 h
= Math
.max(h
- pb
.h
- mb
.h
, 0);
8348 setBox(node
, box
.l
, box
.t
, w
, h
);
8351 // =============================
8353 // =============================
8355 geom
.isBodyLtr
= function isBodyLtr(/*Document?*/ doc
){
8357 // Returns true if the current language is left-to-right, and false otherwise.
8359 // Optional document to query. If unspecified, use win.doc.
8362 doc
= doc
|| win
.doc
;
8363 return (win
.body(doc
).dir
|| doc
.documentElement
.dir
|| "ltr").toLowerCase() == "ltr"; // Boolean
8366 geom
.docScroll
= function docScroll(/*Document?*/ doc
){
8368 // Returns an object with {node, x, y} with corresponding offsets.
8370 // Optional document to query. If unspecified, use win.doc.
8373 doc
= doc
|| win
.doc
;
8374 var node
= win
.doc
.parentWindow
|| win
.doc
.defaultView
; // use UI window, not dojo.global window. TODO: use dojo/window::get() except for circular dependency problem
8375 return "pageXOffset" in node
? {x
: node
.pageXOffset
, y
: node
.pageYOffset
} :
8376 (node
= has("quirks") ? win
.body(doc
) : doc
.documentElement
) &&
8377 {x
: geom
.fixIeBiDiScrollLeft(node
.scrollLeft
|| 0, doc
), y
: node
.scrollTop
|| 0 };
8381 geom
.getIeDocumentElementOffset
= function getIeDocumentElementOffset(/*Document?*/ doc
){
8383 // returns the offset in x and y from the document body to the
8384 // visual edge of the page for IE
8386 // Optional document to query. If unspecified, use win.doc.
8388 // The following values in IE contain an offset:
8391 // | node.getBoundingClientRect().left
8392 // | node.getBoundingClientRect().top
8393 // But other position related values do not contain this offset,
8394 // such as node.offsetLeft, node.offsetTop, node.style.left and
8395 // node.style.top. The offset is always (2, 2) in LTR direction.
8396 // When the body is in RTL direction, the offset counts the width
8397 // of left scroll bar's width. This function computes the actual
8400 //NOTE: assumes we're being called in an IE browser
8402 doc
= doc
|| win
.doc
;
8403 var de
= doc
.documentElement
; // only deal with HTML element here, position() handles body/quirks
8406 var r
= de
.getBoundingClientRect(), // works well for IE6+
8407 l
= r
.left
, t
= r
.top
;
8409 l
+= de
.clientLeft
; // scrollbar size in strict/RTL, or,
8410 t
+= de
.clientTop
; // HTML border size in strict
8413 x
: l
< 0 ? 0 : l
, // FRAME element border size can lead to inaccurate negative values
8425 geom
.fixIeBiDiScrollLeft
= function fixIeBiDiScrollLeft(/*Integer*/ scrollLeft
, /*Document?*/ doc
){
8427 // In RTL direction, scrollLeft should be a negative value, but IE
8428 // returns a positive one. All codes using documentElement.scrollLeft
8429 // must call this function to fix this error, otherwise the position
8430 // will offset to right when there is a horizontal scrollbar.
8431 // scrollLeft: Number
8433 // Optional document to query. If unspecified, use win.doc.
8436 // In RTL direction, scrollLeft should be a negative value, but IE
8437 // returns a positive one. All codes using documentElement.scrollLeft
8438 // must call this function to fix this error, otherwise the position
8439 // will offset to right when there is a horizontal scrollbar.
8441 doc
= doc
|| win
.doc
;
8443 if(ie
&& !geom
.isBodyLtr(doc
)){
8444 var qk
= has("quirks"),
8445 de
= qk
? win
.body(doc
) : doc
.documentElement
,
8446 pwin
= win
.global
; // TODO: use winUtils.get(doc) after resolving circular dependency b/w dom-geometry.js and dojo/window.js
8447 if(ie
== 6 && !qk
&& pwin
.frameElement
&& de
.scrollHeight
> de
.clientHeight
){
8448 scrollLeft
+= de
.clientLeft
; // workaround ie6+strict+rtl+iframe+vertical-scrollbar bug where clientWidth is too small by clientLeft pixels
8450 return (ie
< 8 || qk
) ? (scrollLeft
+ de
.clientWidth
- de
.scrollWidth
) : -scrollLeft
; // Integer
8452 return scrollLeft
; // Integer
8455 geom
.position = function(/*DomNode*/ node
, /*Boolean?*/ includeScroll
){
8457 // Gets the position and size of the passed element relative to
8458 // the viewport (if includeScroll==false), or relative to the
8459 // document root (if includeScroll==true).
8462 // Returns an object of the form:
8463 // `{ x: 100, y: 300, w: 20, h: 15 }`.
8464 // If includeScroll==true, the x and y values will include any
8465 // document offsets that may affect the position relative to the
8467 // Uses the border-box model (inclusive of border and padding but
8468 // not margin). Does not act as a setter.
8469 // node: DOMNode|String
8470 // includeScroll: Boolean?
8473 node
= dom
.byId(node
);
8474 var db
= win
.body(node
.ownerDocument
),
8475 ret
= node
.getBoundingClientRect();
8476 ret
= {x
: ret
.left
, y
: ret
.top
, w
: ret
.right
- ret
.left
, h
: ret
.bottom
- ret
.top
};
8479 // On IE<9 there's a 2px offset that we need to adjust for, see dojo.getIeDocumentElementOffset()
8480 var offset
= geom
.getIeDocumentElementOffset(node
.ownerDocument
);
8482 // fixes the position in IE, quirks mode
8483 ret
.x
-= offset
.x
+ (has("quirks") ? db
.clientLeft
+ db
.offsetLeft
: 0);
8484 ret
.y
-= offset
.y
+ (has("quirks") ? db
.clientTop
+ db
.offsetTop
: 0);
8487 // account for document scrolling
8488 // if offsetParent is used, ret value already includes scroll position
8489 // so we may have to actually remove that value if !includeScroll
8491 var scroll
= geom
.docScroll(node
.ownerDocument
);
8496 return ret
; // Object
8499 // random "private" functions wildly used throughout the toolkit
8501 geom
.getMarginSize
= function getMarginSize(/*DomNode*/ node
, /*Object*/ computedStyle
){
8503 // returns an object that encodes the width and height of
8504 // the node's margin box
8505 // node: DOMNode|String
8506 // computedStyle: Object?
8507 // This parameter accepts computed styles object.
8508 // If this parameter is omitted, the functions will call
8509 // dojo.getComputedStyle to get one. It is a better way, calling
8510 // dojo.computedStyle once, and then pass the reference to this
8511 // computedStyle parameter. Wherever possible, reuse the returned
8512 // object of dojo/dom-style.getComputedStyle().
8514 node
= dom
.byId(node
);
8515 var me
= geom
.getMarginExtents(node
, computedStyle
|| style
.getComputedStyle(node
));
8516 var size
= node
.getBoundingClientRect();
8518 w
: (size
.right
- size
.left
) + me
.w
,
8519 h
: (size
.bottom
- size
.top
) + me
.h
8523 geom
.normalizeEvent = function(event
){
8525 // Normalizes the geometry of a DOM event, normalizing the pageX, pageY,
8526 // offsetX, offsetY, layerX, and layerX properties
8528 if(!("layerX" in event
)){
8529 event
.layerX
= event
.offsetX
;
8530 event
.layerY
= event
.offsetY
;
8532 if(!has("dom-addeventlistener")){
8534 // FIXME: scroll position query is duped from dojo.html to
8535 // avoid dependency on that entire module. Now that HTML is in
8536 // Base, we should convert back to something similar there.
8537 var se
= event
.target
;
8538 var doc
= (se
&& se
.ownerDocument
) || document
;
8539 // DO NOT replace the following to use dojo.body(), in IE, document.documentElement should be used
8540 // here rather than document.body
8541 var docBody
= has("quirks") ? doc
.body
: doc
.documentElement
;
8542 var offset
= geom
.getIeDocumentElementOffset(doc
);
8543 event
.pageX
= event
.clientX
+ geom
.fixIeBiDiScrollLeft(docBody
.scrollLeft
|| 0, doc
) - offset
.x
;
8544 event
.pageY
= event
.clientY
+ (docBody
.scrollTop
|| 0) - offset
.y
;
8548 // TODO: evaluate separate getters/setters for position and sizes?
8554 'dojo/dom-prop':function(){
8555 define(["exports", "./_base/kernel", "./sniff", "./_base/lang", "./dom", "./dom-style", "./dom-construct", "./_base/connect"],
8556 function(exports
, dojo
, has
, lang
, dom
, style
, ctr
, conn
){
8560 // This module defines the core dojo DOM properties API.
8561 // Indirectly depends on dojo.empty() and dojo.toDom().
8563 // TODOC: summary not showing up in output, see https://github.com/csnover/js-doc-parse/issues/42
8565 // =============================
8566 // Element properties Functions
8567 // =============================
8569 // helper to connect events
8570 var _evtHdlrMap
= {}, _ctr
= 0, _attrId
= dojo
._scopeName
+ "attrid";
8573 // properties renamed to avoid clashes with reserved words
8574 "class": "className",
8576 // properties written as camelCase
8577 tabindex
: "tabIndex",
8578 readonly
: "readOnly",
8580 frameborder
: "frameBorder",
8582 valuetype
: "valueType"
8585 exports
.get = function getProp(/*DOMNode|String*/ node
, /*String*/ name
){
8587 // Gets a property on an HTML element.
8589 // Handles normalized getting of properties on DOM nodes.
8591 // node: DOMNode|String
8592 // id or reference to the element to get the property on
8594 // the name of the property to get.
8596 // the value of the requested property or its default value
8599 // | // get the current value of the "foo" property on a node
8600 // | dojo.getProp(dojo.byId("nodeId"), "foo");
8601 // | // or we can just pass the id:
8602 // | dojo.getProp("nodeId", "foo");
8604 node
= dom
.byId(node
);
8605 var lc
= name
.toLowerCase(), propName
= exports
.names
[lc
] || name
;
8606 return node
[propName
]; // Anything
8609 exports
.set = function setProp(/*DOMNode|String*/ node
, /*String|Object*/ name
, /*String?*/ value
){
8611 // Sets a property on an HTML element.
8613 // Handles normalized setting of properties on DOM nodes.
8615 // When passing functions as values, note that they will not be
8616 // directly assigned to slots on the node, but rather the default
8617 // behavior will be removed and the new behavior will be added
8618 // using `dojo.connect()`, meaning that event handler properties
8619 // will be normalized and that some caveats with regards to
8620 // non-standard behaviors for onsubmit apply. Namely that you
8621 // should cancel form submission using `dojo.stopEvent()` on the
8622 // passed event object instead of returning a boolean value from
8623 // the handler itself.
8624 // node: DOMNode|String
8625 // id or reference to the element to set the property on
8626 // name: String|Object
8627 // the name of the property to set, or a hash object to set
8628 // multiple properties at once.
8630 // The value to set for the property
8635 // | // use prop() to set the tab index
8636 // | dojo.setProp("nodeId", "tabIndex", 3);
8640 // Set multiple values at once, including event handlers:
8641 // | dojo.setProp("formId", {
8643 // | "tabIndex": -1,
8644 // | "method": "POST",
8645 // | "onsubmit": function(e){
8646 // | // stop submitting the form. Note that the IE behavior
8647 // | // of returning true or false will have no effect here
8648 // | // since our handler is connect()ed to the built-in
8649 // | // onsubmit behavior and so we need to use
8650 // | // dojo.stopEvent() to ensure that the submission
8651 // | // doesn't proceed.
8652 // | dojo.stopEvent(e);
8654 // | // submit the form with Ajax
8655 // | dojo.xhrPost({ form: "formId" });
8660 // Style is s special case: Only set with an object hash of styles
8661 // | dojo.setProp("someNode",{
8664 // | width:"200px", height:"100px", color:"#000"
8669 // Again, only set style as an object hash of styles:
8670 // | var obj = { color:"#fff", backgroundColor:"#000" };
8671 // | dojo.setProp("someNode", "style", obj);
8673 // | // though shorter to use `dojo.style()` in this case:
8674 // | dojo.style("someNode", obj);
8676 node
= dom
.byId(node
);
8677 var l
= arguments
.length
;
8678 if(l
== 2 && typeof name
!= "string"){ // inline'd type check
8679 // the object form of setter: the 2nd argument is a dictionary
8681 exports
.set(node
, x
, name
[x
]);
8683 return node
; // DomNode
8685 var lc
= name
.toLowerCase(), propName
= exports
.names
[lc
] || name
;
8686 if(propName
== "style" && typeof value
!= "string"){ // inline'd type check
8687 // special case: setting a style
8688 style
.set(node
, value
);
8689 return node
; // DomNode
8691 if(propName
== "innerHTML"){
8692 // special case: assigning HTML
8693 // the hash lists elements with read-only innerHTML on IE
8694 if(has("ie") && node
.tagName
.toLowerCase() in {col
: 1, colgroup
: 1,
8695 table
: 1, tbody
: 1, tfoot
: 1, thead
: 1, tr
: 1, title
: 1}){
8697 node
.appendChild(ctr
.toDom(value
, node
.ownerDocument
));
8699 node
[propName
] = value
;
8701 return node
; // DomNode
8703 if(lang
.isFunction(value
)){
8704 // special case: assigning an event handler
8705 // clobber if we can
8706 var attrId
= node
[_attrId
];
8709 node
[_attrId
] = attrId
;
8711 if(!_evtHdlrMap
[attrId
]){
8712 _evtHdlrMap
[attrId
] = {};
8714 var h
= _evtHdlrMap
[attrId
][propName
];
8720 delete node
[propName
];
8723 // ensure that event objects are normalized, etc.
8725 //_evtHdlrMap[attrId][propName] = on(node, propName, value);
8726 _evtHdlrMap
[attrId
][propName
] = conn
.connect(node
, propName
, value
);
8728 node
[propName
] = null;
8730 return node
; // DomNode
8732 node
[propName
] = value
;
8733 return node
; // DomNode
8738 'dojo/when':function(){
8742 ], function(Deferred
, Promise
){
8748 return function when(valueOrPromise
, callback
, errback
, progback
){
8750 // Transparently applies callbacks to values and/or promises.
8752 // Accepts promises but also transparently handles non-promises. If no
8753 // callbacks are provided returns a promise, regardless of the initial
8754 // value. Foreign promises are converted.
8756 // If callbacks are provided and the initial value is not a promise,
8757 // the callback is executed immediately with no error handling. Returns
8758 // a promise if the initial value is a promise, or the result of the
8759 // callback otherwise.
8761 // Either a regular value or an object with a `then()` method that
8762 // follows the Promises/A specification.
8763 // callback: Function?
8764 // Callback to be invoked when the promise is resolved, or a non-promise
8766 // errback: Function?
8767 // Callback to be invoked when the promise is rejected.
8768 // progback: Function?
8769 // Callback to be invoked when the promise emits a progress update.
8770 // returns: dojo/promise/Promise
8771 // Promise, or if a callback is provided, the result of the callback.
8773 var receivedPromise
= valueOrPromise
&& typeof valueOrPromise
.then
=== "function";
8774 var nativePromise
= receivedPromise
&& valueOrPromise
instanceof Promise
;
8776 if(!receivedPromise
){
8778 return callback(valueOrPromise
);
8780 return new Deferred().resolve(valueOrPromise
);
8782 }else if(!nativePromise
){
8783 var deferred
= new Deferred(valueOrPromise
.cancel
);
8784 valueOrPromise
.then(deferred
.resolve
, deferred
.reject
, deferred
.progress
);
8785 valueOrPromise
= deferred
.promise
;
8788 if(callback
|| errback
|| progback
){
8789 return valueOrPromise
.then(callback
, errback
, progback
);
8791 return valueOrPromise
;
8796 'dojo/dom-attr':function(){
8797 define(["exports", "./sniff", "./_base/lang", "./dom", "./dom-style", "./dom-prop"],
8798 function(exports
, has
, lang
, dom
, style
, prop
){
8802 // This module defines the core dojo DOM attributes API.
8804 // TODOC: summary not showing up in output see https://github.com/csnover/js-doc-parse/issues/42
8806 // =============================
8807 // Element attribute Functions
8808 // =============================
8810 // This module will be obsolete soon. Use dojo/prop instead.
8812 // dojo.attr() should conform to http://www.w3.org/TR/DOM-Level-2-Core/
8814 // attribute-related functions (to be obsolete soon)
8816 var forcePropNames
= {
8823 // original attribute names
8827 tabindex
: "tabIndex",
8828 readonly
: "readOnly"
8831 function _hasAttr(node
, name
){
8832 var attr
= node
.getAttributeNode
&& node
.getAttributeNode(name
);
8833 return attr
&& attr
.specified
; // Boolean
8836 // There is a difference in the presence of certain properties and their default values
8837 // between browsers. For example, on IE "disabled" is present on all elements,
8838 // but it is value is "false"; "tabIndex" of <div> returns 0 by default on IE, yet other browsers
8841 exports
.has
= function hasAttr(/*DOMNode|String*/ node
, /*String*/ name
){
8843 // Returns true if the requested attribute is specified on the
8844 // given element, and false otherwise.
8845 // node: DOMNode|String
8846 // id or reference to the element to check
8848 // the name of the attribute
8850 // true if the requested attribute is specified on the
8851 // given element, and false otherwise
8853 var lc
= name
.toLowerCase();
8854 return forcePropNames
[prop
.names
[lc
] || name
] || _hasAttr(dom
.byId(node
), attrNames
[lc
] || name
); // Boolean
8857 exports
.get = function getAttr(/*DOMNode|String*/ node
, /*String*/ name
){
8859 // Gets an attribute on an HTML element.
8861 // Handles normalized getting of attributes on DOM Nodes.
8862 // node: DOMNode|String
8863 // id or reference to the element to get the attribute on
8865 // the name of the attribute to get.
8867 // the value of the requested attribute or null if that attribute does not have a specified or
8871 // | // get the current value of the "foo" attribute on a node
8872 // | dojo.getAttr(dojo.byId("nodeId"), "foo");
8873 // | // or we can just pass the id:
8874 // | dojo.getAttr("nodeId", "foo");
8876 node
= dom
.byId(node
);
8877 var lc
= name
.toLowerCase(),
8878 propName
= prop
.names
[lc
] || name
,
8879 forceProp
= forcePropNames
[propName
],
8880 value
= node
[propName
]; // should we access this attribute via a property or via getAttribute()?
8882 if(forceProp
&& typeof value
!= "undefined"){
8884 return value
; // Anything
8886 if(propName
!= "href" && (typeof value
== "boolean" || lang
.isFunction(value
))){
8888 return value
; // Anything
8891 // we need _hasAttr() here to guard against IE returning a default value
8892 var attrName
= attrNames
[lc
] || name
;
8893 return _hasAttr(node
, attrName
) ? node
.getAttribute(attrName
) : null; // Anything
8896 exports
.set = function setAttr(/*DOMNode|String*/ node
, /*String|Object*/ name
, /*String?*/ value
){
8898 // Sets an attribute on an HTML element.
8900 // Handles normalized setting of attributes on DOM Nodes.
8902 // When passing functions as values, note that they will not be
8903 // directly assigned to slots on the node, but rather the default
8904 // behavior will be removed and the new behavior will be added
8905 // using `dojo.connect()`, meaning that event handler properties
8906 // will be normalized and that some caveats with regards to
8907 // non-standard behaviors for onsubmit apply. Namely that you
8908 // should cancel form submission using `dojo.stopEvent()` on the
8909 // passed event object instead of returning a boolean value from
8910 // the handler itself.
8911 // node: DOMNode|String
8912 // id or reference to the element to set the attribute on
8913 // name: String|Object
8914 // the name of the attribute to set, or a hash of key-value pairs to set.
8916 // the value to set for the attribute, if the name is a string.
8921 // | // use attr() to set the tab index
8922 // | dojo.setAttr("nodeId", "tabIndex", 3);
8925 // Set multiple values at once, including event handlers:
8926 // | dojo.setAttr("formId", {
8928 // | "tabIndex": -1,
8929 // | "method": "POST",
8930 // | "onsubmit": function(e){
8931 // | // stop submitting the form. Note that the IE behavior
8932 // | // of returning true or false will have no effect here
8933 // | // since our handler is connect()ed to the built-in
8934 // | // onsubmit behavior and so we need to use
8935 // | // dojo.stopEvent() to ensure that the submission
8936 // | // doesn't proceed.
8937 // | dojo.stopEvent(e);
8939 // | // submit the form with Ajax
8940 // | dojo.xhrPost({ form: "formId" });
8945 // Style is s special case: Only set with an object hash of styles
8946 // | dojo.setAttr("someNode",{
8949 // | width:"200px", height:"100px", color:"#000"
8954 // Again, only set style as an object hash of styles:
8955 // | var obj = { color:"#fff", backgroundColor:"#000" };
8956 // | dojo.setAttr("someNode", "style", obj);
8958 // | // though shorter to use `dojo.style()` in this case:
8959 // | dojo.setStyle("someNode", obj);
8961 node
= dom
.byId(node
);
8962 if(arguments
.length
== 2){ // inline'd type check
8963 // the object form of setter: the 2nd argument is a dictionary
8965 exports
.set(node
, x
, name
[x
]);
8967 return node
; // DomNode
8969 var lc
= name
.toLowerCase(),
8970 propName
= prop
.names
[lc
] || name
,
8971 forceProp
= forcePropNames
[propName
];
8972 if(propName
== "style" && typeof value
!= "string"){ // inline'd type check
8973 // special case: setting a style
8974 style
.set(node
, value
);
8975 return node
; // DomNode
8977 if(forceProp
|| typeof value
== "boolean" || lang
.isFunction(value
)){
8978 return prop
.set(node
, name
, value
);
8981 node
.setAttribute(attrNames
[lc
] || name
, value
);
8982 return node
; // DomNode
8985 exports
.remove
= function removeAttr(/*DOMNode|String*/ node
, /*String*/ name
){
8987 // Removes an attribute from an HTML element.
8988 // node: DOMNode|String
8989 // id or reference to the element to remove the attribute from
8991 // the name of the attribute to remove
8993 dom
.byId(node
).removeAttribute(attrNames
[name
.toLowerCase()] || name
);
8996 exports
.getNodeProp
= function getNodeProp(/*DomNode|String*/ node
, /*String*/ name
){
8998 // Returns an effective value of a property or an attribute.
8999 // node: DOMNode|String
9000 // id or reference to the element to remove the attribute from
9002 // the name of the attribute
9004 // the value of the attribute
9006 node
= dom
.byId(node
);
9007 var lc
= name
.toLowerCase(), propName
= prop
.names
[lc
] || name
;
9008 if((propName
in node
) && propName
!= "href"){
9010 return node
[propName
]; // Anything
9013 var attrName
= attrNames
[lc
] || name
;
9014 return _hasAttr(node
, attrName
) ? node
.getAttribute(attrName
) : null; // Anything
9019 'dojo/dom-construct':function(){
9020 define(["exports", "./_base/kernel", "./sniff", "./_base/window", "./dom", "./dom-attr", "./on"],
9021 function(exports
, dojo
, has
, win
, dom
, attr
, on
){
9023 // dojo/dom-construct
9025 // This module defines the core dojo DOM construction API.
9027 // TODOC: summary not showing up in output, see https://github.com/csnover/js-doc-parse/issues/42
9029 // support stuff for toDom()
9035 tr
: ["table", "tbody"],
9036 td
: ["table", "tbody", "tr"],
9037 th
: ["table", "thead", "tr"],
9038 legend
: ["fieldset"],
9040 colgroup
: ["table"],
9041 col
: ["table", "colgroup"],
9044 reTag
= /<\s*([\w\:]+)/,
9045 masterNode
= {}, masterNum
= 0,
9046 masterName
= "__" + dojo
._scopeName
+ "ToDomId";
9048 // generate start/end tag strings to use
9049 // for the injection for each special tag wrap case.
9050 for(var param
in tagWrap
){
9051 if(tagWrap
.hasOwnProperty(param
)){
9052 var tw
= tagWrap
[param
];
9053 tw
.pre
= param
== "option" ? '<select multiple="multiple">' : "<" + tw
.join("><") + ">";
9054 tw
.post
= "</" + tw
.reverse().join("></") + ">";
9055 // the last line is destructive: it reverses the array,
9056 // but we don't care at this point
9060 function _insertBefore(/*DomNode*/ node
, /*DomNode*/ ref
){
9061 var parent
= ref
.parentNode
;
9063 parent
.insertBefore(node
, ref
);
9067 function _insertAfter(/*DomNode*/ node
, /*DomNode*/ ref
){
9069 // Try to insert node after ref
9070 var parent
= ref
.parentNode
;
9072 if(parent
.lastChild
== ref
){
9073 parent
.appendChild(node
);
9075 parent
.insertBefore(node
, ref
.nextSibling
);
9080 exports
.toDom
= function toDom(frag
, doc
){
9082 // instantiates an HTML fragment returning the corresponding DOM.
9084 // the HTML fragment
9085 // doc: DocumentNode?
9086 // optional document to use when creating DOM nodes, defaults to
9087 // dojo.doc if not specified.
9089 // Document fragment, unless it's a single node in which case it returns the node itself
9091 // Create a table row:
9092 // | var tr = dojo.toDom("<tr><td>First!</td></tr>");
9094 doc
= doc
|| win
.doc
;
9095 var masterId
= doc
[masterName
];
9097 doc
[masterName
] = masterId
= ++masterNum
+ "";
9098 masterNode
[masterId
] = doc
.createElement("div");
9101 // make sure the frag is a string.
9104 // find the starting tag, and get node wrapper
9105 var match
= frag
.match(reTag
),
9106 tag
= match
? match
[1].toLowerCase() : "",
9107 master
= masterNode
[masterId
],
9109 if(match
&& tagWrap
[tag
]){
9110 wrap
= tagWrap
[tag
];
9111 master
.innerHTML
= wrap
.pre
+ frag
+ wrap
.post
;
9112 for(i
= wrap
.length
; i
; --i
){
9113 master
= master
.firstChild
;
9116 master
.innerHTML
= frag
;
9119 // one node shortcut => return the node itself
9120 if(master
.childNodes
.length
== 1){
9121 return master
.removeChild(master
.firstChild
); // DOMNode
9124 // return multiple nodes as a document fragment
9125 df
= doc
.createDocumentFragment();
9126 while((fc
= master
.firstChild
)){ // intentional assignment
9129 return df
; // DocumentFragment
9132 exports
.place
= function place(/*DOMNode|String*/ node
, /*DOMNode|String*/ refNode
, /*String|Number?*/ position
){
9134 // Attempt to insert node into the DOM, choosing from various positioning options.
9135 // Returns the first argument resolved to a DOM node.
9136 // node: DOMNode|String
9137 // id or node reference, or HTML fragment starting with "<" to place relative to refNode
9138 // refNode: DOMNode|String
9139 // id or node reference to use as basis for placement
9140 // position: String|Number?
9141 // string noting the position of node relative to refNode or a
9142 // number indicating the location in the childNodes collection of refNode.
9143 // Accepted string values are:
9152 // "first" and "last" indicate positions as children of refNode, "replace" replaces refNode,
9153 // "only" replaces all children. position defaults to "last" if not specified
9155 // Returned values is the first argument resolved to a DOM node.
9157 // .place() is also a method of `dojo/NodeList`, allowing `dojo.query` node lookups.
9159 // Place a node by string id as the last child of another node by string id:
9160 // | dojo.place("someNode", "anotherNode");
9162 // Place a node by string id before another node by string id
9163 // | dojo.place("someNode", "anotherNode", "before");
9165 // Create a Node, and place it in the body element (last child):
9166 // | dojo.place("<div></div>", dojo.body());
9168 // Put a new LI as the first child of a list by id:
9169 // | dojo.place("<li></li>", "someUl", "first");
9171 refNode
= dom
.byId(refNode
);
9172 if(typeof node
== "string"){ // inline'd type check
9173 node
= /^\s*</.test(node
) ? exports
.toDom(node
, refNode
.ownerDocument
) : dom
.byId(node
);
9175 if(typeof position
== "number"){ // inline'd type check
9176 var cn
= refNode
.childNodes
;
9177 if(!cn
.length
|| cn
.length
<= position
){
9178 refNode
.appendChild(node
);
9180 _insertBefore(node
, cn
[position
< 0 ? 0 : position
]);
9185 _insertBefore(node
, refNode
);
9188 _insertAfter(node
, refNode
);
9191 refNode
.parentNode
.replaceChild(node
, refNode
);
9194 exports
.empty(refNode
);
9195 refNode
.appendChild(node
);
9198 if(refNode
.firstChild
){
9199 _insertBefore(node
, refNode
.firstChild
);
9202 // else fallthrough...
9203 default: // aka: last
9204 refNode
.appendChild(node
);
9207 return node
; // DomNode
9210 exports
.create
= function create(/*DOMNode|String*/ tag
, /*Object*/ attrs
, /*DOMNode|String?*/ refNode
, /*String?*/ pos
){
9212 // Create an element, allowing for optional attribute decoration
9215 // A DOM Element creation function. A shorthand method for creating a node or
9216 // a fragment, and allowing for a convenient optional attribute setting step,
9217 // as well as an optional DOM placement reference.
9219 // Attributes are set by passing the optional object through `dojo.setAttr`.
9220 // See `dojo.setAttr` for noted caveats and nuances, and API if applicable.
9222 // Placement is done via `dojo.place`, assuming the new node to be the action
9223 // node, passing along the optional reference node and position.
9224 // tag: DOMNode|String
9225 // A string of the element to create (eg: "div", "a", "p", "li", "script", "br"),
9226 // or an existing DOM node to process.
9228 // An object-hash of attributes to set on the newly created node.
9229 // Can be null, if you don't want to set any attributes/styles.
9230 // See: `dojo.setAttr` for a description of available attributes.
9231 // refNode: DOMNode|String?
9232 // Optional reference node. Used by `dojo.place` to place the newly created
9233 // node somewhere in the dom relative to refNode. Can be a DomNode reference
9234 // or String ID of a node.
9236 // Optional positional reference. Defaults to "last" by way of `dojo.place`,
9237 // though can be set to "first","after","before","last", "replace" or "only"
9238 // to further control the placement of the new node relative to the refNode.
9239 // 'refNode' is required if a 'pos' is specified.
9242 // | var n = dojo.create("div");
9245 // Create a DIV with content:
9246 // | var n = dojo.create("div", { innerHTML:"<p>hi</p>" });
9249 // Place a new DIV in the BODY, with no attributes set
9250 // | var n = dojo.create("div", null, dojo.body());
9253 // Create an UL, and populate it with LI's. Place the list as the first-child of a
9254 // node with id="someId":
9255 // | var ul = dojo.create("ul", null, "someId", "first");
9256 // | var items = ["one", "two", "three", "four"];
9257 // | dojo.forEach(items, function(data){
9258 // | dojo.create("li", { innerHTML: data }, ul);
9262 // Create an anchor, with an href. Place in BODY:
9263 // | dojo.create("a", { href:"foo.html", title:"Goto FOO!" }, dojo.body());
9266 // Create a `dojo/NodeList()` from a new element (for syntactic sugar):
9267 // | dojo.query(dojo.create('div'))
9268 // | .addClass("newDiv")
9269 // | .onclick(function(e){ console.log('clicked', e.target) })
9270 // | .place("#someNode"); // redundant, but cleaner.
9274 refNode
= dom
.byId(refNode
);
9275 doc
= refNode
.ownerDocument
;
9277 if(typeof tag
== "string"){ // inline'd type check
9278 tag
= doc
.createElement(tag
);
9280 if(attrs
){ attr
.set(tag
, attrs
); }
9281 if(refNode
){ exports
.place(tag
, refNode
, pos
); }
9282 return tag
; // DomNode
9285 var _empty
= has("ie") ?
9286 function(/*DomNode*/ node
){
9288 node
.innerHTML
= ""; // really fast when it works
9289 }catch(e
){ // IE can generate Unknown Error
9290 for(var c
; c
= node
.lastChild
;){ // intentional assignment
9291 _destroy(c
, node
); // destroy is better than removeChild so TABLE elements are removed in proper order
9295 function(/*DomNode*/ node
){
9296 node
.innerHTML
= "";
9299 exports
.empty
= function empty(/*DOMNode|String*/ node
){
9301 // safely removes all children of the node.
9302 // node: DOMNode|String
9303 // a reference to a DOM node or an id.
9305 // Destroy node's children byId:
9306 // | dojo.empty("someId");
9309 // Destroy all nodes' children in a list by reference:
9310 // | dojo.query(".someNode").forEach(dojo.empty);
9312 _empty(dom
.byId(node
));
9316 function _destroy(/*DomNode*/ node
, /*DomNode*/ parent
){
9317 if(node
.firstChild
){
9321 parent
.removeChild(node
);
9324 exports
.destroy
= function destroy(/*DOMNode|String*/ node
){
9326 // Removes a node from its parent, clobbering it and all of its
9330 // Removes a node from its parent, clobbering it and all of its
9331 // children. Function only works with DomNodes, and returns nothing.
9333 // node: DOMNode|String
9334 // A String ID or DomNode reference of the element to be destroyed
9337 // Destroy a node byId:
9338 // | dojo.destroy("someId");
9341 // Destroy all nodes in a list by reference:
9342 // | dojo.query(".someNode").forEach(dojo.destroy);
9344 node
= dom
.byId(node
);
9345 if(!node
){ return; }
9346 _destroy(node
, node
.parentNode
);
9351 'dojo/request/xhr':function(){
9352 define("dojo/request/xhr", [
9353 '../errors/RequestError',
9359 '../_base/declare' =====*/
9360 ], function(RequestError
, watch
, handlers
, util
, has
/*=====, request, declare =====*/){
9361 has
.add('native-xhr', function(){
9362 // if true, the environment has a native XHR implementation
9363 return typeof XMLHttpRequest
!== 'undefined';
9365 has
.add('dojo-force-activex-xhr', function(){
9366 return has('activex') && !document
.addEventListener
&& window
.location
.protocol
=== 'file:';
9369 has
.add('native-xhr2', function(){
9370 if(!has('native-xhr')){ return; }
9371 var x
= new XMLHttpRequest();
9372 return typeof x
['addEventListener'] !== 'undefined' &&
9373 (typeof opera
=== 'undefined' || typeof x
['upload'] !== 'undefined');
9376 has
.add('native-formdata', function(){
9377 // if true, the environment has a native FormData implementation
9378 return typeof FormData
=== 'function';
9381 function handleResponse(response
, error
){
9382 var _xhr
= response
.xhr
;
9383 response
.status
= response
.xhr
.status
;
9384 response
.text
= _xhr
.responseText
;
9386 if(response
.options
.handleAs
=== 'xml'){
9387 response
.data
= _xhr
.responseXML
;
9400 }else if(util
.checkStatus(_xhr
.status
)){
9401 this.resolve(response
);
9403 error
= new RequestError('Unable to load ' + response
.url
+ ' status: ' + _xhr
.status
, response
);
9409 var isValid
, isReady
, addListeners
, cancel
;
9410 if(has('native-xhr2')){
9411 // Any platform with XHR2 will only use the watch mechanism for timeout.
9413 isValid = function(response
){
9415 // Check to see if the request should be taken out of the watch queue
9416 return !this.isFulfilled();
9418 cancel = function(dfd
, response
){
9420 // Canceler for deferred
9421 response
.xhr
.abort();
9423 addListeners = function(_xhr
, dfd
, response
){
9425 // Adds event listeners to the XMLHttpRequest object
9426 function onLoad(evt
){
9427 dfd
.handleResponse(response
);
9429 function onError(evt
){
9430 var _xhr
= evt
.target
;
9431 var error
= new RequestError('Unable to load ' + response
.url
+ ' status: ' + _xhr
.status
, response
);
9432 dfd
.handleResponse(response
, error
);
9435 function onProgress(evt
){
9436 if(evt
.lengthComputable
){
9437 response
.loaded
= evt
.loaded
;
9438 response
.total
= evt
.total
;
9439 dfd
.progress(response
);
9443 _xhr
.addEventListener('load', onLoad
, false);
9444 _xhr
.addEventListener('error', onError
, false);
9445 _xhr
.addEventListener('progress', onProgress
, false);
9448 _xhr
.removeEventListener('load', onLoad
, false);
9449 _xhr
.removeEventListener('error', onError
, false);
9450 _xhr
.removeEventListener('progress', onProgress
, false);
9454 isValid = function(response
){
9455 return response
.xhr
.readyState
; //boolean
9457 isReady = function(response
){
9458 return 4 === response
.xhr
.readyState
; //boolean
9460 cancel = function(dfd
, response
){
9462 // canceller function for util.deferred call.
9463 var xhr
= response
.xhr
;
9464 var _at
= typeof xhr
.abort
;
9465 if(_at
=== 'function' || _at
=== 'object' || _at
=== 'unknown'){
9478 'Content-Type': 'application/x-www-form-urlencoded'
9481 function xhr(url
, options
, returnDeferred
){
9482 var response
= util
.parseArgs(
9484 util
.deepCreate(defaultOptions
, options
),
9485 has('native-formdata') && options
&& options
.data
&& options
.data
instanceof FormData
9488 options
= response
.options
;
9492 remover
&& remover();
9495 //Make the Deferred object for this xhr request.
9496 var dfd
= util
.deferred(
9504 var _xhr
= response
.xhr
= xhr
._create();
9507 // If XHR factory somehow returns nothings,
9508 // cancel the deferred.
9509 dfd
.cancel(new RequestError('XHR was not created'));
9510 return returnDeferred
? dfd
: dfd
.promise
;
9513 response
.getHeader = function(headerName
){
9514 return this.xhr
.getResponseHeader(headerName
);
9518 remover
= addListeners(_xhr
, dfd
, response
);
9521 var data
= options
.data
,
9522 async
= !options
.sync
,
9523 method
= options
.method
;
9526 // IE6 won't let you call apply() on the native function.
9527 _xhr
.open(method
, url
, async
, options
.user
|| undefined, options
.password
|| undefined);
9529 if(options
.withCredentials
){
9530 _xhr
.withCredentials
= options
.withCredentials
;
9533 var headers
= options
.headers
,
9536 for(var hdr
in headers
){
9537 if(hdr
.toLowerCase() === 'content-type'){
9538 contentType
= headers
[hdr
];
9539 }else if(headers
[hdr
]){
9540 //Only add header if it has a value. This allows for instance, skipping
9541 //insertion of X-Requested-With by specifying empty value.
9542 _xhr
.setRequestHeader(hdr
, headers
[hdr
]);
9547 if(contentType
&& contentType
!== false){
9548 _xhr
.setRequestHeader('Content-Type', contentType
);
9550 if(!headers
|| !('X-Requested-With' in headers
)){
9551 _xhr
.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
9555 util
.notify
.emit('send', response
, dfd
.promise
.cancel
);
9565 return returnDeferred
? dfd
: dfd
.promise
;
9569 xhr = function(url, options){
9571 // Sends a request using XMLHttpRequest with the given URL and options.
9574 // options: dojo/request/xhr.__Options?
9575 // Options for the request.
9576 // returns: dojo/request.__Promise
9578 xhr.__BaseOptions = declare(request.__BaseOptions, {
9580 // Whether to make a synchronous request or not. Default
9581 // is `false` (asynchronous).
9582 // data: String|Object|FormData?
9583 // Data to transfer. This is ignored for GET and DELETE
9586 // Headers to use for the request.
9588 // Username to use during the request.
9589 // password: String?
9590 // Password to use during the request.
9591 // withCredentials: Boolean?
9592 // For cross-site requests, whether to send credentials
9595 xhr.__MethodOptions = declare(null, {
9597 // The HTTP method to use to make the request. Must be
9598 // uppercase. Default is `"GET"`.
9600 xhr.__Options = declare([xhr.__BaseOptions, xhr.__MethodOptions]);
9602 xhr.get = function(url, options){
9604 // Send an HTTP GET request using XMLHttpRequest with the given URL and options.
9607 // options: dojo/request/xhr.__BaseOptions?
9608 // Options for the request.
9609 // returns: dojo/request.__Promise
9611 xhr.post = function(url, options){
9613 // Send an HTTP POST request using XMLHttpRequest with the given URL and options.
9616 // options: dojo/request/xhr.__BaseOptions?
9617 // Options for the request.
9618 // returns: dojo/request.__Promise
9620 xhr.put = function(url, options){
9622 // Send an HTTP PUT request using XMLHttpRequest with the given URL and options.
9625 // options: dojo/request/xhr.__BaseOptions?
9626 // Options for the request.
9627 // returns: dojo/request.__Promise
9629 xhr.del = function(url, options){
9631 // Send an HTTP DELETE request using XMLHttpRequest with the given URL and options.
9634 // options: dojo/request/xhr.__BaseOptions?
9635 // Options for the request.
9636 // returns: dojo/request.__Promise
9639 xhr
._create = function(){
9641 // does the work of portably generating a new XMLHTTPRequest object.
9642 throw new Error('XMLHTTP not available');
9644 if(has('native-xhr') && !has('dojo-force-activex-xhr')){
9645 xhr
._create = function(){
9646 return new XMLHttpRequest();
9648 }else if(has('activex')){
9650 new ActiveXObject('Msxml2.XMLHTTP');
9651 xhr
._create = function(){
9652 return new ActiveXObject('Msxml2.XMLHTTP');
9656 new ActiveXObject('Microsoft.XMLHTTP');
9657 xhr
._create = function(){
9658 return new ActiveXObject('Microsoft.XMLHTTP');
9664 util
.addCommonMethods(xhr
);
9670 'dojo/keys':function(){
9671 define("dojo/keys", ["./_base/kernel", "./sniff"], function(dojo
, has
){
9676 return dojo
.keys
= {
9678 // Definitions for common key values. Client code should test keyCode against these named constants,
9679 // as the actual codes can vary by browser.
9688 META
: has("webkit") ? 91 : 224, // the apple key on macs
9717 NUMPAD_MULTIPLY
: 106,
9744 // virtual key mapping
9745 copyKey
: has("mac") && !has("air") ? (has("safari") ? 91 : 224 ) : 17
9750 'dojo/domReady':function(){
9751 define(['./has'], function(has
){
9754 readyStates
= { 'loaded': 1, 'complete': 1 },
9755 fixReadyState
= typeof doc
.readyState
!= "string",
9756 ready
= !!readyStates
[doc
.readyState
];
9759 if(fixReadyState
){ doc
.readyState
= "loading"; }
9762 var readyQ
= [], tests
= [],
9763 detectReady = function(evt
){
9764 evt
= evt
|| global
.event
;
9765 if(ready
|| (evt
.type
== "readystatechange" && !readyStates
[doc
.readyState
])){ return; }
9769 if(fixReadyState
){ doc
.readyState
= "complete"; }
9771 while(readyQ
.length
){
9772 (readyQ
.shift())(doc
);
9775 on = function(node
, event
){
9776 node
.addEventListener(event
, detectReady
, false);
9777 readyQ
.push(function(){ node
.removeEventListener(event
, detectReady
, false); });
9780 if(!has("dom-addeventlistener")){
9781 on = function(node
, event
){
9782 event
= "on" + event
;
9783 node
.attachEvent(event
, detectReady
);
9784 readyQ
.push(function(){ node
.detachEvent(event
, detectReady
); });
9787 var div
= doc
.createElement("div");
9789 if(div
.doScroll
&& global
.frameElement
=== null){
9790 // the doScroll test is only useful if we're in the top-most frame
9791 tests
.push(function(){
9792 // Derived with permission from Diego Perini's IEContentLoaded
9793 // http://javascript.nwbox.com/IEContentLoaded/
9795 div
.doScroll("left");
9803 on(doc
, "DOMContentLoaded");
9806 if("onreadystatechange" in doc
){
9807 on(doc
, "readystatechange");
9808 }else if(!fixReadyState
){
9809 // if the ready state property exists and there's
9810 // no readystatechange event, poll for the state
9812 tests
.push(function(){
9813 return readyStates
[doc
.readyState
];
9818 var poller = function(){
9819 if(ready
){ return; }
9820 var i
= tests
.length
;
9823 detectReady("poller");
9827 setTimeout(poller
, 30);
9833 function domReady(callback
){
9835 // Plugin to delay require()/define() callback from firing until the DOM has finished loading.
9839 readyQ
.push(callback
);
9842 domReady
.load = function(id
, req
, load
){
9850 'dojo/_base/lang':function(){
9851 define("dojo/_base/lang", ["./kernel", "../has", "../sniff"], function(dojo
, has
){
9855 has
.add("bug-for-in-skips-shadowed", function(){
9856 // if true, the for-in iterator skips object properties that exist in Object's prototype (IE 6 - ?)
9857 for(var i
in {toString
: 1}){
9865 has("bug-for-in-skips-shadowed") ?
9866 "hasOwnProperty.valueOf.isPrototypeOf.propertyIsEnumerable.toLocaleString.toString.constructor".split(".") : [],
9868 _extraLen
= _extraNames
.length
,
9870 getProp = function(/*Array*/parts
, /*Boolean*/create
, /*Object*/context
){
9871 var p
, i
= 0, dojoGlobal
= dojo
.global
;
9878 context
= dojo
.scopeMap
[p
] && dojo
.scopeMap
[p
][1];
9880 context
= context
|| (p
in dojoGlobal
? dojoGlobal
[p
] : (create
? dojoGlobal
[p
] = {} : undefined));
9883 while(context
&& (p
= parts
[i
++])){
9884 context
= (p
in context
? context
[p
] : (create
? context
[p
] = {} : undefined));
9886 return context
; // mixed
9889 opts
= Object
.prototype.toString
,
9891 efficient = function(obj
, offset
, startWith
){
9892 return (startWith
||[]).concat(Array
.prototype.slice
.call(obj
, offset
||0));
9895 _pattern
= /\{([^\}]+)\}/g;
9900 // This module defines Javascript language extensions.
9902 // _extraNames: String[]
9903 // Lists property names that must be explicitly processed during for-in iteration
9904 // in environments that have has("bug-for-in-skips-shadowed") true.
9905 _extraNames
:_extraNames
,
9907 _mixin: function(dest
, source
, copyFunc
){
9909 // Copies/adds all properties of source to dest; returns dest.
9911 // The object to which to copy/add all properties contained in source.
9913 // The object from which to draw all properties to copy into dest.
9914 // copyFunc: Function?
9915 // The process used to copy/add a property in source; defaults to the Javascript assignment operator.
9917 // dest, as modified
9919 // All properties, including functions (sometimes termed "methods"), excluding any non-standard extensions
9920 // found in Object.prototype, are copied/added to dest. Copying/adding each particular property is
9921 // delegated to copyFunc (if any); copyFunc defaults to the Javascript assignment operator if not provided.
9922 // Notice that by default, _mixin executes a so-called "shallow copy" and aggregate types are copied/added by reference.
9923 var name
, s
, i
, empty
= {};
9924 for(name
in source
){
9925 // the (!(name in empty) || empty[name] !== s) condition avoids copying properties in "source"
9926 // inherited from Object.prototype. For example, if dest has a custom toString() method,
9927 // don't overwrite it with the toString() method that source inherited from Object.prototype
9929 if(!(name
in dest
) || (dest
[name
] !== s
&& (!(name
in empty
) || empty
[name
] !== s
))){
9930 dest
[name
] = copyFunc
? copyFunc(s
) : s
;
9934 if(has("bug-for-in-skips-shadowed")){
9936 for(i
= 0; i
< _extraLen
; ++i
){
9937 name
= _extraNames
[i
];
9939 if(!(name
in dest
) || (dest
[name
] !== s
&& (!(name
in empty
) || empty
[name
] !== s
))){
9940 dest
[name
] = copyFunc
? copyFunc(s
) : s
;
9946 return dest
; // Object
9949 mixin: function(dest
, sources
){
9951 // Copies/adds all properties of one or more sources to dest; returns dest.
9953 // The object to which to copy/add all properties contained in source. If dest is falsy, then
9954 // a new object is manufactured before copying/adding properties begins.
9955 // sources: Object...
9956 // One of more objects from which to draw all properties to copy into dest. sources are processed
9957 // left-to-right and if more than one of these objects contain the same property name, the right-most
9960 // dest, as modified
9962 // All properties, including functions (sometimes termed "methods"), excluding any non-standard extensions
9963 // found in Object.prototype, are copied/added from sources to dest. sources are processed left to right.
9964 // The Javascript assignment operator is used to copy/add each property; therefore, by default, mixin
9965 // executes a so-called "shallow copy" and aggregate types are copied/added by reference.
9967 // make a shallow copy of an object
9968 // | var copy = lang.mixin({}, source);
9970 // many class constructors often take an object which specifies
9971 // values to be configured on the object. In this case, it is
9972 // often simplest to call `lang.mixin` on the `this` object:
9973 // | declare("acme.Base", null, {
9974 // | constructor: function(properties){
9975 // | // property configuration:
9976 // | lang.mixin(this, properties);
9978 // | console.log(this.quip);
9981 // | quip: "I wasn't born yesterday, you know - I've seen movies.",
9985 // | // create an instance of the class and configure it
9986 // | var b = new acme.Base({quip: "That's what it does!" });
9988 // copy in properties from multiple objects
9989 // | var flattened = lang.mixin(
9991 // | name: "Frylock",
9995 // | name: "Carl Brutanananadilewski"
9999 // | // will print "Carl Brutanananadilewski"
10000 // | console.log(flattened.name);
10001 // | // will print "true"
10002 // | console.log(flattened.braces);
10004 if(!dest
){ dest
= {}; }
10005 for(var i
= 1, l
= arguments
.length
; i
< l
; i
++){
10006 lang
._mixin(dest
, arguments
[i
]);
10008 return dest
; // Object
10011 setObject: function(name
, value
, context
){
10013 // Set a property from a dot-separated string, such as "A.B.C"
10015 // Useful for longer api chains where you have to test each object in
10016 // the chain, or when you have an object reference in string format.
10017 // Objects are created as needed along `path`. Returns the passed
10018 // value if setting is successful or `undefined` if not.
10020 // Path to a property, in the form "A.B.C".
10022 // value or object to place at location given by name
10023 // context: Object?
10024 // Optional. Object to use as root of path. Defaults to
10027 // set the value of `foo.bar.baz`, regardless of whether
10028 // intermediate objects already exist:
10029 // | lang.setObject("foo.bar.baz", value);
10031 // without `lang.setObject`, we often see code like this:
10032 // | // ensure that intermediate objects are available
10033 // | if(!obj["parent"]){ obj.parent = {}; }
10034 // | if(!obj.parent["child"]){ obj.parent.child = {}; }
10035 // | // now we can safely set the property
10036 // | obj.parent.child.prop = "some value";
10037 // whereas with `lang.setObject`, we can shorten that to:
10038 // | lang.setObject("parent.child.prop", "some value", obj);
10040 var parts
= name
.split("."), p
= parts
.pop(), obj
= getProp(parts
, true, context
);
10041 return obj
&& p
? (obj
[p
] = value
) : undefined; // Object
10044 getObject: function(name
, create
, context
){
10046 // Get a property from a dot-separated string, such as "A.B.C"
10048 // Useful for longer api chains where you have to test each object in
10049 // the chain, or when you have an object reference in string format.
10051 // Path to an property, in the form "A.B.C".
10052 // create: Boolean?
10053 // Optional. Defaults to `false`. If `true`, Objects will be
10054 // created at any point along the 'path' that is undefined.
10055 // context: Object?
10056 // Optional. Object to use as root of path. Defaults to
10057 // 'dojo.global'. Null may be passed.
10058 return getProp(name
.split("."), create
, context
); // Object
10061 exists: function(name
, obj
){
10063 // determine if an object supports a given method
10065 // useful for longer api chains where you have to test each object in
10066 // the chain. Useful for object and method detection.
10068 // Path to an object, in the form "A.B.C".
10070 // Object to use as root of path. Defaults to
10071 // 'dojo.global'. Null may be passed.
10073 // | // define an object
10078 // | // search the global scope
10079 // | lang.exists("foo.bar"); // true
10080 // | lang.exists("foo.bar.baz"); // false
10082 // | // search from a particular scope
10083 // | lang.exists("bar", foo); // true
10084 // | lang.exists("bar.baz", foo); // false
10085 return lang
.getObject(name
, false, obj
) !== undefined; // Boolean
10088 // Crockford (ish) functions
10090 isString: function(it
){
10092 // Return true if it is a String
10095 return (typeof it
== "string" || it
instanceof String
); // Boolean
10098 isArray: function(it
){
10100 // Return true if it is an Array.
10101 // Does not work on Arrays created in other windows.
10104 return it
&& (it
instanceof Array
|| typeof it
== "array"); // Boolean
10107 isFunction: function(it
){
10109 // Return true if it is a Function
10112 return opts
.call(it
) === "[object Function]";
10115 isObject: function(it
){
10117 // Returns true if it is a JavaScript object (or an Array, a Function
10121 return it
!== undefined &&
10122 (it
=== null || typeof it
== "object" || lang
.isArray(it
) || lang
.isFunction(it
)); // Boolean
10125 isArrayLike: function(it
){
10127 // similar to isArray() but more permissive
10131 // If it walks like a duck and quacks like a duck, return `true`
10133 // Doesn't strongly test for "arrayness". Instead, settles for "isn't
10134 // a string or number and has a length property". Arguments objects
10135 // and DOM collections will return true when passed to
10136 // isArrayLike(), but will return false when passed to
10138 return it
&& it
!== undefined && // Boolean
10139 // keep out built-in constructors (Number, String, ...) which have length
10141 !lang
.isString(it
) && !lang
.isFunction(it
) &&
10142 !(it
.tagName
&& it
.tagName
.toLowerCase() == 'form') &&
10143 (lang
.isArray(it
) || isFinite(it
.length
));
10146 isAlien: function(it
){
10148 // Returns true if it is a built-in function or some other kind of
10149 // oddball that *should* report as a function but doesn't
10150 return it
&& !lang
.isFunction(it
) && /\{\s*\[native code\]\s*\}/.test(String(it
)); // Boolean
10153 extend: function(ctor
, props
){
10155 // Adds all properties and methods of props to constructor's
10156 // prototype, making them available to all instances created with
10159 // Target constructor to extend.
10161 // One or more objects to mix into ctor.prototype
10162 for(var i
=1, l
=arguments
.length
; i
<l
; i
++){
10163 lang
._mixin(ctor
.prototype, arguments
[i
]);
10165 return ctor
; // Object
10168 _hitchArgs: function(scope
, method
){
10169 var pre
= lang
._toArray(arguments
, 2);
10170 var named
= lang
.isString(method
);
10172 // arrayify arguments
10173 var args
= lang
._toArray(arguments
);
10174 // locate our method
10175 var f
= named
? (scope
||dojo
.global
)[method
] : method
;
10176 // invoke with collected args
10177 return f
&& f
.apply(scope
|| this, pre
.concat(args
)); // mixed
10181 hitch: function(scope
, method
){
10183 // Returns a function that will only ever execute in the a given scope.
10184 // This allows for easy use of object member functions
10185 // in callbacks and other places in which the "this" keyword may
10186 // otherwise not reference the expected scope.
10187 // Any number of default positional arguments may be passed as parameters
10188 // beyond "method".
10189 // Each of these values will be used to "placehold" (similar to curry)
10190 // for the hitched function.
10192 // The scope to use when method executes. If method is a string,
10193 // scope is also the object containing method.
10194 // method: Function|String...
10195 // A function to be hitched to scope, or the name of the method in
10196 // scope to be hitched.
10198 // | lang.hitch(foo, "bar")();
10199 // runs foo.bar() in the scope of foo
10201 // | lang.hitch(foo, myFunction);
10202 // returns a function that runs myFunction in the scope of foo
10204 // Expansion on the default positional arguments passed along from
10205 // hitch. Passed args are mixed first, additional args after.
10206 // | var foo = { bar: function(a, b, c){ console.log(a, b, c); } };
10207 // | var fn = lang.hitch(foo, "bar", 1, 2);
10208 // | fn(3); // logs "1, 2, 3"
10210 // | var foo = { bar: 2 };
10211 // | lang.hitch(foo, function(){ this.bar = 10; })();
10212 // execute an anonymous function in scope of foo
10213 if(arguments
.length
> 2){
10214 return lang
._hitchArgs
.apply(dojo
, arguments
); // Function
10220 if(lang
.isString(method
)){
10221 scope
= scope
|| dojo
.global
;
10222 if(!scope
[method
]){ throw(['lang.hitch: scope["', method
, '"] is null (scope="', scope
, '")'].join('')); }
10223 return function(){ return scope
[method
].apply(scope
, arguments
|| []); }; // Function
10225 return !scope
? method : function(){ return method
.apply(scope
, arguments
|| []); }; // Function
10228 delegate
: (function(){
10229 // boodman/crockford delegation w/ cornford optimization
10231 return function(obj
, props
){
10232 TMP
.prototype = obj
;
10233 var tmp
= new TMP();
10234 TMP
.prototype = null;
10236 lang
._mixin(tmp
, props
);
10238 return tmp
; // Object
10242 delegate: function(obj, props){
10244 // Returns a new object which "looks" to obj for properties which it
10245 // does not have a value for. Optionally takes a bag of properties to
10246 // seed the returned object with initially.
10248 // This is a small implementation of the Boodman/Crockford delegation
10249 // pattern in JavaScript. An intermediate object constructor mediates
10250 // the prototype chain for the returned object, using it to delegate
10251 // down to obj for property lookup when object-local lookup fails.
10252 // This can be thought of similarly to ES4's "wrap", save that it does
10253 // not act on types but rather on pure objects.
10255 // The object to delegate to for properties not found directly on the
10256 // return object or in props.
10257 // props: Object...
10258 // an object containing properties to assign to the returned object
10260 // an Object of anonymous type
10262 // | var foo = { bar: "baz" };
10263 // | var thinger = lang.delegate(foo, { thud: "xyzzy"});
10264 // | thinger.bar == "baz"; // delegated to foo
10265 // | foo.thud == undefined; // by definition
10266 // | thinger.thud == "xyzzy"; // mixed in from props
10267 // | foo.bar = "thonk";
10268 // | thinger.bar == "thonk"; // still delegated to foo's bar
10272 _toArray
: has("ie") ?
10274 function slow(obj
, offset
, startWith
){
10275 var arr
= startWith
||[];
10276 for(var x
= offset
|| 0; x
< obj
.length
; x
++){
10281 return function(obj
){
10282 return ((obj
.item
) ? slow
: efficient
).apply(this, arguments
);
10286 _toArray: function(obj, offset, startWith){
10288 // Converts an array-like object (i.e. arguments, DOMCollection) to an
10289 // array. Returns a new Array with the elements of obj.
10291 // the object to "arrayify". We expect the object to have, at a
10292 // minimum, a length property which corresponds to integer-indexed
10295 // the location in obj to start iterating from. Defaults to 0.
10297 // startWith: Array?
10298 // An array to pack with the properties of obj. If provided,
10299 // properties in obj are appended at the end of startWith and
10300 // startWith is the returned array.
10304 partial: function(/*Function|String*/ method
/*, ...*/){
10306 // similar to hitch() except that the scope object is left to be
10307 // whatever the execution context eventually becomes.
10309 // Calling lang.partial is the functional equivalent of calling:
10310 // | lang.hitch(null, funcName, ...);
10312 // The function to "wrap"
10313 var arr
= [ null ];
10314 return lang
.hitch
.apply(dojo
, arr
.concat(lang
._toArray(arguments
))); // Function
10317 clone: function(/*anything*/ src
){
10319 // Clones objects (including DOM nodes) and all children.
10320 // Warning: do not clone cyclic structures.
10322 // The object to clone
10323 if(!src
|| typeof src
!= "object" || lang
.isFunction(src
)){
10324 // null, undefined, any non-object, or function
10325 return src
; // anything
10327 if(src
.nodeType
&& "cloneNode" in src
){
10329 return src
.cloneNode(true); // Node
10331 if(src
instanceof Date
){
10333 return new Date(src
.getTime()); // Date
10335 if(src
instanceof RegExp
){
10337 return new RegExp(src
); // RegExp
10340 if(lang
.isArray(src
)){
10343 for(i
= 0, l
= src
.length
; i
< l
; ++i
){
10345 r
.push(lang
.clone(src
[i
]));
10348 // we don't clone functions for performance reasons
10349 // }else if(d.isFunction(src)){
10351 // r = function(){ return src.apply(this, arguments); };
10354 r
= src
.constructor ? new src
.constructor() : {};
10356 return lang
._mixin(r
, src
, lang
.clone
);
10360 trim
: String
.prototype.trim
?
10361 function(str
){ return str
.trim(); } :
10362 function(str
){ return str
.replace(/^\s\s*/, '').replace(/\s\s*$/, ''); },
10364 trim: function(str){
10366 // Trims whitespace from both sides of the string
10368 // String to be trimmed
10370 // Returns the trimmed string
10372 // This version of trim() was selected for inclusion into the base due
10373 // to its compact size and relatively good performance
10374 // (see [Steven Levithan's blog](http://blog.stevenlevithan.com/archives/faster-trim-javascript)
10375 // Uses String.prototype.trim instead, if available.
10376 // The fastest but longest version of this function is located at
10377 // lang.string.trim()
10381 replace: function(tmpl
, map
, pattern
){
10383 // Performs parameterized substitutions on a string. Throws an
10384 // exception if any parameter is unmatched.
10386 // String to be used as a template.
10387 // map: Object|Function
10388 // If an object, it is used as a dictionary to look up substitutions.
10389 // If a function, it is called for every substitution with following parameters:
10390 // a whole match, a name, an offset, and the whole template
10391 // string (see https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/String/replace
10392 // for more details).
10394 // Optional regular expression objects that overrides the default pattern.
10395 // Must be global and match one item. The default is: /\{([^\}]+)\}/g,
10396 // which matches patterns like that: "{xxx}", where "xxx" is any sequence
10397 // of characters, which doesn't include "}".
10399 // Returns the substituted string.
10401 // | // uses a dictionary for substitutions:
10402 // | lang.replace("Hello, {name.first} {name.last} AKA {nick}!",
10406 // | first: "Robert",
10408 // | last: "Cringely"
10411 // | // returns: Hello, Robert Cringely AKA Bob!
10413 // | // uses an array for substitutions:
10414 // | lang.replace("Hello, {0} {2}!",
10415 // | ["Robert", "X", "Cringely"]);
10416 // | // returns: Hello, Robert Cringely!
10418 // | // uses a function for substitutions:
10419 // | function sum(a){
10421 // | arrayforEach(a, function(x){ t += x; });
10425 // | "{count} payments averaging {avg} USD per payment.",
10427 // | { payments: [11, 16, 12] },
10428 // | function(_, key){
10430 // | case "count": return this.payments.length;
10431 // | case "min": return Math.min.apply(Math, this.payments);
10432 // | case "max": return Math.max.apply(Math, this.payments);
10433 // | case "sum": return sum(this.payments);
10434 // | case "avg": return sum(this.payments) / this.payments.length;
10439 // | // prints: 3 payments averaging 13 USD per payment.
10441 // | // uses an alternative PHP-like pattern for substitutions:
10442 // | lang.replace("Hello, ${0} ${2}!",
10443 // | ["Robert", "X", "Cringely"], /\$\{([^\}]+)\}/g);
10444 // | // returns: Hello, Robert Cringely!
10446 return tmpl
.replace(pattern
|| _pattern
, lang
.isFunction(map
) ?
10447 map : function(_
, k
){ return lang
.getObject(k
, false, map
); });
10451 1 && lang
.mixin(dojo
, lang
);
10458 'dojo/request/util':function(){
10459 define("dojo/request/util", [
10461 '../errors/RequestError',
10462 '../errors/CancelError',
10467 ], function(exports
, RequestError
, CancelError
, Deferred
, ioQuery
, array
, lang
){
10468 exports
.deepCopy
= function deepCopy(target
, source
){
10469 for(var name
in source
){
10470 var tval
= target
[name
],
10471 sval
= source
[name
];
10473 if(tval
&& typeof tval
=== 'object' && sval
&& typeof sval
=== 'object'){
10474 exports
.deepCopy(tval
, sval
);
10476 target
[name
] = sval
;
10483 exports
.deepCreate
= function deepCreate(source
, properties
){
10484 properties
= properties
|| {};
10485 var target
= lang
.delegate(source
),
10488 for(name
in source
){
10489 value
= source
[name
];
10491 if(value
&& typeof value
=== 'object'){
10492 target
[name
] = exports
.deepCreate(value
, properties
[name
]);
10495 return exports
.deepCopy(target
, properties
);
10498 var freeze
= Object
.freeze
|| function(obj
){ return obj
; };
10499 function okHandler(response
){
10500 return freeze(response
);
10503 exports
.deferred
= function deferred(response
, cancel
, isValid
, isReady
, handleResponse
, last
){
10504 var def
= new Deferred(function(reason
){
10505 cancel
&& cancel(def
, response
);
10507 if(!reason
|| !(reason
instanceof RequestError
) && !(reason
instanceof CancelError
)){
10508 return new CancelError('Request canceled', response
);
10513 def
.response
= response
;
10514 def
.isValid
= isValid
;
10515 def
.isReady
= isReady
;
10516 def
.handleResponse
= handleResponse
;
10518 function errHandler(error
){
10519 error
.response
= response
;
10522 var responsePromise
= def
.then(okHandler
).otherwise(errHandler
);
10524 if(exports
.notify
){
10525 responsePromise
.then(
10526 lang
.hitch(exports
.notify
, 'emit', 'load'),
10527 lang
.hitch(exports
.notify
, 'emit', 'error')
10531 var dataPromise
= responsePromise
.then(function(response
){
10532 return response
.data
|| response
.text
;
10535 var promise
= freeze(lang
.delegate(dataPromise
, {
10536 response
: responsePromise
10541 def
.then(function(response
){
10542 last
.call(def
, response
);
10543 }, function(error
){
10544 last
.call(def
, response
, error
);
10548 def
.promise
= promise
;
10549 def
.then
= promise
.then
;
10554 exports
.addCommonMethods
= function addCommonMethods(provider
, methods
){
10555 array
.forEach(methods
||['GET', 'POST', 'PUT', 'DELETE'], function(method
){
10556 provider
[(method
=== 'DELETE' ? 'DEL' : method
).toLowerCase()] = function(url
, options
){
10557 options
= lang
.delegate(options
||{});
10558 options
.method
= method
;
10559 return provider(url
, options
);
10564 exports
.parseArgs
= function parseArgs(url
, options
, skipData
){
10565 var data
= options
.data
,
10566 query
= options
.query
;
10568 if(data
&& !skipData
){
10569 if(typeof data
=== 'object'){
10570 options
.data
= ioQuery
.objectToQuery(data
);
10575 if(typeof query
=== 'object'){
10576 query
= ioQuery
.objectToQuery(query
);
10578 if(options
.preventCache
){
10579 query
+= (query
? '&' : '') + 'request.preventCache=' + (+(new Date
));
10581 }else if(options
.preventCache
){
10582 query
= 'request.preventCache=' + (+(new Date
));
10586 url
+= (~url
.indexOf('?') ? '&' : '?') + query
;
10592 getHeader: function(headerName
){ return null; }
10596 exports
.checkStatus = function(stat
){
10598 return (stat
>= 200 && stat
< 300) || // allow any 2XX response code
10599 stat
=== 304 || // or, get it out of the cache
10600 stat
=== 1223 || // or, Internet Explorer mangled the status code
10601 !stat
; // or, we're Titanium/browser chrome/chrome extension requesting a local file
10606 'dojo/Evented':function(){
10607 define("dojo/Evented", ["./aspect", "./on"], function(aspect
, on
){
10612 var after
= aspect
.after
;
10613 function Evented(){
10615 // A class that can be used as a mixin or base class,
10616 // to add on() and emit() methods to a class
10617 // for listening for events and emitting events:
10619 // | define(["dojo/Evented"], function(Evented){
10620 // | var EventedWidget = dojo.declare([Evented, dijit._Widget], {...});
10621 // | widget = new EventedWidget();
10622 // | widget.on("open", function(event){
10623 // | ... do something with event
10626 // | widget.emit("open", {name:"some event", ...});
10628 Evented
.prototype = {
10629 on: function(type
, listener
){
10630 return on
.parse(this, type
, listener
, function(target
, type
){
10631 return after(target
, 'on' + type
, listener
, true);
10634 emit: function(type
, event
){
10636 args
.push
.apply(args
, arguments
);
10637 return on
.emit
.apply(on
, args
);
10644 'dojo/mouse':function(){
10645 define("dojo/mouse", ["./_base/kernel", "./on", "./has", "./dom", "./_base/window"], function(dojo
, on
, has
, dom
, win
){
10650 has
.add("dom-quirks", win
.doc
&& win
.doc
.compatMode
== "BackCompat");
10651 has
.add("events-mouseenter", win
.doc
&& "onmouseenter" in win
.doc
.createElement("div"));
10652 has
.add("events-mousewheel", win
.doc
&& 'onmousewheel' in win
.doc
);
10655 if((has("dom-quirks") && has("ie")) || !has("dom-addeventlistener")){
10660 // helper functions
10661 isButton: function(e
, button
){ return e
.button
& button
; },
10662 isLeft: function(e
){ return e
.button
& 1; },
10663 isMiddle: function(e
){ return e
.button
& 4; },
10664 isRight: function(e
){ return e
.button
& 2; }
10671 // helper functions
10672 isButton: function(e
, button
){ return e
.button
== button
; },
10673 isLeft: function(e
){ return e
.button
== 0; },
10674 isMiddle: function(e
){ return e
.button
== 1; },
10675 isRight: function(e
){ return e
.button
== 2; }
10678 dojo
.mouseButtons
= mouseButtons
;
10681 dojo.mouseButtons = {
10683 // Numeric value of the left mouse button for the platform.
10686 // Numeric value of the middle mouse button for the platform.
10689 // Numeric value of the right mouse button for the platform.
10692 isButton: function(e, button){
10694 // Checks an event object for a pressed button
10696 // Event object to examine
10698 // The button value (example: dojo.mouseButton.LEFT)
10699 return e.button == button; // Boolean
10701 isLeft: function(e){
10703 // Checks an event object for the pressed left button
10705 // Event object to examine
10706 return e.button == 0; // Boolean
10708 isMiddle: function(e){
10710 // Checks an event object for the pressed middle button
10712 // Event object to examine
10713 return e.button == 1; // Boolean
10715 isRight: function(e){
10717 // Checks an event object for the pressed right button
10719 // Event object to examine
10720 return e.button == 2; // Boolean
10725 function eventHandler(type
, selectHandler
){
10726 // emulation of mouseenter/leave with mouseover/out using descendant checking
10727 var handler = function(node
, listener
){
10728 return on(node
, type
, function(evt
){
10730 return selectHandler(evt
, listener
);
10732 if(!dom
.isDescendant(evt
.relatedTarget
, node
)){
10733 return listener
.call(this, evt
);
10737 handler
.bubble = function(select
){
10738 return eventHandler(type
, function(evt
, listener
){
10739 // using a selector, use the select function to determine if the mouse moved inside the selector and was previously outside the selector
10740 var target
= select(evt
.target
);
10741 var relatedTarget
= evt
.relatedTarget
;
10742 if(target
&& (target
!= (relatedTarget
&& relatedTarget
.nodeType
== 1 && select(relatedTarget
)))){
10743 return listener
.call(target
, evt
);
10750 if(has("events-mousewheel")){
10751 wheel
= 'mousewheel';
10753 wheel = function(node
, listener
){
10754 return on(node
, 'DOMMouseScroll', function(evt
){
10755 evt
.wheelDelta
= -evt
.detail
;
10756 listener
.call(this, evt
);
10762 // This module provide mouse event handling utility functions and exports
10763 // mouseenter and mouseleave event emulation.
10765 // To use these events, you register a mouseenter like this:
10766 // | define(["dojo/on", dojo/mouse"], function(on, mouse){
10767 // | on(targetNode, mouse.enter, function(event){
10768 // | dojo.addClass(targetNode, "highlighted");
10770 // | on(targetNode, mouse.leave, function(event){
10771 // | dojo.removeClass(targetNode, "highlighted");
10774 _eventHandler
: eventHandler
, // for dojo/touch
10776 // enter: Synthetic Event
10777 // This is an extension event for the mouseenter that IE provides, emulating the
10778 // behavior on other browsers.
10779 enter
: eventHandler("mouseover"),
10781 // leave: Synthetic Event
10782 // This is an extension event for the mouseleave that IE provides, emulating the
10783 // behavior on other browsers.
10784 leave
: eventHandler("mouseout"),
10786 // wheel: Normalized Mouse Wheel Event
10787 // This is an extension event for the mousewheel that non-Mozilla browsers provide,
10788 // emulating the behavior on Mozilla based browsers.
10791 isLeft
: mouseButtons
.isLeft
,
10793 isLeft: function(){
10795 // Test an event object (from a mousedown event) to see if the left button was pressed.
10799 isMiddle
: mouseButtons
.isMiddle
,
10801 isMiddle: function(){
10803 // Test an event object (from a mousedown event) to see if the middle button was pressed.
10807 isRight
: mouseButtons
.isRight
10809 , isRight: function(){
10811 // Test an event object (from a mousedown event) to see if the right button was pressed.
10818 'dojo/topic':function(){
10819 define("dojo/topic", ["./Evented"], function(Evented
){
10824 var hub
= new Evented
;
10829 // | topic.subscribe("some/topic", function(event){
10830 // | ... do something with event
10832 // | topic.publish("some/topic", {name:"some event", ...});
10834 publish: function(topic
, event
){
10836 // Publishes a message to a topic on the pub/sub hub. All arguments after
10837 // the first will be passed to the subscribers, so any number of arguments
10838 // can be provided (not just event).
10840 // The name of the topic to publish to
10842 // An event to distribute to the topic listeners
10843 return hub
.emit
.apply(hub
, arguments
);
10846 subscribe: function(topic
, listener
){
10848 // Subscribes to a topic on the pub/sub hub
10850 // The topic to subscribe to
10851 // listener: Function
10852 // A function to call when a message is published to the given topic
10853 return hub
.on
.apply(hub
, arguments
);
10859 'dojo/_base/xhr':function(){
10860 define("dojo/_base/xhr", [
10865 /*===== "./declare", =====*/
10875 "../request/watch",
10878 ], function(dojo, has, require, ioq, /*===== declare, =====*/ dom
, domForm
, Deferred
, config
, json
, lang
, array
, on
, aspect
, watch
, _xhr
, util
){
10883 dojo._xhrObj = function(){
10885 // does the work of portably generating a new XMLHTTPRequest object.
10888 dojo
._xhrObj
= _xhr
._create
;
10890 var cfg
= dojo
.config
;
10892 // mix in io-query and dom-form
10893 dojo
.objectToQuery
= ioq
.objectToQuery
;
10894 dojo
.queryToObject
= ioq
.queryToObject
;
10895 dojo
.fieldToObject
= domForm
.fieldToObject
;
10896 dojo
.formToObject
= domForm
.toObject
;
10897 dojo
.formToQuery
= domForm
.toQuery
;
10898 dojo
.formToJson
= domForm
.toJson
;
10900 // need to block async callbacks from snatching this thread as the result
10901 // of an async callback might call another sync XHR, this hangs khtml forever
10902 // must checked by watchInFlight()
10904 dojo
._blockAsync
= false;
10906 // MOW: remove dojo._contentHandlers alias in 2.0
10907 var handlers
= dojo
._contentHandlers
= dojo
.contentHandlers
= {
10909 // A map of available XHR transport handle types. Name matches the
10910 // `handleAs` attribute passed to XHR calls.
10912 // A map of available XHR transport handle types. Name matches the
10913 // `handleAs` attribute passed to XHR calls. Each contentHandler is
10914 // called, passing the xhr object for manipulation. The return value
10915 // from the contentHandler will be passed to the `load` or `handle`
10916 // functions defined in the original xhr call.
10918 // Creating a custom content-handler:
10919 // | xhr.contentHandlers.makeCaps = function(xhr){
10920 // | return xhr.responseText.toUpperCase();
10924 // | url:"foo.txt",
10925 // | handleAs:"makeCaps",
10926 // | load: function(data){ /* data is a toUpper version of foo.txt */ }
10929 "text": function(xhr
){
10931 // A contentHandler which simply returns the plaintext response data
10932 return xhr
.responseText
;
10934 "json": function(xhr
){
10936 // A contentHandler which returns a JavaScript object created from the response data
10937 return json
.fromJson(xhr
.responseText
|| null);
10939 "json-comment-filtered": function(xhr
){
10941 // A contentHandler which expects comment-filtered JSON.
10943 // A contentHandler which expects comment-filtered JSON.
10944 // the json-comment-filtered option was implemented to prevent
10945 // "JavaScript Hijacking", but it is less secure than standard JSON. Use
10946 // standard JSON instead. JSON prefixing can be used to subvert hijacking.
10948 // Will throw a notice suggesting to use application/json mimetype, as
10949 // json-commenting can introduce security issues. To decrease the chances of hijacking,
10950 // use the standard `json` contentHandler, and prefix your "JSON" with: {}&&
10952 // use djConfig.useCommentedJson = true to turn off the notice
10953 if(!config
.useCommentedJson
){
10954 console
.warn("Consider using the standard mimetype:application/json."
10955 + " json-commenting can introduce security issues. To"
10956 + " decrease the chances of hijacking, use the standard the 'json' handler and"
10957 + " prefix your json with: {}&&\n"
10958 + "Use djConfig.useCommentedJson=true to turn off this message.");
10961 var value
= xhr
.responseText
;
10962 var cStartIdx
= value
.indexOf("\/*");
10963 var cEndIdx
= value
.lastIndexOf("*\/");
10964 if(cStartIdx
== -1 || cEndIdx
== -1){
10965 throw new Error("JSON was not comment filtered");
10967 return json
.fromJson(value
.substring(cStartIdx
+2, cEndIdx
));
10969 "javascript": function(xhr
){
10971 // A contentHandler which evaluates the response data, expecting it to be valid JavaScript
10973 // FIXME: try Moz and IE specific eval variants?
10974 return dojo
.eval(xhr
.responseText
);
10976 "xml": function(xhr
){
10978 // A contentHandler returning an XML Document parsed from the response data
10979 var result
= xhr
.responseXML
;
10982 if((!result
|| !result
.documentElement
)){
10983 //WARNING: this branch used by the xml handling in dojo.io.iframe,
10984 //so be sure to test dojo.io.iframe if making changes below.
10985 var ms = function(n
){ return "MSXML" + n
+ ".DOMDocument"; };
10986 var dp
= ["Microsoft.XMLDOM", ms(6), ms(4), ms(3), ms(2)];
10987 array
.some(dp
, function(p
){
10989 var dom
= new ActiveXObject(p
);
10991 dom
.loadXML(xhr
.responseText
);
10993 }catch(e
){ return false; }
10998 return result
; // DOMDocument
11000 "json-comment-optional": function(xhr
){
11002 // A contentHandler which checks the presence of comment-filtered JSON and
11003 // alternates between the `json` and `json-comment-filtered` contentHandlers.
11004 if(xhr
.responseText
&& /^[^{\[]*\/\*/.test(xhr
.responseText
)){
11005 return handlers
["json-comment-filtered"](xhr
);
11007 return handlers
["json"](xhr
);
11014 // kwargs function parameter definitions. Assigning to dojo namespace rather than making them local variables
11015 // because they are used by dojo/io modules too
11017 dojo.__IoArgs = declare(null, {
11019 // URL to server endpoint.
11020 // content: Object?
11021 // Contains properties with string values. These
11022 // properties will be serialized as name1=value2 and
11023 // passed in the request.
11024 // timeout: Integer?
11025 // Milliseconds to wait for the response. If this time
11026 // passes, the then error callbacks are called.
11028 // DOM node for a form. Used to extract the form values
11029 // and send to the server.
11030 // preventCache: Boolean?
11031 // Default is false. If true, then a
11032 // "dojo.preventCache" parameter is sent in the request
11033 // with a value that changes with each request
11034 // (timestamp). Useful only with GET-type requests.
11035 // handleAs: String?
11036 // Acceptable values depend on the type of IO
11037 // transport (see specific IO calls for more information).
11038 // rawBody: String?
11039 // Sets the raw body for an HTTP request. If this is used, then the content
11040 // property is ignored. This is mostly useful for HTTP methods that have
11041 // a body to their requests, like PUT or POST. This property can be used instead
11042 // of postData and putData for dojo/_base/xhr.rawXhrPost and dojo/_base/xhr.rawXhrPut respectively.
11043 // ioPublish: Boolean?
11044 // Set this explicitly to false to prevent publishing of topics related to
11045 // IO operations. Otherwise, if djConfig.ioPublish is set to true, topics
11046 // will be published via dojo/topic.publish() for different phases of an IO operation.
11047 // See dojo/main.__IoPublish for a list of topics that are published.
11049 load: function(response, ioArgs){
11051 // This function will be
11052 // called on a successful HTTP response code.
11053 // ioArgs: dojo/main.__IoCallbackArgs
11054 // Provides additional information about the request.
11055 // response: Object
11056 // The response in the format as defined with handleAs.
11059 error: function(response, ioArgs){
11061 // This function will
11062 // be called when the request fails due to a network or server error, the url
11063 // is invalid, etc. It will also be called if the load or handle callback throws an
11064 // exception, unless djConfig.debugAtAllCosts is true. This allows deployed applications
11065 // to continue to run even when a logic error happens in the callback, while making
11066 // it easier to troubleshoot while in debug mode.
11067 // ioArgs: dojo/main.__IoCallbackArgs
11068 // Provides additional information about the request.
11069 // response: Object
11070 // The response in the format as defined with handleAs.
11073 handle: function(loadOrError, response, ioArgs){
11075 // This function will
11076 // be called at the end of every request, whether or not an error occurs.
11077 // loadOrError: String
11078 // Provides a string that tells you whether this function
11079 // was called because of success (load) or failure (error).
11080 // response: Object
11081 // The response in the format as defined with handleAs.
11082 // ioArgs: dojo/main.__IoCallbackArgs
11083 // Provides additional information about the request.
11087 dojo.__IoCallbackArgs = declare(null, {
11089 // the original object argument to the IO call.
11090 // xhr: XMLHttpRequest
11091 // For XMLHttpRequest calls only, the
11092 // XMLHttpRequest object that was used for the
11095 // The final URL used for the call. Many times it
11096 // will be different than the original args.url
11099 // For non-GET requests, the
11100 // name1=value1&name2=value2 parameters sent up in
11102 // handleAs: String
11103 // The final indicator on how the response will be
11106 // For dojo/io/script calls only, the internal
11107 // script ID used for the request.
11108 // canDelete: Boolean
11109 // For dojo/io/script calls only, indicates
11110 // whether the script tag that represents the
11111 // request can be deleted after callbacks have
11112 // been called. Used internally to know when
11113 // cleanup can happen on JSONP-type requests.
11115 // For dojo/io/script calls only: holds the JSON
11116 // response for JSONP-type requests. Used
11117 // internally to hold on to the JSON responses.
11118 // You should not need to access it directly --
11119 // the same object should be passed to the success
11120 // callbacks directly.
11123 dojo.__IoPublish = declare(null, {
11125 // This is a list of IO topics that can be published
11126 // if djConfig.ioPublish is set to true. IO topics can be
11127 // published for any Input/Output, network operation. So,
11128 // dojo.xhr, dojo.io.script and dojo.io.iframe can all
11129 // trigger these topics to be published.
11131 // "/dojo/io/start" is sent when there are no outstanding IO
11132 // requests, and a new IO request is started. No arguments
11133 // are passed with this topic.
11135 // "/dojo/io/send" is sent whenever a new IO request is started.
11136 // It passes the dojo.Deferred for the request with the topic.
11138 // "/dojo/io/load" is sent whenever an IO request has loaded
11139 // successfully. It passes the response and the dojo.Deferred
11140 // for the request with the topic.
11142 // "/dojo/io/error" is sent whenever an IO request has errored.
11143 // It passes the error and the dojo.Deferred
11144 // for the request with the topic.
11146 // "/dojo/io/done" is sent whenever an IO request has completed,
11147 // either by loading or by erroring. It passes the error and
11148 // the dojo.Deferred for the request with the topic.
11150 // "/dojo/io/stop" is sent when all outstanding IO requests have
11151 // finished. No arguments are passed with this topic.
11156 dojo
._ioSetArgs = function(/*dojo/main.__IoArgs*/args,
11157 /*Function*/canceller
,
11158 /*Function*/okHandler
,
11159 /*Function*/errHandler
){
11161 // sets up the Deferred and ioArgs property on the Deferred so it
11162 // can be used in an io call.
11164 // The args object passed into the public io call. Recognized properties on
11165 // the args object are:
11167 // The canceller function used for the Deferred object. The function
11168 // will receive one argument, the Deferred object that is related to the
11171 // The first OK callback to be registered with Deferred. It has the opportunity
11172 // to transform the OK response. It will receive one argument -- the Deferred
11173 // object returned from this function.
11175 // The first error callback to be registered with Deferred. It has the opportunity
11176 // to do cleanup on an error. It will receive two arguments: error (the
11177 // Error object) and dfd, the Deferred object returned from this function.
11179 var ioArgs
= {args
: args
, url
: args
.url
};
11181 //Get values from form if requested.
11182 var formObject
= null;
11184 var form
= dom
.byId(args
.form
);
11185 //IE requires going through getAttributeNode instead of just getAttribute in some form cases,
11186 //so use it for all. See #2844
11187 var actnNode
= form
.getAttributeNode("action");
11188 ioArgs
.url
= ioArgs
.url
|| (actnNode
? actnNode
.value
: null);
11189 formObject
= domForm
.toObject(form
);
11192 // set up the query params
11196 // potentially over-ride url-provided params w/ form values
11197 miArgs
.push(formObject
);
11200 // stuff in content over-rides what's set by form
11201 miArgs
.push(args
.content
);
11203 if(args
.preventCache
){
11204 miArgs
.push({"dojo.preventCache": new Date().valueOf()});
11206 ioArgs
.query
= ioq
.objectToQuery(lang
.mixin
.apply(null, miArgs
));
11208 // .. and the real work of getting the deferred in order, etc.
11209 ioArgs
.handleAs
= args
.handleAs
|| "text";
11210 var d
= new Deferred(function(dfd
){
11211 dfd
.canceled
= true;
11212 canceller
&& canceller(dfd
);
11214 var err
= dfd
.ioArgs
.error
;
11216 err
= new Error("request cancelled");
11217 err
.dojoType
="cancel";
11218 dfd
.ioArgs
.error
= err
;
11222 d
.addCallback(okHandler
);
11224 //Support specifying load, error and handle callback functions from the args.
11225 //For those callbacks, the "this" object will be the args object.
11226 //The callbacks will get the deferred result value as the
11227 //first argument and the ioArgs object as the second argument.
11228 var ld
= args
.load
;
11229 if(ld
&& lang
.isFunction(ld
)){
11230 d
.addCallback(function(value
){
11231 return ld
.call(args
, value
, ioArgs
);
11234 var err
= args
.error
;
11235 if(err
&& lang
.isFunction(err
)){
11236 d
.addErrback(function(value
){
11237 return err
.call(args
, value
, ioArgs
);
11240 var handle
= args
.handle
;
11241 if(handle
&& lang
.isFunction(handle
)){
11242 d
.addBoth(function(value
){
11243 return handle
.call(args
, value
, ioArgs
);
11247 // Attach error handler last (not including topic publishing)
11248 // to catch any errors that may have been generated from load
11249 // or handle functions.
11250 d
.addErrback(function(error
){
11251 return errHandler(error
, d
);
11254 //Plug in topic publishing, if dojo.publish is loaded.
11255 if(cfg
.ioPublish
&& dojo
.publish
&& ioArgs
.args
.ioPublish
!== false){
11258 dojo
.publish("/dojo/io/load", [d
, res
]);
11262 dojo
.publish("/dojo/io/error", [d
, res
]);
11266 d
.addBoth(function(res
){
11267 dojo
.publish("/dojo/io/done", [d
, res
]);
11274 // FIXME: need to wire up the xhr object's abort method to something
11275 // analogous in the Deferred
11279 var _deferredOk = function(/*Deferred*/dfd
){
11281 // okHandler function for dojo._ioSetArgs call.
11283 var ret
= handlers
[dfd
.ioArgs
.handleAs
](dfd
.ioArgs
.xhr
);
11284 return ret
=== undefined ? null : ret
;
11286 var _deferError = function(/*Error*/error
, /*Deferred*/dfd
){
11288 // errHandler function for dojo._ioSetArgs call.
11290 if(!dfd
.ioArgs
.args
.failOk
){
11291 console
.error(error
);
11296 //Use a separate count for knowing if we are starting/stopping io calls.
11297 var _checkPubCount = function(dfd
){
11298 if(_pubCount
<= 0){
11300 if(cfg
.ioPublish
&& dojo
.publish
&& (!dfd
|| dfd
&& dfd
.ioArgs
.args
.ioPublish
!== false)){
11301 dojo
.publish("/dojo/io/stop");
11307 aspect
.after(watch
, "_onAction", function(){
11310 aspect
.after(watch
, "_onInFlight", _checkPubCount
);
11312 dojo
._ioCancelAll
= watch
.cancelAll
;
11314 dojo._ioCancelAll = function(){
11316 // Cancels all pending IO requests, regardless of IO type
11317 // (xhr, script, iframe).
11321 dojo
._ioNotifyStart = function(/*Deferred*/dfd
){
11323 // If dojo.publish is available, publish topics
11324 // about the start of a request queue and/or the
11325 // the beginning of request.
11327 // Used by IO transports. An IO transport should
11328 // call this method before making the network connection.
11329 if(cfg
.ioPublish
&& dojo
.publish
&& dfd
.ioArgs
.args
.ioPublish
!== false){
11331 dojo
.publish("/dojo/io/start");
11334 dojo
.publish("/dojo/io/send", [dfd
]);
11338 dojo
._ioWatch = function(dfd
, validCheck
, ioCheck
, resHandle
){
11340 // Watches the io request represented by dfd to see if it completes.
11342 // The Deferred object to watch.
11343 // validCheck: Function
11344 // Function used to check if the IO request is still valid. Gets the dfd
11345 // object as its only argument.
11346 // ioCheck: Function
11347 // Function used to check if basic IO call worked. Gets the dfd
11348 // object as its only argument.
11349 // resHandle: Function
11350 // Function used to process response. Gets the dfd
11351 // object as its only argument.
11353 var args
= dfd
.ioArgs
.options
= dfd
.ioArgs
.args
;
11355 response
: dfd
.ioArgs
,
11356 isValid: function(response
){
11357 return validCheck(dfd
);
11359 isReady: function(response
){
11360 return ioCheck(dfd
);
11362 handleResponse: function(response
){
11363 return resHandle(dfd
);
11368 _checkPubCount(dfd
);
11371 var _defaultContentType
= "application/x-www-form-urlencoded";
11373 dojo
._ioAddQueryToUrl = function(/*dojo.__IoCallbackArgs*/ioArgs
){
11375 // Adds query params discovered by the io deferred construction to the URL.
11376 // Only use this for operations which are fundamentally GET-type operations.
11377 if(ioArgs
.query
.length
){
11378 ioArgs
.url
+= (ioArgs
.url
.indexOf("?") == -1 ? "?" : "&") + ioArgs
.query
;
11379 ioArgs
.query
= null;
11384 dojo.__XhrArgs = declare(dojo.__IoArgs, {
11386 // In addition to the properties listed for the dojo._IoArgs type,
11387 // the following properties are allowed for dojo.xhr* methods.
11388 // handleAs: String?
11389 // Acceptable values are: text (default), json, json-comment-optional,
11390 // json-comment-filtered, javascript, xml. See `dojo/_base/xhr.contentHandlers`
11392 // false is default. Indicates whether the request should
11393 // be a synchronous (blocking) request.
11394 // headers: Object?
11395 // Additional HTTP headers to send in the request.
11396 // failOk: Boolean?
11397 // false is default. Indicates whether a request should be
11398 // allowed to fail (and therefore no console error message in
11399 // the event of a failure)
11400 // contentType: String|Boolean
11401 // "application/x-www-form-urlencoded" is default. Set to false to
11402 // prevent a Content-Type header from being sent, or to a string
11403 // to send a different Content-Type.
11407 dojo
.xhr = function(/*String*/ method
, /*dojo.__XhrArgs*/ args
, /*Boolean?*/ hasBody
){
11409 // Deprecated. Use dojo/request instead.
11411 // Sends an HTTP request with the given method.
11412 // See also dojo.xhrGet(), xhrPost(), xhrPut() and dojo.xhrDelete() for shortcuts
11413 // for those HTTP methods. There are also methods for "raw" PUT and POST methods
11414 // via dojo.rawXhrPut() and dojo.rawXhrPost() respectively.
11416 // HTTP method to be used, such as GET, POST, PUT, DELETE. Should be uppercase.
11418 // If the request has an HTTP body, then pass true for hasBody.
11421 //Make the Deferred object for this xhr request.
11422 var dfd
= dojo
._ioSetArgs(args
, function(dfd
){
11423 rDfd
&& rDfd
.cancel();
11424 }, _deferredOk
, _deferError
);
11425 var ioArgs
= dfd
.ioArgs
;
11427 //Allow for specifying the HTTP body completely.
11428 if("postData" in args
){
11429 ioArgs
.query
= args
.postData
;
11430 }else if("putData" in args
){
11431 ioArgs
.query
= args
.putData
;
11432 }else if("rawBody" in args
){
11433 ioArgs
.query
= args
.rawBody
;
11434 }else if((arguments
.length
> 2 && !hasBody
) || "POST|PUT".indexOf(method
.toUpperCase()) === -1){
11435 //Check for hasBody being passed. If no hasBody,
11436 //then only append query string if not a POST or PUT request.
11437 dojo
._ioAddQueryToUrl(ioArgs
);
11443 timeout
: args
.timeout
,
11444 withCredentials
: args
.withCredentials
,
11448 if(typeof args
.headers
!== 'undefined'){
11449 options
.headers
= args
.headers
;
11451 if(typeof args
.contentType
!== 'undefined'){
11452 if(!options
.headers
){
11453 options
.headers
= {};
11455 options
.headers
['Content-Type'] = args
.contentType
;
11457 if(typeof ioArgs
.query
!== 'undefined'){
11458 options
.data
= ioArgs
.query
;
11460 if(typeof args
.sync
!== 'undefined'){
11461 options
.sync
= args
.sync
;
11464 dojo
._ioNotifyStart(dfd
);
11466 rDfd
= _xhr(ioArgs
.url
, options
, true);
11468 // If XHR creation fails, dojo/request/xhr throws
11469 // When this happens, cancel the deferred
11475 dfd
.ioArgs
.xhr
= rDfd
.response
.xhr
;
11477 rDfd
.then(function(){
11479 }).otherwise(function(error
){
11480 ioArgs
.error
= error
;
11481 if(error
.response
){
11482 error
.status
= error
.response
.status
;
11483 error
.responseText
= error
.response
.text
;
11484 error
.xhr
= error
.response
.xhr
;
11488 return dfd
; // dojo/_base/Deferred
11491 dojo
.xhrGet = function(/*dojo.__XhrArgs*/ args
){
11493 // Sends an HTTP GET request to the server.
11494 return dojo
.xhr("GET", args
); // dojo/_base/Deferred
11497 dojo
.rawXhrPost
= dojo
.xhrPost = function(/*dojo.__XhrArgs*/ args
){
11499 // Sends an HTTP POST request to the server. In addition to the properties
11500 // listed for the dojo.__XhrArgs type, the following property is allowed:
11502 // String. Send raw data in the body of the POST request.
11503 return dojo
.xhr("POST", args
, true); // dojo/_base/Deferred
11506 dojo
.rawXhrPut
= dojo
.xhrPut = function(/*dojo.__XhrArgs*/ args
){
11508 // Sends an HTTP PUT request to the server. In addition to the properties
11509 // listed for the dojo.__XhrArgs type, the following property is allowed:
11511 // String. Send raw data in the body of the PUT request.
11512 return dojo
.xhr("PUT", args
, true); // dojo/_base/Deferred
11515 dojo
.xhrDelete = function(/*dojo.__XhrArgs*/ args
){
11517 // Sends an HTTP DELETE request to the server.
11518 return dojo
.xhr("DELETE", args
); // dojo/_base/Deferred
11522 dojo.wrapForm = function(formNode){
11524 // A replacement for FormBind, but not implemented yet.
11526 // FIXME: need to think harder about what extensions to this we might
11527 // want. What should we allow folks to do w/ this? What events to
11529 throw new Error("dojo.wrapForm not yet implemented");
11533 dojo
._isDocumentOk = function(x
){
11534 return util
.checkStatus(x
.status
);
11537 dojo
._getText = function(url
){
11539 dojo
.xhrGet({url
:url
, sync
:true, load:function(text
){
11545 // Add aliases for static functions to dojo.xhr since dojo.xhr is what's returned from this module
11546 lang
.mixin(dojo
.xhr
, {
11547 _xhrObj
: dojo
._xhrObj
,
11548 fieldToObject
: domForm
.fieldToObject
,
11549 formToObject
: domForm
.toObject
,
11550 objectToQuery
: ioq
.objectToQuery
,
11551 formToQuery
: domForm
.toQuery
,
11552 formToJson
: domForm
.toJson
,
11553 queryToObject
: ioq
.queryToObject
,
11554 contentHandlers
: handlers
,
11555 _ioSetArgs
: dojo
._ioSetArgs
,
11556 _ioCancelAll
: dojo
._ioCancelAll
,
11557 _ioNotifyStart
: dojo
._ioNotifyStart
,
11558 _ioWatch
: dojo
._ioWatch
,
11559 _ioAddQueryToUrl
: dojo
._ioAddQueryToUrl
,
11560 _isDocumentOk
: dojo
._isDocumentOk
,
11561 _getText
: dojo
._getText
,
11563 post
: dojo
.xhrPost
,
11565 del
: dojo
.xhrDelete
// because "delete" is a reserved word
11572 'dojo/_base/unload':function(){
11573 define(["./kernel", "./lang", "../on"], function(dojo
, lang
, on
){
11582 // This module contains the document and window unload detection API.
11584 addOnWindowUnload: function(/*Object|Function?*/ obj
, /*String|Function?*/ functionName
){
11586 // registers a function to be triggered when window.onunload
11589 // The first time that addOnWindowUnload is called Dojo
11590 // will register a page listener to trigger your unload
11591 // handler with. Note that registering these handlers may
11592 // destroy "fastback" page caching in browsers that support
11593 // it. Be careful trying to modify the DOM or access
11594 // JavaScript properties during this phase of page unloading:
11595 // they may not always be available. Consider
11596 // addOnUnload() if you need to modify the DOM or do
11597 // heavy JavaScript work since it fires at the equivalent of
11598 // the page's "onbeforeunload" event.
11600 // | unload.addOnWindowUnload(functionPointer)
11601 // | unload.addOnWindowUnload(object, "functionName");
11602 // | unload.addOnWindowUnload(object, function(){ /* ... */});
11604 if (!dojo
.windowUnloaded
){
11605 on(win
, "unload", (dojo
.windowUnloaded = function(){
11607 // signal fired by impending window destruction. You may use
11608 // dojo.addOnWindowUnload() to register a listener for this
11609 // event. NOTE: if you wish to dojo.connect() to this method
11610 // to perform page/application cleanup, be aware that this
11611 // event WILL NOT fire if no handler has been registered with
11612 // addOnWindowUnload(). This behavior started in Dojo 1.3.
11613 // Previous versions always triggered windowUnloaded(). See
11614 // addOnWindowUnload for more info.
11617 on(win
, "unload", lang
.hitch(obj
, functionName
));
11620 addOnUnload: function(/*Object?|Function?*/ obj
, /*String|Function?*/ functionName
){
11622 // registers a function to be triggered when the page unloads.
11624 // The first time that addOnUnload is called Dojo will
11625 // register a page listener to trigger your unload handler
11628 // In a browser environment, the functions will be triggered
11629 // during the window.onbeforeunload event. Be careful of doing
11630 // too much work in an unload handler. onbeforeunload can be
11631 // triggered if a link to download a file is clicked, or if
11632 // the link is a javascript: link. In these cases, the
11633 // onbeforeunload event fires, but the document is not
11634 // actually destroyed. So be careful about doing destructive
11635 // operations in a dojo.addOnUnload callback.
11637 // Further note that calling dojo.addOnUnload will prevent
11638 // browsers from using a "fast back" cache to make page
11639 // loading via back button instantaneous.
11641 // | dojo.addOnUnload(functionPointer)
11642 // | dojo.addOnUnload(object, "functionName")
11643 // | dojo.addOnUnload(object, function(){ /* ... */});
11645 on(win
, "beforeunload", lang
.hitch(obj
, functionName
));
11649 dojo
.addOnWindowUnload
= unload
.addOnWindowUnload
;
11650 dojo
.addOnUnload
= unload
.addOnUnload
;
11657 'dojo/Deferred':function(){
11661 "./errors/CancelError",
11662 "./promise/Promise",
11663 "./promise/instrumentation"
11664 ], function(has
, lang
, CancelError
, Promise
, instrumentation
){
11673 var FULFILLED_ERROR_MESSAGE
= "This deferred has already been fulfilled.";
11675 var freezeObject
= Object
.freeze
|| function(){};
11677 var signalWaiting = function(waiting
, type
, result
, rejection
, deferred
){
11679 if(type
=== REJECTED
&& Deferred
.instrumentRejected
&& waiting
.length
=== 0){
11680 Deferred
.instrumentRejected(result
, false, rejection
, deferred
);
11684 for(var i
= 0; i
< waiting
.length
; i
++){
11685 signalListener(waiting
[i
], type
, result
, rejection
);
11689 var signalListener = function(listener
, type
, result
, rejection
){
11690 var func
= listener
[type
];
11691 var deferred
= listener
.deferred
;
11694 var newResult
= func(result
);
11695 if(type
=== PROGRESS
){
11696 if(typeof newResult
!== "undefined"){
11697 signalDeferred(deferred
, type
, newResult
);
11700 if(newResult
&& typeof newResult
.then
=== "function"){
11701 listener
.cancel
= newResult
.cancel
;
11703 // Only make resolvers if they're actually going to be used
11704 makeDeferredSignaler(deferred
, RESOLVED
),
11705 makeDeferredSignaler(deferred
, REJECTED
),
11706 makeDeferredSignaler(deferred
, PROGRESS
));
11709 signalDeferred(deferred
, RESOLVED
, newResult
);
11712 signalDeferred(deferred
, REJECTED
, error
);
11715 signalDeferred(deferred
, type
, result
);
11719 if(type
=== REJECTED
&& Deferred
.instrumentRejected
){
11720 Deferred
.instrumentRejected(result
, !!func
, rejection
, deferred
.promise
);
11725 var makeDeferredSignaler = function(deferred
, type
){
11726 return function(value
){
11727 signalDeferred(deferred
, type
, value
);
11731 var signalDeferred = function(deferred
, type
, result
){
11732 if(!deferred
.isCanceled()){
11735 deferred
.progress(result
);
11738 deferred
.resolve(result
);
11741 deferred
.reject(result
);
11747 var Deferred = function(canceler
){
11749 // Creates a new deferred. This API is preferred over
11750 // `dojo/_base/Deferred`.
11752 // Creates a new deferred, as an abstraction over (primarily)
11753 // asynchronous operations. The deferred is the private interface
11754 // that should not be returned to calling code. That's what the
11755 // `promise` is for. See `dojo/promise/Promise`.
11756 // canceler: Function?
11757 // Will be invoked if the deferred is canceled. The canceler
11758 // receives the reason the deferred was canceled as its argument.
11759 // The deferred is rejected with its return value, or a new
11760 // `dojo/errors/CancelError` instance.
11762 // promise: dojo/promise/Promise
11763 // The public promise object that clients can add callbacks to.
11764 var promise
= this.promise
= new Promise();
11766 var deferred
= this;
11767 var fulfilled
, result
, rejection
;
11768 var canceled
= false;
11771 if( 1 && Error
.captureStackTrace
){
11772 Error
.captureStackTrace(deferred
, Deferred
);
11773 Error
.captureStackTrace(promise
, Deferred
);
11776 this.isResolved
= promise
.isResolved = function(){
11778 // Checks whether the deferred has been resolved.
11779 // returns: Boolean
11781 return fulfilled
=== RESOLVED
;
11784 this.isRejected
= promise
.isRejected = function(){
11786 // Checks whether the deferred has been rejected.
11787 // returns: Boolean
11789 return fulfilled
=== REJECTED
;
11792 this.isFulfilled
= promise
.isFulfilled = function(){
11794 // Checks whether the deferred has been resolved or rejected.
11795 // returns: Boolean
11797 return !!fulfilled
;
11800 this.isCanceled
= promise
.isCanceled = function(){
11802 // Checks whether the deferred has been canceled.
11803 // returns: Boolean
11808 this.progress = function(update
, strict
){
11810 // Emit a progress update on the deferred.
11812 // Emit a progress update on the deferred. Progress updates
11813 // can be used to communicate updates about the asynchronous
11814 // operation before it has finished.
11816 // The progress update. Passed to progbacks.
11817 // strict: Boolean?
11818 // If strict, will throw an error if the deferred has already
11819 // been fulfilled and consequently no progress can be emitted.
11820 // returns: dojo/promise/Promise
11821 // Returns the original promise for the deferred.
11824 signalWaiting(waiting
, PROGRESS
, update
, null, deferred
);
11826 }else if(strict
=== true){
11827 throw new Error(FULFILLED_ERROR_MESSAGE
);
11833 this.resolve = function(value
, strict
){
11835 // Resolve the deferred.
11837 // Resolve the deferred, putting it in a success state.
11839 // The result of the deferred. Passed to callbacks.
11840 // strict: Boolean?
11841 // If strict, will throw an error if the deferred has already
11842 // been fulfilled and consequently cannot be resolved.
11843 // returns: dojo/promise/Promise
11844 // Returns the original promise for the deferred.
11847 // Set fulfilled, store value. After signaling waiting listeners unset
11849 signalWaiting(waiting
, fulfilled
= RESOLVED
, result
= value
, null, deferred
);
11852 }else if(strict
=== true){
11853 throw new Error(FULFILLED_ERROR_MESSAGE
);
11859 var reject
= this.reject = function(error
, strict
){
11861 // Reject the deferred.
11863 // Reject the deferred, putting it in an error state.
11865 // The error result of the deferred. Passed to errbacks.
11866 // strict: Boolean?
11867 // If strict, will throw an error if the deferred has already
11868 // been fulfilled and consequently cannot be rejected.
11869 // returns: dojo/promise/Promise
11870 // Returns the original promise for the deferred.
11873 if( 1 && Error
.captureStackTrace
){
11874 Error
.captureStackTrace(rejection
= {}, reject
);
11876 signalWaiting(waiting
, fulfilled
= REJECTED
, result
= error
, rejection
, deferred
);
11879 }else if(strict
=== true){
11880 throw new Error(FULFILLED_ERROR_MESSAGE
);
11886 this.then
= promise
.then = function(callback
, errback
, progback
){
11888 // Add new callbacks to the deferred.
11890 // Add new callbacks to the deferred. Callbacks can be added
11891 // before or after the deferred is fulfilled.
11892 // callback: Function?
11893 // Callback to be invoked when the promise is resolved.
11894 // Receives the resolution value.
11895 // errback: Function?
11896 // Callback to be invoked when the promise is rejected.
11897 // Receives the rejection error.
11898 // progback: Function?
11899 // Callback to be invoked when the promise emits a progress
11900 // update. Receives the progress update.
11901 // returns: dojo/promise/Promise
11902 // Returns a new promise for the result of the callback(s).
11903 // This can be used for chaining many asynchronous operations.
11905 var listener
= [progback
, callback
, errback
];
11906 // Ensure we cancel the promise we're waiting for, or if callback/errback
11907 // have returned a promise, cancel that one.
11908 listener
.cancel
= promise
.cancel
;
11909 listener
.deferred
= new Deferred(function(reason
){
11910 // Check whether cancel is really available, returned promises are not
11911 // required to expose `cancel`
11912 return listener
.cancel
&& listener
.cancel(reason
);
11914 if(fulfilled
&& !waiting
){
11915 signalListener(listener
, fulfilled
, result
, rejection
);
11917 waiting
.push(listener
);
11919 return listener
.deferred
.promise
;
11922 this.cancel
= promise
.cancel = function(reason
, strict
){
11924 // Inform the deferred it may cancel its asynchronous operation.
11926 // Inform the deferred it may cancel its asynchronous operation.
11927 // The deferred's (optional) canceler is invoked and the
11928 // deferred will be left in a rejected state. Can affect other
11929 // promises that originate with the same deferred.
11931 // A message that may be sent to the deferred's canceler,
11932 // explaining why it's being canceled.
11933 // strict: Boolean?
11934 // If strict, will throw an error if the deferred has already
11935 // been fulfilled and consequently cannot be canceled.
11937 // Returns the rejection reason if the deferred was canceled
11941 // Cancel can be called even after the deferred is fulfilled
11943 var returnedReason
= canceler(reason
);
11944 reason
= typeof returnedReason
=== "undefined" ? reason
: returnedReason
;
11948 // Allow canceler to provide its own reason, but fall back to a CancelError
11949 if(typeof reason
=== "undefined"){
11950 reason
= new CancelError();
11954 }else if(fulfilled
=== REJECTED
&& result
=== reason
){
11957 }else if(strict
=== true){
11958 throw new Error(FULFILLED_ERROR_MESSAGE
);
11962 freezeObject(promise
);
11965 Deferred
.prototype.toString = function(){
11967 // Returns `[object Deferred]`.
11969 return "[object Deferred]";
11972 if(instrumentation
){
11973 instrumentation(Deferred
);
11980 'dojo/_base/NodeList':function(){
11981 define("dojo/_base/NodeList", ["./kernel", "../query", "./array", "./html", "../NodeList-dom"], function(dojo
, query
, array
){
11983 // dojo/_base/NodeList
11988 // This module extends dojo/NodeList with the legacy connect(), coords(),
11989 // blur(), focus(), change(), click(), error(), keydown(), keypress(),
11990 // keyup(), load(), mousedown(), mouseenter(), mouseleave(), mousemove(),
11991 // mouseout(), mouseover(), mouseup(), and submit() methods.
11995 var NodeList
= query
.NodeList
,
11996 nlp
= NodeList
.prototype;
11998 nlp
.connect
= NodeList
._adaptAsForEach(function(){
11999 // don't bind early to dojo.connect since we no longer explicitly depend on it
12000 return dojo
.connect
.apply(this, arguments
);
12003 nlp.connect = function(methodName, objOrFunc, funcName){
12005 // Attach event handlers to every item of the NodeList. Uses dojo.connect()
12006 // so event properties are normalized.
12008 // Application must manually require() "dojo/_base/connect" before using this method.
12009 // methodName: String
12010 // the name of the method to attach to. For DOM events, this should be
12011 // the lower-case name of the event
12012 // objOrFunc: Object|Function|String
12013 // if 2 arguments are passed (methodName, objOrFunc), objOrFunc should
12014 // reference a function or be the name of the function in the global
12015 // namespace to attach. If 3 arguments are provided
12016 // (methodName, objOrFunc, funcName), objOrFunc must be the scope to
12017 // locate the bound function in
12018 // funcName: String?
12019 // optional. A string naming the function in objOrFunc to bind to the
12020 // event. May also be a function reference.
12022 // add an onclick handler to every button on the page
12023 // | query("div:nth-child(odd)").connect("onclick", function(e){
12024 // | console.log("clicked!");
12027 // attach foo.bar() to every odd div's onmouseover
12028 // | query("div:nth-child(odd)").connect("onmouseover", foo, "bar");
12030 return null; // NodeList
12034 nlp
.coords
= NodeList
._adaptAsMap(dojo
.coords
);
12036 nlp.coords = function(){
12038 // Deprecated: Use position() for border-box x/y/w/h
12039 // or marginBox() for margin-box w/h/l/t.
12040 // Returns the box objects of all elements in a node list as
12041 // an Array (*not* a NodeList). Acts like `domGeom.coords`, though assumes
12042 // the node passed is each node in this list.
12044 return []; // Array
12048 NodeList
.events
= [
12050 // list of all DOM events used in NodeList
12051 "blur", "focus", "change", "click", "error", "keydown", "keypress",
12052 "keyup", "load", "mousedown", "mouseenter", "mouseleave", "mousemove",
12053 "mouseout", "mouseover", "mouseup", "submit"
12056 // FIXME: pseudo-doc the above automatically generated on-event functions
12058 // syntactic sugar for DOM events
12059 array
.forEach(NodeList
.events
, function(evt
){
12060 var _oe
= "on" + evt
;
12061 nlp
[_oe
] = function(a
, b
){
12062 return this.connect(_oe
, a
, b
);
12064 // FIXME: should these events trigger publishes?
12066 return (a ? this.connect(_oe, a, b) :
12067 this.forEach(function(n){
12069 // listeners get buried by
12070 // addEventListener and can't be dug back
12071 // out to be triggered externally.
12073 // http://developer.mozilla.org/en/docs/DOM:element
12075 console.log(n, evt, _oe);
12077 // FIXME: need synthetic event support!
12078 var _e = { target: n, faux: true, type: evt };
12079 // dojo._event_listener._synthesizeEvent({}, { target: n, faux: true, type: evt });
12080 try{ n[evt](_e); }catch(e){ console.log(e); }
12081 try{ n[_oe](_e); }catch(e){ console.log(e); }
12088 dojo
.NodeList
= NodeList
;
12093 'dojo/_base/Color':function(){
12094 define(["./kernel", "./lang", "./array", "./config"], function(dojo
, lang
, ArrayUtil
, config
){
12096 var Color
= dojo
.Color = function(/*Array|String|Object*/ color
){
12098 // Takes a named string, hex string, array of rgb or rgba values,
12099 // an object with r, g, b, and a properties, or another `Color` object
12100 // and creates a new Color instance to work from.
12103 // Work with a Color instance:
12104 // | var c = new Color();
12105 // | c.setColor([0,0,0]); // black
12106 // | var hex = c.toHex(); // #000000
12109 // Work with a node's color:
12110 // | var color = dojo.style("someNode", "backgroundColor");
12111 // | var n = new Color(color);
12112 // | // adjust the color some
12114 // | console.log(n.toString()); // rgb(128, 255, 255);
12115 if(color
){ this.setColor(color
); }
12119 // there's got to be a more space-efficient way to encode or discover
12120 // these!! Use hex?
12123 // Dictionary list of all CSS named colors, by name. Values are 3-item arrays with corresponding RG and B values.
12125 "silver": [192,192,192],
12126 "gray": [128,128,128],
12127 "white": [255,255,255],
12128 "maroon": [128,0,0],
12130 "purple": [128,0,128],
12131 "fuchsia":[255,0,255],
12132 "green": [0,128,0],
12134 "olive": [128,128,0],
12135 "yellow": [255,255,0],
12138 "teal": [0,128,128],
12139 "aqua": [0,255,255],
12140 "transparent": config
.transparentColor
|| [0,0,0,0]
12143 lang
.extend(Color
, {
12144 r
: 255, g
: 255, b
: 255, a
: 1,
12145 _set: function(r
, g
, b
, a
){
12146 var t
= this; t
.r
= r
; t
.g
= g
; t
.b
= b
; t
.a
= a
;
12148 setColor: function(/*Array|String|Object*/ color
){
12150 // Takes a named string, hex string, array of rgb or rgba values,
12151 // an object with r, g, b, and a properties, or another `Color` object
12152 // and sets this color instance to that value.
12155 // | var c = new Color(); // no color
12156 // | c.setColor("#ededed"); // greyish
12157 if(lang
.isString(color
)){
12158 Color
.fromString(color
, this);
12159 }else if(lang
.isArray(color
)){
12160 Color
.fromArray(color
, this);
12162 this._set(color
.r
, color
.g
, color
.b
, color
.a
);
12163 if(!(color
instanceof Color
)){ this.sanitize(); }
12165 return this; // Color
12167 sanitize: function(){
12169 // Ensures the object has correct attributes
12171 // the default implementation does nothing, include dojo.colors to
12172 // augment it with real checks
12173 return this; // Color
12177 // Returns 3 component array of rgb values
12179 // | var c = new Color("#000000");
12180 // | console.log(c.toRgb()); // [0,0,0]
12182 return [t
.r
, t
.g
, t
.b
]; // Array
12184 toRgba: function(){
12186 // Returns a 4 component array of rgba values from the color
12187 // represented by this object.
12189 return [t
.r
, t
.g
, t
.b
, t
.a
]; // Array
12193 // Returns a CSS color string in hexadecimal representation
12195 // | console.log(new Color([0,0,0]).toHex()); // #000000
12196 var arr
= ArrayUtil
.map(["r", "g", "b"], function(x
){
12197 var s
= this[x
].toString(16);
12198 return s
.length
< 2 ? "0" + s
: s
;
12200 return "#" + arr
.join(""); // String
12202 toCss: function(/*Boolean?*/ includeAlpha
){
12204 // Returns a css color string in rgb(a) representation
12206 // | var c = new Color("#FFF").toCss();
12207 // | console.log(c); // rgb('255','255','255')
12208 var t
= this, rgb
= t
.r
+ ", " + t
.g
+ ", " + t
.b
;
12209 return (includeAlpha
? "rgba(" + rgb
+ ", " + t
.a
: "rgb(" + rgb
) + ")"; // String
12211 toString: function(){
12213 // Returns a visual representation of the color
12214 return this.toCss(true); // String
12218 Color
.blendColors
= dojo
.blendColors = function(
12225 // Blend colors end and start with weight from 0 to 1, 0.5 being a 50/50 blend,
12226 // can reuse a previously allocated Color object for the result
12227 var t
= obj
|| new Color();
12228 ArrayUtil
.forEach(["r", "g", "b", "a"], function(x
){
12229 t
[x
] = start
[x
] + (end
[x
] - start
[x
]) * weight
;
12230 if(x
!= "a"){ t
[x
] = Math
.round(t
[x
]); }
12232 return t
.sanitize(); // Color
12235 Color
.fromRgb
= dojo
.colorFromRgb = function(/*String*/ color
, /*Color?*/ obj
){
12237 // Returns a `Color` instance from a string of the form
12238 // "rgb(...)" or "rgba(...)". Optionally accepts a `Color`
12239 // object to update with the parsed value and return instead of
12240 // creating a new object.
12242 // A Color object. If obj is passed, it will be the return value.
12243 var m
= color
.toLowerCase().match(/^rgba?\(([\s\.,0-9]+)\)/);
12244 return m
&& Color
.fromArray(m
[1].split(/\s*,\s*/), obj
); // Color
12247 Color
.fromHex
= dojo
.colorFromHex = function(/*String*/ color
, /*Color?*/ obj
){
12249 // Converts a hex string with a '#' prefix to a color object.
12250 // Supports 12-bit #rgb shorthand. Optionally accepts a
12251 // `Color` object to update with the parsed value.
12254 // A Color object. If obj is passed, it will be the return value.
12257 // | var thing = dojo.colorFromHex("#ededed"); // grey, longhand
12260 // | var thing = dojo.colorFromHex("#000"); // black, shorthand
12261 var t
= obj
|| new Color(),
12262 bits
= (color
.length
== 4) ? 4 : 8,
12263 mask
= (1 << bits
) - 1;
12264 color
= Number("0x" + color
.substr(1));
12266 return null; // Color
12268 ArrayUtil
.forEach(["b", "g", "r"], function(x
){
12269 var c
= color
& mask
;
12271 t
[x
] = bits
== 4 ? 17 * c
: c
;
12277 Color
.fromArray
= dojo
.colorFromArray = function(/*Array*/ a
, /*Color?*/ obj
){
12279 // Builds a `Color` from a 3 or 4 element array, mapping each
12280 // element in sequence to the rgb(a) values of the color.
12282 // | var myColor = dojo.colorFromArray([237,237,237,0.5]); // grey, 50% alpha
12284 // A Color object. If obj is passed, it will be the return value.
12285 var t
= obj
|| new Color();
12286 t
._set(Number(a
[0]), Number(a
[1]), Number(a
[2]), Number(a
[3]));
12287 if(isNaN(t
.a
)){ t
.a
= 1; }
12288 return t
.sanitize(); // Color
12291 Color
.fromString
= dojo
.colorFromString = function(/*String*/ str
, /*Color?*/ obj
){
12293 // Parses `str` for a color value. Accepts hex, rgb, and rgba
12294 // style color values.
12296 // Acceptable input values for str may include arrays of any form
12297 // accepted by dojo.colorFromArray, hex strings such as "#aaaaaa", or
12298 // rgb or rgba strings such as "rgb(133, 200, 16)" or "rgba(10, 10,
12301 // A Color object. If obj is passed, it will be the return value.
12302 var a
= Color
.named
[str
];
12303 return a
&& Color
.fromArray(a
, obj
) || Color
.fromRgb(str
, obj
) || Color
.fromHex(str
, obj
); // Color
12310 'dojo/promise/instrumentation':function(){
12316 ], function(tracer
, has
, lang
, arrayUtil
){
12317 function logError(error
, rejection
, deferred
){
12319 if(error
&& error
.stack
){
12320 stack
+= error
.stack
;
12322 if(rejection
&& rejection
.stack
){
12323 stack
+= "\n ----------------------------------------\n rejected" + rejection
.stack
.split("\n").slice(1).join("\n").replace(/^\s+/, " ");
12325 if(deferred
&& deferred
.stack
){
12326 stack
+= "\n ----------------------------------------\n" + deferred
.stack
;
12328 console
.error(error
, stack
);
12331 function reportRejections(error
, handled
, rejection
, deferred
){
12333 logError(error
, rejection
, deferred
);
12338 var activeTimeout
= false;
12339 var unhandledWait
= 1000;
12340 function trackUnhandledRejections(error
, handled
, rejection
, deferred
){
12342 arrayUtil
.some(errors
, function(obj
, ix
){
12343 if(obj
.error
=== error
){
12344 errors
.splice(ix
, 1);
12348 }else if(!arrayUtil
.some(errors
, function(obj
){ return obj
.error
=== error
; })){
12351 rejection
: rejection
,
12352 deferred
: deferred
,
12353 timestamp
: new Date().getTime()
12357 if(!activeTimeout
){
12358 activeTimeout
= setTimeout(logRejected
, unhandledWait
);
12362 function logRejected(){
12363 var now
= new Date().getTime();
12364 var reportBefore
= now
- unhandledWait
;
12365 errors
= arrayUtil
.filter(errors
, function(obj
){
12366 if(obj
.timestamp
< reportBefore
){
12367 logError(obj
.error
, obj
.rejection
, obj
.deferred
);
12374 activeTimeout
= setTimeout(logRejected
, errors
[0].timestamp
+ unhandledWait
- now
);
12376 activeTimeout
= false;
12380 return function(Deferred
){
12382 // Initialize instrumentation for the Deferred class.
12384 // Initialize instrumentation for the Deferred class.
12385 // Done automatically by `dojo/Deferred` if the
12386 // `deferredInstrumentation` and `useDeferredInstrumentation`
12387 // config options are set.
12389 // Sets up `dojo/promise/tracer` to log to the console.
12391 // Sets up instrumentation of rejected deferreds so unhandled
12392 // errors are logged to the console.
12394 var usage
= has("config-useDeferredInstrumentation");
12396 tracer
.on("resolved", lang
.hitch(console
, "log", "resolved"));
12397 tracer
.on("rejected", lang
.hitch(console
, "log", "rejected"));
12398 tracer
.on("progress", lang
.hitch(console
, "log", "progress"));
12401 if(typeof usage
=== "string"){
12402 args
= usage
.split(",");
12403 usage
= args
.shift();
12405 if(usage
=== "report-rejections"){
12406 Deferred
.instrumentRejected
= reportRejections
;
12407 }else if(usage
=== "report-unhandled-rejections" || usage
=== true || usage
=== 1){
12408 Deferred
.instrumentRejected
= trackUnhandledRejections
;
12409 unhandledWait
= parseInt(args
[0], 10) || unhandledWait
;
12411 throw new Error("Unsupported instrumentation usage <" + usage
+ ">");
12418 'dojo/selector/_loader':function(){
12419 define(["../has", "require"],
12420 function(has
, require
){
12423 var testDiv
= document
.createElement("div");
12424 has
.add("dom-qsa2.1", !!testDiv
.querySelectorAll
);
12425 has
.add("dom-qsa3", function(){
12426 // test to see if we have a reasonable native selector engine available
12428 testDiv
.innerHTML
= "<p class='TEST'></p>"; // test kind of from sizzle
12429 // Safari can't handle uppercase or unicode characters when
12430 // in quirks mode, IE8 can't handle pseudos like :empty
12431 return testDiv
.querySelectorAll(".TEST:empty").length
== 1;
12435 var acme
= "./acme", lite
= "./lite";
12438 // This module handles loading the appropriate selector engine for the given browser
12440 load: function(id
, parentRequire
, loaded
, config
){
12442 // here we implement the default logic for choosing a selector engine
12443 id
= id
== "default" ? has("config-selectorEngine") || "css3" : id
;
12444 id
= id
== "css2" || id
== "lite" ? lite
:
12445 id
== "css2.1" ? has("dom-qsa2.1") ? lite
: acme
:
12446 id
== "css3" ? has("dom-qsa3") ? lite
: acme
:
12447 id
== "acme" ? acme
: (req
= parentRequire
) && id
;
12448 if(id
.charAt(id
.length
-1) == '?'){
12449 id
= id
.substring(0,id
.length
- 1);
12450 var optionalLoad
= true;
12452 // the query engine is optional, only load it if a native one is not available or existing one has not been loaded
12453 if(optionalLoad
&& (has("dom-compliant-qsa") || fullEngine
)){
12454 return loaded(fullEngine
);
12456 // load the referenced selector engine
12457 req([id
], function(engine
){
12458 if(id
!= "./lite"){
12459 fullEngine
= engine
;
12468 'dojo/promise/Promise':function(){
12475 // dojo/promise/Promise
12477 function throwAbstract(){
12478 throw new TypeError("abstract");
12481 return lang
.extend(function Promise(){
12483 // The public interface to a deferred.
12485 // The public interface to a deferred. All promises in Dojo are
12486 // instances of this class.
12488 then: function(callback
, errback
, progback
){
12490 // Add new callbacks to the promise.
12492 // Add new callbacks to the deferred. Callbacks can be added
12493 // before or after the deferred is fulfilled.
12494 // callback: Function?
12495 // Callback to be invoked when the promise is resolved.
12496 // Receives the resolution value.
12497 // errback: Function?
12498 // Callback to be invoked when the promise is rejected.
12499 // Receives the rejection error.
12500 // progback: Function?
12501 // Callback to be invoked when the promise emits a progress
12502 // update. Receives the progress update.
12503 // returns: dojo/promise/Promise
12504 // Returns a new promise for the result of the callback(s).
12505 // This can be used for chaining many asynchronous operations.
12510 cancel: function(reason
, strict
){
12512 // Inform the deferred it may cancel its asynchronous operation.
12514 // Inform the deferred it may cancel its asynchronous operation.
12515 // The deferred's (optional) canceler is invoked and the
12516 // deferred will be left in a rejected state. Can affect other
12517 // promises that originate with the same deferred.
12519 // A message that may be sent to the deferred's canceler,
12520 // explaining why it's being canceled.
12521 // strict: Boolean?
12522 // If strict, will throw an error if the deferred has already
12523 // been fulfilled and consequently cannot be canceled.
12525 // Returns the rejection reason if the deferred was canceled
12531 isResolved: function(){
12533 // Checks whether the promise has been resolved.
12534 // returns: Boolean
12539 isRejected: function(){
12541 // Checks whether the promise has been rejected.
12542 // returns: Boolean
12547 isFulfilled: function(){
12549 // Checks whether the promise has been resolved or rejected.
12550 // returns: Boolean
12555 isCanceled: function(){
12557 // Checks whether the promise has been canceled.
12558 // returns: Boolean
12563 always: function(callbackOrErrback
){
12565 // Add a callback to be invoked when the promise is resolved
12567 // callbackOrErrback: Function?
12568 // A function that is used both as a callback and errback.
12569 // returns: dojo/promise/Promise
12570 // Returns a new promise for the result of the callback/errback.
12572 return this.then(callbackOrErrback
, callbackOrErrback
);
12575 otherwise: function(errback
){
12577 // Add new errbacks to the promise.
12578 // errback: Function?
12579 // Callback to be invoked when the promise is rejected.
12580 // returns: dojo/promise/Promise
12581 // Returns a new promise for the result of the errback.
12583 return this.then(null, errback
);
12590 traceRejected: function(){
12594 toString: function(){
12596 // Returns `[object Promise]`.
12598 return "[object Promise]";
12604 'dojo/request/watch':function(){
12607 '../errors/RequestTimeoutError',
12608 '../errors/CancelError',
12611 '../has!host-browser?dom-addeventlistener?:../on:'
12612 ], function(util
, RequestTimeoutError
, CancelError
, array
, win
, on
){
12613 // avoid setting a timer per request. It degrades performance on IE
12614 // something fierece if we don't use unified loops.
12615 var _inFlightIntvl
= null,
12618 function watchInFlight(){
12620 // internal method that checks each inflight XMLHttpRequest to see
12621 // if it has completed or if the timeout situation applies.
12623 var now
= +(new Date
);
12625 // we need manual loop because we often modify _inFlight (and therefore 'i') while iterating
12626 for(var i
= 0, dfd
; i
< _inFlight
.length
&& (dfd
= _inFlight
[i
]); i
++){
12627 var response
= dfd
.response
,
12628 options
= response
.options
;
12629 if((dfd
.isCanceled
&& dfd
.isCanceled()) || (dfd
.isValid
&& !dfd
.isValid(response
))){
12630 _inFlight
.splice(i
--, 1);
12631 watch
._onAction
&& watch
._onAction();
12632 }else if(dfd
.isReady
&& dfd
.isReady(response
)){
12633 _inFlight
.splice(i
--, 1);
12634 dfd
.handleResponse(response
);
12635 watch
._onAction
&& watch
._onAction();
12636 }else if(dfd
.startTime
){
12638 if(dfd
.startTime
+ (options
.timeout
|| 0) < now
){
12639 _inFlight
.splice(i
--, 1);
12640 // Cancel the request so the io module can do appropriate cleanup.
12641 dfd
.cancel(new RequestTimeoutError('Timeout exceeded', response
));
12642 watch
._onAction
&& watch
._onAction();
12647 watch
._onInFlight
&& watch
._onInFlight(dfd
);
12649 if(!_inFlight
.length
){
12650 clearInterval(_inFlightIntvl
);
12651 _inFlightIntvl
= null;
12655 function watch(dfd
){
12657 // Watches the io request represented by dfd to see if it completes.
12659 // The Deferred object to watch.
12660 // response: Object
12661 // The object used as the value of the request promise.
12662 // validCheck: Function
12663 // Function used to check if the IO request is still valid. Gets the dfd
12664 // object as its only argument.
12665 // ioCheck: Function
12666 // Function used to check if basic IO call worked. Gets the dfd
12667 // object as its only argument.
12668 // resHandle: Function
12669 // Function used to process response. Gets the dfd
12670 // object as its only argument.
12671 if(dfd
.response
.options
.timeout
){
12672 dfd
.startTime
= +(new Date
);
12675 if(dfd
.isFulfilled()){
12676 // bail out if the deferred is already fulfilled
12680 _inFlight
.push(dfd
);
12681 if(!_inFlightIntvl
){
12682 _inFlightIntvl
= setInterval(watchInFlight
, 50);
12685 // handle sync requests separately from async:
12686 // http://bugs.dojotoolkit.org/ticket/8467
12687 if(dfd
.response
.options
.sync
){
12692 watch
.cancelAll
= function cancelAll(){
12694 // Cancels all pending IO requests, regardless of IO type
12696 array
.forEach(_inFlight
, function(dfd
){
12698 dfd
.cancel(new CancelError('All requests canceled.'));
12704 if(win
&& on
&& win
.doc
.attachEvent
){
12705 // Automatically call cancel all io calls on unload in IE
12706 // http://bugs.dojotoolkit.org/ticket/2357
12707 on(win
.global
, 'unload', function(){
12716 'dojo/on':function(){
12717 define(["./has!dom-addeventlistener?:./aspect", "./_base/kernel", "./has"], function(aspect
, dojo
, has
){
12720 if( 1 ){ // check to make sure we are in a browser, this module should work anywhere
12721 var major
= window
.ScriptEngineMajorVersion
;
12722 has
.add("jscript", major
&& (major() + ScriptEngineMinorVersion() / 10));
12723 has
.add("event-orientationchange", has("touch") && !has("android")); // TODO: how do we detect this?
12724 has
.add("event-stopimmediatepropagation", window
.Event
&& !!window
.Event
.prototype && !!window
.Event
.prototype.stopImmediatePropagation
);
12726 var on = function(target
, type
, listener
, dontFix
){
12728 // A function that provides core event listening functionality. With this function
12729 // you can provide a target, event type, and listener to be notified of
12730 // future matching events that are fired.
12731 // target: Element|Object
12732 // This is the target object or DOM element that to receive events from
12733 // type: String|Function
12734 // This is the name of the event to listen for or an extension event type.
12735 // listener: Function
12736 // This is the function that should be called when the event fires.
12738 // An object with a remove() method that can be used to stop listening for this
12741 // To listen for "click" events on a button node, we can do:
12742 // | define(["dojo/on"], function(listen){
12743 // | on(button, "click", clickHandler);
12745 // Evented JavaScript objects can also have their own events.
12746 // | var obj = new Evented;
12747 // | on(obj, "foo", fooHandler);
12748 // And then we could publish a "foo" event:
12749 // | on.emit(obj, "foo", {key: "value"});
12750 // We can use extension events as well. For example, you could listen for a tap gesture:
12751 // | define(["dojo/on", "dojo/gesture/tap", function(listen, tap){
12752 // | on(button, tap, tapHandler);
12754 // which would trigger fooHandler. Note that for a simple object this is equivalent to calling:
12755 // | obj.onfoo({key:"value"});
12756 // If you use on.emit on a DOM node, it will use native event dispatching when possible.
12758 if(typeof target
.on
== "function" && typeof type
!= "function"){
12759 // delegate to the target's on() method, so it can handle it's own listening if it wants
12760 return target
.on(type
, listener
);
12762 // delegate to main listener code
12763 return on
.parse(target
, type
, listener
, addListener
, dontFix
, this);
12765 on
.pausable = function(target
, type
, listener
, dontFix
){
12767 // This function acts the same as on(), but with pausable functionality. The
12768 // returned signal object has pause() and resume() functions. Calling the
12769 // pause() method will cause the listener to not be called for future events. Calling the
12770 // resume() method will cause the listener to again be called for future events.
12772 var signal
= on(target
, type
, function(){
12774 return listener
.apply(this, arguments
);
12777 signal
.pause = function(){
12780 signal
.resume = function(){
12785 on
.once = function(target
, type
, listener
, dontFix
){
12787 // This function acts the same as on(), but will only call the listener once. The
12788 // listener will be called for the first
12789 // event that takes place and then listener will automatically be removed.
12790 var signal
= on(target
, type
, function(){
12791 // remove this listener
12793 // proceed to call the listener
12794 return listener
.apply(this, arguments
);
12798 on
.parse = function(target
, type
, listener
, addListener
, dontFix
, matchesTarget
){
12800 // event handler function
12801 // on(node, touch.press, touchListener);
12802 return type
.call(matchesTarget
, target
, listener
);
12805 if(type
.indexOf(",") > -1){
12806 // we allow comma delimited event names, so you can register for multiple events at once
12807 var events
= type
.split(/\s*,\s*/);
12811 while(eventName
= events
[i
++]){
12812 handles
.push(addListener(target
, eventName
, listener
, dontFix
, matchesTarget
));
12814 handles
.remove = function(){
12815 for(var i
= 0; i
< handles
.length
; i
++){
12816 handles
[i
].remove();
12821 return addListener(target
, type
, listener
, dontFix
, matchesTarget
);
12823 var touchEvents
= /^touch/;
12824 function addListener(target
, type
, listener
, dontFix
, matchesTarget
){
12825 // event delegation:
12826 var selector
= type
.match(/(.*):(.*)/);
12827 // if we have a selector:event, the last one is interpreted as an event, and we use event delegation
12829 type
= selector
[2];
12830 selector
= selector
[1];
12831 // create the extension event for selectors and directly call it
12832 return on
.selector(selector
, type
).call(matchesTarget
, target
, listener
);
12834 // test to see if it a touch event right now, so we don't have to do it every time it fires
12836 if(touchEvents
.test(type
)){
12837 // touch event, fix it
12838 listener
= fixTouchListener(listener
);
12840 if(!has("event-orientationchange") && (type
== "orientationchange")){
12841 //"orientationchange" not supported <= Android 2.1,
12842 //but works through "resize" on window
12845 listener
= fixTouchListener(listener
);
12848 if(addStopImmediate
){
12849 // add stopImmediatePropagation if it doesn't exist
12850 listener
= addStopImmediate(listener
);
12852 // normal path, the target is |this|
12853 if(target
.addEventListener
){
12854 // the target has addEventListener, which should be used if available (might or might not be a node, non-nodes can implement this method as well)
12855 // check for capture conversions
12856 var capture
= type
in captures
,
12857 adjustedType
= capture
? captures
[type
] : type
;
12858 target
.addEventListener(adjustedType
, listener
, capture
);
12859 // create and return the signal
12861 remove: function(){
12862 target
.removeEventListener(adjustedType
, listener
, capture
);
12866 type
= "on" + type
;
12867 if(fixAttach
&& target
.attachEvent
){
12868 return fixAttach(target
, type
, listener
);
12870 throw new Error("Target must be an event emitter");
12873 on
.selector = function(selector
, eventType
, children
){
12875 // Creates a new extension event with event delegation. This is based on
12876 // the provided event type (can be extension event) that
12877 // only calls the listener when the CSS selector matches the target of the event.
12879 // The application must require() an appropriate level of dojo/query to handle the selector.
12881 // The CSS selector to use for filter events and determine the |this| of the event listener.
12883 // The event to listen for
12885 // Indicates if children elements of the selector should be allowed. This defaults to
12888 // | require(["dojo/on", "dojo/mouse", "dojo/query!css2"], function(listen, mouse){
12889 // | on(node, on.selector(".my-class", mouse.enter), handlerForMyHover);
12890 return function(target
, listener
){
12891 // if the selector is function, use it to select the node, otherwise use the matches method
12892 var matchesTarget
= typeof selector
== "function" ? {matches
: selector
} : this,
12893 bubble
= eventType
.bubble
;
12894 function select(eventTarget
){
12895 // see if we have a valid matchesTarget or default to dojo.query
12896 matchesTarget
= matchesTarget
&& matchesTarget
.matches
? matchesTarget
: dojo
.query
;
12897 // there is a selector, so make sure it matches
12898 while(!matchesTarget
.matches(eventTarget
, selector
, target
)){
12899 if(eventTarget
== target
|| children
=== false || !(eventTarget
= eventTarget
.parentNode
) || eventTarget
.nodeType
!= 1){ // intentional assignment
12903 return eventTarget
;
12906 // the event type doesn't naturally bubble, but has a bubbling form, use that, and give it the selector so it can perform the select itself
12907 return on(target
, bubble(select
), listener
);
12909 // standard event delegation
12910 return on(target
, eventType
, function(event
){
12911 // call select to see if we match
12912 var eventTarget
= select(event
.target
);
12913 // if it matches we call the listener
12914 return eventTarget
&& listener
.call(eventTarget
, event
);
12919 function syntheticPreventDefault(){
12920 this.cancelable
= false;
12922 function syntheticStopPropagation(){
12923 this.bubbles
= false;
12925 var slice
= [].slice
,
12926 syntheticDispatch
= on
.emit = function(target
, type
, event
){
12928 // Fires an event on the target object.
12930 // The target object to fire the event on. This can be a DOM element or a plain
12931 // JS object. If the target is a DOM element, native event emiting mechanisms
12932 // are used when possible.
12934 // The event type name. You can emulate standard native events like "click" and
12935 // "mouseover" or create custom events like "open" or "finish".
12937 // An object that provides the properties for the event. See https://developer.mozilla.org/en/DOM/event.initEvent
12938 // for some of the properties. These properties are copied to the event object.
12939 // Of particular importance are the cancelable and bubbles properties. The
12940 // cancelable property indicates whether or not the event has a default action
12941 // that can be cancelled. The event is cancelled by calling preventDefault() on
12942 // the event object. The bubbles property indicates whether or not the
12943 // event will bubble up the DOM tree. If bubbles is true, the event will be called
12944 // on the target and then each parent successively until the top of the tree
12945 // is reached or stopPropagation() is called. Both bubbles and cancelable
12946 // default to false.
12948 // If the event is cancelable and the event is not cancelled,
12949 // emit will return true. If the event is cancelable and the event is cancelled,
12950 // emit will return false.
12952 // Note that this is designed to emit events for listeners registered through
12953 // dojo/on. It should actually work with any event listener except those
12954 // added through IE's attachEvent (IE8 and below's non-W3C event emiting
12955 // doesn't support custom event types). It should work with all events registered
12956 // through dojo/on. Also note that the emit method does do any default
12957 // action, it only returns a value to indicate if the default action should take
12958 // place. For example, emiting a keypress event would not cause a character
12959 // to appear in a textbox.
12961 // To fire our own click event
12962 // | on.emit(dojo.byId("button"), "click", {
12963 // | cancelable: true,
12964 // | bubbles: true,
12968 // We can also fire our own custom events:
12969 // | on.emit(dojo.byId("slider"), "slide", {
12970 // | cancelable: true,
12971 // | bubbles: true,
12972 // | direction: "left-to-right"
12974 var args
= slice
.call(arguments
, 2);
12975 var method
= "on" + type
;
12976 if("parentNode" in target
){
12977 // node (or node-like), create event controller methods
12978 var newEvent
= args
[0] = {};
12979 for(var i
in event
){
12980 newEvent
[i
] = event
[i
];
12982 newEvent
.preventDefault
= syntheticPreventDefault
;
12983 newEvent
.stopPropagation
= syntheticStopPropagation
;
12984 newEvent
.target
= target
;
12985 newEvent
.type
= type
;
12989 // call any node which has a handler (note that ideally we would try/catch to simulate normal event propagation but that causes too much pain for debugging)
12990 target
[method
] && target
[method
].apply(target
, args
);
12991 // and then continue up the parent node chain if it is still bubbling (if started as bubbles and stopPropagation hasn't been called)
12992 }while(event
&& event
.bubbles
&& (target
= target
.parentNode
));
12993 return event
&& event
.cancelable
&& event
; // if it is still true (was cancelable and was cancelled), return the event to indicate default action should happen
12996 if(!has("event-stopimmediatepropagation")){
12997 var stopImmediatePropagation =function(){
12998 this.immediatelyStopped
= true;
12999 this.modified
= true; // mark it as modified so the event will be cached in IE
13001 var addStopImmediate = function(listener
){
13002 return function(event
){
13003 if(!event
.immediatelyStopped
){// check to make sure it hasn't been stopped immediately
13004 event
.stopImmediatePropagation
= stopImmediatePropagation
;
13005 return listener
.apply(this, arguments
);
13010 if(has("dom-addeventlistener")){
13011 // normalize focusin and focusout
13017 // emiter that works with native event handling
13018 on
.emit = function(target
, type
, event
){
13019 if(target
.dispatchEvent
&& document
.createEvent
){
13020 // use the native event emiting mechanism if it is available on the target object
13021 // create a generic event
13022 // we could create branch into the different types of event constructors, but
13023 // that would be a lot of extra code, with little benefit that I can see, seems
13024 // best to use the generic constructor and copy properties over, making it
13025 // easy to have events look like the ones created with specific initializers
13026 var nativeEvent
= target
.ownerDocument
.createEvent("HTMLEvents");
13027 nativeEvent
.initEvent(type
, !!event
.bubbles
, !!event
.cancelable
);
13028 // and copy all our properties over
13029 for(var i
in event
){
13030 var value
= event
[i
];
13031 if(!(i
in nativeEvent
)){
13032 nativeEvent
[i
] = event
[i
];
13035 return target
.dispatchEvent(nativeEvent
) && nativeEvent
;
13037 return syntheticDispatch
.apply(on
, arguments
); // emit for a non-node
13040 // no addEventListener, basically old IE event normalization
13041 on
._fixEvent = function(evt
, sender
){
13043 // normalizes properties on the event object including event
13044 // bubbling methods, keystroke normalization, and x/y positions
13046 // native event object
13048 // node to treat as "currentTarget"
13050 var w
= sender
&& (sender
.ownerDocument
|| sender
.document
|| sender
).parentWindow
|| window
;
13053 if(!evt
){return evt
;}
13054 if(lastEvent
&& evt
.type
== lastEvent
.type
){
13055 // should be same event, reuse event object (so it can be augmented)
13058 if(!evt
.target
){ // check to see if it has been fixed yet
13059 evt
.target
= evt
.srcElement
;
13060 evt
.currentTarget
= (sender
|| evt
.srcElement
);
13061 if(evt
.type
== "mouseover"){
13062 evt
.relatedTarget
= evt
.fromElement
;
13064 if(evt
.type
== "mouseout"){
13065 evt
.relatedTarget
= evt
.toElement
;
13067 if(!evt
.stopPropagation
){
13068 evt
.stopPropagation
= stopPropagation
;
13069 evt
.preventDefault
= preventDefault
;
13073 var c
= ("charCode" in evt
? evt
.charCode
: evt
.keyCode
);
13075 // CTRL-ENTER is CTRL-ASCII(10) on IE, but CTRL-ENTER on Mozilla
13078 }else if(c
==13||c
==27){
13079 c
=0; // Mozilla considers ENTER and ESC non-printable
13081 c
=99; // Mozilla maps CTRL-BREAK to CTRL-c
13083 // Mozilla sets keyCode to 0 when there is a charCode
13084 // but that stops the event on IE.
13092 var lastEvent
, IESignal = function(handle
){
13093 this.handle
= handle
;
13095 IESignal
.prototype.remove = function(){
13096 delete _dojoIEListeners_
[this.handle
];
13098 var fixListener = function(listener
){
13099 // this is a minimal function for closing on the previous listener with as few as variables as possible
13100 return function(evt
){
13101 evt
= on
._fixEvent(evt
, this);
13102 var result
= listener
.call(this, evt
);
13104 // cache the last event and reuse it if we can
13106 setTimeout(function(){
13115 var fixAttach = function(target
, type
, listener
){
13116 listener
= fixListener(listener
);
13117 if(((target
.ownerDocument
? target
.ownerDocument
.parentWindow
: target
.parentWindow
|| target
.window
|| window
) != top
||
13118 has("jscript") < 5.8) &&
13119 !has("config-_allow_leaks")){
13120 // IE will leak memory on certain handlers in frames (IE8 and earlier) and in unattached DOM nodes for JScript 5.7 and below.
13121 // Here we use global redirection to solve the memory leaks
13122 if(typeof _dojoIEListeners_
== "undefined"){
13123 _dojoIEListeners_
= [];
13125 var emiter
= target
[type
];
13126 if(!emiter
|| !emiter
.listeners
){
13127 var oldListener
= emiter
;
13128 emiter
= Function('event', 'var callee = arguments.callee; for(var i = 0; i<callee.listeners.length; i++){var listener = _dojoIEListeners_[callee.listeners[i]]; if(listener){listener.call(this,event);}}');
13129 emiter
.listeners
= [];
13130 target
[type
] = emiter
;
13131 emiter
.global
= this;
13133 emiter
.listeners
.push(_dojoIEListeners_
.push(oldListener
) - 1);
13137 emiter
.listeners
.push(handle
= (emiter
.global
._dojoIEListeners_
.push(listener
) - 1));
13138 return new IESignal(handle
);
13140 return aspect
.after(target
, type
, listener
, true);
13143 var _setKeyChar = function(evt
){
13144 evt
.keyChar
= evt
.charCode
? String
.fromCharCode(evt
.charCode
) : '';
13145 evt
.charOrCode
= evt
.keyChar
|| evt
.keyCode
;
13147 // Called in Event scope
13148 var stopPropagation = function(){
13149 this.cancelBubble
= true;
13151 var preventDefault
= on
._preventDefault = function(){
13152 // Setting keyCode to 0 is the only way to prevent certain keypresses (namely
13153 // ctrl-combinations that correspond to menu accelerator keys).
13154 // Otoh, it prevents upstream listeners from getting this information
13155 // Try to split the difference here by clobbering keyCode only for ctrl
13156 // combinations. If you still need to access the key upstream, bubbledKeyCode is
13157 // provided as a workaround.
13158 this.bubbledKeyCode
= this.keyCode
;
13161 // squelch errors when keyCode is read-only
13162 // (e.g. if keyCode is ctrl or shift)
13167 this.defaultPrevented
= true;
13168 this.returnValue
= false;
13172 var Event = function(){};
13173 var windowOrientation
= window
.orientation
;
13174 var fixTouchListener = function(listener
){
13175 return function(originalEvent
){
13176 //Event normalization(for ontouchxxx and resize):
13177 //1.incorrect e.pageX|pageY in iOS
13178 //2.there are no "e.rotation", "e.scale" and "onorientationchange" in Andriod
13179 //3.More TBD e.g. force | screenX | screenX | clientX | clientY | radiusX | radiusY
13181 // see if it has already been corrected
13182 var event
= originalEvent
.corrected
;
13184 var type
= originalEvent
.type
;
13186 delete originalEvent
.type
; // on some JS engines (android), deleting properties make them mutable
13188 if(originalEvent
.type
){
13189 // deleting properties doesn't work (older iOS), have to use delegation
13190 Event
.prototype = originalEvent
;
13191 var event
= new Event
;
13192 // have to delegate methods to make them work
13193 event
.preventDefault = function(){
13194 originalEvent
.preventDefault();
13196 event
.stopPropagation = function(){
13197 originalEvent
.stopPropagation();
13200 // deletion worked, use property as is
13201 event
= originalEvent
;
13204 originalEvent
.corrected
= event
;
13205 if(type
== 'resize'){
13206 if(windowOrientation
== window
.orientation
){
13207 return null;//double tap causes an unexpected 'resize' in Andriod
13209 windowOrientation
= window
.orientation
;
13210 event
.type
= "orientationchange";
13211 return listener
.call(this, event
);
13213 // We use the original event and augment, rather than doing an expensive mixin operation
13214 if(!("rotation" in event
)){ // test to see if it has rotation
13215 event
.rotation
= 0;
13218 //use event.changedTouches[0].pageX|pageY|screenX|screenY|clientX|clientY|target
13219 var firstChangeTouch
= event
.changedTouches
[0];
13220 for(var i
in firstChangeTouch
){ // use for-in, we don't need to have dependency on dojo/_base/lang here
13221 delete event
[i
]; // delete it first to make it mutable
13222 event
[i
] = firstChangeTouch
[i
];
13225 return listener
.call(this, event
);
13233 'dojo/_base/sniff':function(){
13234 define(["./kernel", "./lang", "../sniff"], function(dojo
, lang
, has
){
13236 // dojo/_base/sniff
13241 // Deprecated. New code should use dojo/sniff.
13242 // This module populates the dojo browser version sniffing properties like dojo.isIE.
13250 // no idea what this is for, or if it's used
13251 dojo
._name
= "browser";
13254 // isBrowser: Boolean
13255 // True if the client is a web-browser
13258 // isFF: Number|undefined
13259 // Version as a Number if client is FireFox. undefined otherwise. Corresponds to
13260 // major detected FireFox version (1.5, 2, 3, etc.)
13263 // isIE: Number|undefined
13264 // Version as a Number if client is MSIE(PC). undefined otherwise. Corresponds to
13265 // major detected IE version (6, 7, 8, etc.)
13268 // isKhtml: Number|undefined
13269 // Version as a Number if client is a KHTML browser. undefined otherwise. Corresponds to major
13270 // detected version.
13271 isKhtml
: has("khtml"),
13273 // isWebKit: Number|undefined
13274 // Version as a Number if client is a WebKit-derived browser (Konqueror,
13275 // Safari, Chrome, etc.). undefined otherwise.
13276 isWebKit
: has("webkit"),
13278 // isMozilla: Number|undefined
13279 // Version as a Number if client is a Mozilla-based browser (Firefox,
13280 // SeaMonkey). undefined otherwise. Corresponds to major detected version.
13281 isMozilla
: has("mozilla"),
13282 // isMoz: Number|undefined
13283 // Version as a Number if client is a Mozilla-based browser (Firefox,
13284 // SeaMonkey). undefined otherwise. Corresponds to major detected version.
13285 isMoz
: has("mozilla"),
13287 // isOpera: Number|undefined
13288 // Version as a Number if client is Opera. undefined otherwise. Corresponds to
13289 // major detected version.
13290 isOpera
: has("opera"),
13292 // isSafari: Number|undefined
13293 // Version as a Number if client is Safari or iPhone. undefined otherwise.
13294 isSafari
: has("safari"),
13296 // isChrome: Number|undefined
13297 // Version as a Number if client is Chrome browser. undefined otherwise.
13298 isChrome
: has("chrome"),
13301 // True if the client runs on Mac
13305 // True if client is iPhone, iPod, or iPad
13308 // isAndroid: Number|undefined
13309 // Version as a Number if client is android browser. undefined otherwise.
13310 isAndroid
: has("android"),
13313 // True if client is Wii
13316 // isQuirks: Boolean
13317 // Page is in quirks mode.
13318 isQuirks
: has("quirks"),
13321 // True if client is Adobe Air
13326 dojo
.locale
= dojo
.locale
|| (has("ie") ? navigator
.userLanguage
: navigator
.language
).toLowerCase();
13332 'dojo/errors/create':function(){
13333 define(["../_base/lang"], function(lang
){
13334 return function(name
, ctor
, base
, props
){
13335 base
= base
|| Error
;
13337 var ErrorCtor = function(message
){
13338 if(base
=== Error
){
13339 if(Error
.captureStackTrace
){
13340 Error
.captureStackTrace(this, ErrorCtor
);
13343 // Error.call() operates on the returned error
13344 // object rather than operating on |this|
13345 var err
= Error
.call(this, message
),
13348 // Copy own properties from err to |this|
13350 if(err
.hasOwnProperty(prop
)){
13351 this[prop
] = err
[prop
];
13355 // messsage is non-enumerable in ES5
13356 this.message
= message
;
13357 // stack is non-enumerable in at least Firefox
13358 this.stack
= err
.stack
;
13360 base
.apply(this, arguments
);
13363 ctor
.apply(this, arguments
);
13367 ErrorCtor
.prototype = lang
.delegate(base
.prototype, props
);
13368 ErrorCtor
.prototype.name
= name
;
13369 ErrorCtor
.prototype.constructor = ErrorCtor
;
13376 'dojo/_base/array':function(){
13377 define(["./kernel", "../has", "./lang"], function(dojo
, has
, lang
){
13379 // dojo/_base/array
13381 // our old simple function builder stuff
13384 function buildFn(fn
){
13385 return cache
[fn
] = new Function("item", "index", "array", fn
); // Function
13387 // magic snippet: if(typeof fn == "string") fn = cache[fn] || buildFn(fn);
13391 function everyOrSome(some
){
13393 return function(a
, fn
, o
){
13394 var i
= 0, l
= a
&& a
.length
|| 0, result
;
13395 if(l
&& typeof a
== "string") a
= a
.split("");
13396 if(typeof fn
== "string") fn
= cache
[fn
] || buildFn(fn
);
13399 result
= !fn
.call(o
, a
[i
], i
, a
);
13406 result
= !fn(a
[i
], i
, a
);
13412 return every
; // Boolean
13416 // indexOf, lastIndexOf
13418 function index(up
){
13419 var delta
= 1, lOver
= 0, uOver
= 0;
13421 delta
= lOver
= uOver
= -1;
13423 return function(a
, x
, from, last
){
13424 if(last
&& delta
> 0){
13425 // TODO: why do we use a non-standard signature? why do we need "last"?
13426 return array
.lastIndexOf(a
, x
, from);
13428 var l
= a
&& a
.length
|| 0, end
= up
? l
+ uOver
: lOver
, i
;
13430 i
= up
? lOver
: l
+ uOver
;
13438 i
= from >= l
? l
+ uOver
: from;
13441 if(l
&& typeof a
== "string") a
= a
.split("");
13442 for(; i
!= end
; i
+= delta
){
13444 return i
; // Number
13447 return -1; // Number
13453 // The Javascript v1.6 array extensions.
13455 every
: everyOrSome(false),
13457 every: function(arr, callback, thisObject){
13459 // Determines whether or not every item in arr satisfies the
13460 // condition implemented by callback.
13461 // arr: Array|String
13462 // the array to iterate on. If a string, operates on individual characters.
13463 // callback: Function|String
13464 // a function is invoked with three arguments: item, index,
13465 // and array and returns true if the condition is met.
13466 // thisObject: Object?
13467 // may be used to scope the call to callback
13468 // returns: Boolean
13470 // This function corresponds to the JavaScript 1.6 Array.every() method, with one difference: when
13471 // run over sparse arrays, this implementation passes the "holes" in the sparse array to
13472 // the callback function with a value of undefined. JavaScript 1.6's every skips the holes in the sparse array.
13473 // For more details, see:
13474 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/every
13476 // | // returns false
13477 // | array.every([1, 2, 3, 4], function(item){ return item>1; });
13479 // | // returns true
13480 // | array.every([1, 2, 3, 4], function(item){ return item>0; });
13484 some
: everyOrSome(true),
13486 some: function(arr, callback, thisObject){
13488 // Determines whether or not any item in arr satisfies the
13489 // condition implemented by callback.
13490 // arr: Array|String
13491 // the array to iterate over. If a string, operates on individual characters.
13492 // callback: Function|String
13493 // a function is invoked with three arguments: item, index,
13494 // and array and returns true if the condition is met.
13495 // thisObject: Object?
13496 // may be used to scope the call to callback
13497 // returns: Boolean
13499 // This function corresponds to the JavaScript 1.6 Array.some() method, with one difference: when
13500 // run over sparse arrays, this implementation passes the "holes" in the sparse array to
13501 // the callback function with a value of undefined. JavaScript 1.6's some skips the holes in the sparse array.
13502 // For more details, see:
13503 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/some
13506 // | array.some([1, 2, 3, 4], function(item){ return item>1; });
13509 // | array.some([1, 2, 3, 4], function(item){ return item<1; });
13513 indexOf
: index(true),
13515 indexOf: function(arr, value, fromIndex, findLast){
13517 // locates the first index of the provided value in the
13518 // passed array. If the value is not found, -1 is returned.
13520 // This method corresponds to the JavaScript 1.6 Array.indexOf method, with one difference: when
13521 // run over sparse arrays, the Dojo function invokes the callback for every index whereas JavaScript
13522 // 1.6's indexOf skips the holes in the sparse array.
13523 // For details on this method, see:
13524 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/indexOf
13527 // fromIndex: Integer?
13528 // findLast: Boolean?
13533 lastIndexOf
: index(false),
13535 lastIndexOf: function(arr, value, fromIndex){
13537 // locates the last index of the provided value in the passed
13538 // array. If the value is not found, -1 is returned.
13540 // This method corresponds to the JavaScript 1.6 Array.lastIndexOf method, with one difference: when
13541 // run over sparse arrays, the Dojo function invokes the callback for every index whereas JavaScript
13542 // 1.6's lastIndexOf skips the holes in the sparse array.
13543 // For details on this method, see:
13544 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/lastIndexOf
13547 // fromIndex: Integer?
13552 forEach: function(arr
, callback
, thisObject
){
13554 // for every item in arr, callback is invoked. Return values are ignored.
13555 // If you want to break out of the loop, consider using array.every() or array.some().
13556 // forEach does not allow breaking out of the loop over the items in arr.
13558 // the array to iterate over. If a string, operates on individual characters.
13560 // a function is invoked with three arguments: item, index, and array
13562 // may be used to scope the call to callback
13564 // This function corresponds to the JavaScript 1.6 Array.forEach() method, with one difference: when
13565 // run over sparse arrays, this implementation passes the "holes" in the sparse array to
13566 // the callback function with a value of undefined. JavaScript 1.6's forEach skips the holes in the sparse array.
13567 // For more details, see:
13568 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/forEach
13570 // | // log out all members of the array:
13571 // | array.forEach(
13572 // | [ "thinger", "blah", "howdy", 10 ],
13573 // | function(item){
13574 // | console.log(item);
13578 // | // log out the members and their indexes
13579 // | array.forEach(
13580 // | [ "thinger", "blah", "howdy", 10 ],
13581 // | function(item, idx, arr){
13582 // | console.log(item, "at index:", idx);
13586 // | // use a scoped object member as the callback
13589 // | prefix: "logged via obj.callback:",
13590 // | callback: function(item){
13591 // | console.log(this.prefix, item);
13595 // | // specifying the scope function executes the callback in that scope
13596 // | array.forEach(
13597 // | [ "thinger", "blah", "howdy", 10 ],
13602 // | // alternately, we can accomplish the same thing with lang.hitch()
13603 // | array.forEach(
13604 // | [ "thinger", "blah", "howdy", 10 ],
13605 // | lang.hitch(obj, "callback")
13607 // arr: Array|String
13608 // callback: Function|String
13609 // thisObject: Object?
13611 var i
= 0, l
= arr
&& arr
.length
|| 0;
13612 if(l
&& typeof arr
== "string") arr
= arr
.split("");
13613 if(typeof callback
== "string") callback
= cache
[callback
] || buildFn(callback
);
13616 callback
.call(thisObject
, arr
[i
], i
, arr
);
13620 callback(arr
[i
], i
, arr
);
13625 map: function(arr
, callback
, thisObject
, Ctr
){
13627 // applies callback to each element of arr and returns
13628 // an Array with the results
13629 // arr: Array|String
13630 // the array to iterate on. If a string, operates on
13631 // individual characters.
13632 // callback: Function|String
13633 // a function is invoked with three arguments, (item, index,
13634 // array), and returns a value
13635 // thisObject: Object?
13636 // may be used to scope the call to callback
13639 // This function corresponds to the JavaScript 1.6 Array.map() method, with one difference: when
13640 // run over sparse arrays, this implementation passes the "holes" in the sparse array to
13641 // the callback function with a value of undefined. JavaScript 1.6's map skips the holes in the sparse array.
13642 // For more details, see:
13643 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map
13645 // | // returns [2, 3, 4, 5]
13646 // | array.map([1, 2, 3, 4], function(item){ return item+1 });
13648 // TODO: why do we have a non-standard signature here? do we need "Ctr"?
13649 var i
= 0, l
= arr
&& arr
.length
|| 0, out
= new (Ctr
|| Array
)(l
);
13650 if(l
&& typeof arr
== "string") arr
= arr
.split("");
13651 if(typeof callback
== "string") callback
= cache
[callback
] || buildFn(callback
);
13654 out
[i
] = callback
.call(thisObject
, arr
[i
], i
, arr
);
13658 out
[i
] = callback(arr
[i
], i
, arr
);
13661 return out
; // Array
13664 filter: function(arr
, callback
, thisObject
){
13666 // Returns a new Array with those items from arr that match the
13667 // condition implemented by callback.
13669 // the array to iterate over.
13670 // callback: Function|String
13671 // a function that is invoked with three arguments (item,
13672 // index, array). The return of this function is expected to
13673 // be a boolean which determines whether the passed-in item
13674 // will be included in the returned array.
13675 // thisObject: Object?
13676 // may be used to scope the call to callback
13679 // This function corresponds to the JavaScript 1.6 Array.filter() method, with one difference: when
13680 // run over sparse arrays, this implementation passes the "holes" in the sparse array to
13681 // the callback function with a value of undefined. JavaScript 1.6's filter skips the holes in the sparse array.
13682 // For more details, see:
13683 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/filter
13685 // | // returns [2, 3, 4]
13686 // | array.filter([1, 2, 3, 4], function(item){ return item>1; });
13688 // TODO: do we need "Ctr" here like in map()?
13689 var i
= 0, l
= arr
&& arr
.length
|| 0, out
= [], value
;
13690 if(l
&& typeof arr
== "string") arr
= arr
.split("");
13691 if(typeof callback
== "string") callback
= cache
[callback
] || buildFn(callback
);
13695 if(callback
.call(thisObject
, value
, i
, arr
)){
13702 if(callback(value
, i
, arr
)){
13707 return out
; // Array
13710 clearCache: function(){
13716 1 && lang
.mixin(dojo
, array
);
13722 'dojo/_base/json':function(){
13723 define(["./kernel", "../json"], function(dojo
, json
){
13731 // This module defines the dojo JSON API.
13735 dojo
.fromJson = function(/*String*/ js
){
13737 // Parses a JavaScript expression and returns a JavaScript value.
13739 // Throws for invalid JavaScript expressions. It does not use a strict JSON parser. It
13740 // always delegates to eval(). The content passed to this method must therefore come
13741 // from a trusted source.
13742 // It is recommend that you use dojo/json's parse function for an
13743 // implementation uses the (faster) native JSON parse when available.
13745 // a string literal of a JavaScript expression, for instance:
13746 // `'{ "foo": [ "bar", 1, { "baz": "thud" } ] }'`
13748 return eval("(" + js
+ ")"); // Object
13752 dojo._escapeString = function(){
13754 // Adds escape sequences for non-visual characters, double quote and
13755 // backslash and surrounds with double quotes to form a valid string
13759 dojo
._escapeString
= json
.stringify
; // just delegate to json.stringify
13761 dojo
.toJsonIndentStr
= "\t";
13762 dojo
.toJson = function(/*Object*/ it
, /*Boolean?*/ prettyPrint
){
13764 // Returns a [JSON](http://json.org) serialization of an object.
13766 // Returns a [JSON](http://json.org) serialization of an object.
13767 // Note that this doesn't check for infinite recursion, so don't do that!
13768 // It is recommend that you use dojo/json's stringify function for an lighter
13769 // and faster implementation that matches the native JSON API and uses the
13770 // native JSON serializer when available.
13772 // an object to be serialized. Objects may define their own
13773 // serialization via a special "__json__" or "json" function
13774 // property. If a specialized serializer has been defined, it will
13775 // be used as a fallback.
13776 // Note that in 1.6, toJson would serialize undefined, but this no longer supported
13777 // since it is not supported by native JSON serializer.
13779 // if true, we indent objects and arrays to make the output prettier.
13780 // The variable `dojo.toJsonIndentStr` is used as the indent string --
13781 // to use something other than the default (tab), change that variable
13782 // before calling dojo.toJson().
13783 // Note that if native JSON support is available, it will be used for serialization,
13784 // and native implementations vary on the exact spacing used in pretty printing.
13786 // A JSON string serialization of the passed-in object.
13788 // simple serialization of a trivial object
13789 // | var jsonStr = dojo.toJson({ howdy: "stranger!", isStrange: true });
13790 // | doh.is('{"howdy":"stranger!","isStrange":true}', jsonStr);
13792 // a custom serializer for an objects of a particular class:
13793 // | dojo.declare("Furby", null, {
13794 // | furbies: "are strange",
13795 // | furbyCount: 10,
13796 // | __json__: function(){
13801 return json
.stringify(it
, function(key
, value
){
13803 var tf
= value
.__json__
||value
.json
;
13804 if(typeof tf
== "function"){
13805 return tf
.call(value
);
13809 }, prettyPrint
&& dojo
.toJsonIndentStr
); // String
13816 'dojo/_base/window':function(){
13817 define("dojo/_base/window", ["./kernel", "./lang", "../sniff"], function(dojo
, lang
, has
){
13819 // dojo/_base/window
13823 // API to save/set/restore the global/document scope.
13825 global
: dojo
.global
,
13829 // Alias for the current window. 'global' can be modified
13830 // for temporary context shifting. See also withGlobal().
13832 // Use this rather than referring to 'window' to ensure your code runs
13833 // correctly in managed contexts.
13837 doc
: this["document"] || null,
13841 // Alias for the current document. 'doc' can be modified
13842 // for temporary context shifting. See also withDoc().
13844 // Use this rather than referring to 'window.document' to ensure your code runs
13845 // correctly in managed contexts.
13847 // | n.appendChild(dojo.doc.createElement('div'));
13851 body: function(/*Document?*/ doc
){
13853 // Return the body element of the specified document or of dojo/_base/window::doc.
13855 // | win.body().appendChild(dojo.doc.createElement('div'));
13857 // Note: document.body is not defined for a strict xhtml document
13858 // Would like to memoize this, but dojo.doc can change vi dojo.withDoc().
13859 doc
= doc
|| dojo
.doc
;
13860 return doc
.body
|| doc
.getElementsByTagName("body")[0]; // Node
13863 setContext: function(/*Object*/ globalObject
, /*DocumentElement*/ globalDocument
){
13865 // changes the behavior of many core Dojo functions that deal with
13866 // namespace and DOM lookup, changing them to work in a new global
13867 // context (e.g., an iframe). The varibles dojo.global and dojo.doc
13868 // are modified as a result of calling this function and the result of
13869 // `dojo.body()` likewise differs.
13870 dojo
.global
= ret
.global
= globalObject
;
13871 dojo
.doc
= ret
.doc
= globalDocument
;
13874 withGlobal: function( /*Object*/ globalObject
,
13875 /*Function*/ callback
,
13876 /*Object?*/ thisObject
,
13877 /*Array?*/ cbArguments
){
13879 // Invoke callback with globalObject as dojo.global and
13880 // globalObject.document as dojo.doc.
13882 // Invoke callback with globalObject as dojo.global and
13883 // globalObject.document as dojo.doc. If provided, globalObject
13884 // will be executed in the context of object thisObject
13885 // When callback() returns or throws an error, the dojo.global
13886 // and dojo.doc will be restored to its previous state.
13888 var oldGlob
= dojo
.global
;
13890 dojo
.global
= ret
.global
= globalObject
;
13891 return ret
.withDoc
.call(null, globalObject
.document
, callback
, thisObject
, cbArguments
);
13893 dojo
.global
= ret
.global
= oldGlob
;
13897 withDoc: function( /*DocumentElement*/ documentObject
,
13898 /*Function*/ callback
,
13899 /*Object?*/ thisObject
,
13900 /*Array?*/ cbArguments
){
13902 // Invoke callback with documentObject as dojo/_base/window::doc.
13904 // Invoke callback with documentObject as dojo/_base/window::doc. If provided,
13905 // callback will be executed in the context of object thisObject
13906 // When callback() returns or throws an error, the dojo/_base/window::doc will
13907 // be restored to its previous state.
13909 var oldDoc
= ret
.doc
,
13910 oldQ
= has("quirks"),
13911 oldIE
= has("ie"), isIE
, mode
, pwin
;
13914 dojo
.doc
= ret
.doc
= documentObject
;
13915 // update dojo.isQuirks and the value of the has feature "quirks".
13916 // remove setting dojo.isQuirks and dojo.isIE for 2.0
13917 dojo
.isQuirks
= has
.add("quirks", dojo
.doc
.compatMode
== "BackCompat", true, true); // no need to check for QuirksMode which was Opera 7 only
13920 if((pwin
= documentObject
.parentWindow
) && pwin
.navigator
){
13921 // re-run IE detection logic and update dojo.isIE / has("ie")
13922 // (the only time parentWindow/navigator wouldn't exist is if we were not
13923 // passed an actual legitimate document object)
13924 isIE
= parseFloat(pwin
.navigator
.appVersion
.split("MSIE ")[1]) || undefined;
13925 mode
= documentObject
.documentMode
;
13926 if(mode
&& mode
!= 5 && Math
.floor(isIE
) != mode
){
13929 dojo
.isIE
= has
.add("ie", isIE
, true, true);
13933 if(thisObject
&& typeof callback
== "string"){
13934 callback
= thisObject
[callback
];
13937 return callback
.apply(thisObject
, cbArguments
|| []);
13939 dojo
.doc
= ret
.doc
= oldDoc
;
13940 dojo
.isQuirks
= has
.add("quirks", oldQ
, true, true);
13941 dojo
.isIE
= has
.add("ie", oldIE
, true, true);
13946 1 && lang
.mixin(dojo
, ret
);
13953 'dojo/dom-class':function(){
13954 define(["./_base/lang", "./_base/array", "./dom"], function(lang
, array
, dom
){
13958 var className
= "className";
13960 /* Part I of classList-based implementation is preserved here for posterity
13961 var classList = "classList";
13962 has.add("dom-classList", function(){
13963 return classList in document.createElement("p");
13967 // =============================
13968 // (CSS) Class Functions
13969 // =============================
13971 var cls
, // exports object
13972 spaces
= /\s+/, a1
= [""];
13974 function str2array(s
){
13975 if(typeof s
== "string" || s
instanceof String
){
13976 if(s
&& !spaces
.test(s
)){
13980 var a
= s
.split(spaces
);
13981 if(a
.length
&& !a
[0]){
13984 if(a
.length
&& !a
[a
.length
- 1]){
13989 // assumed to be an array
13993 return array
.filter(s
, function(x
){ return x
; });
13996 /* Part II of classList-based implementation is preserved here for posterity
13997 if(has("dom-classList")){
13998 // new classList version
14000 contains: function containsClass(node, classStr){
14001 var clslst = classStr && dom.byId(node)[classList];
14002 return clslst && clslst.contains(classStr); // Boolean
14005 add: function addClass(node, classStr){
14006 node = dom.byId(node);
14007 classStr = str2array(classStr);
14008 for(var i = 0, len = classStr.length; i < len; ++i){
14009 node[classList].add(classStr[i]);
14013 remove: function removeClass(node, classStr){
14014 node = dom.byId(node);
14015 if(classStr === undefined){
14016 node[className] = "";
14018 classStr = str2array(classStr);
14019 for(var i = 0, len = classStr.length; i < len; ++i){
14020 node[classList].remove(classStr[i]);
14025 replace: function replaceClass(node, addClassStr, removeClassStr){
14026 node = dom.byId(node);
14027 if(removeClassStr === undefined){
14028 node[className] = "";
14030 removeClassStr = str2array(removeClassStr);
14031 for(var i = 0, len = removeClassStr.length; i < len; ++i){
14032 node[classList].remove(removeClassStr[i]);
14035 addClassStr = str2array(addClassStr);
14036 for(i = 0, len = addClassStr.length; i < len; ++i){
14037 node[classList].add(addClassStr[i]);
14041 toggle: function toggleClass(node, classStr, condition){
14042 node = dom.byId(node);
14043 if(condition === undefined){
14044 classStr = str2array(classStr);
14045 for(var i = 0, len = classStr.length; i < len; ++i){
14046 node[classList].toggle(classStr[i]);
14049 cls[condition ? "add" : "remove"](node, classStr);
14051 return condition; // Boolean
14057 // regular DOM version
14058 var fakeNode
= {}; // for effective replacement
14061 // This module defines the core dojo DOM class API.
14063 contains
: function containsClass(/*DomNode|String*/ node
, /*String*/ classStr
){
14065 // Returns whether or not the specified classes are a portion of the
14066 // class list currently applied to the node.
14067 // node: String|DOMNode
14068 // String ID or DomNode reference to check the class for.
14069 // classStr: String
14070 // A string class name to look for.
14072 // Do something if a node with id="someNode" has class="aSillyClassName" present
14073 // | if(dojo.hasClass("someNode","aSillyClassName")){ ... }
14075 return ((" " + dom
.byId(node
)[className
] + " ").indexOf(" " + classStr
+ " ") >= 0); // Boolean
14078 add
: function addClass(/*DomNode|String*/ node
, /*String|Array*/ classStr
){
14080 // Adds the specified classes to the end of the class list on the
14081 // passed node. Will not re-apply duplicate classes.
14083 // node: String|DOMNode
14084 // String ID or DomNode reference to add a class string too
14086 // classStr: String|Array
14087 // A String class name to add, or several space-separated class names,
14088 // or an array of class names.
14091 // Add a class to some node:
14092 // | require(["dojo/dom-class"], function(domClass){
14093 // | domClass.add("someNode", "anewClass");
14097 // Add two classes at once:
14098 // | require(["dojo/dom-class"], function(domClass){
14099 // | domClass.add("someNode", "firstClass secondClass");
14103 // Add two classes at once (using array):
14104 // | require(["dojo/dom-class"], function(domClass){
14105 // | domClass.add("someNode", ["firstClass", "secondClass"]);
14109 // Available in `dojo/NodeList` for multiple additions
14110 // | require(["dojo/query"], function(query){
14111 // | query("ul > li").addClass("firstLevel");
14114 node
= dom
.byId(node
);
14115 classStr
= str2array(classStr
);
14116 var cls
= node
[className
], oldLen
;
14117 cls
= cls
? " " + cls
+ " " : " ";
14118 oldLen
= cls
.length
;
14119 for(var i
= 0, len
= classStr
.length
, c
; i
< len
; ++i
){
14121 if(c
&& cls
.indexOf(" " + c
+ " ") < 0){
14125 if(oldLen
< cls
.length
){
14126 node
[className
] = cls
.substr(1, cls
.length
- 2);
14130 remove
: function removeClass(/*DomNode|String*/ node
, /*String|Array?*/ classStr
){
14132 // Removes the specified classes from node. No `contains()`
14133 // check is required.
14135 // node: String|DOMNode
14136 // String ID or DomNode reference to remove the class from.
14138 // classStr: String|Array
14139 // An optional String class name to remove, or several space-separated
14140 // class names, or an array of class names. If omitted, all class names
14141 // will be deleted.
14144 // Remove a class from some node:
14145 // | require(["dojo/dom-class"], function(domClass){
14146 // | domClass.remove("someNode", "firstClass");
14150 // Remove two classes from some node:
14151 // | require(["dojo/dom-class"], function(domClass){
14152 // | domClass.remove("someNode", "firstClass secondClass");
14156 // Remove two classes from some node (using array):
14157 // | require(["dojo/dom-class"], function(domClass){
14158 // | domClass.remove("someNode", ["firstClass", "secondClass"]);
14162 // Remove all classes from some node:
14163 // | require(["dojo/dom-class"], function(domClass){
14164 // | domClass.remove("someNode");
14168 // Available in `dojo/NodeList` for multiple removal
14169 // | require(["dojo/query"], function(query){
14170 // | query("ul > li").removeClass("foo");
14173 node
= dom
.byId(node
);
14175 if(classStr
!== undefined){
14176 classStr
= str2array(classStr
);
14177 cls
= " " + node
[className
] + " ";
14178 for(var i
= 0, len
= classStr
.length
; i
< len
; ++i
){
14179 cls
= cls
.replace(" " + classStr
[i
] + " ", " ");
14181 cls
= lang
.trim(cls
);
14185 if(node
[className
] != cls
){ node
[className
] = cls
; }
14188 replace
: function replaceClass(/*DomNode|String*/ node
, /*String|Array*/ addClassStr
, /*String|Array?*/ removeClassStr
){
14190 // Replaces one or more classes on a node if not present.
14191 // Operates more quickly than calling dojo.removeClass and dojo.addClass
14193 // node: String|DOMNode
14194 // String ID or DomNode reference to remove the class from.
14196 // addClassStr: String|Array
14197 // A String class name to add, or several space-separated class names,
14198 // or an array of class names.
14200 // removeClassStr: String|Array?
14201 // A String class name to remove, or several space-separated class names,
14202 // or an array of class names.
14205 // | require(["dojo/dom-class"], function(domClass){
14206 // | domClass.replace("someNode", "add1 add2", "remove1 remove2");
14210 // Replace all classes with addMe
14211 // | require(["dojo/dom-class"], function(domClass){
14212 // | domClass.replace("someNode", "addMe");
14216 // Available in `dojo/NodeList` for multiple toggles
14217 // | require(["dojo/query"], function(query){
14218 // | query(".findMe").replaceClass("addMe", "removeMe");
14221 node
= dom
.byId(node
);
14222 fakeNode
[className
] = node
[className
];
14223 cls
.remove(fakeNode
, removeClassStr
);
14224 cls
.add(fakeNode
, addClassStr
);
14225 if(node
[className
] !== fakeNode
[className
]){
14226 node
[className
] = fakeNode
[className
];
14230 toggle
: function toggleClass(/*DomNode|String*/ node
, /*String|Array*/ classStr
, /*Boolean?*/ condition
){
14232 // Adds a class to node if not present, or removes if present.
14233 // Pass a boolean condition if you want to explicitly add or remove.
14234 // Returns the condition that was specified directly or indirectly.
14236 // node: String|DOMNode
14237 // String ID or DomNode reference to toggle a class string
14239 // classStr: String|Array
14240 // A String class name to toggle, or several space-separated class names,
14241 // or an array of class names.
14244 // If passed, true means to add the class, false means to remove.
14245 // Otherwise dojo.hasClass(node, classStr) is used to detect the class presence.
14248 // | require(["dojo/dom-class"], function(domClass){
14249 // | domClass.toggle("someNode", "hovered");
14253 // Forcefully add a class
14254 // | require(["dojo/dom-class"], function(domClass){
14255 // | domClass.toggle("someNode", "hovered", true);
14259 // Available in `dojo/NodeList` for multiple toggles
14260 // | require(["dojo/query"], function(query){
14261 // | query(".toggleMe").toggleClass("toggleMe");
14264 node
= dom
.byId(node
);
14265 if(condition
=== undefined){
14266 classStr
= str2array(classStr
);
14267 for(var i
= 0, len
= classStr
.length
, c
; i
< len
; ++i
){
14269 cls
[cls
.contains(node
, c
) ? "remove" : "add"](node
, c
);
14272 cls
[condition
? "add" : "remove"](node
, classStr
);
14274 return condition
; // Boolean
14282 'dojo/_base/config':function(){
14283 define(["../has", "require"], function(has
, require
){
14285 // dojo/_base/config
14290 // This module defines the user configuration during bootstrap.
14292 // By defining user configuration as a module value, an entire configuration can be specified in a build,
14293 // thereby eliminating the need for sniffing and or explicitly setting in the global variable dojoConfig.
14294 // Also, when multiple instances of dojo exist in a single application, each will necessarily be located
14295 // at an unique absolute module identifier as given by the package configuration. Implementing configuration
14296 // as a module allows for specifying unique, per-instance configurations.
14298 // Create a second instance of dojo with a different, instance-unique configuration (assume the loader and
14299 // dojo.js are already loaded).
14300 // | // specify a configuration that creates a new instance of dojo at the absolute module identifier "myDojo"
14303 // | name:"myDojo",
14304 // | location:".", //assume baseUrl points to dojo.js
14308 // | // specify a configuration for the myDojo instance
14309 // | define("myDojo/config", {
14310 // | // normal configuration variables go here, e.g.,
14311 // | locale:"fr-ca"
14314 // | // load and use the new instance of dojo
14315 // | require(["myDojo"], function(dojo){
14316 // | // dojo is the new instance of dojo
14317 // | // use as required
14320 // isDebug: Boolean
14321 // Defaults to `false`. If set to `true`, ensures that Dojo provides
14322 // extended debugging feedback via Firebug. If Firebug is not available
14323 // on your platform, setting `isDebug` to `true` will force Dojo to
14324 // pull in (and display) the version of Firebug Lite which is
14325 // integrated into the Dojo distribution, thereby always providing a
14326 // debugging/logging console when `isDebug` is enabled. Note that
14327 // Firebug's `console.*` methods are ALWAYS defined by Dojo. If
14328 // `isDebug` is false and you are on a platform without Firebug, these
14329 // methods will be defined as no-ops.
14333 // The locale to assume for loading localized resources in this page,
14334 // specified according to [RFC 3066](http://www.ietf.org/rfc/rfc3066.txt).
14335 // Must be specified entirely in lowercase, e.g. `en-us` and `zh-cn`.
14336 // See the documentation for `dojo.i18n` and `dojo.requireLocalization`
14337 // for details on loading localized resources. If no locale is specified,
14338 // Dojo assumes the locale of the user agent, according to `navigator.userLanguage`
14339 // or `navigator.language` properties.
14342 // extraLocale: Array
14343 // No default value. Specifies additional locales whose
14344 // resources should also be loaded alongside the default locale when
14345 // calls to `dojo.requireLocalization()` are processed.
14346 extraLocale: undefined,
14349 // The directory in which `dojo.js` is located. Under normal
14350 // conditions, Dojo auto-detects the correct location from which it
14351 // was loaded. You may need to manually configure `baseUrl` in cases
14352 // where you have renamed `dojo.js` or in which `<base>` tags confuse
14353 // some browsers (e.g. IE 6). The variable `dojo.baseUrl` is assigned
14354 // either the value of `djConfig.baseUrl` if one is provided or the
14355 // auto-detected root if not. Other modules are located relative to
14356 // this path. The path should end in a slash.
14357 baseUrl: undefined,
14359 // modulePaths: [deprecated] Object
14360 // A map of module names to paths relative to `dojo.baseUrl`. The
14361 // key/value pairs correspond directly to the arguments which
14362 // `dojo.registerModulePath` accepts. Specifying
14363 // `djConfig.modulePaths = { "foo": "../../bar" }` is the equivalent
14364 // of calling `dojo.registerModulePath("foo", "../../bar");`. Multiple
14365 // modules may be configured via `djConfig.modulePaths`.
14368 // addOnLoad: Function|Array
14369 // Adds a callback via dojo/ready. Useful when Dojo is added after
14370 // the page loads and djConfig.afterOnLoad is true. Supports the same
14371 // arguments as dojo/ready. When using a function reference, use
14372 // `djConfig.addOnLoad = function(){};`. For object with function name use
14373 // `djConfig.addOnLoad = [myObject, "functionName"];` and for object with
14374 // function reference use
14375 // `djConfig.addOnLoad = [myObject, function(){}];`
14378 // parseOnLoad: Boolean
14379 // Run the parser after the page is loaded
14380 parseOnLoad: false,
14382 // require: String[]
14383 // An array of module names to be loaded immediately after dojo.js has been included
14387 // defaultDuration: Number
14388 // Default duration, in milliseconds, for wipe and fade animations within dijits.
14389 // Assigned to dijit.defaultDuration.
14390 defaultDuration: 200,
14392 // dojoBlankHtmlUrl: String
14393 // Used by some modules to configure an empty iframe. Used by dojo/io/iframe and
14394 // dojo/back, and dijit/popup support in IE where an iframe is needed to make sure native
14395 // controls do not bleed through the popups. Normally this configuration variable
14396 // does not need to be set, except when using cross-domain/CDN Dojo builds.
14397 // Save dojo/resources/blank.html to your domain and set `djConfig.dojoBlankHtmlUrl`
14398 // to the path on your domain your copy of blank.html.
14399 dojoBlankHtmlUrl: undefined,
14401 // ioPublish: Boolean?
14402 // Set this to true to enable publishing of topics for the different phases of
14403 // IO operations. Publishing is done via dojo/topic.publish(). See dojo/main.__IoPublish for a list
14404 // of topics that are published.
14407 // useCustomLogger: Anything?
14408 // If set to a value that evaluates to true such as a string or array and
14409 // isDebug is true and Firebug is not available or running, then it bypasses
14410 // the creation of Firebug Lite allowing you to define your own console object.
14411 useCustomLogger: undefined,
14413 // transparentColor: Array
14414 // Array containing the r, g, b components used as transparent color in dojo.Color;
14415 // if undefined, [255,255,255] (white) will be used.
14416 transparentColor: undefined,
14418 // deps: Function|Array
14419 // Defines dependencies to be used before the loader has been loaded.
14420 // When provided, they cause the loader to execute require(deps, callback)
14421 // once it has finished loading. Should be used with callback.
14424 // callback: Function|Array
14425 // Defines a callback to be used when dependencies are defined before
14426 // the loader has been loaded. When provided, they cause the loader to
14427 // execute require(deps, callback) once it has finished loading.
14428 // Should be used with deps.
14429 callback: undefined,
14431 // deferredInstrumentation: Boolean
14432 // Whether deferred instrumentation should be loaded or included
14434 deferredInstrumentation: true,
14436 // useDeferredInstrumentation: Boolean|String
14437 // Whether the deferred instrumentation should be used.
14439 // * `"report-rejections"`: report each rejection as it occurs.
14440 // * `true` or `1` or `"report-unhandled-rejections"`: wait 1 second
14441 // in an attempt to detect unhandled rejections.
14442 useDeferredInstrumentation: "report-unhandled-rejections"
14448 // must be the dojo loader; take a shallow copy of require.rawConfig
14449 var src
= require
.rawConfig
, p
;
14451 result
[p
] = src
[p
];
14454 var adviseHas = function(featureSet
, prefix
, booting
){
14455 for(p
in featureSet
){
14456 p
!="has" && has
.add(prefix
+ p
, featureSet
[p
], 0, booting
);
14460 // must be a built version of the dojo loader; all config stuffed in require.rawConfig
14461 require
.rawConfig
:
14462 // a foreign loader
14463 this.dojoConfig
|| this.djConfig
|| {};
14464 adviseHas(result
, "config", 1);
14465 adviseHas(result
.has
, "", 1);
14472 'dojo/_base/event':function(){
14473 define("dojo/_base/event", ["./kernel", "../on", "../has", "../dom-geometry"], function(dojo
, on
, has
, dom
){
14475 // dojo/_base/event
14478 var fixEvent
= on
._fixEvent
;
14479 on
._fixEvent = function(evt
, se
){
14480 // add some additional normalization for back-compat, this isn't in on.js because it is somewhat more expensive
14481 evt
= fixEvent(evt
, se
);
14483 dom
.normalizeEvent(evt
);
14491 // This module defines dojo DOM event API. Usually you should use dojo/on, and evt.stopPropagation() +
14492 // evt.preventDefault(), rather than this module.
14494 fix: function(/*Event*/ evt
, /*DOMNode*/ sender
){
14496 // normalizes properties on the event object including event
14497 // bubbling methods, keystroke normalization, and x/y positions
14499 // native event object
14501 // node to treat as "currentTarget"
14503 return on
._fixEvent(evt
, sender
);
14505 return evt
; // Event
14508 stop: function(/*Event*/ evt
){
14510 // prevents propagation and clobbers the default action of the
14513 // The event object. If omitted, window.event is used on IE.
14514 if(has("dom-addeventlistener") || (evt
&& evt
.preventDefault
)){
14515 evt
.preventDefault();
14516 evt
.stopPropagation();
14518 evt
= evt
|| window
.event
;
14519 evt
.cancelBubble
= true;
14520 on
._preventDefault
.call(evt
);
14526 dojo
.fixEvent
= ret
.fix
;
14527 dojo
.stopEvent
= ret
.stop
;
14534 'dojo/main':function(){
14536 "./_base/kernel", // kernel.isAsync
14546 "./_base/Deferred",
14549 "./has!dojo-firebug?./_firebug/firebug",
14552 ], function(kernel
, has
, require
, sniff
, lang
, array
, config
, ready
){
14556 // This is the package main module for the dojo package; it loads dojo base appropriate for the execution environment.
14558 // the preferred way to load the dojo firebug console is by setting has("dojo-firebug") true in dojoConfig
14559 // the isDebug config switch is for backcompat and will work fine in sync loading mode; it works in
14560 // async mode too, but there's no guarantee when the module is loaded; therefore, if you need a firebug
14561 // console guaranteed at a particular spot in an app, either set config.has["dojo-firebug"] true before
14562 // loading dojo.js or explicitly include dojo/_firebug/firebug in a dependency list.
14563 if(config
.isDebug
){
14564 require(["./_firebug/firebug"]);
14567 // dojoConfig.require is deprecated; use the loader configuration property deps
14568 1 || has
.add("dojo-config-require", 1);
14570 var deps
= config
.require
;
14572 // config.require may be dot notation
14573 deps
= array
.map(lang
.isArray(deps
) ? deps
: [deps
], function(item
){ return item
.replace(/\./g, "/"); });
14574 if(kernel
.isAsync
){
14577 // this is a bit janky; in 1.6- dojo is defined before these requires are applied; but in 1.7+
14578 // dojo isn't defined until returning from this module; this is only a problem in sync mode
14579 // since we're in sync mode, we know we've got our loader with its priority ready queue
14580 ready(1, function(){require(deps
);});
14589 'dojo/sniff':function(){
14590 define(["./has"], function(has
){
14597 // This module sets has() flags based on the current browser.
14598 // It returns the has() function.
14605 dav
= n
.appVersion
,
14606 tv
= parseFloat(dav
);
14608 has
.add("air", dua
.indexOf("AdobeAIR") >= 0),
14609 has
.add("khtml", dav
.indexOf("Konqueror") >= 0 ? tv
: undefined);
14610 has
.add("webkit", parseFloat(dua
.split("WebKit/")[1]) || undefined);
14611 has
.add("chrome", parseFloat(dua
.split("Chrome/")[1]) || undefined);
14612 has
.add("safari", dav
.indexOf("Safari")>=0 && !has("chrome") ? parseFloat(dav
.split("Version/")[1]) : undefined);
14613 has
.add("mac", dav
.indexOf("Macintosh") >= 0);
14614 has
.add("quirks", document
.compatMode
== "BackCompat");
14615 has
.add("ios", /iPhone|iPod|iPad/.test(dua
));
14616 has
.add("android", parseFloat(dua
.split("Android ")[1]) || undefined);
14618 if(!has("webkit")){
14620 if(dua
.indexOf("Opera") >= 0){
14621 // see http://dev.opera.com/articles/view/opera-ua-string-changes and http://www.useragentstring.com/pages/Opera/
14622 // 9.8 has both styles; <9.8, 9.9 only old style
14623 has
.add("opera", tv
>= 9.8 ? parseFloat(dua
.split("Version/")[1]) || tv
: tv
);
14626 // Mozilla and firefox
14627 if(dua
.indexOf("Gecko") >= 0 && !has("khtml") && !has("webkit")){
14628 has
.add("mozilla", tv
);
14630 if(has("mozilla")){
14631 //We really need to get away from this. Consider a sane isGecko approach for the future.
14632 has
.add("ff", parseFloat(dua
.split("Firefox/")[1] || dua
.split("Minefield/")[1]) || undefined);
14636 if(document
.all
&& !has("opera")){
14637 var isIE
= parseFloat(dav
.split("MSIE ")[1]) || undefined;
14639 //In cases where the page has an HTTP header or META tag with
14640 //X-UA-Compatible, then it is in emulation mode.
14641 //Make sure isIE reflects the desired version.
14642 //document.documentMode of 5 means quirks mode.
14643 //Only switch the value if documentMode's major version
14644 //is different from isIE's major version.
14645 var mode
= document
.documentMode
;
14646 if(mode
&& mode
!= 5 && Math
.floor(isIE
) != mode
){
14650 has
.add("ie", isIE
);
14654 has
.add("wii", typeof opera
!= "undefined" && opera
.wiiremote
);
14662 'dojo/request/handlers':function(){
14668 ], function(JSON
, kernel
, array
, has
){
14669 has
.add('activex', typeof ActiveXObject
!== 'undefined');
14672 if(has('activex')){
14673 // GUIDs obtained from http://msdn.microsoft.com/en-us/library/ms757837(VS.85).aspx
14675 'Msxml2.DOMDocument.6.0',
14676 'Msxml2.DOMDocument.4.0',
14677 'MSXML2.DOMDocument.3.0',
14678 'MSXML.DOMDocument' // 2.0
14681 handleXML = function(response
){
14682 var result
= response
.data
;
14684 if(!result
|| !result
.documentElement
){
14685 var text
= response
.text
;
14686 array
.some(dp
, function(p
){
14688 var dom
= new ActiveXObject(p
);
14692 }catch(e
){ return false; }
14702 'javascript': function(response
){
14703 return kernel
.eval(response
.text
|| '');
14705 'json': function(response
){
14706 return JSON
.parse(response
.text
|| null);
14711 function handle(response
){
14712 var handler
= handlers
[response
.options
.handleAs
];
14714 response
.data
= handler
? handler(response
) : (response
.data
|| response
.text
);
14719 handle
.register = function(name
, handler
){
14720 handlers
[name
] = handler
;
14727 'dojo/ready':function(){
14728 define("dojo/ready", ["./_base/kernel", "./has", "require", "./domReady", "./_base/lang"], function(dojo
, has
, require
, domReady
, lang
){
14732 // This module should be unnecessary in dojo 2.0
14735 // truthy if DOMContentLoaded or better (e.g., window.onload fired) has been achieved
14738 // a function to call to cause onLoad to be called when all requested modules have been loaded
14739 requestCompleteSignal
,
14741 // The queue of functions waiting to execute as soon as dojo.ready conditions satisfied
14744 // prevent recursion in onLoad
14745 onLoadRecursiveGuard
= 0,
14747 handleDomReady = function(){
14749 dojo
._postLoad
= dojo
.config
.afterOnLoad
= true;
14751 requestCompleteSignal(onLoad
);
14755 // run the next function queued with dojo.ready
14756 onLoad = function(){
14757 if(isDomReady
&& !onLoadRecursiveGuard
&& loadQ
.length
){
14758 //guard against recursions into this function
14759 onLoadRecursiveGuard
= 1;
14760 var f
= loadQ
.shift();
14764 // FIXME: signal the error via require.on
14766 onLoadRecursiveGuard
= 0;
14768 onLoadRecursiveGuard
= 0;
14770 requestCompleteSignal(onLoad
);
14775 require
.on("idle", onLoad
);
14776 requestCompleteSignal = function(){
14777 if(require
.idle()){
14779 } // else do nothing, onLoad will be called with the next idle signal
14782 var ready
= dojo
.ready
= dojo
.addOnLoad = function(priority
, context
, callback
){
14784 // Add a function to execute on DOM content loaded and all requested modules have arrived and been evaluated.
14785 // In most cases, the `domReady` plug-in should suffice and this method should not be needed.
14786 // priority: Integer?
14787 // The order in which to exec this callback relative to other callbacks, defaults to 1000
14788 // context: Object?|Function
14789 // The context in which to run execute callback, or a callback if not using context
14790 // callback: Function?
14791 // The function to execute.
14794 // Simple DOM and Modules ready syntax
14795 // | require(["dojo/ready"], function(ready){
14796 // | ready(function(){ alert("Dom ready!"); });
14800 // Using a priority
14801 // | require(["dojo/ready"], function(ready){
14802 // | ready(2, function(){ alert("low priority ready!"); })
14807 // | require(["dojo/ready"], function(ready){
14808 // | ready(foo, function(){
14809 // | // in here, this == foo
14814 // Using dojo/hitch style args:
14815 // | require(["dojo/ready"], function(ready){
14816 // | var foo = { dojoReady: function(){ console.warn(this, "dojo dom and modules ready."); } };
14817 // | ready(foo, "dojoReady");
14820 var hitchArgs
= lang
._toArray(arguments
);
14821 if(typeof priority
!= "number"){
14822 callback
= context
;
14823 context
= priority
;
14828 callback
= callback
?
14829 lang
.hitch
.apply(dojo
, hitchArgs
) :
14833 callback
.priority
= priority
;
14834 for(var i
= 0; i
< loadQ
.length
&& priority
>= loadQ
[i
].priority
; i
++){}
14835 loadQ
.splice(i
, 0, callback
);
14836 requestCompleteSignal();
14839 1 || has
.add("dojo-config-addOnLoad", 1);
14841 var dca
= dojo
.config
.addOnLoad
;
14843 ready
[(lang
.isArray(dca
) ? "apply" : "call")](dojo
, dca
);
14847 if( 1 && dojo
.config
.parseOnLoad
&& !dojo
.isAsync
){
14848 ready(99, function(){
14850 dojo
.deprecated("Add explicit require(['dojo/parser']);", "", "2.0");
14851 require(["dojo/parser"]);
14857 domReady(handleDomReady
);
14866 'dojo/aspect':function(){
14867 define("dojo/aspect", [], function(){
14873 var undefined, nextId
= 0;
14874 function advise(dispatcher
, type
, advice
, receiveArguments
){
14875 var previous
= dispatcher
[type
];
14876 var around
= type
== "around";
14879 var advised
= advice(function(){
14880 return previous
.advice(this, arguments
);
14883 remove: function(){
14884 signal
.cancelled
= true;
14886 advice: function(target
, args
){
14887 return signal
.cancelled
?
14888 previous
.advice(target
, args
) : // cancelled, skip to next one
14889 advised
.apply(target
, args
); // called the advised function
14893 // create the remove handler
14895 remove: function(){
14896 var previous
= signal
.previous
;
14897 var next
= signal
.next
;
14898 if(!next
&& !previous
){
14899 delete dispatcher
[type
];
14902 previous
.next
= next
;
14904 dispatcher
[type
] = next
;
14907 next
.previous
= previous
;
14913 receiveArguments
: receiveArguments
14916 if(previous
&& !around
){
14917 if(type
== "after"){
14918 // add the listener to the end of the list
14919 // note that we had to change this loop a little bit to workaround a bizarre IE10 JIT bug
14920 while(previous
.next
&& (previous
= previous
.next
)){}
14921 previous
.next
= signal
;
14922 signal
.previous
= previous
;
14923 }else if(type
== "before"){
14924 // add to beginning
14925 dispatcher
[type
] = signal
;
14926 signal
.next
= previous
;
14927 previous
.previous
= signal
;
14930 // around or first one just replaces
14931 dispatcher
[type
] = signal
;
14935 function aspect(type
){
14936 return function(target
, methodName
, advice
, receiveArguments
){
14937 var existing
= target
[methodName
], dispatcher
;
14938 if(!existing
|| existing
.target
!= target
){
14939 // no dispatcher in place
14940 target
[methodName
] = dispatcher = function(){
14941 var executionId
= nextId
;
14943 var args
= arguments
;
14944 var before
= dispatcher
.before
;
14946 args
= before
.advice
.apply(this, args
) || args
;
14947 before
= before
.next
;
14950 if(dispatcher
.around
){
14951 var results
= dispatcher
.around
.advice(this, args
);
14954 var after
= dispatcher
.after
;
14955 while(after
&& after
.id
< executionId
){
14956 if(after
.receiveArguments
){
14957 var newResults
= after
.advice
.apply(this, args
);
14958 // change the return value only if a new value was returned
14959 results
= newResults
=== undefined ? results
: newResults
;
14961 results
= after
.advice
.call(this, results
, args
);
14963 after
= after
.next
;
14968 dispatcher
.around
= {advice: function(target
, args
){
14969 return existing
.apply(target
, args
);
14972 dispatcher
.target
= target
;
14974 var results
= advise((dispatcher
|| existing
), type
, advice
, receiveArguments
);
14980 // TODOC: after/before/around return object
14982 var after
= aspect("after");
14984 after = function(target, methodName, advice, receiveArguments){
14986 // The "after" export of the aspect module is a function that can be used to attach
14987 // "after" advice to a method. This function will be executed after the original method
14988 // is executed. By default the function will be called with a single argument, the return
14989 // value of the original method, or the the return value of the last executed advice (if a previous one exists).
14990 // The fourth (optional) argument can be set to true to so the function receives the original
14991 // arguments (from when the original method was called) rather than the return value.
14992 // If there are multiple "after" advisors, they are executed in the order they were registered.
14994 // This is the target object
14995 // methodName: String
14996 // This is the name of the method to attach to.
14997 // advice: Function
14998 // This is function to be called after the original method
14999 // receiveArguments: Boolean?
15000 // If this is set to true, the advice function receives the original arguments (from when the original mehtod
15001 // was called) rather than the return value of the original/previous method.
15003 // A signal object that can be used to cancel the advice. If remove() is called on this signal object, it will
15004 // stop the advice function from being executed.
15008 var before
= aspect("before");
15010 before = function(target, methodName, advice){
15012 // The "before" export of the aspect module is a function that can be used to attach
15013 // "before" advice to a method. This function will be executed before the original method
15014 // is executed. This function will be called with the arguments used to call the method.
15015 // This function may optionally return an array as the new arguments to use to call
15016 // the original method (or the previous, next-to-execute before advice, if one exists).
15017 // If the before method doesn't return anything (returns undefined) the original arguments
15018 // will be preserved.
15019 // If there are multiple "before" advisors, they are executed in the reverse order they were registered.
15021 // This is the target object
15022 // methodName: String
15023 // This is the name of the method to attach to.
15024 // advice: Function
15025 // This is function to be called before the original method
15029 var around
= aspect("around");
15031 around = function(target, methodName, advice){
15033 // The "around" export of the aspect module is a function that can be used to attach
15034 // "around" advice to a method. The advisor function is immediately executed when
15035 // the around() is called, is passed a single argument that is a function that can be
15036 // called to continue execution of the original method (or the next around advisor).
15037 // The advisor function should return a function, and this function will be called whenever
15038 // the method is called. It will be called with the arguments used to call the method.
15039 // Whatever this function returns will be returned as the result of the method call (unless after advise changes it).
15041 // If there are multiple "around" advisors, the most recent one is executed first,
15042 // which can then delegate to the next one and so on. For example:
15043 // | around(obj, "foo", function(originalFoo){
15044 // | return function(){
15045 // | var start = new Date().getTime();
15046 // | var results = originalFoo.apply(this, arguments); // call the original
15047 // | var end = new Date().getTime();
15048 // | console.log("foo execution took " + (end - start) + " ms");
15049 // | return results;
15053 // This is the target object
15054 // methodName: String
15055 // This is the name of the method to attach to.
15056 // advice: Function
15057 // This is function to be called around the original method
15063 // provides aspect oriented programming functionality, allowing for
15064 // one to add before, around, or after advice on existing methods.
15066 // | define(["dojo/aspect"], function(aspect){
15067 // | var signal = aspect.after(targetObject, "methodName", function(someArgument){
15068 // | this will be called when targetObject.methodName() is called, after the original function is called
15072 // The returned signal object can be used to cancel the advice.
15073 // | signal.remove(); // this will stop the advice from being executed anymore
15074 // | aspect.before(targetObject, "methodName", function(someArgument){
15075 // | // this will be called when targetObject.methodName() is called, before the original function is called
15085 'dojo/_base/connect':function(){
15086 define(["./kernel", "../on", "../topic", "../aspect", "./event", "../mouse", "./sniff", "./lang", "../keys"], function(dojo
, on
, hub
, aspect
, eventModule
, mouse
, has
, lang
){
15088 // dojo/_base/connect
15090 has
.add("events-keypress-typed", function(){ // keypresses should only occur a printable character is hit
15091 var testKeyEvent
= {charCode
: 0};
15093 testKeyEvent
= document
.createEvent("KeyboardEvent");
15094 (testKeyEvent
.initKeyboardEvent
|| testKeyEvent
.initKeyEvent
).call(testKeyEvent
, "keypress", true, true, null, false, false, false, false, 9, 3);
15096 return testKeyEvent
.charCode
== 0 && !has("opera");
15099 function connect_(obj
, event
, context
, method
, dontFix
){
15100 method
= lang
.hitch(context
, method
);
15101 if(!obj
|| !(obj
.addEventListener
|| obj
.attachEvent
)){
15102 // it is a not a DOM node and we are using the dojo.connect style of treating a
15103 // method like an event, must go right to aspect
15104 return aspect
.after(obj
|| dojo
.global
, event
, method
, true);
15106 if(typeof event
== "string" && event
.substring(0, 2) == "on"){
15107 event
= event
.substring(2);
15114 // dojo.connect has special handling for these event types
15119 event
= mouse
.enter
;
15122 event
= mouse
.leave
;
15126 return on(obj
, event
, method
, dontFix
);
15145 var evtCopyKey
= has("mac") ? "metaKey" : "ctrlKey";
15148 var _synthesizeEvent = function(evt
, props
){
15149 var faux
= lang
.mixin({}, evt
, props
);
15151 // FIXME: would prefer to use lang.hitch: lang.hitch(evt, evt.preventDefault);
15152 // but it throws an error when preventDefault is invoked on Safari
15153 // does Event.preventDefault not support "apply" on Safari?
15154 faux
.preventDefault = function(){ evt
.preventDefault(); };
15155 faux
.stopPropagation = function(){ evt
.stopPropagation(); };
15158 function setKeyChar(evt
){
15159 evt
.keyChar
= evt
.charCode
? String
.fromCharCode(evt
.charCode
) : '';
15160 evt
.charOrCode
= evt
.keyChar
|| evt
.keyCode
;
15163 if(has("events-keypress-typed")){
15164 // this emulates Firefox's keypress behavior where every keydown can correspond to a keypress
15165 var _trySetKeyCode = function(e
, code
){
15167 // squelch errors when keyCode is read-only
15168 // (e.g. if keyCode is ctrl or shift)
15169 return (e
.keyCode
= code
);
15174 keypress = function(object
, listener
){
15175 var keydownSignal
= on(object
, "keydown", function(evt
){
15176 // munge key/charCode
15178 // These are Windows Virtual Key Codes
15179 // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/WinUI/WindowsUserInterface/UserInput/VirtualKeyCodes.asp
15180 var unprintable
= (k
!=13) && k
!=32 && (k
!=27||!has("ie")) && (k
<48||k
>90) && (k
<96||k
>111) && (k
<186||k
>192) && (k
<219||k
>222) && k
!=229;
15181 // synthesize keypress for most unprintables and CTRL-keys
15182 if(unprintable
||evt
.ctrlKey
){
15183 var c
= unprintable
? 0 : k
;
15186 return listener
.call(evt
.currentTarget
, evt
); // IE will post CTRL-BREAK, CTRL-ENTER as keypress natively
15187 }else if(c
>95 && c
<106){
15188 c
-= 48; // map CTRL-[numpad 0-9] to ASCII
15189 }else if((!evt
.shiftKey
)&&(c
>=65&&c
<=90)){
15190 c
+= 32; // map CTRL-[A-Z] to lowercase
15192 c
= _punctMap
[c
] || c
; // map other problematic CTRL combinations to ASCII
15195 // simulate a keypress event
15196 var faux
= _synthesizeEvent(evt
, {type
: 'keypress', faux
: true, charCode
: c
});
15197 listener
.call(evt
.currentTarget
, faux
);
15199 _trySetKeyCode(evt
, faux
.keyCode
);
15203 var keypressSignal
= on(object
, "keypress", function(evt
){
15204 var c
= evt
.charCode
;
15206 evt
= _synthesizeEvent(evt
, {charCode
: c
, faux
: true});
15207 return listener
.call(this, evt
);
15210 remove: function(){
15211 keydownSignal
.remove();
15212 keypressSignal
.remove();
15218 keypress = function(object
, listener
){
15219 return on(object
, "keypress", function(evt
){
15222 c
=99; // Mozilla maps CTRL-BREAK to CTRL-c
15224 // can't trap some keys at all, like INSERT and DELETE
15225 // there is no differentiating info between DELETE and ".", or INSERT and "-"
15226 c
= c
<32 && !evt
.shiftKey
? 0 : c
;
15227 if(evt
.ctrlKey
&& !evt
.shiftKey
&& c
>=65 && c
<=90){
15228 // lowercase CTRL-[A-Z] keys
15231 return listener
.call(this, _synthesizeEvent(evt
, { charCode
: c
}));
15235 keypress = function(object
, listener
){
15236 return on(object
, "keypress", function(evt
){
15238 return listener
.call(this, evt
);
15246 // This module defines the dojo.connect API.
15247 // This modules also provides keyboard event handling helpers.
15248 // This module exports an extension event for emulating Firefox's keypress handling.
15249 // However, this extension event exists primarily for backwards compatibility and
15250 // is not recommended. WebKit and IE uses an alternate keypress handling (only
15251 // firing for printable characters, to distinguish from keydown events), and most
15252 // consider the WebKit/IE behavior more desirable.
15254 _keypress
:keypress
,
15256 connect:function(obj
, event
, context
, method
, dontFix
){
15258 // `dojo.connect` is a deprecated event handling and delegation method in
15259 // Dojo. It allows one function to "listen in" on the execution of
15260 // any other, triggering the second whenever the first is called. Many
15261 // listeners may be attached to a function, and source functions may
15262 // be either regular function calls or DOM events.
15265 // Connects listeners to actions, so that after event fires, a
15266 // listener is called with the same arguments passed to the original
15269 // Since `dojo.connect` allows the source of events to be either a
15270 // "regular" JavaScript function or a DOM event, it provides a uniform
15271 // interface for listening to all the types of events that an
15272 // application is likely to deal with though a single, unified
15273 // interface. DOM programmers may want to think of it as
15274 // "addEventListener for everything and anything".
15276 // When setting up a connection, the `event` parameter must be a
15277 // string that is the name of the method/event to be listened for. If
15278 // `obj` is null, `kernel.global` is assumed, meaning that connections
15279 // to global methods are supported but also that you may inadvertently
15280 // connect to a global by passing an incorrect object name or invalid
15283 // `dojo.connect` generally is forgiving. If you pass the name of a
15284 // function or method that does not yet exist on `obj`, connect will
15285 // not fail, but will instead set up a stub method. Similarly, null
15286 // arguments may simply be omitted such that fewer than 4 arguments
15287 // may be required to set up a connection See the examples for details.
15289 // The return value is a handle that is needed to
15290 // remove this connection with `dojo.disconnect`.
15293 // The source object for the event function.
15294 // Defaults to `kernel.global` if null.
15295 // If obj is a DOM node, the connection is delegated
15296 // to the DOM event manager (unless dontFix is true).
15299 // String name of the event function in obj.
15300 // I.e. identifies a property `obj[event]`.
15302 // context: Object|null
15303 // The object that method will receive as "this".
15305 // If context is null and method is a function, then method
15306 // inherits the context of event.
15308 // If method is a string then context must be the source
15309 // object object for method (context[method]). If context is null,
15310 // kernel.global is used.
15312 // method: String|Function
15313 // A function reference, or name of a function in context.
15314 // The function identified by method fires after event does.
15315 // method receives the same arguments as the event.
15316 // See context argument comments for information on method's scope.
15318 // dontFix: Boolean?
15319 // If obj is a DOM node, set dontFix to true to prevent delegation
15320 // of this connection to the DOM event manager.
15323 // When obj.onchange(), do ui.update():
15324 // | dojo.connect(obj, "onchange", ui, "update");
15325 // | dojo.connect(obj, "onchange", ui, ui.update); // same
15328 // Using return value for disconnect:
15329 // | var link = dojo.connect(obj, "onchange", ui, "update");
15331 // | dojo.disconnect(link);
15334 // When onglobalevent executes, watcher.handler is invoked:
15335 // | dojo.connect(null, "onglobalevent", watcher, "handler");
15338 // When ob.onCustomEvent executes, customEventHandler is invoked:
15339 // | dojo.connect(ob, "onCustomEvent", null, "customEventHandler");
15340 // | dojo.connect(ob, "onCustomEvent", "customEventHandler"); // same
15343 // When ob.onCustomEvent executes, customEventHandler is invoked
15344 // with the same scope (this):
15345 // | dojo.connect(ob, "onCustomEvent", null, customEventHandler);
15346 // | dojo.connect(ob, "onCustomEvent", customEventHandler); // same
15349 // When globalEvent executes, globalHandler is invoked
15350 // with the same scope (this):
15351 // | dojo.connect(null, "globalEvent", null, globalHandler);
15352 // | dojo.connect("globalEvent", globalHandler); // same
15354 // normalize arguments
15355 var a
=arguments
, args
=[], i
=0;
15356 // if a[0] is a String, obj was omitted
15357 args
.push(typeof a
[0] == "string" ? null : a
[i
++], a
[i
++]);
15358 // if the arg-after-next is a String or Function, context was NOT omitted
15360 args
.push(typeof a1
== "string" || typeof a1
== "function" ? a
[i
++] : null, a
[i
++]);
15361 // absorb any additional arguments
15362 for(var l
=a
.length
; i
<l
; i
++){ args
.push(a
[i
]); }
15363 return connect_
.apply(this, args
);
15366 disconnect:function(handle
){
15368 // Remove a link created by dojo.connect.
15370 // Removes the connection between event and the method referenced by handle.
15372 // the return value of the dojo.connect call that created the connection.
15379 subscribe:function(topic
, context
, method
){
15381 // Attach a listener to a named topic. The listener function is invoked whenever the
15382 // named topic is published (see: dojo.publish).
15383 // Returns a handle which is needed to unsubscribe this listener.
15385 // The topic to which to subscribe.
15386 // context: Object?
15387 // Scope in which method will be invoked, or null for default scope.
15388 // method: String|Function
15389 // The name of a function in context, or a function reference. This is the function that
15390 // is invoked when topic is published.
15392 // | dojo.subscribe("alerts", null, function(caption, message){ alert(caption + "\n" + message); });
15393 // | dojo.publish("alerts", [ "read this", "hello world" ]);
15394 return hub
.subscribe(topic
, lang
.hitch(context
, method
));
15397 publish:function(topic
, args
){
15399 // Invoke all listener method subscribed to topic.
15401 // The name of the topic to publish.
15403 // An array of arguments. The arguments will be applied
15404 // to each topic subscriber (as first class parameters, via apply).
15406 // | dojo.subscribe("alerts", null, function(caption, message){ alert(caption + "\n" + message); };
15407 // | dojo.publish("alerts", [ "read this", "hello world" ]);
15408 return hub
.publish
.apply(hub
, [topic
].concat(args
));
15411 connectPublisher:function(topic
, obj
, event
){
15413 // Ensure that every time obj.event() is called, a message is published
15414 // on the topic. Returns a handle which can be passed to
15415 // dojo.disconnect() to disable subsequent automatic publication on
15418 // The name of the topic to publish.
15420 // The source object for the event function. Defaults to kernel.global
15423 // The name of the event function in obj.
15424 // I.e. identifies a property obj[event].
15426 // | dojo.connectPublisher("/ajax/start", dojo, "xhrGet");
15427 var pf = function(){ connect
.publish(topic
, arguments
); };
15428 return event
? connect
.connect(obj
, event
, pf
) : connect
.connect(obj
, pf
); //Handle
15431 isCopyKey: function(e
){
15433 // Checks an event for the copy key (meta on Mac, and ctrl anywhere else)
15435 // Event object to examine
15436 return e
[evtCopyKey
]; // Boolean
15440 connect
.unsubscribe
= connect
.disconnect
;
15442 connect.unsubscribe = function(handle){
15444 // Remove a topic listener.
15446 // The handle returned from a call to subscribe.
15448 // | var alerter = dojo.subscribe("alerts", null, function(caption, message){ alert(caption + "\n" + message); };
15450 // | dojo.unsubscribe(alerter);
15454 1 && lang
.mixin(dojo
, connect
);
15462 'dojo/errors/CancelError':function(){
15463 define(["./create"], function(create
){
15465 // dojo/errors/CancelError
15470 // Default error if a promise is canceled without a reason.
15474 return create("CancelError", null, null, { dojoType
: "cancel" });
15479 // must use this.require to make this work in node.js
15480 var require
= this.require
;
15481 // consume the cached dojo layer
15482 require({cache
:{}});
15483 !require
.async
&& require(["dojo"]);
15484 require
.boot
&& require
.apply(null, require
.boot
);