|
|
What this is
This file is included in the DevDaily.com
"Java Source Code
Warehouse" project. The intent of this project is to help you "Learn
Java by Example" TM.
Other links
The source code
/*
Copyright (c) 2004-2008, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/book/dojo-book-0-9/introduction/licensing
*/
/*
This is a compiled version of Dojo, built for deployment and not for
development. To get an editable version, please visit:
http://dojotoolkit.org
for documentation and information on getting the source.
*/
;(function(){
/*
dojo, dijit, and dojox must always be the first three, and in that order.
djConfig.scopeMap = [
["dojo", "fojo"],
["dijit", "fijit"],
["dojox", "fojox"]
]
*/
/**Build will replace this comment with a scoped djConfig **/
//The null below can be relaced by a build-time value used instead of djConfig.scopeMap.
var sMap = null;
//See if new scopes need to be defined.
if((sMap || (typeof djConfig != "undefined" && djConfig.scopeMap)) && (typeof window != "undefined")){
var scopeDef = "", scopePrefix = "", scopeSuffix = "", scopeMap = {}, scopeMapRev = {};
sMap = sMap || djConfig.scopeMap;
for(var i = 0; i < sMap.length; i++){
//Make local variables, then global variables that use the locals.
var newScope = sMap[i];
scopeDef += "var " + newScope[0] + " = {}; " + newScope[1] + " = " + newScope[0] + ";" + newScope[1] + "._scopeName = '" + newScope[1] + "';";
scopePrefix += (i == 0 ? "" : ",") + newScope[0];
scopeSuffix += (i == 0 ? "" : ",") + newScope[1];
scopeMap[newScope[0]] = newScope[1];
scopeMapRev[newScope[1]] = newScope[0];
}
eval(scopeDef + "dojo._scopeArgs = [" + scopeSuffix + "];");
dojo._scopePrefixArgs = scopePrefix;
dojo._scopePrefix = "(function(" + scopePrefix + "){";
dojo._scopeSuffix = "})(" + scopeSuffix + ")";
dojo._scopeMap = scopeMap;
dojo._scopeMapRev = scopeMapRev;
}
/*=====
// note:
// 'djConfig' does not exist under 'dojo.*' so that it can be set before the
// 'dojo' variable exists.
// note:
// Setting any of these variables *after* the library has loaded does
// nothing at all.
djConfig = {
// summary:
// Application code can set the global 'djConfig' prior to loading
// the library to override certain global settings for how dojo works.
//
// isDebug: Boolean
// Defaults to `false`. If set to `true`, ensures that Dojo provides
// extende debugging feedback via Firebug. If Firebug is not available
// on your platform, setting `isDebug` to `true` will force Dojo to
// pull in (and display) the version of Firebug Lite which is
// integrated into the Dojo distribution, thereby always providing a
// debugging/logging console when `isDebug` is enabled. Note that
// Firebug's `console.*` methods are ALWAYS defined by Dojo. If
// `isDebug` is false and you are on a platform without Firebug, these
// methods will be defined as no-ops.
isDebug: false,
// debugAtAllCosts: Boolean
// Defaults to `false`. If set to `true`, this triggers an alternate
// mode of the package system in which dependencies are detected and
// only then are resources evaluated in dependency order via
// `<script>` tag inclusion. This may double-request resources and
// cause problems with scripts which expect `dojo.require()` to
// preform synchronously. `debugAtAllCosts` can be an invaluable
// debugging aid, but when using it, ensure that all code which
// depends on Dojo modules is wrapped in `dojo.addOnLoad()` handlers.
// Due to the somewhat unpredictable side-effects of using
// `debugAtAllCosts`, it is strongly recommended that you enable this
// flag as a last resort. `debugAtAllCosts` has no effect when loading
// resources across domains. For usage information, see the
// [Dojo Book](http://dojotoolkit.org/book/book-dojo/part-4-meta-dojo-making-your-dojo-code-run-faster-and-better/debugging-facilities/deb)
debugAtAllCosts: false,
// locale: String
// The locale to assume for loading localized resources in this page,
// specified according to [RFC 3066](http://www.ietf.org/rfc/rfc3066.txt).
// Must be specified entirely in lowercase, e.g. `en-us` and `zh-cn`.
// See the documentation for `dojo.i18n` and `dojo.requireLocalization`
// for details on loading localized resources. If no locale is specified,
// Dojo assumes the locale of the user agent, according to `navigator.userLanguage`
// or `navigator.language` properties.
locale: undefined,
// extraLocale: Array
// No default value. Specifies additional locales whose
// resources should also be loaded alongside the default locale when
// calls to `dojo.requireLocalization()` are processed.
extraLocale: undefined,
// baseUrl: String
// The directory in which `dojo.js` is located. Under normal
// conditions, Dojo auto-detects the correct location from which it
// was loaded. You may need to manually configure `baseUrl` in cases
// where you have renamed `dojo.js` or in which `<base>` tags confuse
// some browsers (e.g., IE 6). The variable `dojo.baseUrl` is assigned
// either the value of `djConfig.baseUrl` if one is provided or the
// auto-detected root if not. Other modules are located relative to
// this path.
baseUrl: undefined,
// modulePaths: Object
// A map of module names to paths relative to `dojo.baseUrl`. The
// key/value pairs correspond directly to the arguments which
// `dojo.registerModulePath` accepts. Specifiying
// `djConfig.modulePaths = { "foo": "../../bar" }` is the equivalent
// of calling `dojo.registerModulePath("foo", "../../bar");`. Multiple
// modules may be configured via `djConfig.modulePaths`.
modulePaths: {},
}
=====*/
(function(){
// firebug stubs
// if((!this["console"])||(!console["firebug"])){
if(!this["console"]){
this.console = {
log: function(){} // no-op
};
}
var cn = [
"assert", "count", "debug", "dir", "dirxml", "error", "group",
"groupEnd", "info", "profile", "profileEnd", "time", "timeEnd",
"trace", "warn", "log"
];
var i=0, tn;
while((tn=cn[i++])){
if(!console[tn]){
(function(){
var tcn = tn+"";
console[tcn] = function(){
var a = Array.apply({}, arguments);
a.unshift(tcn+":");
console.log(a.join(" "));
}
})();
}
}
//TODOC: HOW TO DOC THIS?
// dojo is the root variable of (almost all) our public symbols -- make sure it is defined.
if(typeof dojo == "undefined"){
this.dojo = {
_scopeName: "dojo",
_scopePrefix: "",
_scopePrefixArgs: "",
_scopeSuffix: "",
_scopeMap: {},
_scopeMapRev: {}
};
}
var d = dojo;
//Need placeholders for dijit and dojox for scoping code.
if(typeof dijit == "undefined"){
this.dijit = {_scopeName: "dijit"};
}
if(typeof dojox == "undefined"){
this.dojox = {_scopeName: "dojox"};
}
if(!d._scopeArgs){
d._scopeArgs = [dojo, dijit, dojox];
}
/*=====
dojo.global = {
// summary:
// Alias for the global scope
// (e.g. the window object in a browser).
// description:
// Refer to 'dojo.global' rather than referring to window to ensure your
// code runs correctly in contexts other than web browsers (e.g. Rhino on a server).
}
=====*/
d.global = this;
d.config =/*===== djConfig = =====*/{
isDebug: false,
debugAtAllCosts: false
};
if(typeof djConfig != "undefined"){
for(var opt in djConfig){
d.config[opt] = djConfig[opt];
}
}
var _platforms = ["Browser", "Rhino", "Spidermonkey", "Mobile"];
var t;
while((t=_platforms.shift())){
d["is"+t] = false;
}
/*=====
// Override locale setting, if specified
dojo.locale = {
// summary: the locale as defined by Dojo (read-only)
};
=====*/
dojo.locale = d.config.locale;
var rev = "$Rev: 13141 $".match(/\d+/);
dojo.version = {
// summary:
// version number of dojo
// major: Integer
// Major version. If total version is "1.2.0beta1", will be 1
// minor: Integer
// Minor version. If total version is "1.2.0beta1", will be 2
// patch: Integer
// Patch version. If total version is "1.2.0beta1", will be 0
// flag: String
// Descriptor flag. If total version is "1.2.0beta1", will be "beta1"
// revision: Number
// The SVN rev from which dojo was pulled
major: 0, minor: 0, patch: 0, flag: "dev",
revision: rev ? +rev[0] : 999999, //FIXME: use NaN?
toString: function(){
with(d.version){
return major + "." + minor + "." + patch + flag + " (" + revision + ")"; // String
}
}
}
// Register with the OpenAjax hub
if(typeof OpenAjax != "undefined"){
OpenAjax.hub.registerLibrary(dojo._scopeName, "http://dojotoolkit.org", d.version.toString());
}
dojo._mixin = function(/*Object*/ obj, /*Object*/ props){
// summary:
// Adds all properties and methods of props to obj. This addition
// is "prototype extension safe", so that instances of objects
// will not pass along prototype defaults.
var tobj = {};
for(var x in props){
// the "tobj" condition avoid copying properties in "props"
// inherited from Object.prototype. For example, if obj has a custom
// toString() method, don't overwrite it with the toString() method
// that props inherited from Object.prototype
if(tobj[x] === undefined || tobj[x] != props[x]){
obj[x] = props[x];
}
}
// IE doesn't recognize custom toStrings in for..in
if(d["isIE"] && props){
var p = props.toString;
if(typeof p == "function" && p != obj.toString && p != tobj.toString &&
p != "\nfunction toString() {\n [native code]\n}\n"){
obj.toString = props.toString;
}
}
return obj; // Object
}
dojo.mixin = function(/*Object*/obj, /*Object...*/props){
// summary:
// Adds all properties and methods of props to obj and returns the
// (now modified) obj.
// description:
// `dojo.mixin` can mix multiple source objects into a
// destionation object which is then returned. Unlike regular
// `for...in` iteration, `dojo.mixin` is also smart about avoiding
// extensions which other toolkits may unwisely add to the root
// object prototype
// obj:
// The object to mix properties into. Also the return value.
// props:
// One or more objects whose values are successively copied into
// obj. If more than one of these objects contain the same value,
// the one specified last in the function call will "win".
// example:
// make a shallow copy of an object
// | var copy = dojo.mixin({}, source);
// example:
// many class constructors often take an object which specifies
// values to be configured on the object. In this case, it is
// often simplest to call `dojo.mixin` on the `this` object:
// | dojo.declare("acme.Base", null, {
// | constructor: function(properties){
// | // property configuration:
// | dojo.mixin(this, properties);
// |
// | console.debug(this.quip);
// | // ...
// | },
// | quip: "I wasn't born yesterday, you know - I've seen movies.",
// | // ...
// | });
// |
// | // create an instance of the class and configure it
// | var b = new acme.Base({quip: "That's what it does!" });
// example:
// copy in properties from multiple objects
// | var flattened = dojo.mixin(
// | {
// | name: "Frylock",
// | braces: true,
// | }
// | {
// | name: "Carl Brutanananadilewski"
// | }
// | );
// |
// | // will print "Carl Brutanananadilewski"
// | console.debug(flattened.name);
// | // will print "true"
// | console.debug(flattened.braces);
for(var i=1, l=arguments.length; i<l; i++){
d._mixin(obj, arguments[i]);
}
return obj; // Object
}
dojo._getProp = function(/*Array*/parts, /*Boolean*/create, /*Object*/context){
var obj=context || d.global;
for(var i=0, p; obj && (p=parts[i]); i++){
if(i == 0 && this._scopeMap[p]){
p = this._scopeMap[p];
}
obj = (p in obj ? obj[p] : (create ? obj[p]={} : undefined));
}
return obj; // mixed
}
dojo.setObject = function(/*String*/name, /*Object*/value, /*Object?*/context){
// summary:
// Set a property from a dot-separated string, such as "A.B.C"
// description:
// Useful for longer api chains where you have to test each object in
// the chain, or when you have an object reference in string format.
// Objects are created as needed along `path`. Returns the passed
// value if setting is successful or `undefined` if not.
// name:
// Path to a property, in the form "A.B.C".
// context:
// Optional. Object to use as root of path. Defaults to
// `dojo.global`.
// example:
// set the value of `foo.bar.baz`, regardless of whether
// intermediate objects already exist:
// | dojo.setObject("foo.bar.baz", value);
// example:
// without `dojo.setObject`, we often see code like this:
// | // ensure that intermediate objects are available
// | if(!obj["parent"]){ obj.parent = {}; }
// | if(!obj.parent["child"]){ obj.parent.child= {}; }
// | // now we can safely set the property
// | obj.parent.child.prop = "some value";
// wheras with `dojo.setObject`, we can shorten that to:
// | dojo.setObject("parent.child.prop", "some value", obj);
var parts=name.split("."), p=parts.pop(), obj=d._getProp(parts, true, context);
return obj && p ? (obj[p]=value) : undefined; // Object
}
dojo.getObject = function(/*String*/name, /*Boolean*/create, /*Object*/context){
// summary:
// Get a property from a dot-separated string, such as "A.B.C"
// description:
// Useful for longer api chains where you have to test each object in
// the chain, or when you have an object reference in string format.
// name:
// Path to an property, in the form "A.B.C".
// context:
// Optional. Object to use as root of path. Defaults to
// 'dojo.global'. Null may be passed.
// create:
// Optional. Defaults to `false`. If `true`, Objects will be
// created at any point along the 'path' that is undefined.
return d._getProp(name.split("."), create, context); // Object
}
dojo.exists = function(/*String*/name, /*Object?*/obj){
// summary:
// determine if an object supports a given method
// description:
// useful for longer api chains where you have to test each object in
// the chain
// name:
// Path to an object, in the form "A.B.C".
// obj:
// Object to use as root of path. Defaults to
// 'dojo.global'. Null may be passed.
// example:
// | // define an object
// | var foo = {
// | bar: { }
// | };
// |
// | // search the global scope
// | dojo.exists("foo.bar"); // true
// | dojo.exists("foo.bar.baz"); // false
// |
// | // search from a particular scope
// | dojo.exists("bar", foo); // true
// | dojo.exists("bar.baz", foo); // false
return !!d.getObject(name, false, obj); // Boolean
}
dojo["eval"] = function(/*String*/ scriptFragment){
// summary:
// Perform an evaluation in the global scope. Use this rather than
// calling 'eval()' directly.
// description:
// Placed in a separate function to minimize size of trapped
// exceptions. Calling eval() directly from some other scope may
// complicate tracebacks on some platforms.
// return:
// The result of the evaluation. Often `undefined`
// note:
// - JSC eval() takes an optional second argument which can be 'unsafe'.
// - Mozilla/SpiderMonkey eval() takes an optional second argument which is the
// scope object for new symbols.
// FIXME: investigate Joseph Smarr's technique for IE:
// http://josephsmarr.com/2007/01/31/fixing-eval-to-use-global-scope-in-ie/
// see also:
// http://trac.dojotoolkit.org/ticket/744
return d.global.eval ? d.global.eval(scriptFragment) : eval(scriptFragment); // Object
}
/*=====
dojo.deprecated = function(behaviour, extra, removal){
// summary:
// Log a debug message to indicate that a behavior has been
// deprecated.
// behaviour: String
// The API or behavior being deprecated. Usually in the form
// of "myApp.someFunction()".
// extra: String?
// Text to append to the message. Often provides advice on a
// new function or facility to achieve the same goal during
// the deprecation period.
// removal: String?
// Text to indicate when in the future the behavior will be
// removed. Usually a version number.
// example:
// | dojo.deprecated("myApp.getTemp()", "use myApp.getLocaleTemp() instead", "1.0");
}
dojo.experimental = function(moduleName, extra){
// summary: Marks code as experimental.
// description:
// This can be used to mark a function, file, or module as
// experimental. Experimental code is not ready to be used, and the
// APIs are subject to change without notice. Experimental code may be
// completed deleted without going through the normal deprecation
// process.
// moduleName: String
// The name of a module, or the name of a module file or a specific
// function
// extra: String?
// some additional message for the user
// example:
// | dojo.experimental("dojo.data.Result");
// example:
// | dojo.experimental("dojo.weather.toKelvin()", "PENDING approval from NOAA");
}
=====*/
//Real functions declared in dojo._firebug.firebug.
d.deprecated = d.experimental = function(){};
})();
// vim:ai:ts=4:noet
/*
* loader.js - A bootstrap module. Runs before the hostenv_*.js file. Contains
* all of the package loading methods.
*/
(function(){
var d = dojo;
d.mixin(d, {
_loadedModules: {},
_inFlightCount: 0,
_hasResource: {},
_modulePrefixes: {
dojo: { name: "dojo", value: "." },
// dojox: { name: "dojox", value: "../dojox" },
// dijit: { name: "dijit", value: "../dijit" },
doh: { name: "doh", value: "../util/doh" },
tests: { name: "tests", value: "tests" }
},
_moduleHasPrefix: function(/*String*/module){
// summary: checks to see if module has been established
var mp = this._modulePrefixes;
return !!(mp[module] && mp[module].value); // Boolean
},
_getModulePrefix: function(/*String*/module){
// summary: gets the prefix associated with module
var mp = this._modulePrefixes;
if(this._moduleHasPrefix(module)){
return mp[module].value; // String
}
return module; // String
},
_loadedUrls: [],
//WARNING:
// This variable is referenced by packages outside of bootstrap:
// FloatingPane.js and undo/browser.js
_postLoad: false,
//Egad! Lots of test files push on this directly instead of using dojo.addOnLoad.
_loaders: [],
_unloaders: [],
_loadNotifying: false
});
dojo._loadPath = function(/*String*/relpath, /*String?*/module, /*Function?*/cb){
// summary:
// Load a Javascript module given a relative path
//
// description:
// Loads and interprets the script located at relpath, which is
// relative to the script root directory. If the script is found but
// its interpretation causes a runtime exception, that exception is
// not caught by us, so the caller will see it. We return a true
// value if and only if the script is found.
//
// relpath:
// A relative path to a script (no leading '/', and typically ending
// in '.js').
// module:
// A module whose existance to check for after loading a path. Can be
// used to determine success or failure of the load.
// cb:
// a callback function to pass the result of evaluating the script
var uri = ((relpath.charAt(0) == '/' || relpath.match(/^\w+:/)) ? "" : this.baseUrl) + relpath;
try{
return !module ? this._loadUri(uri, cb) : this._loadUriAndCheck(uri, module, cb); // Boolean
}catch(e){
console.error(e);
return false; // Boolean
}
}
dojo._loadUri = function(/*String*/uri, /*Function?*/cb){
// summary:
// Loads JavaScript from a URI
// description:
// Reads the contents of the URI, and evaluates the contents. This is
// used to load modules as well as resource bundles. Returns true if
// it succeeded. Returns false if the URI reading failed. Throws if
// the evaluation throws.
// uri: a uri which points at the script to be loaded
// cb:
// a callback function to process the result of evaluating the script
// as an expression, typically used by the resource bundle loader to
// load JSON-style resources
if(this._loadedUrls[uri]){
return true; // Boolean
}
var contents = this._getText(uri, true);
if(!contents){ return false; } // Boolean
this._loadedUrls[uri] = true;
this._loadedUrls.push(uri);
if(cb){
contents = '('+contents+')';
}else{
//Only do the scoping if no callback. If a callback is specified,
//it is most likely the i18n bundle stuff.
contents = this._scopePrefix + contents + this._scopeSuffix;
}
if(d.isMoz){ contents += "\r\n//@ sourceURL=" + uri; } // debugging assist for Firebug
var value = d["eval"](contents);
if(cb){ cb(value); }
return true; // Boolean
}
// FIXME: probably need to add logging to this method
dojo._loadUriAndCheck = function(/*String*/uri, /*String*/moduleName, /*Function?*/cb){
// summary: calls loadUri then findModule and returns true if both succeed
var ok = false;
try{
ok = this._loadUri(uri, cb);
}catch(e){
console.error("failed loading " + uri + " with error: " + e);
}
return !!(ok && this._loadedModules[moduleName]); // Boolean
}
dojo.loaded = function(){
// summary:
// signal fired when initial environment and package loading is
// complete. You may use dojo.addOnLoad() or dojo.connect() to
// this method in order to handle initialization tasks that
// require the environment to be initialized. In a browser host,
// declarative widgets will be constructed when this function
// finishes runing.
this._loadNotifying = true;
this._postLoad = true;
var mll = d._loaders;
//Clear listeners so new ones can be added
//For other xdomain package loads after the initial load.
this._loaders = [];
for(var x = 0; x < mll.length; x++){
try{
mll[x]();
}catch(e){
throw e;
console.error("dojo.addOnLoad callback failed: " + e, e); /* let other load events fire, like the parser, but report the error */
}
}
this._loadNotifying = false;
//Make sure nothing else got added to the onload queue
//after this first run. If something did, and we are not waiting for any
//more inflight resources, run again.
if(d._postLoad && d._inFlightCount == 0 && mll.length){
d._callLoaded();
}
}
dojo.unloaded = function(){
// summary:
// signal fired by impending environment destruction. You may use
// dojo.addOnUnload() or dojo.connect() to this method to perform
// page/application cleanup methods.
var mll = this._unloaders;
while(mll.length){
(mll.pop())();
}
}
var onto = function(arr, obj, fn){
if(!fn){
arr.push(obj);
}else if(fn){
var func = (typeof fn == "string") ? obj[fn] : fn;
arr.push(function(){ func.call(obj); });
}
}
dojo.addOnLoad = function(/*Object?*/obj, /*String|Function*/functionName){
// summary:
// Registers a function to be triggered after the DOM has finished
// loading and widgets declared in markup have been instantiated.
// Images and CSS files may or may not have finished downloading when
// the specified function is called. (Note that widgets' CSS and HTML
// code is guaranteed to be downloaded before said widgets are
// instantiated.)
// example:
// | dojo.addOnLoad(functionPointer);
// | dojo.addOnLoad(object, "functionName");
// | dojo.addOnLoad(object, function(){ /* ... */});
onto(d._loaders, obj, functionName);
//Added for xdomain loading. dojo.addOnLoad is used to
//indicate callbacks after doing some dojo.require() statements.
//In the xdomain case, if all the requires are loaded (after initial
//page load), then immediately call any listeners.
if(d._postLoad && d._inFlightCount == 0 && !d._loadNotifying){
d._callLoaded();
}
}
dojo.addOnUnload = function(/*Object?*/obj, /*String|Function?*/functionName){
// summary:
// registers a function to be triggered when the page unloads
// example:
// | dojo.addOnUnload(functionPointer)
// | dojo.addOnUnload(object, "functionName")
// | dojo.addOnUnload(object, function(){ /* ... */});
onto(d._unloaders, obj, functionName);
}
dojo._modulesLoaded = function(){
if(d._postLoad){ return; }
if(d._inFlightCount > 0){
console.warn("files still in flight!");
return;
}
d._callLoaded();
}
dojo._callLoaded = function(){
// The "object" check is for IE, and the other opera check fixes an
// issue in Opera where it could not find the body element in some
// widget test cases. For 0.9, maybe route all browsers through the
// setTimeout (need protection still for non-browser environments
// though). This might also help the issue with FF 2.0 and freezing
// issues where we try to do sync xhr while background css images are
// being loaded (trac #2572)? Consider for 0.9.
if(typeof setTimeout == "object" || (dojo.config.useXDomain && d.isOpera)){
if(dojo.isAIR){
setTimeout(function(){dojo.loaded();}, 0);
}else{
setTimeout(dojo._scopeName + ".loaded();", 0);
}
}else{
d.loaded();
}
}
dojo._getModuleSymbols = function(/*String*/modulename){
// summary:
// Converts a module name in dotted JS notation to an array
// representing the path in the source tree
var syms = modulename.split(".");
for(var i = syms.length; i>0; i--){
var parentModule = syms.slice(0, i).join(".");
if((i==1) && !this._moduleHasPrefix(parentModule)){
// Support default module directory (sibling of dojo) for top-level modules
syms[0] = "../" + syms[0];
}else{
var parentModulePath = this._getModulePrefix(parentModule);
if(parentModulePath != parentModule){
syms.splice(0, i, parentModulePath);
break;
}
}
}
// console.debug(syms);
return syms; // Array
}
dojo._global_omit_module_check = false;
dojo._loadModule = dojo.require = function(/*String*/moduleName, /*Boolean?*/omitModuleCheck){
// summary:
// loads a Javascript module from the appropriate URI
// moduleName:
// module name to load. Module paths are de-referenced by dojo's
// internal mapping of locations to names and are disambiguated by
// longest prefix. See `dojo.registerModulePath()` for details on
// registering new modules.
// omitModuleCheck:
// if `true`, omitModuleCheck skips the step of ensuring that the
// loaded file actually defines the symbol it is referenced by.
// For example if it called as `dojo._loadModule("a.b.c")` and the
// file located at `a/b/c.js` does not define an object `a.b.c`,
// and exception will be throws whereas no exception is raised
// when called as `dojo._loadModule("a.b.c", true)`
// description:
// `dojo._loadModule("A.B")` first checks to see if symbol A.B is
// defined. If it is, it is simply returned (nothing to do).
//
// If it is not defined, it will look for `A/B.js` in the script root
// directory.
//
// `dojo._loadModule` throws an excpetion if it cannot find a file
// to load, or if the symbol `A.B` is not defined after loading.
//
// It returns the object `A.B`.
//
// `dojo._loadModule()` does nothing about importing symbols into
// the current namespace. It is presumed that the caller will
// take care of that. For example, to import all symbols into a
// local block, you might write:
//
// | with (dojo._loadModule("A.B")) {
// | ...
// | }
//
// And to import just the leaf symbol to a local variable:
//
// | var B = dojo._loadModule("A.B");
// | ...
// returns: the required namespace object
omitModuleCheck = this._global_omit_module_check || omitModuleCheck;
//Check if it is already loaded.
var module = this._loadedModules[moduleName];
if(module){
return module;
}
// convert periods to slashes
var relpath = this._getModuleSymbols(moduleName).join("/") + '.js';
var modArg = (!omitModuleCheck) ? moduleName : null;
var ok = this._loadPath(relpath, modArg);
if(!ok && !omitModuleCheck){
throw new Error("Could not load '" + moduleName + "'; last tried '" + relpath + "'");
}
// check that the symbol was defined
// Don't bother if we're doing xdomain (asynchronous) loading.
if(!omitModuleCheck && !this._isXDomain){
// pass in false so we can give better error
module = this._loadedModules[moduleName];
if(!module){
throw new Error("symbol '" + moduleName + "' is not defined after loading '" + relpath + "'");
}
}
return module;
}
dojo.provide = function(/*String*/ resourceName){
// summary:
// Each javascript source file must have at least one
// `dojo.provide()` call at the top of the file, corresponding to
// the file name. For example, `js/dojo/foo.js` must have
// `dojo.provide("dojo.foo");` before any calls to
// `dojo.require()` are made.
// description:
// Each javascript source file is called a resource. When a
// resource is loaded by the browser, `dojo.provide()` registers
// that it has been loaded.
//
// For backwards compatibility reasons, in addition to registering
// the resource, `dojo.provide()` also ensures that the javascript
// object for the module exists. For example,
// `dojo.provide("dojox.data.FlickrStore")`, in addition to
// registering that `FlickrStore.js` is a resource for the
// `dojox.data` module, will ensure that the `dojox.data`
// javascript object exists, so that calls like
// `dojo.data.foo = function(){ ... }` don't fail.
//
// In the case of a build where multiple javascript source files
// are combined into one bigger file (similar to a .lib or .jar
// file), that file may contain multiple dojo.provide() calls, to
// note that it includes multiple resources.
//Make sure we have a string.
resourceName = resourceName + "";
return (d._loadedModules[resourceName] = d.getObject(resourceName, true)); // Object
}
//Start of old bootstrap2:
dojo.platformRequire = function(/*Object*/modMap){
// summary:
// require one or more modules based on which host environment
// Dojo is currently operating in
// description:
// This method takes a "map" of arrays which one can use to
// optionally load dojo modules. The map is indexed by the
// possible dojo.name_ values, with two additional values:
// "default" and "common". The items in the "default" array will
// be loaded if none of the other items have been choosen based on
// dojo.name_, set by your host environment. The items in the
// "common" array will *always* be loaded, regardless of which
// list is chosen.
// example:
// | dojo.platformRequire({
// | browser: [
// | "foo.sample", // simple module
// | "foo.test",
// | ["foo.bar.baz", true] // skip object check in _loadModule
// | ],
// | default: [ "foo.sample._base" ],
// | common: [ "important.module.common" ]
// | });
var common = modMap.common || [];
var result = common.concat(modMap[d._name] || modMap["default"] || []);
for(var x=0; x<result.length; x++){
var curr = result[x];
if(curr.constructor == Array){
d._loadModule.apply(d, curr);
}else{
d._loadModule(curr);
}
}
}
dojo.requireIf = function(/*Boolean*/ condition, /*String*/ resourceName){
// summary:
// If the condition is true then call dojo.require() for the specified
// resource
if(condition === true){
// FIXME: why do we support chained require()'s here? does the build system?
var args = [];
for(var i = 1; i < arguments.length; i++){
args.push(arguments[i]);
}
d.require.apply(d, args);
}
}
dojo.requireAfterIf = d.requireIf;
dojo.registerModulePath = function(/*String*/module, /*String*/prefix){
// summary:
// maps a module name to a path
// description:
// An unregistered module is given the default path of ../[module],
// relative to Dojo root. For example, module acme is mapped to
// ../acme. If you want to use a different module name, use
// dojo.registerModulePath.
// example:
// If your dojo.js is located at this location in the web root:
// | /myapp/js/dojo/dojo/dojo.js
// and your modules are located at:
// | /myapp/js/foo/bar.js
// | /myapp/js/foo/baz.js
// | /myapp/js/foo/thud/xyzzy.js
// Your application can tell Dojo to locate the "foo" namespace by calling:
// | dojo.registerModulePath("foo", "../../foo");
// At which point you can then use dojo.require() to load the
// modules (assuming they provide() the same things which are
// required). The full code might be:
// | <script type="text/javascript"
// | src="/myapp/js/dojo/dojo/dojo.js"></script>
// | <script type="text/javascript">
// | dojo.registerModulePath("foo", "../../foo");
// | dojo.require("foo.bar");
// | dojo.require("foo.baz");
// | dojo.require("foo.thud.xyzzy");
// | </script>
d._modulePrefixes[module] = { name: module, value: prefix };
}
dojo.requireLocalization = function(/*String*/moduleName, /*String*/bundleName, /*String?*/locale, /*String?*/availableFlatLocales){
// summary:
// Declares translated resources and loads them if necessary, in the
// same style as dojo.require. Contents of the resource bundle are
// typically strings, but may be any name/value pair, represented in
// JSON format. See also dojo.i18n.getLocalization.
// moduleName:
// name of the package containing the "nls" directory in which the
// bundle is found
// bundleName:
// bundle name, i.e. the filename without the '.js' suffix
// locale:
// the locale to load (optional) By default, the browser's user
// locale as defined by dojo.locale
// availableFlatLocales:
// A comma-separated list of the available, flattened locales for this
// bundle. This argument should only be set by the build process.
// description:
// Load translated resource bundles provided underneath the "nls"
// directory within a package. Translated resources may be located in
// different packages throughout the source tree. For example, a
// particular widget may define one or more resource bundles,
// structured in a program as follows, where moduleName is
// mycode.mywidget and bundleNames available include bundleone and
// bundletwo:
//
// | ...
// | mycode/
// | mywidget/
// | nls/
// | bundleone.js (the fallback translation, English in this example)
// | bundletwo.js (also a fallback translation)
// | de/
// | bundleone.js
// | bundletwo.js
// | de-at/
// | bundleone.js
// | en/
// | (empty; use the fallback translation)
// | en-us/
// | bundleone.js
// | en-gb/
// | bundleone.js
// | es/
// | bundleone.js
// | bundletwo.js
// | ...etc
// | ...
//
// Each directory is named for a locale as specified by RFC 3066,
// (http://www.ietf.org/rfc/rfc3066.txt), normalized in lowercase.
// Note that the two bundles in the example do not define all the
// same variants. For a given locale, bundles will be loaded for
// that locale and all more general locales above it, including a
// fallback at the root directory. For example, a declaration for
// the "de-at" locale will first load `nls/de-at/bundleone.js`,
// then `nls/de/bundleone.js` and finally `nls/bundleone.js`. The
// data will be flattened into a single Object so that lookups
// will follow this cascading pattern. An optional build step can
// preload the bundles to avoid data redundancy and the multiple
// network hits normally required to load these resources.
d.require("dojo.i18n");
d.i18n._requireLocalization.apply(d.hostenv, arguments);
};
var ore = new RegExp("^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?$");
var ire = new RegExp("^((([^:]+:)?([^@]+))@)?([^:]*)(:([0-9]+))?$");
dojo._Url = function(/*dojo._Url||String...*/){
// summary:
// Constructor to create an object representing a URL.
// It is marked as private, since we might consider removing
// or simplifying it.
// description:
// Each argument is evaluated in order relative to the next until
// a canonical uri is produced. To get an absolute Uri relative to
// the current document use:
// new dojo._Url(document.baseURI, url)
var n = null;
// TODO: support for IPv6, see RFC 2732
var _a = arguments;
var uri = [_a[0]];
// resolve uri components relative to each other
for(var i = 1; i<_a.length; i++){
if(!_a[i]){ continue; }
// Safari doesn't support this.constructor so we have to be explicit
// FIXME: Tracked (and fixed) in Webkit bug 3537.
// http://bugs.webkit.org/show_bug.cgi?id=3537
var relobj = new d._Url(_a[i]+"");
var uriobj = new d._Url(uri[0]+"");
if(
relobj.path == "" &&
!relobj.scheme &&
!relobj.authority &&
!relobj.query
){
if(relobj.fragment != n){
uriobj.fragment = relobj.fragment;
}
relobj = uriobj;
}else if(!relobj.scheme){
relobj.scheme = uriobj.scheme;
if(!relobj.authority){
relobj.authority = uriobj.authority;
if(relobj.path.charAt(0) != "/"){
var path = uriobj.path.substring(0,
uriobj.path.lastIndexOf("/") + 1) + relobj.path;
var segs = path.split("/");
for(var j = 0; j < segs.length; j++){
if(segs[j] == "."){
// flatten "./" references
if(j == segs.length - 1){
segs[j] = "";
}else{
segs.splice(j, 1);
j--;
}
}else if(j > 0 && !(j == 1 && segs[0] == "") &&
segs[j] == ".." && segs[j-1] != ".."){
// flatten "../" references
if(j == (segs.length - 1)){
segs.splice(j, 1);
segs[j - 1] = "";
}else{
segs.splice(j - 1, 2);
j -= 2;
}
}
}
relobj.path = segs.join("/");
}
}
}
uri = [];
if(relobj.scheme){
uri.push(relobj.scheme, ":");
}
if(relobj.authority){
uri.push("//", relobj.authority);
}
uri.push(relobj.path);
if(relobj.query){
uri.push("?", relobj.query);
}
if(relobj.fragment){
uri.push("#", relobj.fragment);
}
}
this.uri = uri.join("");
// break the uri into its main components
var r = this.uri.match(ore);
this.scheme = r[2] || (r[1] ? "" : n);
this.authority = r[4] || (r[3] ? "" : n);
this.path = r[5]; // can never be undefined
this.query = r[7] || (r[6] ? "" : n);
this.fragment = r[9] || (r[8] ? "" : n);
if(this.authority != n){
// server based naming authority
r = this.authority.match(ire);
this.user = r[3] || n;
this.password = r[4] || n;
this.host = r[5];
this.port = r[7] || n;
}
}
dojo._Url.prototype.toString = function(){ return this.uri; };
dojo.moduleUrl = function(/*String*/module, /*dojo._Url||String*/url){
// summary:
// Returns a `dojo._Url` object relative to a module.
// example:
// | var pngPath = dojo.moduleUrl("acme","images/small.png");
// | console.dir(pngPath); // list the object properties
// | // create an image and set it's source to pngPath's value:
// | var img = document.createElement("img");
// | // NOTE: we assign the string representation of the url object
// | img.src = pngPath.toString();
// | // add our image to the document
// | dojo.body().appendChild(img);
// example:
// you may de-reference as far as you like down the package
// hierarchy. This is sometimes handy to avoid lenghty relative
// urls or for building portable sub-packages. In this example,
// the `acme.widget` and `acme.util` directories may be located
// under different roots (see `dojo.registerModulePath`) but the
// the modules which reference them can be unaware of their
// relative locations on the filesystem:
// | // somewhere in a configuration block
// | dojo.registerModulePath("acme.widget", "../../acme/widget");
// | dojo.registerModulePath("acme.util", "../../util");
// |
// | // ...
// |
// | // code in a module using acme resources
// | var tmpltPath = dojo.moduleUrl("acme.widget","templates/template.html");
// | var dataPath = dojo.moduleUrl("acme.util","resources/data.json");
var loc = d._getModuleSymbols(module).join('/');
if(!loc){ return null; }
if(loc.lastIndexOf("/") != loc.length-1){
loc += "/";
}
//If the path is an absolute path (starts with a / or is on another
//domain/xdomain) then don't add the baseUrl.
var colonIndex = loc.indexOf(":");
if(loc.charAt(0) != "/" && (colonIndex == -1 || colonIndex > loc.indexOf("/"))){
loc = d.baseUrl + loc;
}
return new d._Url(loc, url); // String
}
})();
/*=====
dojo.isBrowser = {
// example:
// | if(dojo.isBrowser){ ... }
};
dojo.isFF = {
// example:
// | if(dojo.isFF > 1){ ... }
};
dojo.isIE = {
// example:
// | if(dojo.isIE > 6){
// | // we are IE7
// | }
};
dojo.isSafari = {
// example:
// | if(dojo.isSafari){ ... }
// example:
// Detect iPhone:
// | if(dojo.isSafari && (navigator.userAgent.indexOf("iPhone") < 0)){
// | // we are iPhone. iPod touch reports "iPod" above
// | }
};
dojo = {
// isBrowser: Boolean
// True if the client is a web-browser
isBrowser: true,
// isFF: Number
// Greater than zero if client is FireFox. 0 otherwise. Corresponds to
// major detected FireFox version (1.5, 2, 3, etc.)
isFF: 2,
// isIE: Number
// Greater than zero if client is MSIE(PC). 0 otherwise. Corresponds to
// major detected IE version (6, 7, 8, etc.)
isIE: 6,
// isKhtml: Number
// Greater than zero if client is a KTHML-derived browser (Konqueror,
// Safari, etc.). 0 otherwise. Corresponds to major detected version.
isKhtml: 0,
// isMozilla: Number
// Greater than zero if client is a Mozilla-based browser (Firefox,
// SeaMonkey). 0 otherwise. Corresponds to major detected version.
isMozilla: 0,
// isOpera: Number
// Greater than zero if client is Opera. 0 otherwise. Corresponds to
// major detected version.
isOpera: 0,
// isSafari: Number
// Greater than zero if client is Safari or iPhone. 0 otherwise.
isSafari: 0
}
=====*/
if(typeof window != 'undefined'){
dojo.isBrowser = true;
dojo._name = "browser";
// attempt to figure out the path to dojo if it isn't set in the config
(function(){
var d = dojo;
// this is a scope protection closure. We set browser versions and grab
// the URL we were loaded from here.
// grab the node we were loaded from
if(document && document.getElementsByTagName){
var scripts = document.getElementsByTagName("script");
var rePkg = /dojo(\.xd)?\.js(\W|$)/i;
for(var i = 0; i < scripts.length; i++){
var src = scripts[i].getAttribute("src");
if(!src){ continue; }
var m = src.match(rePkg);
if(m){
// find out where we came from
if(!d.config.baseUrl){
d.config.baseUrl = src.substring(0, m.index);
}
// and find out if we need to modify our behavior
var cfg = scripts[i].getAttribute("djConfig");
if(cfg){
var cfgo = eval("({ "+cfg+" })");
for(var x in cfgo){
dojo.config[x] = cfgo[x];
}
}
break; // "first Dojo wins"
}
}
}
d.baseUrl = d.config.baseUrl;
// fill in the rendering support information in dojo.render.*
var n = navigator;
var dua = n.userAgent;
var dav = n.appVersion;
var tv = parseFloat(dav);
d.isOpera = (dua.indexOf("Opera") >= 0) ? tv : 0;
// safari detection derived from:
// http://developer.apple.com/internet/safari/faq.html#anchor2
// http://developer.apple.com/internet/safari/uamatrix.html
var idx = Math.max(dav.indexOf("WebKit"), dav.indexOf("Safari"), 0);
if(idx){
// try to grab the explicit Safari version first. If we don't get
// one, look for 419.3+ as the indication that we're on something
// "Safari 3-ish". Lastly, default to "Safari 2" handling.
d.isSafari = parseFloat(dav.split("Version/")[1]) || ( ( parseFloat(dav.substr(idx+7)) >= 419.3 ) ? 3 : 2 ) || 2;
}
d.isAIR = (dua.indexOf("AdobeAIR") >= 0) ? 1 : 0;
d.isKhtml = (dav.indexOf("Konqueror") >= 0 || d.isSafari) ? tv : 0;
d.isMozilla = d.isMoz = (dua.indexOf("Gecko") >= 0 && !d.isKhtml) ? tv : 0;
d.isFF = d.isIE = 0;
if(d.isMoz){
d.isFF = parseFloat(dua.split("Firefox/")[1]) || 0;
}
if(document.all && !d.isOpera){
d.isIE = parseFloat(dav.split("MSIE ")[1]) || 0;
}
//Workaround to get local file loads of dojo to work on IE 7
//by forcing to not use native xhr.
if(dojo.isIE && window.location.protocol === "file:"){
dojo.config.ieForceActiveXXhr=true;
}
var cm = document.compatMode;
d.isQuirks = cm == "BackCompat" || cm == "QuirksMode" || d.isIE < 6;
// TODO: is the HTML LANG attribute relevant?
d.locale = dojo.config.locale || (d.isIE ? n.userLanguage : n.language).toLowerCase();
// These are in order of decreasing likelihood; this will change in time.
d._XMLHTTP_PROGIDS = ['Msxml2.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.4.0'];
d._xhrObj = function(){
// summary:
// does the work of portably generating a new XMLHTTPRequest
// object.
var http = null;
var last_e = null;
if(!dojo.isIE || !dojo.config.ieForceActiveXXhr){
try{ http = new XMLHttpRequest(); }catch(e){}
}
if(!http){
for(var i=0; i<3; ++i){
var progid = d._XMLHTTP_PROGIDS[i];
try{
http = new ActiveXObject(progid);
}catch(e){
last_e = e;
}
if(http){
d._XMLHTTP_PROGIDS = [progid]; // so faster next time
break;
}
}
}
if(!http){
throw new Error("XMLHTTP not available: "+last_e);
}
return http; // XMLHTTPRequest instance
}
d._isDocumentOk = function(http){
var stat = http.status || 0;
return (stat >= 200 && stat < 300) || // Boolean
stat == 304 || // allow any 2XX response code
stat == 1223 || // get it out of the cache
(!stat && (location.protocol=="file:" || location.protocol=="chrome:") ); // Internet Explorer mangled the status code
}
//See if base tag is in use.
//This is to fix http://trac.dojotoolkit.org/ticket/3973,
//but really, we need to find out how to get rid of the dojo._Url reference
//below and still have DOH work with the dojo.i18n test following some other
//test that uses the test frame to load a document (trac #2757).
//Opera still has problems, but perhaps a larger issue of base tag support
//with XHR requests (hasBase is true, but the request is still made to document
//path, not base path).
var owloc = window.location+"";
var base = document.getElementsByTagName("base");
var hasBase = (base && base.length > 0);
d._getText = function(/*URI*/ uri, /*Boolean*/ fail_ok){
// summary: Read the contents of the specified uri and return those contents.
// uri:
// A relative or absolute uri. If absolute, it still must be in
// the same "domain" as we are.
// fail_ok:
// Default false. If fail_ok and loading fails, return null
// instead of throwing.
// returns: The response text. null is returned when there is a
// failure and failure is okay (an exception otherwise)
// alert("_getText: " + uri);
// NOTE: must be declared before scope switches ie. this._xhrObj()
var http = this._xhrObj();
if(!hasBase && dojo._Url){
uri = (new dojo._Url(owloc, uri)).toString();
}
/*
console.debug("_getText:", uri);
console.debug(window.location+"");
alert(uri);
*/
if(d.config.cacheBust){
uri += (uri.indexOf("?") == -1 ? "?" : "&") + String(d.config.cacheBust).replace(/\W+/g,"");
}
http.open('GET', uri, false);
try{
http.send(null);
// alert(http);
if(!d._isDocumentOk(http)){
var err = Error("Unable to load "+uri+" status:"+ http.status);
err.status = http.status;
err.responseText = http.responseText;
throw err;
}
}catch(e){
if(fail_ok){ return null; } // null
// rethrow the exception
throw e;
}
return http.responseText; // String
}
})();
dojo._initFired = false;
// BEGIN DOMContentLoaded, from Dean Edwards (http://dean.edwards.name/weblog/2006/06/again/)
dojo._loadInit = function(e){
dojo._initFired = true;
// allow multiple calls, only first one will take effect
// A bug in khtml calls events callbacks for document for event which isnt supported
// for example a created contextmenu event calls DOMContentLoaded, workaround
var type = (e && e.type) ? e.type.toLowerCase() : "load";
if(arguments.callee.initialized || (type != "domcontentloaded" && type != "load")){ return; }
arguments.callee.initialized = true;
if("_khtmlTimer" in dojo){
clearInterval(dojo._khtmlTimer);
delete dojo._khtmlTimer;
}
if(dojo._inFlightCount == 0){
dojo._modulesLoaded();
}
}
dojo._fakeLoadInit = function(){
dojo._loadInit({type: "load"});
}
if(dojo.config.afterOnLoad){
//Dojo is being added to the page after page load, so just trigger
//the init sequence after a timeout. Using a timeout so the rest of this
//script gets evaluated properly.
window.setTimeout(dojo._fakeLoadInit, 1000);
}else{
// START DOMContentLoaded
// Mozilla and Opera 9 expose the event we could use
if(document.addEventListener){
// NOTE:
// due to a threading issue in Firefox 2.0, we can't enable
// DOMContentLoaded on that platform. For more information, see:
// http://trac.dojotoolkit.org/ticket/1704
if(dojo.isOpera || dojo.isFF >= 3 || (dojo.isMoz && dojo.config.enableMozDomContentLoaded === true)){
document.addEventListener("DOMContentLoaded", dojo._loadInit, null);
}
// mainly for Opera 8.5, won't be fired if DOMContentLoaded fired already.
// also used for Mozilla because of trac #1640
window.addEventListener("load", dojo._loadInit, null);
}
if(dojo.isAIR){
window.addEventListener("load", dojo._loadInit, null);
}else if(/(WebKit|khtml)/i.test(navigator.userAgent)){ // sniff
dojo._khtmlTimer = setInterval(function(){
if(/loaded|complete/.test(document.readyState)){
dojo._loadInit(); // call the onload handler
}
}, 10);
}
// END DOMContentLoaded
}
(function(){
var _w = window;
var _handleNodeEvent = function(/*String*/evtName, /*Function*/fp){
// summary:
// non-destructively adds the specified function to the node's
// evtName handler.
// evtName: should be in the form "onclick" for "onclick" handlers.
// Make sure you pass in the "on" part.
var oldHandler = _w[evtName] || function(){};
_w[evtName] = function(){
fp.apply(_w, arguments);
oldHandler.apply(_w, arguments);
};
};
if(dojo.isIE){
// for Internet Explorer. readyState will not be achieved on init
// call, but dojo doesn't need it however, we'll include it
// because we don't know if there are other functions added that
// might. Note that this has changed because the build process
// strips all comments -- including conditional ones.
if(!dojo.config.afterOnLoad){
document.write('<scr'+'ipt defer src="//:" '
+ 'onreadystatechange="if(this.readyState==\'complete\'){' + dojo._scopeName + '._loadInit();}">'
+ '</scr'+'ipt>'
);
}
// IE WebControl hosted in an application can fire "beforeunload" and "unload"
// events when control visibility changes, causing Dojo to unload too soon. The
// following code fixes the problem
// Reference: http://support.microsoft.com/default.aspx?scid=kb;en-us;199155
var _unloading = true;
_handleNodeEvent("onbeforeunload", function(){
_w.setTimeout(function(){ _unloading = false; }, 0);
});
_handleNodeEvent("onunload", function(){
if(_unloading){ dojo.unloaded(); }
});
try{
document.namespaces.add("v","urn:schemas-microsoft-com:vml");
document.createStyleSheet().addRule("v\\:*", "behavior:url(#default#VML)");
}catch(e){}
}else{
// FIXME: dojo.unloaded requires dojo scope, so using anon function wrapper.
_handleNodeEvent("onbeforeunload", function() { dojo.unloaded(); });
}
})();
/*
OpenAjax.subscribe("OpenAjax", "onload", function(){
if(dojo._inFlightCount == 0){
dojo._modulesLoaded();
}
});
OpenAjax.subscribe("OpenAjax", "onunload", function(){
dojo.unloaded();
});
*/
} //if (typeof window != 'undefined')
//Register any module paths set up in djConfig. Need to do this
//in the hostenvs since hostenv_browser can read djConfig from a
//script tag's attribute.
(function(){
var mp = dojo.config["modulePaths"];
if(mp){
for(var param in mp){
dojo.registerModulePath(param, mp[param]);
}
}
})();
//Load debug code if necessary.
if(dojo.config.isDebug){
dojo.require("dojo._firebug.firebug");
}
if(dojo.config.debugAtAllCosts){
dojo.config.useXDomain = true;
dojo.require("dojo._base._loader.loader_xd");
dojo.require("dojo._base._loader.loader_debug");
dojo.require("dojo.i18n");
}
if(!dojo._hasResource["dojo._base.lang"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dojo._base.lang"] = true;
dojo.provide("dojo._base.lang");
// Crockford (ish) functions
dojo.isString = function(/*anything*/ it){
// summary:
// Return true if it is a String
return !!arguments.length && it != null && (typeof it == "string" || it instanceof String); // Boolean
}
dojo.isArray = function(/*anything*/ it){
// summary:
// Return true if it is an Array
return it && (it instanceof Array || typeof it == "array"); // Boolean
}
/*=====
dojo.isFunction = function(it){
// summary: Return true if it is a Function
// it: anything
// return: Boolean
}
=====*/
dojo.isFunction = (function(){
var _isFunction = function(/*anything*/ it){
return it && (typeof it == "function" || it instanceof Function); // Boolean
};
return dojo.isSafari ?
// only slow this down w/ gratuitious casting in Safari since it's what's b0rken
function(/*anything*/ it){
if(typeof it == "function" && it == "[object NodeList]"){ return false; }
return _isFunction(it); // Boolean
} : _isFunction;
})();
dojo.isObject = function(/*anything*/ it){
// summary:
// Returns true if it is a JavaScript object (or an Array, a Function
// or null)
return it !== undefined &&
(it === null || typeof it == "object" || dojo.isArray(it) || dojo.isFunction(it)); // Boolean
}
dojo.isArrayLike = function(/*anything*/ it){
// summary:
// similar to dojo.isArray() but more permissive
// description:
// Doesn't strongly test for "arrayness". Instead, settles for "isn't
// a string or number and has a length property". Arguments objects
// and DOM collections will return true when passed to
// dojo.isArrayLike(), but will return false when passed to
// dojo.isArray().
// return:
// If it walks like a duck and quicks like a duck, return `true`
var d = dojo;
return it && it !== undefined &&
// keep out built-in constructors (Number, String, ...) which have length
// properties
!d.isString(it) && !d.isFunction(it) &&
!(it.tagName && it.tagName.toLowerCase() == 'form') &&
(d.isArray(it) || isFinite(it.length)); // Boolean
}
dojo.isAlien = function(/*anything*/ it){
// summary:
// Returns true if it is a built-in function or some other kind of
// oddball that *should* report as a function but doesn't
return it && !dojo.isFunction(it) && /\{\s*\[native code\]\s*\}/.test(String(it)); // Boolean
}
dojo.extend = function(/*Object*/ constructor, /*Object...*/ props){
// summary:
// Adds all properties and methods of props to constructor's
// prototype, making them available to all instances created with
// constructor.
for(var i=1, l=arguments.length; i<l; i++){
dojo._mixin(constructor.prototype, arguments[i]);
}
return constructor; // Object
}
dojo._hitchArgs = function(scope, method /*,...*/){
var pre = dojo._toArray(arguments, 2);
var named = dojo.isString(method);
return function(){
// arrayify arguments
var args = dojo._toArray(arguments);
// locate our method
var f = named ? (scope||dojo.global)[method] : method;
// invoke with collected args
return f && f.apply(scope || this, pre.concat(args)); // mixed
} // Function
}
dojo.hitch = function(/*Object*/scope, /*Function|String*/method /*,...*/){
// summary:
// Returns a function that will only ever execute in the a given scope.
// This allows for easy use of object member functions
// in callbacks and other places in which the "this" keyword may
// otherwise not reference the expected scope.
// Any number of default positional arguments may be passed as parameters
// beyond "method".
// Each of these values will be used to "placehold" (similar to curry)
// for the hitched function.
// scope:
// The scope to use when method executes. If method is a string,
// scope is also the object containing method.
// method:
// A function to be hitched to scope, or the name of the method in
// scope to be hitched.
// example:
// | dojo.hitch(foo, "bar")();
// runs foo.bar() in the scope of foo
// example:
// | dojo.hitch(foo, myFunction);
// returns a function that runs myFunction in the scope of foo
if(arguments.length > 2){
return dojo._hitchArgs.apply(dojo, arguments); // Function
}
if(!method){
method = scope;
scope = null;
}
if(dojo.isString(method)){
scope = scope || dojo.global;
if(!scope[method]){ throw(['dojo.hitch: scope["', method, '"] is null (scope="', scope, '")'].join('')); }
return function(){ return scope[method].apply(scope, arguments || []); }; // Function
}
return !scope ? method : function(){ return method.apply(scope, arguments || []); }; // Function
}
/*=====
dojo.delegate = function(obj, props){
// summary:
// returns a new object which "looks" to obj for properties which it
// does not have a value for. Optionally takes a bag of properties to
// seed the returned object with initially.
// description:
// This is a small implementaton of the Boodman/Crockford delegation
// pattern in JavaScript. An intermediate object constructor mediates
// the prototype chain for the returned object, using it to delegate
// down to obj for property lookup when object-local lookup fails.
// This can be thought of similarly to ES4's "wrap", save that it does
// not act on types but rather on pure objects.
// obj:
// The object to delegate to for properties not found directly on the
// return object or in props.
// props:
// an object containing properties to assign to the returned object
// returns:
// an Object of anonymous type
// example:
// | var foo = { bar: "baz" };
// | var thinger = dojo.delegate(foo, { thud: "xyzzy"});
// | thinger.bar == "baz"; // delegated to foo
// | foo.thud == undefined; // by definition
// | thinger.thud == "xyzzy"; // mixed in from props
// | foo.bar = "thonk";
// | thinger.bar == "thonk"; // still delegated to foo's bar
}
=====*/
dojo.delegate = dojo._delegate = function(obj, props){
// boodman/crockford delegation
function TMP(){};
TMP.prototype = obj;
var tmp = new TMP();
if(props){
dojo.mixin(tmp, props);
}
return tmp; // Object
}
dojo.partial = function(/*Function|String*/method /*, ...*/){
// summary:
// similar to hitch() except that the scope object is left to be
// whatever the execution context eventually becomes.
// description:
// Calling dojo.partial is the functional equivalent of calling:
// | dojo.hitch(null, funcName, ...);
var arr = [ null ];
return dojo.hitch.apply(dojo, arr.concat(dojo._toArray(arguments))); // Function
}
dojo._toArray = function(/*Object*/obj, /*Number?*/offset, /*Array?*/ startWith){
// summary:
// Converts an array-like object (i.e. arguments, DOMCollection) to an
// array. Returns a new Array with the elements of obj.
// obj:
// the object to "arrayify". We expect the object to have, at a
// minimum, a length property which corresponds to integer-indexed
// properties.
// offset:
// the location in obj to start iterating from. Defaults to 0.
// Optional.
// startWith:
// An array to pack with the properties of obj. If provided,
// properties in obj are appended at the end of startWith and
// startWith is the returned array.
var arr = startWith||[];
for(var x = offset || 0; x < obj.length; x++){
arr.push(obj[x]);
}
return arr; // Array
}
dojo.clone = function(/*anything*/ o){
// summary:
// Clones objects (including DOM nodes) and all children.
// Warning: do not clone cyclic structures.
if(!o){ return o; }
if(dojo.isArray(o)){
var r = [];
for(var i = 0; i < o.length; ++i){
r.push(dojo.clone(o[i]));
}
return r; // Array
}
if(!dojo.isObject(o)){
return o; /*anything*/
}
if(o.nodeType && o.cloneNode){ // isNode
return o.cloneNode(true); // Node
}
if(o instanceof Date){
return new Date(o.getTime()); // Date
}
// Generic objects
var r = new o.constructor(); // specific to dojo.declare()'d classes!
for(var i in o){
if(!(i in r) || r[i] != o[i]){
r[i] = dojo.clone(o[i]);
}
}
return r; // Object
}
dojo.trim = function(/*String*/ str){
// summary:
// trims whitespaces from both sides of the string
// description:
// This version of trim() was selected for inclusion into the base due
// to its compact size and relatively good performance (see Steven
// Levithan's blog:
// http://blog.stevenlevithan.com/archives/faster-trim-javascript).
// The fastest but longest version of this function is located at
// dojo.string.trim()
return str.replace(/^\s\s*/, '').replace(/\s\s*$/, ''); // String
}
}
if(!dojo._hasResource["dojo._base.declare"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dojo._base.declare"] = true;
dojo.provide("dojo._base.declare");
// this file courtesy of the TurboAjax group, licensed under a Dojo CLA
dojo.declare = function(/*String*/ className, /*Function|Function[]*/ superclass, /*Object*/ props){
// summary:
// Create a feature-rich constructor from compact notation
// className:
// The name of the constructor (loosely, a "class")
// stored in the "declaredClass" property in the created prototype
// superclass:
// May be null, a Function, or an Array of Functions. If an array,
// the first element is used as the prototypical ancestor and
// any following Functions become mixin ancestors.
// props:
// An object whose properties are copied to the
// created prototype.
// Add an instance-initialization function by making it a property
// named "constructor".
// description:
// Create a constructor using a compact notation for inheritance and
// prototype extension.
//
// All superclasses (including mixins) must be Functions (not simple Objects).
//
// Mixin ancestors provide a type of multiple inheritance. Prototypes of mixin
// ancestors are copied to the new class: changes to mixin prototypes will
// not affect classes to which they have been mixed in.
//
// "className" is cached in "declaredClass" property of the new class.
//
// example:
// | dojo.declare("my.classes.bar", my.classes.foo, {
// | // properties to be added to the class prototype
// | someValue: 2,
// | // initialization function
// | constructor: function(){
// | this.myComplicatedObject = new ReallyComplicatedObject();
// | },
// | // other functions
// | someMethod: function(){
// | doStuff();
// | }
// | );
// process superclass argument
// var dd=dojo.declare, mixins=null;
var dd = arguments.callee, mixins;
if(dojo.isArray(superclass)){
mixins = superclass;
superclass = mixins.shift();
}
// construct intermediate classes for mixins
if(mixins){
dojo.forEach(mixins, function(m){
if(!m){ throw(className + ": mixin #" + i + " is null"); } // It's likely a required module is not loaded
superclass = dd._delegate(superclass, m);
});
}
// prepare values
var init = (props||0).constructor, ctor = dd._delegate(superclass), fn;
// name methods (experimental)
for(var i in props){ if(dojo.isFunction(fn = props[i]) && !0[i]){fn.nom = i;} } // 0[i] checks Object.prototype
// decorate prototype
dojo.extend(ctor, {declaredClass: className, _constructor: init, preamble: null}, props || 0);
// special help for IE
ctor.prototype.constructor = ctor;
// create named reference
return dojo.setObject(className, ctor); // Function
};
dojo.mixin(dojo.declare, {
_delegate: function(base, mixin){
var bp = (base||0).prototype, mp = (mixin||0).prototype;
// fresh constructor, fresh prototype
var ctor = dojo.declare._makeCtor();
// cache ancestry
dojo.mixin(ctor, {superclass: bp, mixin: mp, extend: dojo.declare._extend});
// chain prototypes
if(base){ctor.prototype = dojo._delegate(bp);}
// add mixin and core
dojo.extend(ctor, dojo.declare._core, mp||0, {_constructor: null, preamble: null});
// special help for IE
ctor.prototype.constructor = ctor;
// name this class for debugging
ctor.prototype.declaredClass = (bp||0).declaredClass + '_' + (mp||0).declaredClass;
return ctor;
},
_extend: function(props){
for(var i in props){ if(dojo.isFunction(fn=props[i]) && !0[i]){fn.nom=i;} }
dojo.extend(this, props);
},
_makeCtor: function(){
// we have to make a function, but don't want to close over anything
return function(){ this._construct(arguments); };
},
_core: {
_construct: function(args){
var c=args.callee, s=c.superclass, ct=s&&s.constructor, m=c.mixin, mct=m&&m.constructor, a=args, ii, fn;
// side-effect of = used on purpose here, lint may complain, don't try this at home
if(a[0]){
// FIXME: preambles for each mixin should be allowed
// FIXME:
// should we allow the preamble here NOT to modify the
// default args, but instead to act on each mixin
// independently of the class instance being constructed
// (for impedence matching)?
// allow any first argument w/ a "preamble" property to act as a
// class preamble (not exclusive of the prototype preamble)
if(/*dojo.isFunction*/((fn = a[0].preamble))){
a = fn.apply(this, a) || a;
}
}
// prototype preamble
if((fn = c.prototype.preamble)){a = fn.apply(this, a) || a;}
// FIXME:
// need to provide an optional prototype-settable
// "_explicitSuper" property which disables this
// initialize superclass
if(ct&&ct.apply){ct.apply(this, a);}
// initialize mixin
if(mct&&mct.apply){mct.apply(this, a);}
// initialize self
if((ii=c.prototype._constructor)){ii.apply(this, args);}
// post construction
if(this.constructor.prototype==c.prototype && (ct=this.postscript)){ ct.apply(this, args); }
},
_findMixin: function(mixin){
var c = this.constructor, p, m;
while(c){
p = c.superclass;
m = c.mixin;
if(m==mixin || (m instanceof mixin.constructor)){return p;}
if(m && (m=m._findMixin(mixin))){return m;}
c = p && p.constructor;
}
},
_findMethod: function(name, method, ptype, has){
// consciously trading readability for bytes and speed in this low-level method
var p=ptype, c, m, f;
do{
c = p.constructor;
m = c.mixin;
// find method by name in our mixin ancestor
if(m && (m=this._findMethod(name, method, m, has))){return m;}
// if we found a named method that either exactly-is or exactly-is-not 'method'
if((f=p[name])&&(has==(f==method))){return p;}
// ascend chain
p = c.superclass;
}while(p);
// if we couldn't find an ancestor in our primary chain, try a mixin chain
return !has && (p=this._findMixin(ptype)) && this._findMethod(name, method, p, has);
},
inherited: function(name, args, newArgs){
// optionalize name argument (experimental)
var a = arguments;
if(!dojo.isString(a[0])){newArgs=args; args=name; name=args.callee.nom;}
a = newArgs||args;
var c = args.callee, p = this.constructor.prototype, fn, mp;
// if not an instance override
if(this[name] != c || p[name] == c){
mp = this._findMethod(name, c, p, true);
if(!mp){throw(this.declaredClass + ': inherited method "' + name + '" mismatch');}
p = this._findMethod(name, c, mp, false);
}
fn = p && p[name];
if(!fn){throw(mp.declaredClass + ': inherited method "' + name + '" not found');}
// if the function exists, invoke it in our scope
return fn.apply(this, a);
}
}
});
}
if(!dojo._hasResource["dojo._base.connect"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dojo._base.connect"] = true;
dojo.provide("dojo._base.connect");
// this file courtesy of the TurboAjax Group, licensed under a Dojo CLA
// low-level delegation machinery
dojo._listener = {
// create a dispatcher function
getDispatcher: function(){
// following comments pulled out-of-line to prevent cloning them
// in the returned function.
// - indices (i) that are really in the array of listeners (ls) will
// not be in Array.prototype. This is the 'sparse array' trick
// that keeps us safe from libs that take liberties with built-in
// objects
// - listener is invoked with current scope (this)
return function(){
var ap=Array.prototype, c=arguments.callee, ls=c._listeners, t=c.target;
// return value comes from original target function
var r=t && t.apply(this, arguments);
// invoke listeners after target function
for(var i in ls){
if(!(i in ap)){
ls[i].apply(this, arguments);
}
}
// return value comes from original target function
return r;
}
},
// add a listener to an object
add: function(/*Object*/ source, /*String*/ method, /*Function*/ listener){
// Whenever 'method' is invoked, 'listener' will have the same scope.
// Trying to supporting a context object for the listener led to
// complexity.
// Non trivial to provide 'once' functionality here
// because listener could be the result of a dojo.hitch call,
// in which case two references to the same hitch target would not
// be equivalent.
source = source || dojo.global;
// The source method is either null, a dispatcher, or some other function
var f = source[method];
// Ensure a dispatcher
if(!f||!f._listeners){
var d = dojo._listener.getDispatcher();
// original target function is special
d.target = f;
// dispatcher holds a list of listeners
d._listeners = [];
// redirect source to dispatcher
f = source[method] = d;
}
// The contract is that a handle is returned that can
// identify this listener for disconnect.
//
// The type of the handle is private. Here is it implemented as Integer.
// DOM event code has this same contract but handle is Function
// in non-IE browsers.
//
// We could have separate lists of before and after listeners.
return f._listeners.push(listener) ; /*Handle*/
},
// remove a listener from an object
remove: function(/*Object*/ source, /*String*/ method, /*Handle*/ handle){
var f = (source||dojo.global)[method];
// remember that handle is the index+1 (0 is not a valid handle)
if(f && f._listeners && handle--){
delete f._listeners[handle];
}
}
};
// Multiple delegation for arbitrary methods.
// This unit knows nothing about DOM,
// but we include DOM aware
// documentation and dontFix
// argument here to help the autodocs.
// Actual DOM aware code is in event.js.
dojo.connect = function(/*Object|null*/ obj,
/*String*/ event,
/*Object|null*/ context,
/*String|Function*/ method,
/*Boolean*/ dontFix){
// summary:
// Create a link that calls one function when another executes.
//
// description:
// Connects method to event, so that after event fires, method
// does too. All connected functions are passed the same arguments as
// the event function was initially called with. You may connect as
// many methods to event as needed.
//
// event must be a string. If obj is null, dojo.global is used.
//
// null arguments may simply be omitted.
//
// obj[event] can resolve to a function or undefined (null).
// If obj[event] is null, it is assigned a function.
//
// The return value is a handle that is needed to
// remove this connection with dojo.disconnect.
//
// obj:
// The source object for the event function.
// Defaults to dojo.global if null.
// If obj is a DOM node, the connection is delegated
// to the DOM event manager (unless dontFix is true).
//
// event:
// String name of the event function in obj.
// I.e. identifies a property obj[event].
//
// context:
// The object that method will receive as "this".
//
// If context is null and method is a function, then method
// inherits the context of event.
//
// If method is a string then context must be the source
// object object for method (context[method]). If context is null,
// dojo.global is used.
//
// method:
// A function reference, or name of a function in context.
// The function identified by method fires after event does.
// method receives the same arguments as the event.
// See context argument comments for information on method's scope.
//
// dontFix:
// If obj is a DOM node, set dontFix to true to prevent delegation
// of this connection to the DOM event manager.
//
// example:
// When obj.onchange(), do ui.update():
// | dojo.connect(obj, "onchange", ui, "update");
// | dojo.connect(obj, "onchange", ui, ui.update); // same
//
// example:
// Using return value for disconnect:
// | var link = dojo.connect(obj, "onchange", ui, "update");
// | ...
// | dojo.disconnect(link);
//
// example:
// When onglobalevent executes, watcher.handler is invoked:
// | dojo.connect(null, "onglobalevent", watcher, "handler");
//
// example:
// When ob.onCustomEvent executes, customEventHandler is invoked:
// | dojo.connect(ob, "onCustomEvent", null, "customEventHandler");
// | dojo.connect(ob, "onCustomEvent", "customEventHandler"); // same
//
// example:
// When ob.onCustomEvent executes, customEventHandler is invoked
// with the same scope (this):
// | dojo.connect(ob, "onCustomEvent", null, customEventHandler);
// | dojo.connect(ob, "onCustomEvent", customEventHandler); // same
//
// example:
// When globalEvent executes, globalHandler is invoked
// with the same scope (this):
// | dojo.connect(null, "globalEvent", null, globalHandler);
// | dojo.connect("globalEvent", globalHandler); // same
// normalize arguments
var a=arguments, args=[], i=0;
// if a[0] is a String, obj was ommited
args.push(dojo.isString(a[0]) ? null : a[i++], a[i++]);
// if the arg-after-next is a String or Function, context was NOT omitted
var a1 = a[i+1];
args.push(dojo.isString(a1)||dojo.isFunction(a1) ? a[i++] : null, a[i++]);
// absorb any additional arguments
for(var l=a.length; i<l; i++){ args.push(a[i]); }
// do the actual work
return dojo._connect.apply(this, args); /*Handle*/
}
// used by non-browser hostenvs. always overriden by event.js
dojo._connect = function(obj, event, context, method){
var l=dojo._listener, h=l.add(obj, event, dojo.hitch(context, method));
return [obj, event, h, l]; // Handle
}
dojo.disconnect = function(/*Handle*/ handle){
// summary:
// Remove a link created by dojo.connect.
// description:
// Removes the connection between event and the method referenced by handle.
// handle:
// the return value of the dojo.connect call that created the connection.
if(handle && handle[0] !== undefined){
dojo._disconnect.apply(this, handle);
// let's not keep this reference
delete handle[0];
}
}
dojo._disconnect = function(obj, event, handle, listener){
listener.remove(obj, event, handle);
}
// topic publish/subscribe
dojo._topics = {};
dojo.subscribe = function(/*String*/ topic, /*Object|null*/ context, /*String|Function*/ method){
// summary:
// Attach a listener to a named topic. The listener function is invoked whenever the
// named topic is published (see: dojo.publish).
// Returns a handle which is needed to unsubscribe this listener.
// context:
// Scope in which method will be invoked, or null for default scope.
// method:
// The name of a function in context, or a function reference. This is the function that
// is invoked when topic is published.
// example:
// | dojo.subscribe("alerts", null, function(caption, message){ alert(caption + "\n" + message); };
// | dojo.publish("alerts", [ "read this", "hello world" ]);
// support for 2 argument invocation (omitting context) depends on hitch
return [topic, dojo._listener.add(dojo._topics, topic, dojo.hitch(context, method))]; /*Handle*/
}
dojo.unsubscribe = function(/*Handle*/ handle){
// summary:
// Remove a topic listener.
// handle:
// The handle returned from a call to subscribe.
// example:
// | var alerter = dojo.subscribe("alerts", null, function(caption, message){ alert(caption + "\n" + message); };
// | ...
// | dojo.unsubscribe(alerter);
if(handle){
dojo._listener.remove(dojo._topics, handle[0], handle[1]);
}
}
dojo.publish = function(/*String*/ topic, /*Array*/ args){
// summary:
// Invoke all listener method subscribed to topic.
// topic:
// The name of the topic to publish.
// args:
// An array of arguments. The arguments will be applied
// to each topic subscriber (as first class parameters, via apply).
// example:
// | dojo.subscribe("alerts", null, function(caption, message){ alert(caption + "\n" + message); };
// | dojo.publish("alerts", [ "read this", "hello world" ]);
// Note that args is an array, which is more efficient vs variable length
// argument list. Ideally, var args would be implemented via Array
// throughout the APIs.
var f = dojo._topics[topic];
if(f){
f.apply(this, args||[]);
}
}
dojo.connectPublisher = function( /*String*/ topic,
/*Object|null*/ obj,
/*String*/ event){
// summary:
// Ensure that everytime obj.event() is called, a message is published
// on the topic. Returns a handle which can be passed to
// dojo.disconnect() to disable subsequent automatic publication on
// the topic.
// topic:
// The name of the topic to publish.
// obj:
// The source object for the event function. Defaults to dojo.global
// if null.
// event:
// The name of the event function in obj.
// I.e. identifies a property obj[event].
// example:
// | dojo.connectPublisher("/ajax/start", dojo, "xhrGet"};
var pf = function(){ dojo.publish(topic, arguments); }
return (event) ? dojo.connect(obj, event, pf) : dojo.connect(obj, pf); //Handle
};
}
if(!dojo._hasResource["dojo._base.Deferred"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dojo._base.Deferred"] = true;
dojo.provide("dojo._base.Deferred");
dojo.Deferred = function(/*Function?*/ canceller){
// summary:
// Encapsulates a sequence of callbacks in response to a value that
// may not yet be available. This is modeled after the Deferred class
// from Twisted <http://twistedmatrix.com>.
// description:
// JavaScript has no threads, and even if it did, threads are hard.
// Deferreds are a way of abstracting non-blocking events, such as the
// final response to an XMLHttpRequest. Deferreds create a promise to
// return a response a some point in the future and an easy way to
// register your interest in receiving that response.
//
// The most important methods for Deffered users are:
//
// * addCallback(handler)
// * addErrback(handler)
// * callback(result)
// * errback(result)
//
// In general, when a function returns a Deferred, users then "fill
// in" the second half of the contract by registering callbacks and
// error handlers. You may register as many callback and errback
// handlers as you like and they will be executed in the order
// registered when a result is provided. Usually this result is
// provided as the result of an asynchronous operation. The code
// "managing" the Deferred (the code that made the promise to provide
// an answer later) will use the callback() and errback() methods to
// communicate with registered listeners about the result of the
// operation. At this time, all registered result handlers are called
// *with the most recent result value*.
//
// Deferred callback handlers are treated as a chain, and each item in
// the chain is required to return a value that will be fed into
// successive handlers. The most minimal callback may be registered
// like this:
//
// | var d = new dojo.Deferred();
// | d.addCallback(function(result){ return result; });
//
// Perhaps the most common mistake when first using Deferreds is to
// forget to return a value (in most cases, the value you were
// passed).
//
// The sequence of callbacks is internally represented as a list of
// 2-tuples containing the callback/errback pair. For example, the
// following call sequence:
//
// | var d = new dojo.Deferred();
// | d.addCallback(myCallback);
// | d.addErrback(myErrback);
// | d.addBoth(myBoth);
// | d.addCallbacks(myCallback, myErrback);
//
// is translated into a Deferred with the following internal
// representation:
//
// | [
// | [myCallback, null],
// | [null, myErrback],
// | [myBoth, myBoth],
// | [myCallback, myErrback]
// | ]
//
// The Deferred also keeps track of its current status (fired). Its
// status may be one of three things:
//
// * -1: no value yet (initial condition)
// * 0: success
// * 1: error
//
// A Deferred will be in the error state if one of the following three
// conditions are met:
//
// 1. The result given to callback or errback is "instanceof" Error
// 2. The previous callback or errback raised an exception while
// executing
// 3. The previous callback or errback returned a value
// "instanceof" Error
//
// Otherwise, the Deferred will be in the success state. The state of
// the Deferred determines the next element in the callback sequence
// to run.
//
// When a callback or errback occurs with the example deferred chain,
// something equivalent to the following will happen (imagine
// that exceptions are caught and returned):
//
// | // d.callback(result) or d.errback(result)
// | if(!(result instanceof Error)){
// | result = myCallback(result);
// | }
// | if(result instanceof Error){
// | result = myErrback(result);
// | }
// | result = myBoth(result);
// | if(result instanceof Error){
// | result = myErrback(result);
// | }else{
// | result = myCallback(result);
// | }
//
// The result is then stored away in case another step is added to the
// callback sequence. Since the Deferred already has a value
// available, any new callbacks added will be called immediately.
//
// There are two other "advanced" details about this implementation
// that are useful:
//
// Callbacks are allowed to return Deferred instances themselves, so
// you can build complicated sequences of events with ease.
//
// The creator of the Deferred may specify a canceller. The canceller
// is a function that will be called if Deferred.cancel is called
// before the Deferred fires. You can use this to implement clean
// aborting of an XMLHttpRequest, etc. Note that cancel will fire the
// deferred with a CancelledError (unless your canceller returns
// another kind of error), so the errbacks should be prepared to
// handle that error for cancellable Deferreds.
// example:
// | var deferred = new dojo.Deferred();
// | setTimeout(function(){ deferred.callback({success: true}); }, 1000);
// | return deferred;
// example:
// Deferred objects are often used when making code asynchronous. It
// may be easiest to write functions in a synchronous manner and then
// split code using a deferred to trigger a response to a long-lived
// operation. For example, instead of register a callback function to
// denote when a rendering operation completes, the function can
// simply return a deferred:
//
// | // callback style:
// | function renderLotsOfData(data, callback){
// | var success = false
// | try{
// | for(var x in data){
// | renderDataitem(data[x]);
// | }
// | success = true;
// | }catch(e){ }
// | if(callback){
// | callback(success);
// | }
// | }
//
// | // using callback style
// | renderLotsOfData(someDataObj, function(success){
// | // handles success or failure
// | if(!success){
// | promptUserToRecover();
// | }
// | });
// | // NOTE: no way to add another callback here!!
// example:
// Using a Deferred doesn't simplify the sending code any, but it
// provides a standard interface for callers and senders alike,
// providing both with a simple way to service multiple callbacks for
// an operation and freeing both sides from worrying about details
// such as "did this get called already?". With Deferreds, new
// callbacks can be added at any time.
//
// | // Deferred style:
// | function renderLotsOfData(data){
// | var d = new dojo.Deferred();
// | try{
// | for(var x in data){
// | renderDataitem(data[x]);
// | }
// | d.callback(true);
// | }catch(e){
// | d.errback(new Error("rendering failed"));
// | }
// | return d;
// | }
//
// | // using Deferred style
// | renderLotsOfData(someDataObj).addErrback(function(){
// | promptUserToRecover();
// | });
// | // NOTE: addErrback and addCallback both return the Deferred
// | // again, so we could chain adding callbacks or save the
// | // deferred for later should we need to be notified again.
// example:
// In this example, renderLotsOfData is syncrhonous and so both
// versions are pretty artificial. Putting the data display on a
// timeout helps show why Deferreds rock:
//
// | // Deferred style and async func
// | function renderLotsOfData(data){
// | var d = new dojo.Deferred();
// | setTimeout(function(){
// | try{
// | for(var x in data){
// | renderDataitem(data[x]);
// | }
// | d.callback(true);
// | }catch(e){
// | d.errback(new Error("rendering failed"));
// | }
// | }, 100);
// | return d;
// | }
//
// | // using Deferred style
// | renderLotsOfData(someDataObj).addErrback(function(){
// | promptUserToRecover();
// | });
//
// Note that the caller doesn't have to change his code at all to
// handle the asynchronous case.
this.chain = [];
this.id = this._nextId();
this.fired = -1;
this.paused = 0;
this.results = [null, null];
this.canceller = canceller;
this.silentlyCancelled = false;
};
dojo.extend(dojo.Deferred, {
/*
makeCalled: function(){
// summary:
// returns a new, empty deferred, which is already in the called
// state. Calling callback() or errback() on this deferred will
// yeild an error and adding new handlers to it will result in
// them being called immediately.
var deferred = new dojo.Deferred();
deferred.callback();
return deferred;
},
toString: function(){
var state;
if(this.fired == -1){
state = 'unfired';
}else{
state = this.fired ? 'success' : 'error';
}
return 'Deferred(' + this.id + ', ' + state + ')';
},
*/
_nextId: (function(){
var n = 1;
return function(){ return n++; };
})(),
cancel: function(){
// summary:
// Cancels a Deferred that has not yet received a value, or is
// waiting on another Deferred as its value.
// description:
// If a canceller is defined, the canceller is called. If the
// canceller did not return an error, or there was no canceller,
// then the errback chain is started.
var err;
if(this.fired == -1){
if(this.canceller){
err = this.canceller(this);
}else{
this.silentlyCancelled = true;
}
if(this.fired == -1){
if(!(err instanceof Error)){
var res = err;
err = new Error("Deferred Cancelled");
err.dojoType = "cancel";
err.cancelResult = res;
}
this.errback(err);
}
}else if( (this.fired == 0) &&
(this.results[0] instanceof dojo.Deferred)
){
this.results[0].cancel();
}
},
_resback: function(res){
// summary:
// The private primitive that means either callback or errback
this.fired = ((res instanceof Error) ? 1 : 0);
this.results[this.fired] = res;
this._fire();
},
_check: function(){
if(this.fired != -1){
if(!this.silentlyCancelled){
throw new Error("already called!");
}
this.silentlyCancelled = false;
return;
}
},
callback: function(res){
// summary:
// Begin the callback sequence with a non-error value.
/*
callback or errback should only be called once on a given
Deferred.
*/
this._check();
this._resback(res);
},
errback: function(/*Error*/res){
// summary:
// Begin the callback sequence with an error result.
this._check();
if(!(res instanceof Error)){
res = new Error(res);
}
this._resback(res);
},
addBoth: function(/*Function|Object*/cb, /*String?*/cbfn){
// summary:
// Add the same function as both a callback and an errback as the
// next element on the callback sequence.This is useful for code
// that you want to guarantee to run, e.g. a finalizer.
var enclosed = dojo.hitch.apply(dojo, arguments);
return this.addCallbacks(enclosed, enclosed);
},
addCallback: function(/*Function|Object*/cb, /*String?*/cbfn /*...*/){
// summary:
// Add a single callback to the end of the callback sequence.
return this.addCallbacks(dojo.hitch.apply(dojo, arguments));
},
addErrback: function(cb, cbfn){
// summary:
// Add a single callback to the end of the callback sequence.
return this.addCallbacks(null, dojo.hitch.apply(dojo, arguments));
},
addCallbacks: function(cb, eb){
// summary:
// Add separate callback and errback to the end of the callback
// sequence.
this.chain.push([cb, eb])
if(this.fired >= 0){
this._fire();
}
return this;
},
_fire: function(){
// summary:
// Used internally to exhaust the callback sequence when a result
// is available.
var chain = this.chain;
var fired = this.fired;
var res = this.results[fired];
var self = this;
var cb = null;
while(
(chain.length > 0) &&
(this.paused == 0)
){
// Array
var f = chain.shift()[fired];
if(!f){ continue; }
try{
res = f(res);
fired = ((res instanceof Error) ? 1 : 0);
if(res instanceof dojo.Deferred){
cb = function(res){
self._resback(res);
// inlined from _pause()
self.paused--;
if(
(self.paused == 0) &&
(self.fired >= 0)
){
self._fire();
}
}
// inlined from _unpause
this.paused++;
}
}catch(err){
console.debug(err);
fired = 1;
res = err;
}
}
this.fired = fired;
this.results[fired] = res;
if((cb)&&(this.paused)){
// this is for "tail recursion" in case the dependent
// deferred is already fired
res.addBoth(cb);
}
}
});
}
if(!dojo._hasResource["dojo._base.json"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dojo._base.json"] = true;
dojo.provide("dojo._base.json");
dojo.fromJson = function(/*String*/ json){
// summary:
// Parses a [JSON](http://json.org) string to return a JavaScript object.
// json:
// a string literal of a JSON item, for instance:
// `'{ "foo": [ "bar", 1, { "baz": "thud" } ] }'`
return eval("(" + json + ")"); // Object
}
dojo._escapeString = function(/*String*/str){
//summary:
// Adds escape sequences for non-visual characters, double quote and
// backslash and surrounds with double quotes to form a valid string
// literal.
return ('"' + str.replace(/(["\\])/g, '\\$1') + '"').
replace(/[\f]/g, "\\f").replace(/[\b]/g, "\\b").replace(/[\n]/g, "\\n").
replace(/[\t]/g, "\\t").replace(/[\r]/g, "\\r"); // string
}
dojo.toJsonIndentStr = "\t";
dojo.toJson = function(/*Object*/ it, /*Boolean?*/ prettyPrint, /*String?*/ _indentStr){
// summary:
// Returns a [JSON](http://json.org) serialization of an object.
//
// description:
// Returns a [JSON](http://json.org) serialization of an object.
// Note that this doesn't check for infinite recursion, so don't do that!
//
// it:
// an object to be serialized. Objects may define their own
// serialization via a special "__json__" or "json" function
// property. If a specialized serializer has been defined, it will
// be used as a fallback.
//
// prettyPrint:
// if true, we indent objects and arrays to make the output prettier.
// The variable dojo.toJsonIndentStr is used as the indent string
// -- to use something other than the default (tab),
// change that variable before calling dojo.toJson().
//
// _indentStr:
// private variable for recursive calls when pretty printing, do not use.
if(it === undefined){
return "undefined";
}
var objtype = typeof it;
if(objtype == "number" || objtype == "boolean"){
return it + "";
}
if(it === null){
return "null";
}
if(dojo.isString(it)){
return dojo._escapeString(it);
}
if(it.nodeType && it.cloneNode){ // isNode
return ""; // FIXME: would something like outerHTML be better here?
}
// recurse
var recurse = arguments.callee;
// short-circuit for objects that support "json" serialization
// if they return "self" then just pass-through...
var newObj;
_indentStr = _indentStr || "";
var nextIndent = prettyPrint ? _indentStr + dojo.toJsonIndentStr : "";
if(typeof it.__json__ == "function"){
newObj = it.__json__();
if(it !== newObj){
return recurse(newObj, prettyPrint, nextIndent);
}
}
if(typeof it.json == "function"){
newObj = it.json();
if(it !== newObj){
return recurse(newObj, prettyPrint, nextIndent);
}
}
var sep = prettyPrint ? " " : "";
var newLine = prettyPrint ? "\n" : "";
// array
if(dojo.isArray(it)){
var res = dojo.map(it, function(obj){
var val = recurse(obj, prettyPrint, nextIndent);
if(typeof val != "string"){
val = "undefined";
}
return newLine + nextIndent + val;
});
return "[" + res.join("," + sep) + newLine + _indentStr + "]";
}
/*
// look in the registry
try {
window.o = it;
newObj = dojo.json.jsonRegistry.match(it);
return recurse(newObj, prettyPrint, nextIndent);
}catch(e){
// console.debug(e);
}
// it's a function with no adapter, skip it
*/
if(objtype == "function"){
return null; // null
}
// generic object code path
var output = [];
for(var key in it){
var keyStr;
if(typeof key == "number"){
keyStr = '"' + key + '"';
}else if(typeof key == "string"){
keyStr = dojo._escapeString(key);
}else{
// skip non-string or number keys
continue;
}
val = recurse(it[key], prettyPrint, nextIndent);
if(typeof val != "string"){
// skip non-serializable values
continue;
}
// FIXME: use += on Moz!!
// MOW NOTE: using += is a pain because you have to account for the dangling comma...
output.push(newLine + nextIndent + keyStr + ":" + sep + val);
}
return "{" + output.join("," + sep) + newLine + _indentStr + "}"; // String
}
}
if(!dojo._hasResource["dojo._base.array"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dojo._base.array"] = true;
dojo.provide("dojo._base.array");
(function(){
var _getParts = function(arr, obj, cb){
return [
dojo.isString(arr) ? arr.split("") : arr,
obj || dojo.global,
// FIXME: cache the anonymous functions we create here?
dojo.isString(cb) ? new Function("item", "index", "array", cb) : cb
];
};
dojo.mixin(dojo, {
indexOf: function( /*Array*/ array,
/*Object*/ value,
/*Integer?*/ fromIndex,
/*Boolean?*/ findLast){
// summary:
// locates the first index of the provided value in the
// passed array. If the value is not found, -1 is returned.
// description:
// For details on this method, see:
// <http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:indexOf>
var step = 1, end = array.length || 0, i = 0;
if(findLast){
i = end - 1;
step = end = -1;
}
if(fromIndex != undefined){ i = fromIndex; }
if((findLast && i > end) || i < end){
for(; i != end; i += step){
if(array[i] == value){ return i; }
}
}
return -1; // Number
},
lastIndexOf: function(/*Array*/array, /*Object*/value, /*Integer?*/fromIndex){
// summary:
// locates the last index of the provided value in the passed array.
// If the value is not found, -1 is returned.
// description:
// For details on this method, see:
// <http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:lastIndexOf>
return dojo.indexOf(array, value, fromIndex, true); // Number
},
forEach: function(/*Array|String*/arr, /*Function|String*/callback, /*Object?*/thisObject){
// summary:
// for every item in arr, callback is invoked. Return values are ignored.
// arr: the array to iterate on. If a string, operates on individual characters.
// callback: a function is invoked with three arguments: item, index, and array
// thisObject: may be used to scope the call to callback
// description:
// This function corresponds to the JavaScript 1.6 Array.forEach() method.
// In environments that support JavaScript 1.6, this function is a passthrough to the built-in method.
// For more details, see:
// <http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:forEach>
// match the behavior of the built-in forEach WRT empty arrs
if(!arr || !arr.length){ return; }
// FIXME: there are several ways of handilng thisObject. Is
// dojo.global always the default context?
var _p = _getParts(arr, thisObject, callback); arr = _p[0];
for(var i=0,l=_p[0].length; i<l; i++){
_p[2].call(_p[1], arr[i], i, arr);
}
},
_everyOrSome: function(/*Boolean*/every, /*Array|String*/arr, /*Function|String*/callback, /*Object?*/thisObject){
var _p = _getParts(arr, thisObject, callback); arr = _p[0];
for(var i = 0, l = arr.length; i < l; i++){
var result = !!_p[2].call(_p[1], arr[i], i, arr);
if(every ^ result){
return result; // Boolean
}
}
return every; // Boolean
},
every: function(/*Array|String*/arr, /*Function|String*/callback, /*Object?*/thisObject){
// summary:
// Determines whether or not every item in arr satisfies the
// condition implemented by callback.
// arr: the array to iterate on. If a string, operates on individual characters.
// callback: a function is invoked with three arguments: item, index, and array and returns true
// if the condition is met.
// thisObject: may be used to scope the call to callback
// description:
// This function corresponds to the JavaScript 1.6 Array.every() method.
// In environments that support JavaScript 1.6, this function is a passthrough to the built-in method.
// For more details, see:
// <http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:every>
// example:
// | dojo.every([1, 2, 3, 4], function(item){ return item>1; });
// returns false
// example:
// | dojo.every([1, 2, 3, 4], function(item){ return item>0; });
// returns true
return this._everyOrSome(true, arr, callback, thisObject); // Boolean
},
some: function(/*Array|String*/arr, /*Function|String*/callback, /*Object?*/thisObject){
// summary:
// Determines whether or not any item in arr satisfies the
// condition implemented by callback.
// arr: the array to iterate on. If a string, operates on individual characters.
// callback: a function is invoked with three arguments: item, index, and array and returns true
// if the condition is met.
// thisObject: may be used to scope the call to callback
// description:
// This function corresponds to the JavaScript 1.6 Array.some() method.
// In environments that support JavaScript 1.6, this function is a passthrough to the built-in method.
// For more details, see:
// <http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:some>
// example:
// | dojo.some([1, 2, 3, 4], function(item){ return item>1; });
// returns true
// example:
// | dojo.some([1, 2, 3, 4], function(item){ return item<1; });
// returns false
return this._everyOrSome(false, arr, callback, thisObject); // Boolean
},
map: function(/*Array|String*/arr, /*Function|String*/callback, /*Function?*/thisObject){
// summary:
// applies callback to each element of arr and returns
// an Array with the results
// arr: the array to iterate on. If a string, operates on individual characters.
// callback: a function is invoked with three arguments: item, index, and array and returns a value
// thisObject: may be used to scope the call to callback
// description:
// This function corresponds to the JavaScript 1.6 Array.map() method.
// In environments that support JavaScript 1.6, this function is a passthrough to the built-in method.
// For more details, see:
// <http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:map>
// example:
// | dojo.map([1, 2, 3, 4], function(item){ return item+1 });
// returns [2, 3, 4, 5]
var _p = _getParts(arr, thisObject, callback); arr = _p[0];
var outArr = (arguments[3] ? (new arguments[3]()) : []);
for(var i=0;i<arr.length;++i){
outArr.push(_p[2].call(_p[1], arr[i], i, arr));
}
return outArr; // Array
},
filter: function(/*Array*/arr, /*Function|String*/callback, /*Object?*/thisObject){
// summary:
// Returns a new Array with those items from arr that match the
// condition implemented by callback.
// arr: the array to iterate on. If a string, operates on individual characters.
// callback: a function is invoked with three arguments: item, index, and array and returns true
// if the condition is met.
// thisObject: may be used to scope the call to callback
// description:
// This function corresponds to the JavaScript 1.6 Array.filter() method.
// In environments that support JavaScript 1.6, this function is a passthrough to the built-in method.
// For more details, see:
// <http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:filter>
// example:
// | dojo.filter([1, 2, 3, 4], function(item){ return item>1; });
// returns [2, 3, 4]
var _p = _getParts(arr, thisObject, callback); arr = _p[0];
var outArr = [];
for(var i = 0; i < arr.length; i++){
if(_p[2].call(_p[1], arr[i], i, arr)){
outArr.push(arr[i]);
}
}
return outArr; // Array
}
});
})();
}
if(!dojo._hasResource["dojo._base.Color"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dojo._base.Color"] = true;
dojo.provide("dojo._base.Color");
dojo.Color = function(/*Array|String|Object*/ color){
// summary:
// takes a named string, hex string, array of rgb or rgba values,
// an object with r, g, b, and a properties, or another dojo.Color object
if(color){ this.setColor(color); }
};
// FIXME: there's got to be a more space-efficient way to encode or discover these!! Use hex?
dojo.Color.named = {
black: [0,0,0],
silver: [192,192,192],
gray: [128,128,128],
white: [255,255,255],
maroon: [128,0,0],
red: [255,0,0],
purple: [128,0,128],
fuchsia: [255,0,255],
green: [0,128,0],
lime: [0,255,0],
olive: [128,128,0],
yellow: [255,255,0],
navy: [0,0,128],
blue: [0,0,255],
teal: [0,128,128],
aqua: [0,255,255]
};
dojo.extend(dojo.Color, {
r: 255, g: 255, b: 255, a: 1,
_set: function(r, g, b, a){
var t = this; t.r = r; t.g = g; t.b = b; t.a = a;
},
setColor: function(/*Array|String|Object*/ color){
// summary:
// takes a named string, hex string, array of rgb or rgba values,
// an object with r, g, b, and a properties, or another dojo.Color object
var d = dojo;
if(d.isString(color)){
d.colorFromString(color, this);
}else if(d.isArray(color)){
d.colorFromArray(color, this);
}else{
this._set(color.r, color.g, color.b, color.a);
if(!(color instanceof d.Color)){ this.sanitize(); }
}
return this; // dojo.Color
},
sanitize: function(){
// summary:
// makes sure that the object has correct attributes
// description:
// the default implementation does nothing, include dojo.colors to
// augment it to real checks
return this; // dojo.Color
},
toRgb: function(){
// summary: returns 3 component array of rgb values
var t = this;
return [t.r, t.g, t.b]; // Array
},
toRgba: function(){
// summary: returns a 4 component array of rgba values
var t = this;
return [t.r, t.g, t.b, t.a]; // Array
},
toHex: function(){
// summary: returns a css color string in hexadecimal representation
var arr = dojo.map(["r", "g", "b"], function(x){
var s = this[x].toString(16);
return s.length < 2 ? "0" + s : s;
}, this);
return "#" + arr.join(""); // String
},
toCss: function(/*Boolean?*/ includeAlpha){
// summary: returns a css color string in rgb(a) representation
var t = this, rgb = t.r + ", " + t.g + ", " + t.b;
return (includeAlpha ? "rgba(" + rgb + ", " + t.a : "rgb(" + rgb) + ")"; // String
},
toString: function(){
// summary: returns a visual representation of the color
return this.toCss(true); // String
}
});
dojo.blendColors = function(
/*dojo.Color*/ start,
/*dojo.Color*/ end,
/*Number*/ weight,
/*dojo.Color?*/ obj
){
// summary:
// blend colors end and start with weight from 0 to 1, 0.5 being a 50/50 blend,
// can reuse a previously allocated dojo.Color object for the result
var d = dojo, t = obj || new dojo.Color();
d.forEach(["r", "g", "b", "a"], function(x){
t[x] = start[x] + (end[x] - start[x]) * weight;
if(x != "a"){ t[x] = Math.round(t[x]); }
});
return t.sanitize(); // dojo.Color
};
dojo.colorFromRgb = function(/*String*/ color, /*dojo.Color?*/ obj){
// summary: get rgb(a) array from css-style color declarations
var m = color.toLowerCase().match(/^rgba?\(([\s\.,0-9]+)\)/);
return m && dojo.colorFromArray(m[1].split(/\s*,\s*/), obj); // dojo.Color
};
dojo.colorFromHex = function(/*String*/ color, /*dojo.Color?*/ obj){
// summary: converts a hex string with a '#' prefix to a color object.
// Supports 12-bit #rgb shorthand.
var d = dojo, t = obj || new d.Color(),
bits = (color.length == 4) ? 4 : 8,
mask = (1 << bits) - 1;
color = Number("0x" + color.substr(1));
if(isNaN(color)){
return null; // dojo.Color
}
d.forEach(["b", "g", "r"], function(x){
var c = color & mask;
color >>= bits;
t[x] = bits == 4 ? 17 * c : c;
});
t.a = 1;
return t; // dojo.Color
};
dojo.colorFromArray = function(/*Array*/ a, /*dojo.Color?*/ obj){
// summary: builds a color from 1, 2, 3, or 4 element array
var t = obj || new dojo.Color();
t._set(Number(a[0]), Number(a[1]), Number(a[2]), Number(a[3]));
if(isNaN(t.a)){ t.a = 1; }
return t.sanitize(); // dojo.Color
};
dojo.colorFromString = function(/*String*/ str, /*dojo.Color?*/ obj){
// summary:
// parses str for a color value.
// description:
// Acceptable input values for str may include arrays of any form
// accepted by dojo.colorFromArray, hex strings such as "#aaaaaa", or
// rgb or rgba strings such as "rgb(133, 200, 16)" or "rgba(10, 10,
// 10, 50)"
// returns:
// a dojo.Color object. If obj is passed, it will be the return value.
var a = dojo.Color.named[str];
return a && dojo.colorFromArray(a, obj) || dojo.colorFromRgb(str, obj) || dojo.colorFromHex(str, obj);
};
}
if(!dojo._hasResource["dojo._base"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dojo._base"] = true;
dojo.provide("dojo._base");
}
if(!dojo._hasResource["dojo._base.window"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dojo._base.window"] = true;
dojo.provide("dojo._base.window");
dojo._gearsObject = function(){
// summary:
// factory method to get a Google Gears plugin instance to
// expose in the browser runtime environment, if present
var factory;
var results;
var gearsObj = dojo.getObject("google.gears");
if(gearsObj){ return gearsObj; } // already defined elsewhere
if(typeof GearsFactory != "undefined"){ // Firefox
factory = new GearsFactory();
}else{
if(dojo.isIE){
// IE
try{
factory = new ActiveXObject("Gears.Factory");
}catch(e){
// ok to squelch; there's no gears factory. move on.
}
}else if(navigator.mimeTypes["application/x-googlegears"]){
// Safari?
factory = document.createElement("object");
factory.setAttribute("type", "application/x-googlegears");
factory.setAttribute("width", 0);
factory.setAttribute("height", 0);
factory.style.display = "none";
document.documentElement.appendChild(factory);
}
}
// still nothing?
if(!factory){ return null; }
// define the global objects now; don't overwrite them though if they
// were somehow set internally by the Gears plugin, which is on their
// dev roadmap for the future
dojo.setObject("google.gears.factory", factory);
return dojo.getObject("google.gears");
};
/*=====
dojo.isGears = {
// summary: True if client is using Google Gears
};
=====*/
// see if we have Google Gears installed, and if
// so, make it available in the runtime environment
// and in the Google standard 'google.gears' global object
dojo.isGears = (!!dojo._gearsObject())||0;
/*=====
dojo.doc = {
// summary:
// Alias for the current document. 'dojo.doc' can be modified
// for temporary context shifting. Also see dojo.withDoc().
// description:
// Refer to dojo.doc rather
// than referring to 'window.document' to ensure your code runs
// correctly in managed contexts.
// example:
// | n.appendChild(dojo.doc.createElement('div'));
}
=====*/
dojo.doc = window["document"] || null;
dojo.body = function(){
// summary:
// Return the body element of the document
// return the body object associated with dojo.doc
// example:
// | dojo.body().appendChild(dojo.doc.createElement('div'));
// Note: document.body is not defined for a strict xhtml document
// Would like to memoize this, but dojo.doc can change vi dojo.withDoc().
return dojo.doc.body || dojo.doc.getElementsByTagName("body")[0]; // Node
}
dojo.setContext = function(/*Object*/globalObject, /*DocumentElement*/globalDocument){
// summary:
// changes the behavior of many core Dojo functions that deal with
// namespace and DOM lookup, changing them to work in a new global
// context (e.g., an iframe). The varibles dojo.global and dojo.doc
// are modified as a result of calling this function and the result of
// `dojo.body()` likewise differs.
dojo.global = globalObject;
dojo.doc = globalDocument;
};
dojo._fireCallback = function(callback, context, cbArguments){
if(context && dojo.isString(callback)){
callback = context[callback];
}
return callback.apply(context, cbArguments || [ ]);
}
dojo.withGlobal = function( /*Object*/globalObject,
/*Function*/callback,
/*Object?*/thisObject,
/*Array?*/cbArguments){
// summary:
// Call callback with globalObject as dojo.global and
// globalObject.document as dojo.doc. If provided, globalObject
// will be executed in the context of object thisObject
// description:
// When callback() returns or throws an error, the dojo.global
// and dojo.doc will be restored to its previous state.
var rval;
var oldGlob = dojo.global;
var oldDoc = dojo.doc;
try{
dojo.setContext(globalObject, globalObject.document);
rval = dojo._fireCallback(callback, thisObject, cbArguments);
}finally{
dojo.setContext(oldGlob, oldDoc);
}
return rval;
}
dojo.withDoc = function( /*Object*/documentObject,
/*Function*/callback,
/*Object?*/thisObject,
/*Array?*/cbArguments){
// summary:
// Call callback with documentObject as dojo.doc. If provided,
// callback will be executed in the context of object thisObject
// description:
// When callback() returns or throws an error, the dojo.doc will
// be restored to its previous state.
var rval;
var oldDoc = dojo.doc;
try{
dojo.doc = documentObject;
rval = dojo._fireCallback(callback, thisObject, cbArguments);
}finally{
dojo.doc = oldDoc;
}
return rval;
};
}
if(!dojo._hasResource["dojo._base.event"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dojo._base.event"] = true;
dojo.provide("dojo._base.event");
// this file courtesy of the TurboAjax Group, licensed under a Dojo CLA
(function(){
// DOM event listener machinery
var del = (dojo._event_listener = {
add: function(/*DOMNode*/node, /*String*/name, /*Function*/fp){
if(!node){return;}
name = del._normalizeEventName(name);
fp = del._fixCallback(name, fp);
var oname = name;
if(!dojo.isIE && (name == "mouseenter" || name == "mouseleave")){
var ofp = fp;
//oname = name;
name = (name == "mouseenter") ? "mouseover" : "mouseout";
fp = function(e){
// thanks ben!
if(!dojo.isDescendant(e.relatedTarget, node)){
// e.type = oname; // FIXME: doesn't take? SJM: event.type is generally immutable.
return ofp.call(this, e);
}
}
}
node.addEventListener(name, fp, false);
return fp; /*Handle*/
},
remove: function(/*DOMNode*/node, /*String*/event, /*Handle*/handle){
// summary:
// clobbers the listener from the node
// node:
// DOM node to attach the event to
// event:
// the name of the handler to remove the function from
// handle:
// the handle returned from add
if (node){
node.removeEventListener(del._normalizeEventName(event), handle, false);
}
},
_normalizeEventName: function(/*String*/name){
// Generally, name should be lower case, unless it is special
// somehow (e.g. a Mozilla DOM event).
// Remove 'on'.
return name.slice(0,2) =="on" ? name.slice(2) : name;
},
_fixCallback: function(/*String*/name, fp){
// By default, we only invoke _fixEvent for 'keypress'
// If code is added to _fixEvent for other events, we have
// to revisit this optimization.
// This also applies to _fixEvent overrides for Safari and Opera
// below.
return name != "keypress" ? fp : function(e){ return fp.call(this, del._fixEvent(e, this)); };
},
_fixEvent: function(evt, sender){
// _fixCallback only attaches us to keypress.
// Switch on evt.type anyway because we might
// be called directly from dojo.fixEvent.
switch(evt.type){
case "keypress":
del._setKeyChar(evt);
break;
}
return evt;
},
_setKeyChar: function(evt){
evt.keyChar = evt.charCode ? String.fromCharCode(evt.charCode) : '';
}
});
// DOM events
dojo.fixEvent = function(/*Event*/evt, /*DOMNode*/sender){
// summary:
// normalizes properties on the event object including event
// bubbling methods, keystroke normalization, and x/y positions
// evt: Event
// native event object
// sender: DOMNode
// node to treat as "currentTarget"
return del._fixEvent(evt, sender);
}
dojo.stopEvent = function(/*Event*/evt){
// summary:
// prevents propagation and clobbers the default action of the
// passed event
// evt: Event
// The event object. If omitted, window.event is used on IE.
evt.preventDefault();
evt.stopPropagation();
// NOTE: below, this method is overridden for IE
}
// the default listener to use on dontFix nodes, overriden for IE
var node_listener = dojo._listener;
// Unify connect and event listeners
dojo._connect = function(obj, event, context, method, dontFix){
// FIXME: need a more strict test
var isNode = obj && (obj.nodeType||obj.attachEvent||obj.addEventListener);
// choose one of three listener options: raw (connect.js), DOM event on a Node, custom event on a Node
// we need the third option to provide leak prevention on broken browsers (IE)
var lid = !isNode ? 0 : (!dontFix ? 1 : 2), l = [dojo._listener, del, node_listener][lid];
// create a listener
var h = l.add(obj, event, dojo.hitch(context, method));
// formerly, the disconnect package contained "l" directly, but if client code
// leaks the disconnect package (by connecting it to a node), referencing "l"
// compounds the problem.
// instead we return a listener id, which requires custom _disconnect below.
// return disconnect package
return [ obj, event, h, lid ];
}
dojo._disconnect = function(obj, event, handle, listener){
([dojo._listener, del, node_listener][listener]).remove(obj, event, handle);
}
// Constants
// Public: client code should test
// keyCode against these named constants, as the
// actual codes can vary by browser.
dojo.keys = {
// summary: definitions for common key values
BACKSPACE: 8,
TAB: 9,
CLEAR: 12,
ENTER: 13,
SHIFT: 16,
CTRL: 17,
ALT: 18,
PAUSE: 19,
CAPS_LOCK: 20,
ESCAPE: 27,
SPACE: 32,
PAGE_UP: 33,
PAGE_DOWN: 34,
END: 35,
HOME: 36,
LEFT_ARROW: 37,
UP_ARROW: 38,
RIGHT_ARROW: 39,
DOWN_ARROW: 40,
INSERT: 45,
DELETE: 46,
HELP: 47,
LEFT_WINDOW: 91,
RIGHT_WINDOW: 92,
SELECT: 93,
NUMPAD_0: 96,
NUMPAD_1: 97,
NUMPAD_2: 98,
NUMPAD_3: 99,
NUMPAD_4: 100,
NUMPAD_5: 101,
NUMPAD_6: 102,
NUMPAD_7: 103,
NUMPAD_8: 104,
NUMPAD_9: 105,
NUMPAD_MULTIPLY: 106,
NUMPAD_PLUS: 107,
NUMPAD_ENTER: 108,
NUMPAD_MINUS: 109,
NUMPAD_PERIOD: 110,
NUMPAD_DIVIDE: 111,
F1: 112,
F2: 113,
F3: 114,
F4: 115,
F5: 116,
F6: 117,
F7: 118,
F8: 119,
F9: 120,
F10: 121,
F11: 122,
F12: 123,
F13: 124,
F14: 125,
F15: 126,
NUM_LOCK: 144,
SCROLL_LOCK: 145
};
// IE event normalization
if(dojo.isIE){
var _trySetKeyCode = function(e, code){
try{
// squelch errors when keyCode is read-only
// (e.g. if keyCode is ctrl or shift)
return (e.keyCode = code);
}catch(e){
return 0;
}
}
// by default, use the standard listener
var iel = dojo._listener;
// dispatcher tracking property
if(!dojo.config._allow_leaks){
// custom listener that handles leak protection for DOM events
node_listener = iel = dojo._ie_listener = {
// support handler indirection: event handler functions are
// referenced here. Event dispatchers hold only indices.
handlers: [],
// add a listener to an object
add: function(/*Object*/ source, /*String*/ method, /*Function*/ listener){
source = source || dojo.global;
var f = source[method];
if(!f||!f._listeners){
var d = dojo._getIeDispatcher();
// original target function is special
d.target = f && (ieh.push(f) - 1);
// dispatcher holds a list of indices into handlers table
d._listeners = [];
// redirect source to dispatcher
f = source[method] = d;
}
return f._listeners.push(ieh.push(listener) - 1) ; /*Handle*/
},
// remove a listener from an object
remove: function(/*Object*/ source, /*String*/ method, /*Handle*/ handle){
var f = (source||dojo.global)[method], l = f && f._listeners;
if(f && l && handle--){
delete ieh[l[handle]];
delete l[handle];
}
}
};
// alias used above
var ieh = iel.handlers;
}
dojo.mixin(del, {
add: function(/*DOMNode*/node, /*String*/event, /*Function*/fp){
if(!node){return;} // undefined
event = del._normalizeEventName(event);
if(event=="onkeypress"){
// we need to listen to onkeydown to synthesize
// keypress events that otherwise won't fire
// on IE
var kd = node.onkeydown;
if(!kd || !kd._listeners || !kd._stealthKeydownHandle){
var h = del.add(node, "onkeydown", del._stealthKeyDown);
kd = node.onkeydown;
kd._stealthKeydownHandle = h;
kd._stealthKeydownRefs = 1;
}else{
kd._stealthKeydownRefs++;
}
}
return iel.add(node, event, del._fixCallback(fp));
},
remove: function(/*DOMNode*/node, /*String*/event, /*Handle*/handle){
event = del._normalizeEventName(event);
iel.remove(node, event, handle);
if(event=="onkeypress"){
var kd = node.onkeydown;
if(--kd._stealthKeydownRefs <= 0){
iel.remove(node, "onkeydown", kd._stealthKeydownHandle);
delete kd._stealthKeydownHandle;
}
}
},
_normalizeEventName: function(/*String*/eventName){
// Generally, eventName should be lower case, unless it is
// special somehow (e.g. a Mozilla event)
// ensure 'on'
return eventName.slice(0,2) != "on" ? "on" + eventName : eventName;
},
_nop: function(){},
_fixEvent: function(/*Event*/evt, /*DOMNode*/sender){
// summary:
// normalizes properties on the event object including event
// bubbling methods, keystroke normalization, and x/y positions
// evt: native event object
// sender: node to treat as "currentTarget"
if(!evt){
var w = sender && (sender.ownerDocument || sender.document || sender).parentWindow || window;
evt = w.event;
}
if(!evt){return(evt);}
evt.target = evt.srcElement;
evt.currentTarget = (sender || evt.srcElement);
evt.layerX = evt.offsetX;
evt.layerY = evt.offsetY;
// FIXME: scroll position query is duped from dojo.html to
// avoid dependency on that entire module. Now that HTML is in
// Base, we should convert back to something similar there.
var se = evt.srcElement, doc = (se && se.ownerDocument) || document;
// DO NOT replace the following to use dojo.body(), in IE, document.documentElement should be used
// here rather than document.body
var docBody = ((dojo.isIE < 6) || (doc["compatMode"] == "BackCompat")) ? doc.body : doc.documentElement;
var offset = dojo._getIeDocumentElementOffset();
evt.pageX = evt.clientX + dojo._fixIeBiDiScrollLeft(docBody.scrollLeft || 0) - offset.x;
evt.pageY = evt.clientY + (docBody.scrollTop || 0) - offset.y;
if(evt.type == "mouseover"){
evt.relatedTarget = evt.fromElement;
}
if(evt.type == "mouseout"){
evt.relatedTarget = evt.toElement;
}
evt.stopPropagation = del._stopPropagation;
evt.preventDefault = del._preventDefault;
return del._fixKeys(evt);
},
_fixKeys: function(evt){
switch(evt.type){
case "keypress":
var c = ("charCode" in evt ? evt.charCode : evt.keyCode);
if (c==10){
// CTRL-ENTER is CTRL-ASCII(10) on IE, but CTRL-ENTER on Mozilla
c=0;
evt.keyCode = 13;
}else if(c==13||c==27){
c=0; // Mozilla considers ENTER and ESC non-printable
}else if(c==3){
c=99; // Mozilla maps CTRL-BREAK to CTRL-c
}
// Mozilla sets keyCode to 0 when there is a charCode
// but that stops the event on IE.
evt.charCode = c;
del._setKeyChar(evt);
break;
}
return evt;
},
// some ctrl-key combinations (mostly w/punctuation) do not emit a char code in IE
// we map those virtual key codes to ascii here
// not valid for all (non-US) keyboards, so maybe we shouldn't bother
_punctMap: {
106:42,
111:47,
186:59,
187:43,
188:44,
189:45,
190:46,
191:47,
192:96,
219:91,
220:92,
221:93,
222:39
},
_stealthKeyDown: function(evt){
// IE doesn't fire keypress for most non-printable characters.
// other browsers do, we simulate it here.
var kp = evt.currentTarget.onkeypress;
// only works if kp exists and is a dispatcher
if(!kp || !kp._listeners){ return; }
// munge key/charCode
var k=evt.keyCode;
// These are Windows Virtual Key Codes
// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/WinUI/WindowsUserInterface/UserInput/VirtualKeyCodes.asp
var unprintable = (k!=13)&&(k!=32)&&(k!=27)&&(k<48||k>90)&&(k<96||k>111)&&(k<186||k>192)&&(k<219||k>222);
// synthesize keypress for most unprintables and CTRL-keys
if(unprintable||evt.ctrlKey){
var c = unprintable ? 0 : k;
if(evt.ctrlKey){
if(k==3 || k==13){
return; // IE will post CTRL-BREAK, CTRL-ENTER as keypress natively
}else if(c>95 && c<106){
c -= 48; // map CTRL-[numpad 0-9] to ASCII
}else if((!evt.shiftKey)&&(c>=65&&c<=90)){
c += 32; // map CTRL-[A-Z] to lowercase
}else{
c = del._punctMap[c] || c; // map other problematic CTRL combinations to ASCII
}
}
// simulate a keypress event
var faux = del._synthesizeEvent(evt, {type: 'keypress', faux: true, charCode: c});
kp.call(evt.currentTarget, faux);
evt.cancelBubble = faux.cancelBubble;
evt.returnValue = faux.returnValue;
_trySetKeyCode(evt, faux.keyCode);
}
},
// Called in Event scope
_stopPropagation: function(){
this.cancelBubble = true;
},
_preventDefault: function(){
// Setting keyCode to 0 is the only way to prevent certain keypresses (namely
// ctrl-combinations that correspond to menu accelerator keys).
// Otoh, it prevents upstream listeners from getting this information
// Try to split the difference here by clobbering keyCode only for ctrl
// combinations. If you still need to access the key upstream, bubbledKeyCode is
// provided as a workaround.
this.bubbledKeyCode = this.keyCode;
if(this.ctrlKey){_trySetKeyCode(this, 0);}
this.returnValue = false;
}
});
// override stopEvent f |