/* Copyright (c) 2004-2016, The JS Foundation All Rights Reserved. Available via Academic Free License >= 2.1 OR the modified BSD license. see: http://dojotoolkit.org/license for details */ /* This is an optimized version of Dojo, built for deployment and not for development. To get sources and documentation, please visit: http://dojotoolkit.org */ (function( userConfig, defaultConfig ){ // summary: // This is the "source loader" and is the entry point for Dojo during development. You may also load Dojo with // any AMD-compliant loader via the package main module dojo/main. // description: // This is the "source loader" for Dojo. It provides an AMD-compliant loader that can be configured // to operate in either synchronous or asynchronous modes. After the loader is defined, dojo is loaded // IAW the package main module dojo/main. In the event you wish to use a foreign loader, you may load dojo as a package // via the package main module dojo/main and this loader is not required; see dojo/package.json for details. // // In order to keep compatibility with the v1.x line, this loader includes additional machinery that enables // the dojo.provide, dojo.require et al API. This machinery is loaded by default, but may be dynamically removed // via the has.js API and statically removed via the build system. // // This loader includes sniffing machinery to determine the environment; the following environments are supported: // // - browser // - node.js // - rhino // // This is the so-called "source loader". As such, it includes many optional features that may be discarded by // building a customized version with the build system. // Design and Implementation Notes // // This is a dojo-specific adaption of bdLoad, donated to the dojo foundation by Altoviso LLC. // // This function defines an AMD-compliant (http://wiki.commonjs.org/wiki/Modules/AsynchronousDefinition) // loader that can be configured to operate in either synchronous or asynchronous modes. // // Since this machinery implements a loader, it does not have the luxury of using a load system and/or // leveraging a utility library. This results in an unpleasantly long file; here is a road map of the contents: // // 1. Small library for use implementing the loader. // 2. Define the has.js API; this is used throughout the loader to bracket features. // 3. Define the node.js and rhino sniffs and sniff. // 4. Define the loader's data. // 5. Define the configuration machinery. // 6. Define the script element sniffing machinery and sniff for configuration data. // 7. Configure the loader IAW the provided user, default, and sniffing data. // 8. Define the global require function. // 9. Define the module resolution machinery. // 10. Define the module and plugin module definition machinery // 11. Define the script injection machinery. // 12. Define the window load detection. // 13. Define the logging API. // 14. Define the tracing API. // 16. Define the AMD define function. // 17. Define the dojo v1.x provide/require machinery--so called "legacy" modes. // 18. Publish global variables. // // Language and Acronyms and Idioms // // moduleId: a CJS module identifier, (used for public APIs) // mid: moduleId (used internally) // packageId: a package identifier (used for public APIs) // pid: packageId (used internally); the implied system or default package has pid==="" // pack: package is used internally to reference a package object (since javascript has reserved words including "package") // prid: plugin resource identifier // The integer constant 1 is used in place of true and 0 in place of false. // // The "foreign-loader" has condition is defined if another loader is being used (e.g. webpack) and this code is only // needed for resolving module identifiers based on the config. In this case, only the functions require.toUrl and // require.toAbsMid are supported. The require and define functions are not supported. // define global var globalObject = (function(){ if (typeof global !== 'undefined' && typeof global !== 'function') { // global spec defines a reference to the global object called 'global' // https://github.com/tc39/proposal-global // `global` is also defined in NodeJS return global; } else if (typeof window !== 'undefined') { // window is defined in browsers return window; } else if (typeof self !== 'undefined') { // self is defined in WebWorkers return self; } return this; })(); // define a minimal library to help build the loader var noop = function(){ }, isEmpty = function(it){ for(var p in it){ return 0; } return 1; }, toString = {}.toString, isFunction = function(it){ return toString.call(it) == "[object Function]"; }, isString = function(it){ return toString.call(it) == "[object String]"; }, isArray = function(it){ return toString.call(it) == "[object Array]"; }, forEach = function(vector, callback){ if(vector){ for(var i = 0; i < vector.length;){ callback(vector[i++]); } } }, mix = function(dest, src){ for(var p in src){ dest[p] = src[p]; } return dest; }, makeError = function(error, info){ return mix(new Error(error), {src:"dojoLoader", info:info}); }, uidSeed = 1, uid = function(){ // Returns a unique identifier (within the lifetime of the document) of the form /_d+/. return "_" + uidSeed++; }, // FIXME: how to doc window.require() api // this will be the global require function; define it immediately so we can start hanging things off of it req = function( config, //(object, optional) hash of configuration properties dependencies, //(array of commonjs.moduleId, optional) list of modules to be loaded before applying callback callback //(function, optional) lambda expression to apply to module values implied by dependencies ){ return contextRequire(config, dependencies, callback, 0, req); }, // the loader uses the has.js API to control feature inclusion/exclusion; define then use throughout global = globalObject, doc = global.document, element = doc && doc.createElement("DiV"), has = req.has = function(name){ return isFunction(hasCache[name]) ? (hasCache[name] = hasCache[name](global, doc, element)) : hasCache[name]; }, hasCache = has.cache = defaultConfig.hasCache; if (isFunction(userConfig)) { userConfig = userConfig(globalObject); } has.add = function(name, test, now, force){ (hasCache[name]===undefined || force) && (hasCache[name] = test); return now && has(name); }; 0 && has.add("host-node", userConfig.has && "host-node" in userConfig.has ? userConfig.has["host-node"] : (typeof process == "object" && process.versions && process.versions.node && process.versions.v8)); if( 0 ){ // fixup the default config for node.js environment require("./_base/configNode.js").config(defaultConfig); // remember node's require (with respect to baseUrl==dojo's root) defaultConfig.loaderPatch.nodeRequire = require; } 0 && has.add("host-rhino", userConfig.has && "host-rhino" in userConfig.has ? userConfig.has["host-rhino"] : (typeof load == "function" && (typeof Packages == "function" || typeof Packages == "object"))); if( 0 ){ // owing to rhino's lame feature that hides the source of the script, give the user a way to specify the baseUrl... for(var baseUrl = userConfig.baseUrl || ".", arg, rhinoArgs = this.arguments, i = 0; i < rhinoArgs.length;){ arg = (rhinoArgs[i++] + "").split("="); if(arg[0] == "baseUrl"){ baseUrl = arg[1]; break; } } load(baseUrl + "/_base/configRhino.js"); rhinoDojoConfig(defaultConfig, baseUrl, rhinoArgs); } has.add("host-webworker", ((typeof WorkerGlobalScope !== 'undefined') && (self instanceof WorkerGlobalScope))); if(has("host-webworker")){ mix(defaultConfig.hasCache, { "host-browser": 0, "dom": 0, "dojo-dom-ready-api": 0, "dojo-sniff": 0, "dojo-inject-api": 1, "host-webworker": 1, "dojo-guarantee-console": 0 // console is immutable in FF30+, see https://bugs.dojotoolkit.org/ticket/18100 }); defaultConfig.loaderPatch = { injectUrl: function(url, callback){ // TODO: // This is not async, nor can it be in Webworkers. It could be made better by passing // the entire require array into importScripts at. This way the scripts are loaded in // async mode; even if the callbacks are ran in sync. It is not a major issue as webworkers // tend to be long running where initial startup is not a major factor. try{ importScripts(url); callback(); }catch(e){ console.info("failed to load resource (" + url + ")"); console.error(e); } } }; } // userConfig has tests override defaultConfig has tests; do this after the environment detection because // the environment detection usually sets some has feature values in the hasCache. for(var p in userConfig.has){ has.add(p, userConfig.has[p], 0, 1); } // // define the loader data // // the loader will use these like symbols if the loader has the traceApi; otherwise // define magic numbers so that modules can be provided as part of defaultConfig var requested = 1, arrived = 2, nonmodule = 3, executing = 4, executed = 5; if( 0 ){ // these make debugging nice; but using strings for symbols is a gross rookie error; don't do it for production code requested = "requested"; arrived = "arrived"; nonmodule = "not-a-module"; executing = "executing"; executed = "executed"; } var legacyMode = 0, sync = "sync", xd = "xd", syncExecStack = [], dojoRequirePlugin = 0, checkDojoRequirePlugin = noop, transformToAmd = noop, getXhr; if( 1 ){ req.isXdUrl = noop; req.initSyncLoader = function(dojoRequirePlugin_, checkDojoRequirePlugin_, transformToAmd_){ // the first dojo/_base/loader loaded gets to define these variables; they are designed to work // in the presence of zero to many mapped dojo/_base/loaders if(!dojoRequirePlugin){ dojoRequirePlugin = dojoRequirePlugin_; checkDojoRequirePlugin = checkDojoRequirePlugin_; transformToAmd = transformToAmd_; } return { sync:sync, requested:requested, arrived:arrived, nonmodule:nonmodule, executing:executing, executed:executed, syncExecStack:syncExecStack, modules:modules, execQ:execQ, getModule:getModule, injectModule:injectModule, setArrived:setArrived, signal:signal, finishExec:finishExec, execModule:execModule, dojoRequirePlugin:dojoRequirePlugin, getLegacyMode:function(){return legacyMode;}, guardCheckComplete:guardCheckComplete }; }; if( 1 || has("host-webworker")){ // in legacy sync mode, the loader needs a minimal XHR library var locationProtocol = location.protocol, locationHost = location.host; req.isXdUrl = function(url){ if(/^\./.test(url)){ // begins with a dot is always relative to page URL; therefore not xdomain return false; } if(/^\/\//.test(url)){ // for v1.6- backcompat, url starting with // indicates xdomain return true; } // get protocol and host // \/+ takes care of the typical file protocol that looks like file:///drive/path/to/file // locationHost is falsy if file protocol => if locationProtocol matches and is "file:", || will return false var match = url.match(/^([^\/\:]+\:)\/+([^\/]+)/); return match && (match[1] != locationProtocol || (locationHost && match[2] != locationHost)); }; // note: to get the file:// protocol to work in FF, you must set security.fileuri.strict_origin_policy to false in about:config 1 || has.add("dojo-xhr-factory", 1); has.add("dojo-force-activex-xhr", 1 && !doc.addEventListener && window.location.protocol == "file:"); has.add("native-xhr", typeof XMLHttpRequest != "undefined"); if(has("native-xhr") && !has("dojo-force-activex-xhr")){ getXhr = function(){ return new XMLHttpRequest(); }; }else{ // if in the browser an old IE; find an xhr for(var XMLHTTP_PROGIDS = ['Msxml2.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.4.0'], progid, i = 0; i < 3;){ try{ progid = XMLHTTP_PROGIDS[i++]; if(new ActiveXObject(progid)){ // this progid works; therefore, use it from now on break; } }catch(e){ // squelch; we're just trying to find a good ActiveX progid // if they all fail, then progid ends up as the last attempt and that will signal the error // the first time the client actually tries to exec an xhr } } getXhr = function(){ return new ActiveXObject(progid); }; } req.getXhr = getXhr; has.add("dojo-gettext-api", 1); req.getText = function(url, async, onLoad){ var xhr = getXhr(); xhr.open('GET', fixupUrl(url), false); xhr.send(null); if(xhr.status == 200 || (!location.host && !xhr.status)){ if(onLoad){ onLoad(xhr.responseText, async); } }else{ throw makeError("xhrFailed", xhr.status); } return xhr.responseText; }; } }else{ req.async = 1; } // // loader eval // var eval_ = has("csp-restrictions") ? // noop eval if there are csp restrictions function(){} : // use the function constructor so our eval is scoped close to (but not in) in the global space with minimal pollution new Function('return eval(arguments[0]);'); req.eval = function(text, hint){ return eval_(text + "\r\n//# sourceURL=" + hint); }; // // loader micro events API // var listenerQueues = {}, error = "error", signal = req.signal = function(type, args){ var queue = listenerQueues[type]; // notice we run a copy of the queue; this allows listeners to add/remove // other listeners without affecting this particular signal forEach(queue && queue.slice(0), function(listener){ listener.apply(null, isArray(args) ? args : [args]); }); }, on = req.on = function(type, listener){ // notice a queue is not created until a client actually connects var queue = listenerQueues[type] || (listenerQueues[type] = []); queue.push(listener); return { remove:function(){ for(var i = 0; i (alias, actual) = [], paths // CommonJS paths = {}, pathsMapProg // list of (from-path, to-path, regex, length) derived from paths; // a "program" to apply paths; see computeMapProg = [], packs // a map from packageId to package configuration object; see fixupPackageInfo = {}, map = req.map // AMD map config variable; dojo/_base/kernel needs req.map to figure out the scope map = {}, mapProgs // vector of quads as described by computeMapProg; map-key is AMD map key, map-value is AMD map value = [], modules // A hash:(mid) --> (module-object) the module namespace // // pid: the package identifier to which the module belongs (e.g., "dojo"); "" indicates the system or default package // mid: the fully-resolved (i.e., mappings have been applied) module identifier without the package identifier (e.g., "dojo/io/script") // url: the URL from which the module was retrieved // pack: the package object of the package to which the module belongs // executed: 0 => not executed; executing => in the process of traversing deps and running factory; executed => factory has been executed // deps: the dependency vector for this module (vector of modules objects) // def: the factory for this module // result: the result of the running the factory for this module // injected: (0 | requested | arrived) the status of the module; nonmodule means the resource did not call define // load: plugin load function; applicable only for plugins // // Modules go through several phases in creation: // // 1. Requested: some other module's definition or a require application contained the requested module in // its dependency vector or executing code explicitly demands a module via req.require. // // 2. Injected: a script element has been appended to the insert-point element demanding the resource implied by the URL // // 3. Loaded: the resource injected in [2] has been evaluated. // // 4. Defined: the resource contained a define statement that advised the loader about the module. Notice that some // resources may just contain a bundle of code and never formally define a module via define // // 5. Evaluated: the module was defined via define and the loader has evaluated the factory and computed a result. = {}, cacheBust // query string to append to module URLs to bust browser cache = "", cache // hash:(mid | url)-->(function | string) // // A cache of resources. The resources arrive via a config.cache object, which is a hash from either mid --> function or // url --> string. The url key is distinguished from the mid key by always containing the prefix "url:". url keys as provided // by config.cache always have a string value that represents the contents of the resource at the given url. mid keys as provided // by configl.cache always have a function value that causes the same code to execute as if the module was script injected. // // Both kinds of key-value pairs are entered into cache via the function consumePendingCache, which may relocate keys as given // by any mappings *iff* the config.cache was received as part of a module resource request. // // Further, for mid keys, the implied url is computed and the value is entered into that key as well. This allows mapped modules // to retrieve cached items that may have arrived consequent to another namespace. // = {}, urlKeyPrefix // the prefix to prepend to a URL key in the cache. = "url:", pendingCacheInsert // hash:(mid)-->(function) // // Gives a set of cache modules pending entry into cache. When cached modules are published to the loader, they are // entered into pendingCacheInsert; modules are then pressed into cache upon (1) AMD define or (2) upon receiving another // independent set of cached modules. (1) is the usual case, and this case allows normalizing mids given in the pending // cache for the local configuration, possibly relocating modules. = {}, dojoSniffConfig // map of configuration variables // give the data-dojo-config as sniffed from the document (if any) = {}, insertPointSibling // the nodes used to locate where scripts are injected into the document = 0; if( 1 ){ if (!has("foreign-loader")) { var consumePendingCacheInsert = function(referenceModule, clear){ clear = clear !== false; var p, item, match, now, m; for(p in pendingCacheInsert){ item = pendingCacheInsert[p]; match = p.match(/^url\:(.+)/); if(match){ cache[urlKeyPrefix + toUrl(match[1], referenceModule)] = item; }else if(p=="*now"){ now = item; }else if(p!="*noref"){ m = getModuleInfo(p, referenceModule, true); cache[m.mid] = cache[urlKeyPrefix + m.url] = item; } } if(now){ now(createRequire(referenceModule)); } if(clear){ pendingCacheInsert = {}; } }; } var escapeString = function(s){ return s.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, function(c){ return "\\" + c; }); }, computeMapProg = function(map, dest){ // This routine takes a map as represented by a JavaScript object and initializes dest, a vector of // quads of (map-key, map-value, refex-for-map-key, length-of-map-key), sorted decreasing by length- // of-map-key. The regex looks for the map-key followed by either "/" or end-of-string at the beginning // of a the search source. Notice the map-value is irrelevant to the algorithm dest.splice(0, dest.length); for(var p in map){ dest.push([ p, map[p], new RegExp("^" + escapeString(p) + "(\/|$)"), p.length]); } dest.sort(function(lhs, rhs){ return rhs[3] - lhs[3]; }); return dest; }, computeAliases = function(config, dest){ forEach(config, function(pair){ // take a fixed-up copy... dest.push([isString(pair[0]) ? new RegExp("^" + escapeString(pair[0]) + "$") : pair[0], pair[1]]); }); }, fixupPackageInfo = function(packageInfo){ // calculate the precise (name, location, main, mappings) for a package var name = packageInfo.name; if(!name){ // packageInfo must be a string that gives the name name = packageInfo; packageInfo = {name:name}; } packageInfo = mix({main:"main"}, packageInfo); packageInfo.location = packageInfo.location ? packageInfo.location : name; // packageMap is deprecated in favor of AMD map if(packageInfo.packageMap){ map[name] = packageInfo.packageMap; } if(!packageInfo.main.indexOf("./")){ packageInfo.main = packageInfo.main.substring(2); } // now that we've got a fully-resolved package object, push it into the configuration packs[name] = packageInfo; }, delayedModuleConfig // module config cannot be consumed until the loader is completely initialized; therefore, all // module config detected during booting is memorized and applied at the end of loader initialization // TODO: this is a bit of a kludge; all config should be moved to end of loader initialization, but // we'll delay this chore and do it with a final loader 1.x cleanup after the 2.x loader prototyping is complete = [], config = function(config, booting, referenceModule){ for(var p in config){ if(p=="waitSeconds"){ req.waitms = (config[p] || 0) * 1000; } if(p=="cacheBust"){ cacheBust = config[p] ? (isString(config[p]) ? config[p] : (new Date()).getTime() + "") : ""; } if(p=="baseUrl" || p=="combo"){ req[p] = config[p]; } if( 1 && p=="async"){ // falsy or "sync" => legacy sync loader // "xd" => sync but loading xdomain tree and therefore loading asynchronously (not configurable, set automatically by the loader) // "legacyAsync" => permanently in "xd" by choice // "debugAtAllCosts" => trying to load everything via script injection (not implemented) // otherwise, must be truthy => AMD // legacyMode: sync | legacyAsync | xd | false var mode = config[p]; req.legacyMode = legacyMode = (isString(mode) && /sync|legacyAsync/.test(mode) ? mode : (!mode ? sync : false)); req.async = !legacyMode; } if(config[p]!==hasCache){ // accumulate raw config info for client apps which can use this to pass their own config req.rawConfig[p] = config[p]; p!="has" && has.add("config-"+p, config[p], 0, booting); } } // make sure baseUrl exists if(!req.baseUrl){ req.baseUrl = "./"; } // make sure baseUrl ends with a slash if(!/\/$/.test(req.baseUrl)){ req.baseUrl += "/"; } // now do the special work for has, packages, packagePaths, paths, aliases, and cache for(p in config.has){ has.add(p, config.has[p], 0, booting); } // for each package found in any packages config item, augment the packs map owned by the loader forEach(config.packages, fixupPackageInfo); // for each packagePath found in any packagePaths config item, augment the packageConfig // packagePaths is deprecated; remove in 2.0 for(var baseUrl in config.packagePaths){ forEach(config.packagePaths[baseUrl], function(packageInfo){ var location = baseUrl + "/" + packageInfo; if(isString(packageInfo)){ packageInfo = {name:packageInfo}; } packageInfo.location = location; fixupPackageInfo(packageInfo); }); } // notice that computeMapProg treats the dest as a reference; therefore, if/when that variable // is published (see dojo-publish-privates), the published variable will always hold a valid value. // this must come after all package processing since package processing may mutate map computeMapProg(mix(map, config.map), mapProgs); forEach(mapProgs, function(item){ item[1] = computeMapProg(item[1], []); if(item[0]=="*"){ mapProgs.star = item; } }); // push in any paths and recompute the internal pathmap computeMapProg(mix(paths, config.paths), pathsMapProg); // aliases computeAliases(config.aliases, aliases); if (!has("foreign-loader")) { if(booting){ delayedModuleConfig.push({config:config.config}); }else{ for(p in config.config){ var module = getModule(p, referenceModule); module.config = mix(module.config || {}, config.config[p]); } } // push in any new cache values if(config.cache){ consumePendingCacheInsert(); pendingCacheInsert = config.cache; //inject now all depencies so cache is available for mapped module consumePendingCacheInsert(0, !!config.cache["*noref"]); } } signal("config", [config, req.rawConfig]); }; // // execute the various sniffs; userConfig can override and value // if(has("dojo-cdn") || 1 ){ // the sniff regex looks for a src attribute ending in dojo.js, optionally preceded with a path. // match[3] returns the path to dojo.js (if any) without the trailing slash. This is used for the // dojo location on CDN deployments and baseUrl when either/both of these are not provided // explicitly in the config data; this is the 1.6- behavior. var scripts = doc.getElementsByTagName("script"), i = 0, script, dojoDir, src, match; while(i < scripts.length){ script = scripts[i++]; if((src = script.getAttribute("src")) && (match = src.match(/(((.*)\/)|^)dojo\.js(\W|$)/i))){ // sniff dojoDir and baseUrl dojoDir = match[3] || ""; defaultConfig.baseUrl = defaultConfig.baseUrl || dojoDir; // remember an insertPointSibling insertPointSibling = script; } // sniff configuration on attribute in script element if((src = (script.getAttribute("data-dojo-config") || script.getAttribute("djConfig")))){ dojoSniffConfig = req.eval("({ " + src + " })", "data-dojo-config"); // remember an insertPointSibling insertPointSibling = script; } // sniff requirejs attribute if( 0 ){ if((src = script.getAttribute("data-main"))){ dojoSniffConfig.deps = dojoSniffConfig.deps || [src]; } } } } if( 0 ){ // pass down doh.testConfig from parent as if it were a data-dojo-config try{ if(window.parent != window && window.parent.require){ var doh = window.parent.require("doh"); doh && mix(dojoSniffConfig, doh.testConfig); } }catch(e){} } // configure the loader; let the user override defaults req.rawConfig = {}; config(defaultConfig, 1); // do this before setting userConfig/sniffConfig to allow userConfig/sniff overrides if(has("dojo-cdn")){ packs.dojo.location = dojoDir; if(dojoDir){ dojoDir += "/"; } packs.dijit.location = dojoDir + "../dijit/"; packs.dojox.location = dojoDir + "../dojox/"; } config(userConfig, 1); config(dojoSniffConfig, 1); }else{ // no config API, assume defaultConfig has everything the loader needs...for the entire lifetime of the application paths = defaultConfig.paths; pathsMapProg = defaultConfig.pathsMapProg; packs = defaultConfig.packs; aliases = defaultConfig.aliases; mapProgs = defaultConfig.mapProgs; modules = defaultConfig.modules; cache = defaultConfig.cache; cacheBust = defaultConfig.cacheBust; // remember the default config for other processes (e.g., dojo/config) req.rawConfig = defaultConfig; } if (!has("foreign-loader")) { if( 0 ){ req.combo = req.combo || {add:noop}; var comboPending = 0, combosPending = [], comboPendingTimer = null; } // build the loader machinery iaw configuration, including has feature tests var injectDependencies = function(module){ // checkComplete!=0 holds the idle signal; we're not idle if we're injecting dependencies guardCheckComplete(function(){ forEach(module.deps, injectModule); if( 0 && comboPending && !comboPendingTimer){ comboPendingTimer = setTimeout(function() { comboPending = 0; comboPendingTimer = null; req.combo.done(function(mids, url) { var onLoadCallback= function(){ // defQ is a vector of module definitions 1-to-1, onto mids runDefQ(0, mids); checkComplete(); }; combosPending.push(mids); injectingModule = mids; req.injectUrl(url, onLoadCallback, mids); injectingModule = 0; }, req); }, 0); } }); }, contextRequire = function(a1, a2, a3, referenceModule, contextRequire){ var module, syntheticMid; if(isString(a1)){ // signature is (moduleId) module = getModule(a1, referenceModule, true); if(module && module.executed){ return module.result; } throw makeError("undefinedModule", a1); } if(!isArray(a1)){ // a1 is a configuration config(a1, 0, referenceModule); // juggle args; (a2, a3) may be (dependencies, callback) a1 = a2; a2 = a3; } if(isArray(a1)){ // signature is (requestList [,callback]) if(!a1.length){ a2 && a2(); }else{ syntheticMid = "require*" + uid(); // resolve the request list with respect to the reference module for(var mid, deps = [], i = 0; i < a1.length;){ mid = a1[i++]; deps.push(getModule(mid, referenceModule)); } // construct a synthetic module to control execution of the requestList, and, optionally, callback module = mix(makeModuleInfo("", syntheticMid, 0, ""), { injected: arrived, deps: deps, def: a2 || noop, require: referenceModule ? referenceModule.require : req, gc: 1 //garbage collect }); modules[module.mid] = module; // checkComplete!=0 holds the idle signal; we're not idle if we're injecting dependencies injectDependencies(module); // try to immediately execute // if already traversing a factory tree, then strict causes circular dependency to abort the execution; maybe // it's possible to execute this require later after the current traversal completes and avoid the circular dependency. // ...but *always* insist on immediate in synch mode var strict = checkCompleteGuard && legacyMode!=sync; guardCheckComplete(function(){ execModule(module, strict); }); if(!module.executed){ // some deps weren't on board or circular dependency detected and strict; therefore, push into the execQ execQ.push(module); } checkComplete(); } } return contextRequire; }, createRequire = function(module){ if(!module){ return req; } var result = module.require; if(!result){ result = function(a1, a2, a3){ return contextRequire(a1, a2, a3, module, result); }; module.require = mix(result, req); result.module = module; result.toUrl = function(name){ return toUrl(name, module); }; result.toAbsMid = function(mid){ return toAbsMid(mid, module); }; if( 0 ){ result.undef = function(mid){ req.undef(mid, module); }; } if( 1 ){ result.syncLoadNls = function(mid){ var nlsModuleInfo = getModuleInfo(mid, module), nlsModule = modules[nlsModuleInfo.mid]; if(!nlsModule || !nlsModule.executed){ cached = cache[nlsModuleInfo.mid] || cache[urlKeyPrefix + nlsModuleInfo.url]; if(cached){ evalModuleText(cached); nlsModule = modules[nlsModuleInfo.mid]; } } return nlsModule && nlsModule.executed && nlsModule.result; }; } } return result; }, execQ = // The list of modules that need to be evaluated. [], defQ = // The queue of define arguments sent to loader. [], waiting = // The set of modules upon which the loader is waiting for definition to arrive {}, setRequested = function(module){ module.injected = requested; waiting[module.mid] = 1; if(module.url){ waiting[module.url] = module.pack || 1; } startTimer(); }, setArrived = function(module){ module.injected = arrived; delete waiting[module.mid]; if(module.url){ delete waiting[module.url]; } if(isEmpty(waiting)){ clearTimer(); 1 && legacyMode==xd && (legacyMode = sync); } }, execComplete = req.idle = // says the loader has completed (or not) its work function(){ return !defQ.length && isEmpty(waiting) && !execQ.length && !checkCompleteGuard; }; } var runMapProg = function(targetMid, map){ // search for targetMid in map; return the map item if found; falsy otherwise if(map){ for(var i = 0; i < map.length; i++){ if(map[i][2].test(targetMid)){ return map[i]; } } } return 0; }, compactPath = function(path){ var result = [], segment, lastSegment; path = path.replace(/\\/g, '/').split('/'); while(path.length){ segment = path.shift(); if(segment==".." && result.length && lastSegment!=".."){ result.pop(); lastSegment = result[result.length - 1]; }else if(segment!="."){ result.push(lastSegment= segment); } // else ignore "." } return result.join("/"); }, makeModuleInfo = function(pid, mid, pack, url){ if( 1 ){ var xd= req.isXdUrl(url); return {pid:pid, mid:mid, pack:pack, url:url, executed:0, def:0, isXd:xd, isAmd:!!(xd || (packs[pid] && packs[pid].isAmd))}; }else{ return {pid:pid, mid:mid, pack:pack, url:url, executed:0, def:0}; } }, getModuleInfo_ = function(mid, referenceModule, packs, modules, baseUrl, mapProgs, pathsMapProg, aliases, alwaysCreate, fromPendingCache){ // arguments are passed instead of using lexical variables so that this function my be used independent of the loader (e.g., the builder) // alwaysCreate is useful in this case so that getModuleInfo never returns references to real modules owned by the loader var pid, pack, midInPackage, mapItem, url, result, isRelative, requestedMid; requestedMid = mid; isRelative = /^\./.test(mid); if(/(^\/)|(\:)|(\.js$)/.test(mid) || (isRelative && !referenceModule)){ // absolute path or protocol of .js filetype, or relative path but no reference module and therefore relative to page // whatever it is, it's not a module but just a URL of some sort // note: pid===0 indicates the routine is returning an unmodified mid return makeModuleInfo(0, mid, 0, mid); }else{ // relative module ids are relative to the referenceModule; get rid of any dots mid = compactPath(isRelative ? (referenceModule.mid + "/../" + mid) : mid); if(/^\./.test(mid)){ throw makeError("irrationalPath", mid); } // at this point, mid is an absolute mid // map the mid if(!fromPendingCache && !isRelative && mapProgs.star){ mapItem = runMapProg(mid, mapProgs.star[1]); } if(!mapItem && referenceModule){ mapItem = runMapProg(referenceModule.mid, mapProgs); mapItem = mapItem && runMapProg(mid, mapItem[1]); } if(mapItem){ mid = mapItem[1] + mid.substring(mapItem[3]); } match = mid.match(/^([^\/]+)(\/(.+))?$/); pid = match ? match[1] : ""; if((pack = packs[pid])){ mid = pid + "/" + (midInPackage = (match[3] || pack.main)); }else{ pid = ""; } // search aliases var candidateLength = 0, candidate = 0; forEach(aliases, function(pair){ var match = mid.match(pair[0]); if(match && match.length>candidateLength){ candidate = isFunction(pair[1]) ? mid.replace(pair[0], pair[1]) : pair[1]; } }); if(candidate){ return getModuleInfo_(candidate, 0, packs, modules, baseUrl, mapProgs, pathsMapProg, aliases, alwaysCreate); } result = modules[mid]; if(result){ return alwaysCreate ? makeModuleInfo(result.pid, result.mid, result.pack, result.url) : modules[mid]; } } // get here iff the sought-after module does not yet exist; therefore, we need to compute the URL given the // fully resolved (i.e., all relative indicators and package mapping resolved) module id // note: pid!==0 indicates the routine is returning a url that has .js appended unmodified mid mapItem = runMapProg(mid, pathsMapProg); if(mapItem){ url = mapItem[1] + mid.substring(mapItem[3]); }else if(pid){ url = (pack.location.slice(-1) === '/' ? pack.location.slice(0, -1) : pack.location) + "/" + midInPackage; }else if(has("config-tlmSiblingOfDojo")){ url = "../" + mid; }else{ url = mid; } // if result is not absolute, add baseUrl if(!(/(^\/)|(\:)/.test(url))){ url = baseUrl + url; } url += ".js"; return makeModuleInfo(pid, mid, pack, compactPath(url)); }, getModuleInfo = function(mid, referenceModule, fromPendingCache){ return getModuleInfo_(mid, referenceModule, packs, modules, req.baseUrl, mapProgs, pathsMapProg, aliases, undefined, fromPendingCache); }; if (!has("foreign-loader")) { var resolvePluginResourceId = function(plugin, prid, referenceModule){ return plugin.normalize ? plugin.normalize(prid, function(mid){return toAbsMid(mid, referenceModule);}) : toAbsMid(prid, referenceModule); }, dynamicPluginUidGenerator = 0, getModule = function(mid, referenceModule, immediate){ // compute and optionally construct (if necessary) the module implied by the mid with respect to referenceModule var match, plugin, prid, result; match = mid.match(/^(.+?)\!(.*)$/); if(match){ // name was ! plugin = getModule(match[1], referenceModule, immediate); if( 1 && legacyMode == sync && !plugin.executed){ injectModule(plugin); if(plugin.injected===arrived && !plugin.executed){ guardCheckComplete(function(){ execModule(plugin); }); } if(plugin.executed){ promoteModuleToPlugin(plugin); }else{ // we are in xdomain mode for some reason execQ.unshift(plugin); } } if(plugin.executed === executed && !plugin.load){ // executed the module not knowing it was a plugin promoteModuleToPlugin(plugin); } // if the plugin has not been loaded, then can't resolve the prid and must assume this plugin is dynamic until we find out otherwise if(plugin.load){ prid = resolvePluginResourceId(plugin, match[2], referenceModule); mid = (plugin.mid + "!" + (plugin.dynamic ? ++dynamicPluginUidGenerator + "!" : "") + prid); }else{ prid = match[2]; mid = plugin.mid + "!" + (++dynamicPluginUidGenerator) + "!waitingForPlugin"; } result = {plugin:plugin, mid:mid, req:createRequire(referenceModule), prid:prid}; }else{ result = getModuleInfo(mid, referenceModule); } return modules[result.mid] || (!immediate && (modules[result.mid] = result)); }; } var toAbsMid = req.toAbsMid = function(mid, referenceModule){ return getModuleInfo(mid, referenceModule).mid; }, toUrl = req.toUrl = function(name, referenceModule){ var moduleInfo = getModuleInfo(name+"/x", referenceModule), url= moduleInfo.url; return fixupUrl(moduleInfo.pid===0 ? // if pid===0, then name had a protocol or absolute path; either way, toUrl is the identify function in such cases name : // "/x.js" since getModuleInfo automatically appends ".js" and we appended "/x" to make name look like a module id url.substring(0, url.length-5) ); }; if (!has("foreign-loader")) { var nonModuleProps = { injected: arrived, executed: executed, def: nonmodule, result: nonmodule }, makeCjs = function(mid){ return modules[mid] = mix({mid:mid}, nonModuleProps); }, cjsRequireModule = makeCjs("require"), cjsExportsModule = makeCjs("exports"), cjsModuleModule = makeCjs("module"), runFactory = function(module, args){ req.trace("loader-run-factory", [module.mid]); var factory = module.def, result; 1 && syncExecStack.unshift(module); if(has("config-dojo-loader-catches")){ try{ result= isFunction(factory) ? factory.apply(null, args) : factory; }catch(e){ signal(error, module.result = makeError("factoryThrew", [module, e])); } }else{ result= isFunction(factory) ? factory.apply(null, args) : factory; } module.result = result===undefined && module.cjs ? module.cjs.exports : result; 1 && syncExecStack.shift(module); }, abortExec = {}, defOrder = 0, promoteModuleToPlugin = function(pluginModule){ var plugin = pluginModule.result; pluginModule.dynamic = plugin.dynamic; pluginModule.normalize = plugin.normalize; pluginModule.load = plugin.load; return pluginModule; }, resolvePluginLoadQ = function(plugin){ // plugins is a newly executed module that has a loadQ waiting to run // step 1: traverse the loadQ and fixup the mid and prid; remember the map from original mid to new mid // recall the original mid was created before the plugin was on board and therefore it was impossible to // compute the final mid; accordingly, prid may or may not change, but the mid will definitely change var map = {}; forEach(plugin.loadQ, function(pseudoPluginResource){ // manufacture and insert the real module in modules var prid = resolvePluginResourceId(plugin, pseudoPluginResource.prid, pseudoPluginResource.req.module), mid = plugin.dynamic ? pseudoPluginResource.mid.replace(/waitingForPlugin$/, prid) : (plugin.mid + "!" + prid), pluginResource = mix(mix({}, pseudoPluginResource), {mid:mid, prid:prid, injected:0}); if(!modules[mid] || !modules[mid].injected /*for require.undef*/){ // create a new (the real) plugin resource and inject it normally now that the plugin is on board injectPlugin(modules[mid] = pluginResource); } // else this was a duplicate request for the same (plugin, rid) for a nondynamic plugin // pluginResource is really just a placeholder with the wrong mid (because we couldn't calculate it until the plugin was on board) // mark is as arrived and delete it from modules; the real module was requested above map[pseudoPluginResource.mid] = modules[mid]; setArrived(pseudoPluginResource); delete modules[pseudoPluginResource.mid]; }); plugin.loadQ = 0; // step2: replace all references to any placeholder modules with real modules var substituteModules = function(module){ for(var replacement, deps = module.deps || [], i = 0; i")]); return (!module.def || strict) ? abortExec : (module.cjs && module.cjs.exports); } // at this point the module is either not executed or fully executed if(!module.executed){ if(!module.def){ return abortExec; } var mid = module.mid, deps = module.deps || [], arg, argResult, args = [], i = 0; if( 0 ){ circleTrace.push(mid); req.trace("loader-exec-module", ["exec", circleTrace.length, mid]); } // for circular dependencies, assume the first module encountered was executed OK // modules that circularly depend on a module that has not run its factory will get // the pre-made cjs.exports===module.result. They can take a reference to this object and/or // add properties to it. When the module finally runs its factory, the factory can // read/write/replace this object. Notice that so long as the object isn't replaced, any // reference taken earlier while walking the deps list is still valid. module.executed = executing; while((arg = deps[i++])){ argResult = ((arg === cjsRequireModule) ? createRequire(module) : ((arg === cjsExportsModule) ? module.cjs.exports : ((arg === cjsModuleModule) ? module.cjs : execModule(arg, strict)))); if(argResult === abortExec){ module.executed = 0; req.trace("loader-exec-module", ["abort", mid]); 0 && circleTrace.pop(); return abortExec; } args.push(argResult); } runFactory(module, args); finishExec(module); 0 && circleTrace.pop(); } // at this point the module is guaranteed fully executed return module.result; }, checkCompleteGuard = 0, guardCheckComplete = function(proc){ try{ checkCompleteGuard++; proc(); }catch(e){ // https://bugs.dojotoolkit.org/ticket/16617 throw e; }finally{ checkCompleteGuard--; } if(execComplete()){ signal("idle", []); } }, checkComplete = function(){ // keep going through the execQ as long as at least one factory is executed // plugins, recursion, cached modules all make for many execution path possibilities if(checkCompleteGuard){ return; } guardCheckComplete(function(){ checkDojoRequirePlugin(); for(var currentDefOrder, module, i = 0; i < execQ.length;){ currentDefOrder = defOrder; module = execQ[i]; execModule(module); if(currentDefOrder!=defOrder){ // defOrder was bumped one or more times indicating something was executed (note, this indicates // the execQ was modified, maybe a lot (for example a later module causes an earlier module to execute) checkDojoRequirePlugin(); i = 0; }else{ // nothing happened; check the next module in the exec queue i++; } } }); }; } var fixupUrl= typeof userConfig.fixupUrl == "function" ? userConfig.fixupUrl : function(url){ url += ""; // make sure url is a Javascript string (some paths may be a Java string) return url + (cacheBust ? ((/\?/.test(url) ? "&" : "?") + cacheBust) : ""); }; if( 0 ){ req.undef = function(moduleId, referenceModule){ // In order to reload a module, it must be undefined (this routine) and then re-requested. // This is useful for testing frameworks (at least). var module = getModule(moduleId, referenceModule); setArrived(module); mix(module, {def:0, executed:0, injected:0, node:0, load:0}); }; } if( 1 ){ if(has("dojo-loader-eval-hint-url")===undefined){ has.add("dojo-loader-eval-hint-url", 1); } var injectPlugin = function( module ){ // injects the plugin module given by module; may have to inject the plugin itself var plugin = module.plugin; if(plugin.executed === executed && !plugin.load){ // executed the module not knowing it was a plugin promoteModuleToPlugin(plugin); } var onLoad = function(def){ module.result = def; setArrived(module); finishExec(module); checkComplete(); }; if(plugin.load){ plugin.load(module.prid, module.req, onLoad); }else if(plugin.loadQ){ plugin.loadQ.push(module); }else{ // the unshift instead of push is important: we don't want plugins to execute as // dependencies of some other module because this may cause circles when the plugin // loadQ is run; also, generally, we want plugins to run early since they may load // several other modules and therefore can potentially unblock many modules plugin.loadQ = [module]; execQ.unshift(plugin); injectModule(plugin); } }, // for IE, injecting a module may result in a recursive execution if the module is in the cache cached = 0, injectingModule = 0, injectingCachedModule = 0, evalModuleText = function(text, module){ // see def() for the injectingCachedModule bracket; it simply causes a short, safe circuit if(has("config-stripStrict")){ text = text.replace(/(["'])use strict\1/g, ''); } injectingCachedModule = 1; if(has("config-dojo-loader-catches")){ try{ if(text===cached){ cached.call(null); }else{ req.eval(text, has("dojo-loader-eval-hint-url") ? module.url : module.mid); } }catch(e){ signal(error, makeError("evalModuleThrew", module)); } }else{ if(text===cached){ cached.call(null); }else{ req.eval(text, has("dojo-loader-eval-hint-url") ? module.url : module.mid); } } injectingCachedModule = 0; }, injectModule = function(module){ // Inject the module. In the browser environment, this means appending a script element into // the document; in other environments, it means loading a file. // // If in synchronous mode, then get the module synchronously if it's not xdomainLoading. var mid = module.mid, url = module.url; if(module.executed || module.injected || waiting[mid] || (module.url && ((module.pack && waiting[module.url]===module.pack) || waiting[module.url]==1))){ return; } setRequested(module); if( 0 ){ var viaCombo = 0; if(module.plugin && module.plugin.isCombo){ // a combo plugin; therefore, must be handled by combo service // the prid should have already been converted to a URL (if required by the plugin) during // the normalize process; in any event, there is no way for the loader to know how to // to the conversion; therefore the third argument is zero req.combo.add(module.plugin.mid, module.prid, 0, req); viaCombo = 1; }else if(!module.plugin){ viaCombo = req.combo.add(0, module.mid, module.url, req); } if(viaCombo){ comboPending= 1; return; } } if(module.plugin){ injectPlugin(module); return; } // else a normal module (not a plugin) var onLoadCallback = function(){ runDefQ(module); if(module.injected !== arrived){ // the script that contained the module arrived and has been executed yet // nothing was added to the defQ (so it wasn't an AMD module) and the module // wasn't marked as arrived by dojo.provide (so it wasn't a v1.6- module); // therefore, it must not have been a module; adjust state accordingly if(has("dojo-enforceDefine")){ signal(error, makeError("noDefine", module)); return; } setArrived(module); mix(module, nonModuleProps); req.trace("loader-define-nonmodule", [module.url]); } if( 1 && legacyMode){ // must call checkComplete even in for sync loader because we may be in xdomainLoading mode; // but, if xd loading, then don't call checkComplete until out of the current sync traversal // in order to preserve order of execution of the dojo.required modules !syncExecStack.length && checkComplete(); }else{ checkComplete(); } }; cached = cache[mid] || cache[urlKeyPrefix + module.url]; if(cached){ req.trace("loader-inject", ["cache", module.mid, url]); evalModuleText(cached, module); onLoadCallback(); return; } if( 1 && legacyMode){ if(module.isXd){ // switch to async mode temporarily; if current legacyMode!=sync, then is must be one of {legacyAsync, xd, false} legacyMode==sync && (legacyMode = xd); // fall through and load via script injection }else if(module.isAmd && legacyMode!=sync){ // fall through and load via script injection }else{ // mode may be sync, xd/legacyAsync, or async; module may be AMD or legacy; but module is always located on the same domain var xhrCallback = function(text){ if(legacyMode==sync){ // the top of syncExecStack gives the current synchronously executing module; the loader needs // to know this if it has to switch to async loading in the middle of evaluating a legacy module // this happens when a modules dojo.require's a module that must be loaded async because it's xdomain // (using unshift/shift because there is no back() methods for Javascript arrays) syncExecStack.unshift(module); evalModuleText(text, module); syncExecStack.shift(); // maybe the module was an AMD module runDefQ(module); // legacy modules never get to defineModule() => cjs and injected never set; also evaluation implies executing if(!module.cjs){ setArrived(module); finishExec(module); } if(module.finish){ // while synchronously evaluating this module, dojo.require was applied referencing a module // that had to be loaded async; therefore, the loader stopped answering all dojo.require // requests so they could be answered completely in the correct sequence; module.finish gives // the list of dojo.requires that must be re-applied once all target modules are available; // make a synthetic module to execute the dojo.require's in the correct order // compute a guaranteed-unique mid for the synthetic finish module; remember the finish vector; remove it from the reference module // TODO: can we just leave the module.finish...what's it hurting? var finishMid = mid + "*finish", finish = module.finish; delete module.finish; def(finishMid, ["dojo", ("dojo/require!" + finish.join(",")).replace(/\./g, "/")], function(dojo){ forEach(finish, function(mid){ dojo.require(mid); }); }); // unshift, not push, which causes the current traversal to be reattempted from the top execQ.unshift(getModule(finishMid)); } onLoadCallback(); }else{ text = transformToAmd(module, text); if(text){ evalModuleText(text, module); onLoadCallback(); }else{ // if transformToAmd returned falsy, then the module was already AMD and it can be script-injected // do so to improve debugability(even though it means another download...which probably won't happen with a good browser cache) injectingModule = module; req.injectUrl(fixupUrl(url), onLoadCallback, module); injectingModule = 0; } } }; req.trace("loader-inject", ["xhr", module.mid, url, legacyMode!=sync]); if(has("config-dojo-loader-catches")){ try{ req.getText(url, legacyMode!=sync, xhrCallback); }catch(e){ signal(error, makeError("xhrInjectFailed", [module, e])); } }else{ req.getText(url, legacyMode!=sync, xhrCallback); } return; } } // else async mode or fell through in xdomain loading mode; either way, load by script injection req.trace("loader-inject", ["script", module.mid, url]); injectingModule = module; req.injectUrl(fixupUrl(url), onLoadCallback, module); injectingModule = 0; }, defineModule = function(module, deps, def){ req.trace("loader-define-module", [module.mid, deps]); if( 0 && module.plugin && module.plugin.isCombo){ // the module is a plugin resource loaded by the combo service // note: check for module.plugin should be enough since normal plugin resources should // not follow this path; module.plugin.isCombo is future-proofing belt and suspenders module.result = isFunction(def) ? def() : def; setArrived(module); finishExec(module); return module; } var mid = module.mid; if(module.injected === arrived){ signal(error, makeError("multipleDefine", module)); return module; } mix(module, { deps: deps, def: def, cjs: { id: module.mid, uri: module.url, exports: (module.result = {}), setExports: function(exports){ module.cjs.exports = exports; }, config:function(){ return module.config; } } }); // resolve deps with respect to this module for(var i = 0; deps[i]; i++){ deps[i] = getModule(deps[i], module); } if( 1 && legacyMode && !waiting[mid]){ // the module showed up without being asked for; it was probably in a // | var paths = {}; paths[moduleName.replace(/\./g, "/")] = prefix; require({paths:paths}); }; 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 chosen 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 (dojo.require) // | ], // | default: [ "foo.sample._base" ], // | common: [ "important.module.common" ] // | }); var result = (modMap.common || []).concat(modMap[dojo._name] || modMap["default"] || []), temp; while(result.length){ if(lang.isArray(temp = result.shift())){ dojo.require.apply(dojo, temp); }else{ dojo.require(temp); } } }; dojo.requireIf = dojo.requireAfterIf = function(/*Boolean*/ condition, /*String*/ moduleName, /*Boolean?*/omitModuleCheck){ // summary: // If the condition is true then call `dojo.require()` for the specified // resource // // example: // | dojo.requireIf(dojo.isBrowser, "my.special.Module"); if(condition){ dojo.require(moduleName, omitModuleCheck); } }; dojo.requireLocalization = function(/*String*/moduleName, /*String*/bundleName, /*String?*/locale){ require(["../i18n"], function(i18n){ i18n.getLocalization(moduleName, bundleName, locale); }); }; return { // summary: // This module defines the v1.x synchronous loader API. extractLegacyApiApplications:extractLegacyApiApplications, require:dojoRequirePlugin, loadInit:dojoLoadInitPlugin }; }); }, 'dojo/_base/kernel':function(){ define(["../global", "../has", "./config", "require", "module"], function(global, has, config, require, module){ // module: // dojo/_base/kernel // This module is the foundational module of the dojo boot sequence; it defines the dojo object. var // loop variables for this module i, p, // create dojo, dijit, and dojox // FIXME: in 2.0 remove dijit, dojox being created by dojo dijit = {}, dojox = {}, dojo = { // summary: // This module is the foundational module of the dojo boot sequence; it defines the dojo object. // notice dojo takes ownership of the value of the config module config:config, global:global, dijit:dijit, dojox:dojox }; // Configure the scope map. For a 100% AMD application, the scope map is not needed other than to provide // a _scopeName property for the dojo, dijit, and dojox root object so those packages can create // unique names in the global space. // // Built, legacy modules use the scope map to allow those modules to be expressed as if dojo, dijit, and dojox, // where global when in fact they are either global under different names or not global at all. In v1.6-, the // config variable "scopeMap" was used to map names as used within a module to global names. This has been // subsumed by the AMD map configuration variable which can relocate packages to different names. For backcompat, // only the "*" mapping is supported. See http://livedocs.dojotoolkit.org/developer/design/loader#legacy-cross-domain-mode for details. // // The following computations contort the packageMap for this dojo instance into a scopeMap. var scopeMap = // a map from a name used in a legacy module to the (global variable name, object addressed by that name) // always map dojo, dijit, and dojox { dojo:["dojo", dojo], dijit:["dijit", dijit], dojox:["dojox", dojox] }, packageMap = // the package map for this dojo instance; note, a foreign loader or no pacakgeMap results in the above default config (require.map && require.map[module.id.match(/[^\/]+/)[0]]), item; // process all mapped top-level names for this instance of dojo for(p in packageMap){ if(scopeMap[p]){ // mapped dojo, dijit, or dojox scopeMap[p][0] = packageMap[p]; }else{ // some other top-level name scopeMap[p] = [packageMap[p], {}]; } } // publish those names to _scopeName and, optionally, the global namespace for(p in scopeMap){ item = scopeMap[p]; item[1]._scopeName = item[0]; if(!config.noGlobals){ global[item[0]] = item[1]; } } dojo.scopeMap = scopeMap; /*===== dojo.__docParserConfigureScopeMap(scopeMap); =====*/ // FIXME: dojo.baseUrl and dojo.config.baseUrl should be deprecated dojo.baseUrl = dojo.config.baseUrl = require.baseUrl; dojo.isAsync = ! 1 || require.async; dojo.locale = config.locale; var rev = "$Rev:$".match(/[0-9a-f]{7,}/); dojo.version = { // summary: // Version number of the Dojo Toolkit // description: // Hash about the version, including // // - 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 Git rev from which dojo was pulled major: 1, minor: 17, patch: 3, flag: "", revision: rev ? rev[0] : NaN, toString: function(){ var v = dojo.version; return v.major + "." + v.minor + "." + v.patch + v.flag + " (" + v.revision + ")"; // String } }; // If 1 is truthy, then as a dojo module is defined it should push it's definitions // into the dojo object, and conversely. In 2.0, it will likely be unusual to augment another object // as a result of defining a module. This has feature gives a way to force 2.0 behavior as the code // is migrated. Absent specific advice otherwise, set extend-dojo to truthy. 1 || has.add("extend-dojo", 1); if(!has("csp-restrictions")){ (Function("d", "d.eval = function(){return d.global.eval ? d.global.eval(arguments[0]) : eval(arguments[0]);}"))(dojo); } /*===== dojo.eval = function(scriptText){ // summary: // A legacy method created for use exclusively by internal Dojo methods. Do not use this method // directly unless you understand its possibly-different implications on the platforms your are targeting. // description: // Makes an attempt to evaluate scriptText in the global scope. The function works correctly for browsers // that support indirect eval. // // As usual, IE does not. On IE, the only way to implement global eval is to // use execScript. Unfortunately, execScript does not return a value and breaks some current usages of dojo.eval. // This implementation uses the technique of executing eval in the scope of a function that is a single scope // frame below the global scope; thereby coming close to the global scope. Note carefully that // // dojo.eval("var pi = 3.14;"); // // will define global pi in non-IE environments, but define pi only in a temporary local scope for IE. If you want // to define a global variable using dojo.eval, write something like // // dojo.eval("window.pi = 3.14;") // scriptText: // The text to evaluation. // returns: // The result of the evaluation. Often `undefined` }; =====*/ if( 0 ){ dojo.exit = function(exitcode){ quit(exitcode); }; }else{ dojo.exit = function(){ }; } if(!has("host-webworker")){ // console is immutable in FF30+, https://bugs.dojotoolkit.org/ticket/18100 1 || has.add("dojo-guarantee-console", // ensure that console.log, console.warn, etc. are defined 1 ); } if( 1 ){ // IE 9 bug: https://bugs.dojotoolkit.org/ticket/18197 has.add("console-as-object", function () { return Function.prototype.bind && console && typeof console.log === "object"; }); typeof console != "undefined" || (console = {}); // intentional assignment // Be careful to leave 'log' always at the end var cn = [ "assert", "count", "debug", "dir", "dirxml", "error", "group", "groupEnd", "info", "profile", "profileEnd", "time", "timeEnd", "trace", "warn", "log" ]; var tn; i = 0; while((tn = cn[i++])){ if(!console[tn]){ (function(){ var tcn = tn + ""; console[tcn] = ('log' in console) ? function(){ var a = Array.prototype.slice.call(arguments); a.unshift(tcn + ":"); console["log"](a.join(" ")); } : function(){}; console[tcn]._fake = true; })(); }else if(has("console-as-object")){ console[tn] = Function.prototype.bind.call(console[tn], console); } } } has.add("dojo-debug-messages", // include dojo.deprecated/dojo.experimental implementations !!config.isDebug ); dojo.deprecated = dojo.experimental = function(){}; if(has("dojo-debug-messages")){ dojo.deprecated = function(/*String*/ behaviour, /*String?*/ extra, /*String?*/ 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"); var message = "DEPRECATED: " + behaviour; if(extra){ message += " " + extra; } if(removal){ message += " -- will be removed in version: " + removal; } console.warn(message); }; dojo.experimental = function(/* String */ moduleName, /* String? */ 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"); var message = "EXPERIMENTAL: " + moduleName + " -- APIs subject to change without notice."; if(extra){ message += " " + extra; } console.warn(message); }; } 1 || has.add("dojo-modulePaths", // consume dojo.modulePaths processing 1 ); if( 1 ){ // notice that modulePaths won't be applied to any require's before the dojo/_base/kernel factory is run; // this is the v1.6- behavior. if(config.modulePaths){ dojo.deprecated("dojo.modulePaths", "use paths configuration"); var paths = {}; for(p in config.modulePaths){ paths[p.replace(/\./g, "/")] = config.modulePaths[p]; } require({paths:paths}); } } 1 || has.add("dojo-moduleUrl", // include dojo.moduleUrl 1 ); if( 1 ){ dojo.moduleUrl = function(/*String*/module, /*String?*/url){ // summary: // Returns a URL 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"); // | img.src = pngPath; // | // 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 lengthy 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"); dojo.deprecated("dojo.moduleUrl()", "use require.toUrl", "2.0"); // require.toUrl requires a filetype; therefore, just append the suffix "/*.*" to guarantee a filetype, then // remove the suffix from the result. This way clients can request a url w/out a filetype. This should be // rare, but it maintains backcompat for the v1.x line (note: dojo.moduleUrl will be removed in v2.0). // Notice * is an illegal filename so it won't conflict with any real path map that may exist the paths config. var result = null; if(module){ result = require.toUrl(module.replace(/\./g, "/") + (url ? ("/" + url) : "") + "/*.*").replace(/\/\*\.\*/, "") + (url ? "" : "/"); } return result; }; } dojo._hasResource = {}; // for backward compatibility with layers built with 1.6 tooling return dojo; }); }, 'dojo/global':function(){ define(function(){ if (typeof global !== 'undefined' && typeof global !== 'function') { // global spec defines a reference to the global object called 'global' // https://github.com/tc39/proposal-global // `global` is also defined in NodeJS return global; } else if (typeof window !== 'undefined') { // window is defined in browsers return window; } else if (typeof self !== 'undefined') { // self is defined in WebWorkers return self; } return this; }); }, 'dojo/has':function(){ define(["./global", "require", "module"], function(global, require, module){ // module: // dojo/has // summary: // Defines the has.js API and several feature tests used by dojo. // description: // This module defines the has API as described by the project has.js with the following additional features: // // - the has test cache is exposed at has.cache. // - the method has.add includes a forth parameter that controls whether or not existing tests are replaced // - the loader's has cache may be optionally copied into this module's has cahce. // // This module adopted from https://github.com/phiggins42/has.js; thanks has.js team! // try to pull the has implementation from the loader; both the dojo loader and bdLoad provide one // if using a foreign loader, then the has cache may be initialized via the config object for this module // WARNING: if a foreign loader defines require.has to be something other than the has.js API, then this implementation fail var has = require.has || function(){}; if(! 1 ){ var isBrowser = // the most fundamental decision: are we in the browser? typeof window != "undefined" && typeof location != "undefined" && typeof document != "undefined" && window.location == location && window.document == document, // has API variables doc = isBrowser && document, element = doc && doc.createElement("DiV"), cache = (module.config && module.config()) || {}; has = function(name){ // summary: // Return the current value of the named feature. // // name: String|Integer // The name (if a string) or identifier (if an integer) of the feature to test. // // description: // Returns the value of the feature named by name. The feature must have been // previously added to the cache by has.add. return typeof cache[name] == "function" ? (cache[name] = cache[name](global, doc, element)) : cache[name]; // Boolean }; has.cache = cache; has.add = function(name, test, now, force){ // summary: // Register a new feature test for some named feature. // name: String|Integer // The name (if a string) or identifier (if an integer) of the feature to test. // test: Function // A test function to register. If a function, queued for testing until actually // needed. The test function should return a boolean indicating // the presence of a feature or bug. // now: Boolean? // Optional. Omit if `test` is not a function. Provides a way to immediately // run the test and cache the result. // force: Boolean? // Optional. If the test already exists and force is truthy, then the existing // test will be replaced; otherwise, add does not replace an existing test (that // is, by default, the first test advice wins). // example: // A redundant test, testFn with immediate execution: // | has.add("javascript", function(){ return true; }, true); // // example: // Again with the redundantness. You can do this in your tests, but we should // not be doing this in any internal has.js tests // | has.add("javascript", true); // // example: // Three things are passed to the testFunction. `global`, `document`, and a generic element // from which to work your test should the need arise. // | has.add("bug-byid", function(g, d, el){ // | // g == global, typically window, yadda yadda // | // d == document object // | // el == the generic element. a `has` element. // | return false; // fake test, byid-when-form-has-name-matching-an-id is slightly longer // | }); (typeof cache[name]=="undefined" || force) && (cache[name]= test); return now && has(name); }; // since we're operating under a loader that doesn't provide a has API, we must explicitly initialize // has as it would have otherwise been initialized by the dojo loader; use has.add to the builder // can optimize these away iff desired 1 || has.add("host-browser", isBrowser); 0 && has.add("host-node", (typeof process == "object" && process.versions && process.versions.node && process.versions.v8)); 0 && has.add("host-rhino", (typeof load == "function" && (typeof Packages == "function" || typeof Packages == "object"))); 1 || has.add("dom", isBrowser); 1 || has.add("dojo-dom-ready-api", 1); 1 || has.add("dojo-sniff", 1); } if( 1 ){ // Common application level tests has.add("dom-addeventlistener", !!document.addEventListener); // Do the device and browser have touch capability? has.add("touch", "ontouchstart" in document || ("onpointerdown" in document && navigator.maxTouchPoints > 0) || window.navigator.msMaxTouchPoints); // Touch events support has.add("touch-events", "ontouchstart" in document); // Test if pointer events are supported and enabled, with either standard names ("pointerdown" etc.) or // IE specific names ("MSPointerDown" etc.). Tests are designed to work on embedded C# WebBrowser Controls // in addition to IE, Edge, and future versions of Firefox and Chrome. // Note that on IE11, has("pointer-events") and has("MSPointer") are both true. has.add("pointer-events", "pointerEnabled" in window.navigator ? window.navigator.pointerEnabled : "PointerEvent" in window); has.add("MSPointer", window.navigator.msPointerEnabled); // The "pointermove"" event is only continuously emitted in a touch environment if // the target node's "touch-action"" CSS property is set to "none" // https://www.w3.org/TR/pointerevents/#the-touch-action-css-property has.add("touch-action", has("touch") && has("pointer-events")); // I don't know if any of these tests are really correct, just a rough guess has.add("device-width", screen.availWidth || innerWidth); // Tests for DOMNode.attributes[] behavior: // - dom-attributes-explicit - attributes[] only lists explicitly user specified attributes // - dom-attributes-specified-flag (IE8) - need to check attr.specified flag to skip attributes user didn't specify // - Otherwise, in IE6-7. attributes[] will list hundreds of values, so need to do outerHTML to get attrs instead. var form = document.createElement("form"); has.add("dom-attributes-explicit", form.attributes.length == 0); // W3C has.add("dom-attributes-specified-flag", form.attributes.length > 0 && form.attributes.length < 40); // IE8 } has.clearElement = function(element){ // summary: // Deletes the contents of the element passed to test functions. element.innerHTML= ""; return element; }; has.normalize = function(id, toAbsMid){ // summary: // Resolves id into a module id based on possibly-nested tenary expression that branches on has feature test value(s). // // toAbsMid: Function // Resolves a relative module id into an absolute module id var tokens = id.match(/[\?:]|[^:\?]*/g), i = 0, get = function(skip){ var term = tokens[i++]; if(term == ":"){ // empty string module name, resolves to 0 return 0; }else{ // postfixed with a ? means it is a feature to branch on, the term is the name of the feature if(tokens[i++] == "?"){ if(!skip && has(term)){ // matched the feature, get the first value from the options return get(); }else{ // did not match, get the second value, passing over the first get(true); return get(skip); } } // a module return term || 0; } }; id = get(); return id && toAbsMid(id); }; has.load = function(id, parentRequire, loaded){ // summary: // Conditional loading of AMD modules based on a has feature test value. // id: String // Gives the resolved module id to load. // parentRequire: Function // The loader require function with respect to the module that contained the plugin resource in it's // dependency list. // loaded: Function // Callback to loader that consumes result of plugin demand. if(id){ parentRequire([id], loaded); }else{ loaded(); } }; return has; }); }, 'dojo/_base/config':function(){ define(["../global", "../has", "require"], function(global, has, require){ // module: // dojo/_base/config /*===== return { // summary: // This module defines the user configuration during bootstrap. // description: // By defining user configuration as a module value, an entire configuration can be specified in a build, // thereby eliminating the need for sniffing and or explicitly setting in the global variable dojoConfig. // Also, when multiple instances of dojo exist in a single application, each will necessarily be located // at an unique absolute module identifier as given by the package configuration. Implementing configuration // as a module allows for specifying unique, per-instance configurations. // example: // Create a second instance of dojo with a different, instance-unique configuration (assume the loader and // dojo.js are already loaded). // | // specify a configuration that creates a new instance of dojo at the absolute module identifier "myDojo" // | require({ // | packages:[{ // | name:"myDojo", // | location:".", //assume baseUrl points to dojo.js // | }] // | }); // | // | // specify a configuration for the myDojo instance // | define("myDojo/config", { // | // normal configuration variables go here, e.g., // | locale:"fr-ca" // | }); // | // | // load and use the new instance of dojo // | require(["myDojo"], function(dojo){ // | // dojo is the new instance of dojo // | // use as required // | }); // isDebug: Boolean // Defaults to `false`. If set to `true`, ensures that Dojo provides // extended debugging feedback to the console. isDebug: 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 `` 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. The path should end in a slash. baseUrl: undefined, // modulePaths: [deprecated] 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. Specifying // `djConfig.modulePaths = { "foo": "../../bar" }` is the equivalent // of calling `dojo.registerModulePath("foo", "../../bar");`. Multiple // modules may be configured via `djConfig.modulePaths`. modulePaths: {}, // addOnLoad: Function|Array // Adds a callback via dojo/ready. Useful when Dojo is added after // the page loads and djConfig.afterOnLoad is true. Supports the same // arguments as dojo/ready. When using a function reference, use // `djConfig.addOnLoad = function(){};`. For object with function name use // `djConfig.addOnLoad = [myObject, "functionName"];` and for object with // function reference use // `djConfig.addOnLoad = [myObject, function(){}];` addOnLoad: null, // parseOnLoad: Boolean // Run the parser after the page is loaded parseOnLoad: false, // require: String[] // An array of module names to be loaded immediately after dojo.js has been included // in a page. require: [], // defaultDuration: Number // Default duration, in milliseconds, for wipe and fade animations within dijits. // Assigned to dijit.defaultDuration. defaultDuration: 200, // dojoBlankHtmlUrl: String // Used by some modules to configure an empty iframe. Used by dojo/io/iframe and // dojo/back, and dijit/popup support in IE where an iframe is needed to make sure native // controls do not bleed through the popups. Normally this configuration variable // does not need to be set, except when using cross-domain/CDN Dojo builds. // Save dojo/resources/blank.html to your domain and set `djConfig.dojoBlankHtmlUrl` // to the path on your domain your copy of blank.html. dojoBlankHtmlUrl: undefined, // ioPublish: Boolean? // Set this to true to enable publishing of topics for the different phases of // IO operations. Publishing is done via dojo/topic.publish(). See dojo/main.__IoPublish for a list // of topics that are published. ioPublish: false, // transparentColor: Array // Array containing the r, g, b components used as transparent color in dojo.Color; // if undefined, [255,255,255] (white) will be used. transparentColor: undefined, // deps: Function|Array // Defines dependencies to be used before the loader has been loaded. // When provided, they cause the loader to execute require(deps, callback) // once it has finished loading. Should be used with callback. deps: undefined, // callback: Function|Array // Defines a callback to be used when dependencies are defined before // the loader has been loaded. When provided, they cause the loader to // execute require(deps, callback) once it has finished loading. // Should be used with deps. callback: undefined, // deferredInstrumentation: Boolean // Whether deferred instrumentation should be loaded or included // in builds. deferredInstrumentation: true, // useDeferredInstrumentation: Boolean|String // Whether the deferred instrumentation should be used. // // * `"report-rejections"`: report each rejection as it occurs. // * `true` or `1` or `"report-unhandled-rejections"`: wait 1 second // in an attempt to detect unhandled rejections. useDeferredInstrumentation: "report-unhandled-rejections" }; =====*/ var result = {}; if( 1 ){ // must be the dojo loader; take a shallow copy of require.rawConfig var src = require.rawConfig, p; for(p in src){ result[p] = src[p]; } }else{ var adviseHas = function(featureSet, prefix, booting){ for(p in featureSet){ p!="has" && has.add(prefix + p, featureSet[p], 0, booting); } }; result = 1 ? // must be a built version of the dojo loader; all config stuffed in require.rawConfig require.rawConfig : // a foreign loader global.dojoConfig || global.djConfig || {}; adviseHas(result, "config", 1); adviseHas(result.has, "", 1); } if(!result.locale && typeof navigator != "undefined"){ // Default locale for browsers (ensure it's read from user-settings not download locale). var language = (navigator.languages && navigator.languages.length) ? navigator.languages[0] : (navigator.language || navigator.userLanguage); if(language){ result.locale = language.toLowerCase(); } } return result; }); }, 'dojo/json':function(){ define(["./has"], function(has){ "use strict"; var hasJSON = typeof JSON != "undefined"; has.add("json-parse", hasJSON); // all the parsers work fine // Firefox 3.5/Gecko 1.9 fails to use replacer in stringify properly https://bugzilla.mozilla.org/show_bug.cgi?id=509184 has.add("json-stringify", hasJSON && JSON.stringify({a:0}, function(k,v){return v||1;}) == '{"a":1}'); /*===== return { // summary: // Functions to parse and serialize JSON parse: function(str, strict){ // summary: // Parses a [JSON](http://json.org) string to return a JavaScript object. // description: // This function follows [native JSON API](https://developer.mozilla.org/en/JSON) // Throws for invalid JSON strings. This delegates to eval() if native JSON // support is not available. By default this will evaluate any valid JS expression. // With the strict parameter set to true, the parser will ensure that only // valid JSON strings are parsed (otherwise throwing an error). Without the strict // parameter, the content passed to this method must come // from a trusted source. // str: // a string literal of a JSON item, for instance: // `'{ "foo": [ "bar", 1, { "baz": "thud" } ] }'` // strict: // When set to true, this will ensure that only valid, secure JSON is ever parsed. // Make sure this is set to true for untrusted content. Note that on browsers/engines // without native JSON support, setting this to true will run slower. }, stringify: function(value, replacer, spacer){ // summary: // Returns a [JSON](http://json.org) serialization of an object. // description: // Returns a [JSON](http://json.org) serialization of an object. // This function follows [native JSON API](https://developer.mozilla.org/en/JSON) // Note that this doesn't check for infinite recursion, so don't do that! // value: // A value to be serialized. // replacer: // A replacer function that is called for each value and can return a replacement // spacer: // A spacer string to be used for pretty printing of JSON // example: // simple serialization of a trivial object // | define(["dojo/json"], function(JSON){ // | var jsonStr = JSON.stringify({ howdy: "stranger!", isStrange: true }); // | doh.is('{"howdy":"stranger!","isStrange":true}', jsonStr); } }; =====*/ if(has("json-stringify")){ return JSON; }else{ var 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 }; return { parse: has("json-parse") ? JSON.parse : function(str, strict){ if(strict && !/^([\s\[\{]*(?:"(?:\\.|[^"])*"|-?\d[\d\.]*(?:[Ee][+-]?\d+)?|null|true|false|)[\s\]\}]*(?:,|:|$))+$/.test(str)){ throw new SyntaxError("Invalid characters in JSON"); } return eval('(' + str + ')'); }, stringify: function(value, replacer, spacer){ var undef; if(typeof replacer == "string"){ spacer = replacer; replacer = null; } function stringify(it, indent, key){ if(replacer){ it = replacer(key, it); } var val, objtype = typeof it; if(objtype == "number"){ return isFinite(it) ? it + "" : "null"; } if(objtype == "boolean"){ return it + ""; } if(it === null){ return "null"; } if(typeof it == "string"){ return escapeString(it); } if(objtype == "function" || objtype == "undefined"){ return undef; // undefined } // short-circuit for objects that support "json" serialization // if they return "self" then just pass-through... if(typeof it.toJSON == "function"){ return stringify(it.toJSON(key), indent, key); } if(it instanceof Date){ return '"{FullYear}-{Month+}-{Date}T{Hours}:{Minutes}:{Seconds}Z"'.replace(/\{(\w+)(\+)?\}/g, function(t, prop, plus){ var num = it["getUTC" + prop]() + (plus ? 1 : 0); return num < 10 ? "0" + num : num; }); } if(it.valueOf() !== it){ // primitive wrapper, try again unwrapped: return stringify(it.valueOf(), indent, key); } var nextIndent= spacer ? (indent + spacer) : ""; /* we used to test for DOM nodes and throw, but FF serializes them as {}, so cross-browser consistency is probably not efficiently attainable */ var sep = spacer ? " " : ""; var newLine = spacer ? "\n" : ""; // array if(it instanceof Array){ var itl = it.length, res = []; for(key = 0; key < itl; key++){ var obj = it[key]; val = stringify(obj, nextIndent, key); if(typeof val != "string"){ val = "null"; } res.push(newLine + nextIndent + val); } return "[" + res.join(",") + newLine + indent + "]"; } // generic object code path var output = []; for(key in it){ var keyStr; if(it.hasOwnProperty(key)){ if(typeof key == "number"){ keyStr = '"' + key + '"'; }else if(typeof key == "string"){ keyStr = escapeString(key); }else{ // skip non-string or number keys continue; } val = stringify(it[key], nextIndent, key); if(typeof val != "string"){ // skip non-serializable values continue; } // At this point, the most non-IE browsers don't get in this branch // (they have native JSON), so push is definitely the way to output.push(newLine + nextIndent + keyStr + ":" + sep + val); } } return "{" + output.join(",") + newLine + indent + "}"; // String } return stringify(value, "", ""); } }; } }); }, 'dojo/_base/lang':function(){ define(["./kernel", "../has", "../sniff"], function(dojo, has){ // module: // dojo/_base/lang has.add("bug-for-in-skips-shadowed", function(){ // if true, the for-in iterator skips object properties that exist in Object's prototype (IE 6 - ?) for(var i in {toString: 1}){ return 0; } return 1; }); // Helper methods var _extraNames = has("bug-for-in-skips-shadowed") ? "hasOwnProperty.valueOf.isPrototypeOf.propertyIsEnumerable.toLocaleString.toString.constructor".split(".") : [], _extraLen = _extraNames.length, getProp = function(/*Array*/parts, /*Boolean*/create, /*Object*/context){ if(!context){ if(parts[0] && dojo.scopeMap[parts[0]]) { // Voodoo code from the old days where "dojo" or "dijit" maps to some special object // rather than just window.dojo context = dojo.scopeMap[parts.shift()][1]; }else{ context = dojo.global; } } try{ for(var i = 0; i < parts.length; i++){ var p = parts[i]; // Fix for prototype pollution CVE-2021-23450 if (p === '__proto__' || p === 'constructor') { return; } if(!(p in context)){ if(create){ context[p] = {}; }else{ return; // return undefined } } context = context[p]; } return context; // mixed }catch(e){ // "p in context" throws an exception when context is a number, boolean, etc. rather than an object, // so in that corner case just return undefined (by having no return statement) } }, opts = Object.prototype.toString, efficient = function(obj, offset, startWith){ return (startWith||[]).concat(Array.prototype.slice.call(obj, offset||0)); }, _pattern = /\{([^\}]+)\}/g; // Module export var lang = { // summary: // This module defines Javascript language extensions. // _extraNames: String[] // Lists property names that must be explicitly processed during for-in iteration // in environments that have has("bug-for-in-skips-shadowed") true. _extraNames:_extraNames, _mixin: function(dest, source, copyFunc){ // summary: // Copies/adds all properties of source to dest; returns dest. // dest: Object // The object to which to copy/add all properties contained in source. // source: Object // The object from which to draw all properties to copy into dest. // copyFunc: Function? // The process used to copy/add a property in source; defaults to the Javascript assignment operator. // returns: // dest, as modified // description: // All properties, including functions (sometimes termed "methods"), excluding any non-standard extensions // found in Object.prototype, are copied/added to dest. Copying/adding each particular property is // delegated to copyFunc (if any); copyFunc defaults to the Javascript assignment operator if not provided. // Notice that by default, _mixin executes a so-called "shallow copy" and aggregate types are copied/added by reference. var name, s, i, empty = {}; for(name in source){ // the (!(name in empty) || empty[name] !== s) condition avoids copying properties in "source" // inherited from Object.prototype. For example, if dest has a custom toString() method, // don't overwrite it with the toString() method that source inherited from Object.prototype s = source[name]; if(!(name in dest) || (dest[name] !== s && (!(name in empty) || empty[name] !== s))){ dest[name] = copyFunc ? copyFunc(s) : s; } } if(has("bug-for-in-skips-shadowed")){ if(source){ for(i = 0; i < _extraLen; ++i){ name = _extraNames[i]; s = source[name]; if(!(name in dest) || (dest[name] !== s && (!(name in empty) || empty[name] !== s))){ dest[name] = copyFunc ? copyFunc(s) : s; } } } } return dest; // Object }, mixin: function(dest, sources){ // summary: // Copies/adds all properties of one or more sources to dest; returns dest. // dest: Object // The object to which to copy/add all properties contained in source. If dest is falsy, then // a new object is manufactured before copying/adding properties begins. // sources: Object... // One of more objects from which to draw all properties to copy into dest. sources are processed // left-to-right and if more than one of these objects contain the same property name, the right-most // value "wins". // returns: Object // dest, as modified // description: // All properties, including functions (sometimes termed "methods"), excluding any non-standard extensions // found in Object.prototype, are copied/added from sources to dest. sources are processed left to right. // The Javascript assignment operator is used to copy/add each property; therefore, by default, mixin // executes a so-called "shallow copy" and aggregate types are copied/added by reference. // example: // make a shallow copy of an object // | var copy = lang.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 `lang.mixin` on the `this` object: // | declare("acme.Base", null, { // | constructor: function(properties){ // | // property configuration: // | lang.mixin(this, properties); // | // | console.log(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 = lang.mixin( // | { // | name: "Frylock", // | braces: true // | }, // | { // | name: "Carl Brutanananadilewski" // | } // | ); // | // | // will print "Carl Brutanananadilewski" // | console.log(flattened.name); // | // will print "true" // | console.log(flattened.braces); if(!dest){ dest = {}; } for(var i = 1, l = arguments.length; i < l; i++){ lang._mixin(dest, arguments[i]); } return dest; // Object }, setObject: function(name, value, 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: String // Path to a property, in the form "A.B.C". // value: anything // value or object to place at location given by name // context: Object? // 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: // | lang.setObject("foo.bar.baz", value); // example: // without `lang.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"; // whereas with `lang.setObject`, we can shorten that to: // | lang.setObject("parent.child.prop", "some value", obj); var parts = name.split("."), p = parts.pop(), obj = getProp(parts, true, context); return obj && p ? (obj[p] = value) : undefined; // Object }, getObject: function(name, create, 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: String // Path to an property, in the form "A.B.C". // create: Boolean? // Optional. Defaults to `false`. If `true`, Objects will be // created at any point along the 'path' that is undefined. // context: Object? // Optional. Object to use as root of path. Defaults to // 'dojo.global'. Null may be passed. return !name ? context : getProp(name.split("."), create, context); // Object }, exists: function(name, 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. Useful for object and method detection. // name: String // Path to an object, in the form "A.B.C". // obj: Object? // 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 // | lang.exists("foo.bar"); // true // | lang.exists("foo.bar.baz"); // false // | // | // search from a particular scope // | lang.exists("bar", foo); // true // | lang.exists("bar.baz", foo); // false return lang.getObject(name, false, obj) !== undefined; // Boolean }, // Crockford (ish) functions isString: function(it){ // summary: // Return true if it is a String // it: anything // Item to test. return (typeof it == "string" || it instanceof String); // Boolean }, isArray: Array.isArray || function(it){ // summary: // Return true if it is an Array. // it: anything // Item to test. return opts.call(it) == "[object Array]"; // Boolean }, isFunction: function(it){ // summary: // Return true if it is a Function // it: anything // Item to test. return opts.call(it) === "[object Function]"; }, isObject: function(it){ // summary: // Returns true if it is a JavaScript object (or an Array, a Function // or null) // it: anything // Item to test. return it !== undefined && (it === null || typeof it == "object" || lang.isArray(it) || lang.isFunction(it)); // Boolean }, isArrayLike: function(it){ // summary: // similar to isArray() but more permissive // it: anything // Item to test. // returns: // If it walks like a duck and quacks like a duck, return `true` // 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 // isArrayLike(), but will return false when passed to // isArray(). return !!it && // Boolean // keep out built-in constructors (Number, String, ...) which have length // properties !lang.isString(it) && !lang.isFunction(it) && !(it.tagName && it.tagName.toLowerCase() == 'form') && (lang.isArray(it) || isFinite(it.length)); }, isAlien: function(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 && !lang.isFunction(it) && /\{\s*\[native code\]\s*\}/.test(String(it)); // Boolean }, extend: function(ctor, props){ // summary: // Adds all properties and methods of props to constructor's // prototype, making them available to all instances created with // constructor. // ctor: Object // Target constructor to extend. // props: Object // One or more objects to mix into ctor.prototype for(var i=1, l=arguments.length; i 2){ return lang._hitchArgs.apply(dojo, arguments); // Function } if(!method){ method = scope; scope = null; } if(lang.isString(method)){ scope = scope || dojo.global; if(!scope[method]){ throw(['lang.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 }, delegate: (function(){ // boodman/crockford delegation w/ cornford optimization function TMP(){} return function(obj, props){ TMP.prototype = obj; var tmp = new TMP(); TMP.prototype = null; if(props){ lang._mixin(tmp, props); } return tmp; // Object }; })(), /*===== 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 implementation 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: Object // The object to delegate to for properties not found directly on the // return object or in props. // props: Object... // an object containing properties to assign to the returned object // returns: // an Object of anonymous type // example: // | var foo = { bar: "baz" }; // | var thinger = lang.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 }, =====*/ _toArray: has("ie") ? (function(){ function slow(obj, offset, startWith){ var arr = startWith||[]; for(var x = offset || 0; x < obj.length; x++){ arr.push(obj[x]); } return arr; } return function(obj){ return ((obj.item) ? slow : efficient).apply(this, arguments); }; })() : efficient, /*===== _toArray: function(obj, offset, startWith){ // summary: // Converts an array-like object (i.e. arguments, DOMCollection) to an // array. Returns a new Array with the elements of obj. // obj: Object // the object to "arrayify". We expect the object to have, at a // minimum, a length property which corresponds to integer-indexed // properties. // offset: Number? // the location in obj to start iterating from. Defaults to 0. // Optional. // startWith: Array? // 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. }, =====*/ 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 lang.partial is the functional equivalent of calling: // | lang.hitch(null, funcName, ...); // method: // The function to "wrap" var arr = [ null ]; return lang.hitch.apply(dojo, arr.concat(lang._toArray(arguments))); // Function }, clone: function(/*anything*/ src){ // summary: // Clones objects (including DOM nodes) and all children. // Warning: do not clone cyclic structures. // src: // The object to clone if(!src || typeof src != "object" || lang.isFunction(src)){ // null, undefined, any non-object, or function return src; // anything } if(src.nodeType && "cloneNode" in src){ // DOM Node return src.cloneNode(true); // Node } if(src instanceof Date){ // Date return new Date(src.getTime()); // Date } if(src instanceof RegExp){ // RegExp return new RegExp(src); // RegExp } var r, i, l; if(lang.isArray(src)){ // array r = []; for(i = 0, l = src.length; i < l; ++i){ if(i in src){ r[i] = lang.clone(src[i]); } } // we don't clone functions for performance reasons // }else if(d.isFunction(src)){ // // function // r = function(){ return src.apply(this, arguments); }; }else{ // generic objects r = src.constructor ? new src.constructor() : {}; } return lang._mixin(r, src, lang.clone); }, trim: String.prototype.trim ? function(str){ return str.trim(); } : function(str){ return str.replace(/^\s\s*/, '').replace(/\s\s*$/, ''); }, /*===== trim: function(str){ // summary: // Trims whitespace from both sides of the string // str: String // String to be trimmed // returns: String // Returns the trimmed 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) // Uses String.prototype.trim instead, if available. // The fastest but longest version of this function is located at // lang.string.trim() }, =====*/ replace: function(tmpl, map, pattern){ // summary: // Performs parameterized substitutions on a string. Throws an // exception if any parameter is unmatched. // tmpl: String // String to be used as a template. // map: Object|Function // If an object, it is used as a dictionary to look up substitutions. // If a function, it is called for every substitution with following parameters: // a whole match, a name, an offset, and the whole template // string (see https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/String/replace // for more details). // pattern: RegEx? // Optional regular expression objects that overrides the default pattern. // Must be global and match one item. The default is: /\{([^\}]+)\}/g, // which matches patterns like that: "{xxx}", where "xxx" is any sequence // of characters, which doesn't include "}". // returns: String // Returns the substituted string. // example: // | // uses a dictionary for substitutions: // | lang.replace("Hello, {name.first} {name.last} AKA {nick}!", // | { // | nick: "Bob", // | name: { // | first: "Robert", // | middle: "X", // | last: "Cringely" // | } // | }); // | // returns: Hello, Robert Cringely AKA Bob! // example: // | // uses an array for substitutions: // | lang.replace("Hello, {0} {2}!", // | ["Robert", "X", "Cringely"]); // | // returns: Hello, Robert Cringely! // example: // | // uses a function for substitutions: // | function sum(a){ // | var t = 0; // | arrayforEach(a, function(x){ t += x; }); // | return t; // | } // | lang.replace( // | "{count} payments averaging {avg} USD per payment.", // | lang.hitch( // | { payments: [11, 16, 12] }, // | function(_, key){ // | switch(key){ // | case "count": return this.payments.length; // | case "min": return Math.min.apply(Math, this.payments); // | case "max": return Math.max.apply(Math, this.payments); // | case "sum": return sum(this.payments); // | case "avg": return sum(this.payments) / this.payments.length; // | } // | } // | ) // | ); // | // prints: 3 payments averaging 13 USD per payment. // example: // | // uses an alternative PHP-like pattern for substitutions: // | lang.replace("Hello, ${0} ${2}!", // | ["Robert", "X", "Cringely"], /\$\{([^\}]+)\}/g); // | // returns: Hello, Robert Cringely! return tmpl.replace(pattern || _pattern, lang.isFunction(map) ? map : function(_, k){ return lang.getObject(k, false, map); }); } }; 1 && lang.mixin(dojo, lang); return lang; }); }, 'dojo/sniff':function(){ define(["./has"], function(has){ // module: // dojo/sniff /*===== return function(){ // summary: // This module sets has() flags based on the current browser. // It returns the has() function. }; =====*/ if( 1 ){ var n = navigator, dua = n.userAgent, dav = n.appVersion, tv = parseFloat(dav); has.add("air", dua.indexOf("AdobeAIR") >= 0); has.add("wp", parseFloat(dua.split("Windows Phone")[1]) || undefined); has.add("msapp", parseFloat(dua.split("MSAppHost/")[1]) || undefined); has.add("khtml", dav.indexOf("Konqueror") >= 0 ? tv : undefined); has.add("edge", parseFloat(dua.split("Edge/")[1]) || undefined); has.add("opr", parseFloat(dua.split("OPR/")[1]) || undefined); // NOTE: https://dev.opera.com/blog/opera-user-agent-strings-opera-15-and-beyond/ has.add("webkit", !has("wp") // NOTE: necessary since Windows Phone 8.1 Update 1, see #18540 && !has("edge") && parseFloat(dua.split("WebKit/")[1]) || undefined); has.add("chrome", !has("edge") && !has("opr") && parseFloat(dua.split("Chrome/")[1]) || undefined); has.add("android", !has("wp") // NOTE: necessary since Windows Phone 8.1 Update 1, see #18528 && parseFloat(dua.split("Android ")[1]) || undefined); has.add("safari", dav.indexOf("Safari") >= 0 && !has("wp") // NOTE: necessary since Windows Phone 8.1 Update 1, see #18540 && !has("chrome") && !has("android") && !has("edge") && !has("opr") ? parseFloat(dav.split("Version/")[1]) : undefined); has.add("mac", dav.indexOf("Macintosh") >= 0); has.add("quirks", document.compatMode == "BackCompat"); if(!has("wp") // NOTE: necessary since Windows Phone 8.1 Update 1, see #18528 && dua.match(/(iPhone|iPod|iPad)/)){ var p = RegExp.$1.replace(/P/, "p"); var v = dua.match(/OS ([\d_]+)/) ? RegExp.$1 : "1"; var os = parseFloat(v.replace(/_/, ".").replace(/_/g, "")); has.add(p, os); // "iphone", "ipad" or "ipod" has.add("ios", os); } has.add("bb", (dua.indexOf("BlackBerry") >= 0 || dua.indexOf("BB10") >= 0) && parseFloat(dua.split("Version/")[1]) || undefined); has.add("trident", parseFloat(dav.split("Trident/")[1]) || undefined); has.add("svg", typeof SVGAngle !== "undefined"); if(!has("webkit")){ // Opera if(dua.indexOf("Opera") >= 0){ // see http://dev.opera.com/articles/view/opera-ua-string-changes and http://www.useragentstring.com/pages/Opera/ // 9.8 has both styles; <9.8, 9.9 only old style has.add("opera", tv >= 9.8 ? parseFloat(dua.split("Version/")[1]) || tv : tv); } // Mozilla and firefox if(dua.indexOf("Gecko") >= 0 && !has("wp") // NOTE: necessary since Windows Phone 8.1 Update 1 && !has("khtml") && !has("trident") && !has("edge")){ has.add("mozilla", tv); } if(has("mozilla")){ //We really need to get away from this. Consider a sane isGecko approach for the future. has.add("ff", parseFloat(dua.split("Firefox/")[1] || dua.split("Minefield/")[1]) || undefined); } // IE if(document.all && !has("opera")){ var isIE = parseFloat(dav.split("MSIE ")[1]) || undefined; //In cases where the page has an HTTP header or META tag with //X-UA-Compatible, then it is in emulation mode. //Make sure isIE reflects the desired version. //document.documentMode of 5 means quirks mode. //Only switch the value if documentMode's major version //is different from isIE's major version. var mode = document.documentMode; if(mode && mode != 5 && Math.floor(isIE) != mode){ isIE = mode; } has.add("ie", isIE); } // Wii has.add("wii", typeof opera != "undefined" && opera.wiiremote); } } return has; }); }, 'dojo/_base/array':function(){ define(["./kernel", "../has", "./lang"], function(dojo, has, lang){ // module: // dojo/_base/array // our old simple function builder stuff var cache = {}, u; var buildFn; if(!has("csp-restrictions")){ buildFn = function (fn){ return cache[fn] = new Function("item", "index", "array", fn); // Function }; } // magic snippet: if(typeof fn == "string") fn = cache[fn] || buildFn(fn); // every & some function everyOrSome(some){ var every = !some; return function(a, fn, o){ var i = 0, l = a && a.length || 0, result; if(l && typeof a == "string") a = a.split(""); if(typeof fn == "string"){ if(has("csp-restrictions")){ throw new TypeError("callback must be a function"); } else{ fn = cache[fn] || buildFn(fn); } } if(o){ for(; i < l; ++i){ result = !fn.call(o, a[i], i, a); if(some ^ result){ return !result; } } }else{ for(; i < l; ++i){ result = !fn(a[i], i, a); if(some ^ result){ return !result; } } } return every; // Boolean }; } // indexOf, lastIndexOf function index(up){ var delta = 1, lOver = 0, uOver = 0; if(!up){ delta = lOver = uOver = -1; } return function(a, x, from, last){ if(last && delta > 0){ // TODO: why do we use a non-standard signature? why do we need "last"? return array.lastIndexOf(a, x, from); } var l = a && a.length || 0, end = up ? l + uOver : lOver, i; if(from === u){ i = up ? lOver : l + uOver; }else{ if(from < 0){ i = l + from; if(i < 0){ i = lOver; } }else{ i = from >= l ? l + uOver : from; } } if(l && typeof a == "string") a = a.split(""); for(; i != end; i += delta){ if(a[i] == x){ return i; // Number } } return -1; // Number }; } var array = { // summary: // The Javascript v1.6 array extensions. every: everyOrSome(false), /*===== every: function(arr, callback, thisObject){ // summary: // Determines whether or not every item in arr satisfies the // condition implemented by callback. // arr: Array|String // the array to iterate on. If a string, operates on individual characters. // callback: Function|String // a function is invoked with three arguments: item, index, // and array and returns true if the condition is met. // thisObject: Object? // may be used to scope the call to callback // returns: Boolean // description: // This function corresponds to the JavaScript 1.6 Array.every() method, with one difference: when // run over sparse arrays, this implementation passes the "holes" in the sparse array to // the callback function with a value of undefined. JavaScript 1.6's every skips the holes in the sparse array. // For more details, see: // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/every // example: // | // returns false // | array.every([1, 2, 3, 4], function(item){ return item>1; }); // example: // | // returns true // | array.every([1, 2, 3, 4], function(item){ return item>0; }); }, =====*/ some: everyOrSome(true), /*===== some: function(arr, callback, thisObject){ // summary: // Determines whether or not any item in arr satisfies the // condition implemented by callback. // arr: Array|String // the array to iterate over. If a string, operates on individual characters. // callback: Function|String // a function is invoked with three arguments: item, index, // and array and returns true if the condition is met. // thisObject: Object? // may be used to scope the call to callback // returns: Boolean // description: // This function corresponds to the JavaScript 1.6 Array.some() method, with one difference: when // run over sparse arrays, this implementation passes the "holes" in the sparse array to // the callback function with a value of undefined. JavaScript 1.6's some skips the holes in the sparse array. // For more details, see: // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/some // example: // | // is true // | array.some([1, 2, 3, 4], function(item){ return item>1; }); // example: // | // is false // | array.some([1, 2, 3, 4], function(item){ return item<1; }); }, =====*/ indexOf: index(true), /*===== indexOf: function(arr, value, fromIndex, findLast){ // summary: // locates the first index of the provided value in the // passed array. If the value is not found, -1 is returned. // description: // This method corresponds to the JavaScript 1.6 Array.indexOf method, with two differences: // // 1. when run over sparse arrays, the Dojo function invokes the callback for every index // whereas JavaScript 1.6's indexOf skips the holes in the sparse array. // 2. uses equality (==) rather than strict equality (===) // // For details on this method, see: // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/indexOf // arr: Array // value: Object // fromIndex: Integer? // findLast: Boolean? // Makes indexOf() work like lastIndexOf(). Used internally; not meant for external usage. // returns: Number }, =====*/ lastIndexOf: index(false), /*===== lastIndexOf: function(arr, value, fromIndex){ // summary: // locates the last index of the provided value in the passed // array. If the value is not found, -1 is returned. // description: // This method corresponds to the JavaScript 1.6 Array.lastIndexOf method, with two differences: // // 1. when run over sparse arrays, the Dojo function invokes the callback for every index // whereas JavaScript 1.6's lasIndexOf skips the holes in the sparse array. // 2. uses equality (==) rather than strict equality (===) // // For details on this method, see: // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/lastIndexOf // arr: Array, // value: Object, // fromIndex: Integer? // returns: Number }, =====*/ forEach: function(arr, callback, thisObject){ // summary: // for every item in arr, callback is invoked. Return values are ignored. // If you want to break out of the loop, consider using array.every() or array.some(). // forEach does not allow breaking out of the loop over the items in arr. // arr: // the array to iterate over. 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, with one difference: when // run over sparse arrays, this implementation passes the "holes" in the sparse array to // the callback function with a value of undefined. JavaScript 1.6's forEach skips the holes in the sparse array. // For more details, see: // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/forEach // example: // | // log out all members of the array: // | array.forEach( // | [ "thinger", "blah", "howdy", 10 ], // | function(item){ // | console.log(item); // | } // | ); // example: // | // log out the members and their indexes // | array.forEach( // | [ "thinger", "blah", "howdy", 10 ], // | function(item, idx, arr){ // | console.log(item, "at index:", idx); // | } // | ); // example: // | // use a scoped object member as the callback // | // | var obj = { // | prefix: "logged via obj.callback:", // | callback: function(item){ // | console.log(this.prefix, item); // | } // | }; // | // | // specifying the scope function executes the callback in that scope // | array.forEach( // | [ "thinger", "blah", "howdy", 10 ], // | obj.callback, // | obj // | ); // | // | // alternately, we can accomplish the same thing with lang.hitch() // | array.forEach( // | [ "thinger", "blah", "howdy", 10 ], // | lang.hitch(obj, "callback") // | ); // arr: Array|String // callback: Function|String // thisObject: Object? var i = 0, l = arr && arr.length || 0; if(l && typeof arr == "string") arr = arr.split(""); if(typeof callback == "string"){ if(has("csp-restrictions")){ throw new TypeError("callback must be a function"); } else{ callback = cache[callback] || buildFn(callback); } } if(thisObject){ for(; i < l; ++i){ callback.call(thisObject, arr[i], i, arr); } }else{ for(; i < l; ++i){ callback(arr[i], i, arr); } } }, map: function(arr, callback, thisObject, Ctr){ // summary: // applies callback to each element of arr and returns // an Array with the results // arr: Array|String // the array to iterate on. If a string, operates on // individual characters. // callback: Function|String // a function is invoked with three arguments, (item, index, // array), and returns a value // thisObject: Object? // may be used to scope the call to callback // returns: Array // description: // This function corresponds to the JavaScript 1.6 Array.map() method, with one difference: when // run over sparse arrays, this implementation passes the "holes" in the sparse array to // the callback function with a value of undefined. JavaScript 1.6's map skips the holes in the sparse array. // For more details, see: // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map // example: // | // returns [2, 3, 4, 5] // | array.map([1, 2, 3, 4], function(item){ return item+1 }); // TODO: why do we have a non-standard signature here? do we need "Ctr"? var i = 0, l = arr && arr.length || 0, out = new (Ctr || Array)(l); if(l && typeof arr == "string") arr = arr.split(""); if(typeof callback == "string"){ if(has("csp-restrictions")){ throw new TypeError("callback must be a function"); } else{ callback = cache[callback] || buildFn(callback); } } if(thisObject){ for(; i < l; ++i){ out[i] = callback.call(thisObject, arr[i], i, arr); } }else{ for(; i < l; ++i){ out[i] = callback(arr[i], i, arr); } } return out; // Array }, filter: function(arr, callback, thisObject){ // summary: // Returns a new Array with those items from arr that match the // condition implemented by callback. // arr: Array // the array to iterate over. // callback: Function|String // a function that is invoked with three arguments (item, // index, array). The return of this function is expected to // be a boolean which determines whether the passed-in item // will be included in the returned array. // thisObject: Object? // may be used to scope the call to callback // returns: Array // description: // This function corresponds to the JavaScript 1.6 Array.filter() method, with one difference: when // run over sparse arrays, this implementation passes the "holes" in the sparse array to // the callback function with a value of undefined. JavaScript 1.6's filter skips the holes in the sparse array. // For more details, see: // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/filter // example: // | // returns [2, 3, 4] // | array.filter([1, 2, 3, 4], function(item){ return item>1; }); // TODO: do we need "Ctr" here like in map()? var i = 0, l = arr && arr.length || 0, out = [], value; if(l && typeof arr == "string") arr = arr.split(""); if(typeof callback == "string"){ if(has("csp-restrictions")){ throw new TypeError("callback must be a function"); } else{ callback = cache[callback] || buildFn(callback); } } if(thisObject){ for(; i < l; ++i){ value = arr[i]; if(callback.call(thisObject, value, i, arr)){ out.push(value); } } }else{ for(; i < l; ++i){ value = arr[i]; if(callback(value, i, arr)){ out.push(value); } } } return out; // Array }, clearCache: function(){ cache = {}; } }; 1 && lang.mixin(dojo, array); return array; }); }, 'dojo/text':function(){ define(["./_base/kernel", "require", "./has", "./request"], function(dojo, require, has, request){ // module: // dojo/text var getText; if( 1 ){ getText= function(url, sync, load){ request(url, {sync:!!sync, headers: { 'X-Requested-With': null } }).then(load); }; }else{ // Path for node.js and rhino, to load from local file system. // TODO: use node.js native methods rather than depending on a require.getText() method to exist. if(require.getText){ getText= require.getText; }else{ console.error("dojo/text plugin failed to load because loader does not support getText"); } } var theCache = {}, strip= function(text){ //Strips declarations so that external SVG and XML //documents can be added to a document without worry. Also, if the string //is an HTML document, only the part inside the body tag is returned. if(text){ text= text.replace(/^\s*<\?xml(\s)+version=[\'\"](\d)*.(\d)*[\'\"](\s)*\?>/im, ""); var matches= text.match(/]*>\s*([\s\S]+)\s*<\/body>/im); if(matches){ text= matches[1]; } }else{ text = ""; } return text; }, notFound = {}, pending = {}; dojo.cache = function(/*String||Object*/module, /*String*/url, /*String||Object?*/value){ // summary: // A getter and setter for storing the string content associated with the // module and url arguments. // description: // If module is a string that contains slashes, then it is interpretted as a fully // resolved path (typically a result returned by require.toUrl), and url should not be // provided. This is the preferred signature. If module is a string that does not // contain slashes, then url must also be provided and module and url are used to // call `dojo.moduleUrl()` to generate a module URL. This signature is deprecated. // If value is specified, the cache value for the moduleUrl will be set to // that value. Otherwise, dojo.cache will fetch the moduleUrl and store it // in its internal cache and return that cached value for the URL. To clear // a cache value pass null for value. Since XMLHttpRequest (XHR) is used to fetch the // the URL contents, only modules on the same domain of the page can use this capability. // The build system can inline the cache values though, to allow for xdomain hosting. // module: String||Object // If a String with slashes, a fully resolved path; if a String without slashes, the // module name to use for the base part of the URL, similar to module argument // to `dojo.moduleUrl`. If an Object, something that has a .toString() method that // generates a valid path for the cache item. For example, a dojo._Url object. // url: String // The rest of the path to append to the path derived from the module argument. If // module is an object, then this second argument should be the "value" argument instead. // value: String||Object? // If a String, the value to use in the cache for the module/url combination. // If an Object, it can have two properties: value and sanitize. The value property // should be the value to use in the cache, and sanitize can be set to true or false, // to indicate if XML declarations should be removed from the value and if the HTML // inside a body tag in the value should be extracted as the real value. The value argument // or the value property on the value argument are usually only used by the build system // as it inlines cache content. // example: // To ask dojo.cache to fetch content and store it in the cache (the dojo["cache"] style // of call is used to avoid an issue with the build system erroneously trying to intern // this example. To get the build system to intern your dojo.cache calls, use the // "dojo.cache" style of call): // | //If template.html contains "

Hello

" that will be // | //the value for the text variable. // | //Note: This is pre-AMD, deprecated syntax // | var text = dojo["cache"]("my.module", "template.html"); // example: // To ask dojo.cache to fetch content and store it in the cache, and sanitize the input // (the dojo["cache"] style of call is used to avoid an issue with the build system // erroneously trying to intern this example. To get the build system to intern your // dojo.cache calls, use the "dojo.cache" style of call): // | //If template.html contains "

Hello

", the // | //text variable will contain just "

Hello

". // | //Note: This is pre-AMD, deprecated syntax // | var text = dojo["cache"]("my.module", "template.html", {sanitize: true}); // example: // Same example as previous, but demonstrates how an object can be passed in as // the first argument, then the value argument can then be the second argument. // | //If template.html contains "

Hello

", the // | //text variable will contain just "

Hello

". // | //Note: This is pre-AMD, deprecated syntax // | var text = dojo["cache"](new dojo._Url("my/module/template.html"), {sanitize: true}); // * (string string [value]) => (module, url, value) // * (object [value]) => (module, value), url defaults to "" // // * if module is an object, then it must be convertable to a string // * (module, url) module + (url ? ("/" + url) : "") must be a legal argument to require.toUrl // * value may be a string or an object; if an object then may have the properties "value" and/or "sanitize" var key; if(typeof module=="string"){ if(/\//.test(module)){ // module is a version 1.7+ resolved path key = module; value = url; }else{ // module is a version 1.6- argument to dojo.moduleUrl key = require.toUrl(module.replace(/\./g, "/") + (url ? ("/" + url) : "")); } }else{ key = module + ""; value = url; } var val = (value != undefined && typeof value != "string") ? value.value : value, sanitize = value && value.sanitize; if(typeof val == "string"){ //We have a string, set cache value theCache[key] = val; return sanitize ? strip(val) : val; }else if(val === null){ //Remove cached value delete theCache[key]; return null; }else{ //Allow cache values to be empty strings. If key property does //not exist, fetch it. if(!(key in theCache)){ getText(key, true, function(text){ theCache[key]= text; }); } return sanitize ? strip(theCache[key]) : theCache[key]; } }; return { // summary: // This module implements the dojo/text! plugin and the dojo.cache API. // description: // We choose to include our own plugin to leverage functionality already contained in dojo // and thereby reduce the size of the plugin compared to various foreign loader implementations. // Also, this allows foreign AMD loaders to be used without their plugins. // // CAUTION: this module is designed to optionally function synchronously to support the dojo v1.x synchronous // loader. This feature is outside the scope of the CommonJS plugins specification. // the dojo/text caches it's own resources because of dojo.cache dynamic: true, normalize: function(id, toAbsMid){ // id is something like (path may be relative): // // "path/to/text.html" // "path/to/text.html!strip" var parts= id.split("!"), url= parts[0]; return (/^\./.test(url) ? toAbsMid(url) : url) + (parts[1] ? "!" + parts[1] : ""); }, load: function(id, require, load){ // id: String // Path to the resource. // require: Function // Object that include the function toUrl with given id returns a valid URL from which to load the text. // load: Function // Callback function which will be called, when the loading finished. // id is something like (path is always absolute): // // "path/to/text.html" // "path/to/text.html!strip" var parts= id.split("!"), stripFlag= parts.length>1, absMid= parts[0], url = require.toUrl(parts[0]), requireCacheUrl = "url:" + url, text = notFound, finish = function(text){ load(stripFlag ? strip(text) : text); }; if(absMid in theCache){ text = theCache[absMid]; }else if(require.cache && requireCacheUrl in require.cache){ text = require.cache[requireCacheUrl]; }else if(url in theCache){ text = theCache[url]; } if(text===notFound){ if(pending[url]){ pending[url].push(finish); }else{ var pendingList = pending[url] = [finish]; getText(url, !require.async, function(text){ theCache[absMid]= theCache[url]= text; for(var i = 0; i/nls/*` and // therefore never looks like a relative return /^\./.test(id) ? toAbsMid(id) : id; }, getLocalesToLoad = function(targetLocale){ var list = config.extraLocale || []; list = lang.isArray(list) ? list : [list]; list.push(targetLocale); return list; }, load = function(id, require, load){ // summary: // id is in one of the following formats // // 1. /nls/ // => load the bundle, localized to config.locale; load all bundles localized to // config.extraLocale (if any); return the loaded bundle localized to config.locale. // // 2. /nls// // => load then return the bundle localized to // // 3. *preload*/nls/* // => for config.locale and all config.extraLocale, load all bundles found // in the best-matching bundle rollup. A value of 1 is returned, which // is meaningless other than to say the plugin is executing the requested // preloads // // In cases 1 and 2, is always normalized to an absolute module id upon entry; see // normalize. In case 3, it is assumed to be absolute; this is arranged by the builder. // // To load a bundle means to insert the bundle into the plugin's cache and publish the bundle // value to the loader. Given , , and a particular , the cache key // // /nls// // // will hold the value. Similarly, then plugin will publish this value to the loader by // // define("/nls//", ); // // Given this algorithm, other machinery can provide fast load paths be preplacing // values in the plugin's cache, which is public. When a load is demanded the // cache is inspected before starting any loading. Explicitly placing values in the plugin // cache is an advanced/experimental feature that should not be needed; use at your own risk. // // For the normal AMD algorithm, the root bundle is loaded first, which instructs the // plugin what additional localized bundles are required for a particular locale. These // additional locales are loaded and a mix of the root and each progressively-specific // locale is returned. For example: // // 1. The client demands "dojo/i18n!some/path/nls/someBundle // // 2. The loader demands load(some/path/nls/someBundle) // // 3. This plugin require's "some/path/nls/someBundle", which is the root bundle. // // 4. Assuming config.locale is "ab-cd-ef" and the root bundle indicates that localizations // are available for "ab" and "ab-cd-ef" (note the missing "ab-cd", then the plugin // requires "some/path/nls/ab/someBundle" and "some/path/nls/ab-cd-ef/someBundle" // // 5. Upon receiving all required bundles, the plugin constructs the value of the bundle // ab-cd-ef as... // // mixin(mixin(mixin({}, require("some/path/nls/someBundle"), // require("some/path/nls/ab/someBundle")), // require("some/path/nls/ab-cd-ef/someBundle")); // // This value is inserted into the cache and published to the loader at the // key/module-id some/path/nls/someBundle/ab-cd-ef. // // The special preload signature (case 3) instructs the plugin to stop servicing all normal requests // (further preload requests will be serviced) until all ongoing preloading has completed. // // The preload signature instructs the plugin that a special rollup module is available that contains // one or more flattened, localized bundles. The JSON array of available locales indicates which locales // are available. Here is an example: // // *preload*some/path/nls/someModule*["root", "ab", "ab-cd-ef"] // // This indicates the following rollup modules are available: // // some/path/nls/someModule_ROOT // some/path/nls/someModule_ab // some/path/nls/someModule_ab-cd-ef // // Each of these modules is a normal AMD module that contains one or more flattened bundles in a hash. // For example, assume someModule contained the bundles some/bundle/path/someBundle and // some/bundle/path/someOtherBundle, then some/path/nls/someModule_ab would be expressed as follows: // // define({ // some/bundle/path/someBundle:, // some/bundle/path/someOtherBundle:, // }); // // E.g., given this design, preloading for locale=="ab" can execute the following algorithm: // // require(["some/path/nls/someModule_ab"], function(rollup){ // for(var p in rollup){ // var id = p + "/ab", // cache[id] = rollup[p]; // define(id, rollup[p]); // } // }); // // Similarly, if "ab-cd" is requested, the algorithm can determine that "ab" is the best available and // load accordingly. // // The builder will write such rollups for every layer if a non-empty localeList profile property is // provided. Further, the builder will include the following cache entry in the cache associated with // any layer. // // "*now":function(r){r(['dojo/i18n!*preload*/nls/*']);} // // The *now special cache module instructs the loader to apply the provided function to context-require // with respect to the particular layer being defined. This causes the plugin to hold all normal service // requests until all preloading is complete. // // Notice that this algorithm is rarely better than the standard AMD load algorithm. Consider the normal case // where the target locale has a single segment and a layer depends on a single bundle: // // Without Preloads: // // 1. Layer loads root bundle. // 2. bundle is demanded; plugin loads single localized bundle. // // With Preloads: // // 1. Layer causes preloading of target bundle. // 2. bundle is demanded; service is delayed until preloading complete; bundle is returned. // // In each case a single transaction is required to load the target bundle. In cases where multiple bundles // are required and/or the locale has multiple segments, preloads still requires a single transaction whereas // the normal path requires an additional transaction for each additional bundle/locale-segment. However all // of these additional transactions can be done concurrently. Owing to this analysis, the entire preloading // algorithm can be discard during a build by setting the has feature dojo-preload-i18n-Api to false. var match = nlsRe.exec(id), bundlePath = match[1] + "/", bundleName = match[5] || match[4], bundlePathAndName = bundlePath + bundleName, localeSpecified = (match[5] && match[4]), targetLocale = localeSpecified || dojo.locale || "", loadTarget = bundlePathAndName + "/" + targetLocale, loadList = localeSpecified ? [targetLocale] : getLocalesToLoad(targetLocale), remaining = loadList.length, finish = function(){ if(!--remaining){ load(lang.delegate(cache[loadTarget])); } }, split = id.split("*"), preloadDemand = split[1] == "preload"; if(has("dojo-preload-i18n-Api")){ if(preloadDemand){ if(!cache[id]){ // use cache[id] to prevent multiple preloads of the same preload; this shouldn't happen, but // who knows what over-aggressive human optimizers may attempt cache[id] = 1; preloadL10n(split[2], json.parse(split[3]), 1, require); } // don't stall the loader! load(1); } if(preloadDemand || (waitForPreloads(id, require, load) && !cache[loadTarget])){ return; } } else if (preloadDemand) { // If a build is created with nls resources and 'dojo-preload-i18n-Api' has not been set to false, // the built file will include a preload in the cache (which looks about like so:) // '*now':function(r){r(['dojo/i18n!*preload*dojo/nls/dojo*["ar","ca","cs","da","de","el","en-gb","en-us","es-es","fi-fi","fr-fr","he-il","hu","it-it","ja-jp","ko-kr","nl-nl","nb","pl","pt-br","pt-pt","ru","sk","sl","sv","th","tr","zh-tw","zh-cn","ROOT"]']);} // If the consumer of the build sets 'dojo-preload-i18n-Api' to false in the Dojo config, the cached // preload will not be parsed and will result in an attempt to call 'require' passing it the unparsed // preload, which is not a valid module id. // In this case we should skip this request. load(1); return; } array.forEach(loadList, function(locale){ var target = bundlePathAndName + "/" + locale; if(has("dojo-preload-i18n-Api")){ checkForLegacyModules(target); } if(!cache[target]){ doLoad(require, bundlePathAndName, bundlePath, bundleName, locale, finish); }else{ finish(); } }); }; if(has("dojo-preload-i18n-Api") || 1 ){ var normalizeLocale = thisModule.normalizeLocale = function(locale){ var result = locale ? locale.toLowerCase() : dojo.locale; return result == "root" ? "ROOT" : result; }, isXd = function(mid, contextRequire){ return ( 1 && 1 ) ? contextRequire.isXdUrl(require.toUrl(mid + ".js")) : true; }, preloading = 0, preloadWaitQueue = [], preloadL10n = thisModule._preloadLocalizations = function(/*String*/bundlePrefix, /*Array*/localesGenerated, /*boolean?*/ guaranteedAmdFormat, /*function?*/ contextRequire){ // summary: // Load available flattened resource bundles associated with a particular module for dojo/locale and all dojo/config.extraLocale (if any) // description: // Only called by built layer files. The entire locale hierarchy is loaded. For example, // if locale=="ab-cd", then ROOT, "ab", and "ab-cd" are loaded. This is different than v1.6- // in that the v1.6- would only load ab-cd...which was *always* flattened. // // If guaranteedAmdFormat is true, then the module can be loaded with require thereby circumventing the detection algorithm // and the extra possible extra transaction. // If this function is called from legacy code, then guaranteedAmdFormat and contextRequire will be undefined. Since the function // needs a require in order to resolve module ids, fall back to the context-require associated with this dojo/i18n module, which // itself may have been mapped. contextRequire = contextRequire || require; function doRequire(mid, callback){ if(isXd(mid, contextRequire) || guaranteedAmdFormat){ contextRequire([mid], callback); }else{ syncRequire([mid], callback, contextRequire); } } function forEachLocale(locale, func){ // given locale= "ab-cd-ef", calls func on "ab-cd-ef", "ab-cd", "ab", "ROOT"; stops calling the first time func returns truthy var parts = locale.split("-"); while(parts.length){ if(func(parts.join("-"))){ return; } parts.pop(); } func("ROOT"); } function preloadingAddLock(){ preloading++; } function preloadingRelLock(){ --preloading; while(!preloading && preloadWaitQueue.length){ load.apply(null, preloadWaitQueue.shift()); } } function cacheId(path, name, loc, require){ // path is assumed to have a trailing "/" return require.toAbsMid(path + name + "/" + loc) } function preload(locale){ locale = normalizeLocale(locale); forEachLocale(locale, function(loc){ if(array.indexOf(localesGenerated, loc) >= 0){ var mid = bundlePrefix.replace(/\./g, "/") + "_" + loc; preloadingAddLock(); doRequire(mid, function(rollup){ for(var p in rollup){ var bundle = rollup[p], match = p.match(/(.+)\/([^\/]+)$/), bundleName, bundlePath; // If there is no match, the bundle is not a regular bundle from an AMD layer. if (!match){continue;} bundleName = match[2]; bundlePath = match[1] + "/"; // backcompat if(!bundle._localized){continue;} var localized; if(loc === "ROOT"){ var root = localized = bundle._localized; delete bundle._localized; root.root = bundle; cache[require.toAbsMid(p)] = root; }else{ localized = bundle._localized; cache[cacheId(bundlePath, bundleName, loc, require)] = bundle; } if(loc !== locale){ // capture some locale variables var improveBundle = function improveBundle(bundlePath, bundleName, bundle, localized){ // locale was not flattened and we've fallen back to a less-specific locale that was flattened // for example, we had a flattened 'fr', a 'fr-ca' is available for at least this bundle, and // locale==='fr-ca'; therefore, we must improve the bundle as retrieved from the rollup by // manually loading the fr-ca version of the bundle and mixing this into the already-retrieved 'fr' // version of the bundle. // // Remember, different bundles may have different sets of locales available. // // we are really falling back on the regular algorithm here, but--hopefully--starting with most // of the required bundles already on board as given by the rollup and we need to "manually" load // only one locale from a few bundles...or even better...we won't find anything better to load. // This algorithm ensures there is nothing better to load even when we can only load a less-specific rollup. // // note: this feature is only available in async mode // inspect the loaded bundle that came from the rollup to see if something better is available // for any bundle in a rollup, more-specific available locales are given at localized. var requiredBundles = [], cacheIds = []; forEachLocale(locale, function(loc){ if(localized[loc]){ requiredBundles.push(require.toAbsMid(bundlePath + loc + "/" + bundleName)); cacheIds.push(cacheId(bundlePath, bundleName, loc, require)); } }); if(requiredBundles.length){ preloadingAddLock(); contextRequire(requiredBundles, function(){ // requiredBundles was constructed by forEachLocale so it contains locales from // less specific to most specific. // the loop starts with the most specific locale, the last one. for(var i = requiredBundles.length - 1; i >= 0 ; i--){ bundle = lang.mixin(lang.clone(bundle), arguments[i]); cache[cacheIds[i]] = bundle; } // this is the best possible (maybe a perfect match, maybe not), accept it cache[cacheId(bundlePath, bundleName, locale, require)] = lang.clone(bundle); preloadingRelLock(); }); }else{ // this is the best possible (definitely not a perfect match), accept it cache[cacheId(bundlePath, bundleName, locale, require)] = bundle; } }; improveBundle(bundlePath, bundleName, bundle, localized); } } preloadingRelLock(); }); return true; } return false; }); } preload(); array.forEach(dojo.config.extraLocale, preload); }, waitForPreloads = function(id, require, load){ if(preloading){ preloadWaitQueue.push([id, require, load]); } return preloading; }, checkForLegacyModules = function() {}; } if( 1 ){ // this code path assumes the dojo loader and won't work with a standard AMD loader var amdValue = {}, l10nCache = {}, evalBundle, syncRequire = function(deps, callback, require){ var results = []; array.forEach(deps, function(mid){ var url = require.toUrl(mid + ".js"); function load(text){ if (!evalBundle) { // use the function ctor to keep the minifiers away (also come close to global scope, but this is secondary) evalBundle = new Function( "__bundle", // the bundle to evalutate "__checkForLegacyModules", // a function that checks if __bundle defined __mid in the global space "__mid", // the mid that __bundle is intended to define "__amdValue", // returns one of: // 1 => the bundle was an AMD bundle // a legacy bundle object that is the value of __mid // instance of Error => could not figure out how to evaluate bundle // used to detect when __bundle calls define "var define = function(mid, factory){define.called = 1; __amdValue.result = factory || mid;}," + " require = function(){define.called = 1;};" + "try{" + "define.called = 0;" + "eval(__bundle);" + "if(define.called==1)" // bundle called define; therefore signal it's an AMD bundle + "return __amdValue;" + "if((__checkForLegacyModules = __checkForLegacyModules(__mid)))" // bundle was probably a v1.6- built NLS flattened NLS bundle that defined __mid in the global space + "return __checkForLegacyModules;" + "}catch(e){}" // evaulating the bundle was *neither* an AMD *nor* a legacy flattened bundle // either way, re-eval *after* surrounding with parentheses + "try{" + "return eval('('+__bundle+')');" + "}catch(e){" + "return e;" + "}" ); } var result = evalBundle(text, checkForLegacyModules, mid, amdValue); if(result===amdValue){ // the bundle was an AMD module; re-inject it through the normal AMD path // we gotta do this since it could be an anonymous module and simply evaluating // the text here won't provide the loader with the context to know what // module is being defined()'d. With browser caching, this should be free; further // this entire code path can be circumvented by using the AMD format to begin with results.push(cache[url] = amdValue.result); }else{ if(result instanceof Error){ console.error("failed to evaluate i18n bundle; url=" + url, result); result = {}; } // nls// indicates not the root. results.push(cache[url] = (/nls\/[^\/]+\/[^\/]+$/.test(url) ? result : {root:result, _v1x:1})); } } if(cache[url]){ results.push(cache[url]); }else{ var bundle = require.syncLoadNls(mid); // need to check for legacy module here because there might be a legacy module for a // less specific locale (which was not looked up during the first checkForLegacyModules // call in load()). // Also need to reverse the locale and the module name in the mid because syncRequire // deps parameters uses the AMD style package/nls/locale/module while legacy code uses // package/nls/module/locale. if(!bundle){ bundle = checkForLegacyModules(mid.replace(/nls\/([^\/]*)\/([^\/]*)$/, "nls/$2/$1")); } if(bundle){ results.push(bundle); }else{ if(!xhr){ try{ require.getText(url, true, load); }catch(e){ results.push(cache[url] = {}); } }else{ xhr.get({ url:url, sync:true, load:load, error:function(){ results.push(cache[url] = {}); } }); } } } }); callback && callback.apply(null, results); }; checkForLegacyModules = function(target){ // legacy code may have already loaded [e.g] the raw bundle x/y/z at x.y.z; when true, push into the cache for(var result, names = target.split("/"), object = dojo.global[names[0]], i = 1; object && i 2 && !hasBody) || "POST|PUT".indexOf(method.toUpperCase()) === -1){ //Check for hasBody being passed. If no hasBody, //then only append query string if not a POST or PUT request. dojo._ioAddQueryToUrl(ioArgs); } var options = { method: method, handleAs: "text", timeout: args.timeout, withCredentials: args.withCredentials, ioArgs: ioArgs }; if(typeof args.headers !== 'undefined'){ options.headers = args.headers; } if(typeof args.contentType !== 'undefined'){ if(!options.headers){ options.headers = {}; } options.headers['Content-Type'] = args.contentType; } if(typeof ioArgs.query !== 'undefined'){ options.data = ioArgs.query; } if(typeof args.sync !== 'undefined'){ options.sync = args.sync; } dojo._ioNotifyStart(dfd); try{ rDfd = _xhr(ioArgs.url, options, true); }catch(e){ // If XHR creation fails, dojo/request/xhr throws // When this happens, cancel the deferred dfd.cancel(); return dfd; } // sync ioArgs dfd.ioArgs.xhr = rDfd.response.xhr; rDfd.then(function(){ dfd.resolve(dfd); }).otherwise(function(error){ ioArgs.error = error; if(error.response){ error.status = error.response.status; error.responseText = error.response.text; error.xhr = error.response.xhr; } dfd.reject(error); }); return dfd; // dojo/_base/Deferred }; dojo.xhrGet = function(/*dojo.__XhrArgs*/ args){ // summary: // Sends an HTTP GET request to the server. return dojo.xhr("GET", args); // dojo/_base/Deferred }; dojo.rawXhrPost = dojo.xhrPost = function(/*dojo.__XhrArgs*/ args){ // summary: // Sends an HTTP POST request to the server. In addition to the properties // listed for the dojo.__XhrArgs type, the following property is allowed: // postData: // String. Send raw data in the body of the POST request. return dojo.xhr("POST", args, true); // dojo/_base/Deferred }; dojo.rawXhrPut = dojo.xhrPut = function(/*dojo.__XhrArgs*/ args){ // summary: // Sends an HTTP PUT request to the server. In addition to the properties // listed for the dojo.__XhrArgs type, the following property is allowed: // putData: // String. Send raw data in the body of the PUT request. return dojo.xhr("PUT", args, true); // dojo/_base/Deferred }; dojo.xhrDelete = function(/*dojo.__XhrArgs*/ args){ // summary: // Sends an HTTP DELETE request to the server. return dojo.xhr("DELETE", args); // dojo/_base/Deferred }; /* dojo.wrapForm = function(formNode){ // summary: // A replacement for FormBind, but not implemented yet. // FIXME: need to think harder about what extensions to this we might // want. What should we allow folks to do w/ this? What events to // set/send? throw new Error("dojo.wrapForm not yet implemented"); } */ dojo._isDocumentOk = function(x){ return util.checkStatus(x.status); }; dojo._getText = function(url){ var result; dojo.xhrGet({url:url, sync:true, load:function(text){ result = text; }}); return result; }; // Add aliases for static functions to dojo.xhr since dojo.xhr is what's returned from this module lang.mixin(dojo.xhr, { _xhrObj: dojo._xhrObj, fieldToObject: domForm.fieldToObject, formToObject: domForm.toObject, objectToQuery: ioq.objectToQuery, formToQuery: domForm.toQuery, formToJson: domForm.toJson, queryToObject: ioq.queryToObject, contentHandlers: handlers, _ioSetArgs: dojo._ioSetArgs, _ioCancelAll: dojo._ioCancelAll, _ioNotifyStart: dojo._ioNotifyStart, _ioWatch: dojo._ioWatch, _ioAddQueryToUrl: dojo._ioAddQueryToUrl, _isDocumentOk: dojo._isDocumentOk, _getText: dojo._getText, get: dojo.xhrGet, post: dojo.xhrPost, put: dojo.xhrPut, del: dojo.xhrDelete // because "delete" is a reserved word }); return dojo.xhr; }); }, 'dojo/_base/sniff':function(){ define(["./kernel", "./lang", "../sniff"], function(dojo, lang, has){ // module: // dojo/_base/sniff /*===== return { // summary: // Deprecated. New code should use dojo/sniff. // This module populates the dojo browser version sniffing properties like dojo.isIE. }; =====*/ if(! 1 ){ return has; } // no idea what this is for, or if it's used dojo._name = "browser"; lang.mixin(dojo, { // isBrowser: Boolean // True if the client is a web-browser isBrowser: true, // isFF: Number|undefined // Version as a Number if client is FireFox. undefined otherwise. Corresponds to // major detected FireFox version (1.5, 2, 3, etc.) isFF: has("ff"), // isIE: Number|undefined // Version as a Number if client is MSIE(PC). undefined otherwise. Corresponds to // major detected IE version (6, 7, 8, etc.) isIE: has("ie"), // isKhtml: Number|undefined // Version as a Number if client is a KHTML browser. undefined otherwise. Corresponds to major // detected version. isKhtml: has("khtml"), // isWebKit: Number|undefined // Version as a Number if client is a WebKit-derived browser (Konqueror, // Safari, Chrome, etc.). undefined otherwise. isWebKit: has("webkit"), // isMozilla: Number|undefined // Version as a Number if client is a Mozilla-based browser (Firefox, // SeaMonkey). undefined otherwise. Corresponds to major detected version. isMozilla: has("mozilla"), // isMoz: Number|undefined // Version as a Number if client is a Mozilla-based browser (Firefox, // SeaMonkey). undefined otherwise. Corresponds to major detected version. isMoz: has("mozilla"), // isOpera: Number|undefined // Version as a Number if client is Opera. undefined otherwise. Corresponds to // major detected version. isOpera: has("opera"), // isSafari: Number|undefined // Version as a Number if client is Safari or iPhone. undefined otherwise. isSafari: has("safari"), // isChrome: Number|undefined // Version as a Number if client is Chrome browser. undefined otherwise. isChrome: has("chrome"), // isMac: Boolean // True if the client runs on Mac isMac: has("mac"), // isIos: Number|undefined // Version as a Number if client is iPhone, iPod, or iPad. undefined otherwise. isIos: has("ios"), // isAndroid: Number|undefined // Version as a Number if client is android browser. undefined otherwise. isAndroid: has("android"), // isWii: Boolean // True if client is Wii isWii: has("wii"), // isQuirks: Boolean // Page is in quirks mode. isQuirks: has("quirks"), // isAir: Boolean // True if client is Adobe Air isAir: has("air") }); return has; }); }, 'dojo/io-query':function(){ define(["./_base/lang"], function(lang){ // module: // dojo/io-query var backstop = {}; return { // summary: // This module defines query string processing functions. objectToQuery: function objectToQuery(/*Object*/ map){ // summary: // takes a name/value mapping object and returns a string representing // a URL-encoded version of that object. // example: // this object: // // | { // | blah: "blah", // | multi: [ // | "thud", // | "thonk" // | ] // | }; // // yields the following query string: // // | "blah=blah&multi=thud&multi=thonk" // FIXME: need to implement encodeAscii!! var enc = encodeURIComponent, pairs = []; for(var name in map){ var value = map[name]; if(value != backstop[name]){ var assign = enc(name) + "="; if(lang.isArray(value)){ for(var i = 0, l = value.length; i < l; ++i){ pairs.push(assign + enc(value[i])); } }else{ pairs.push(assign + enc(value)); } } } return pairs.join("&"); // String }, queryToObject: function queryToObject(/*String*/ str){ // summary: // Create an object representing a de-serialized query section of a // URL. Query keys with multiple values are returned in an array. // // example: // This string: // // | "foo=bar&foo=baz&thinger=%20spaces%20=blah&zonk=blarg&" // // results in this object structure: // // | { // | foo: [ "bar", "baz" ], // | thinger: " spaces =blah", // | zonk: "blarg" // | } // // Note that spaces and other urlencoded entities are correctly // handled. var dec = decodeURIComponent, qp = str.split("&"), ret = {}, name, val; for(var i = 0, l = qp.length, item; i < l; ++i){ item = qp[i]; if(item.length){ var s = item.indexOf("="); if(s < 0){ name = dec(item); val = ""; }else{ name = dec(item.slice(0, s)); val = dec(item.slice(s + 1)); } if(typeof ret[name] == "string"){ // inline'd type check ret[name] = [ret[name]]; } if(lang.isArray(ret[name])){ ret[name].push(val); }else{ ret[name] = val; } } } return ret; // Object } }; }); }, 'dojo/dom':function(){ define(["./sniff", "./_base/window", "./_base/kernel"], function(has, win, kernel){ // module: // dojo/dom // FIXME: need to add unit tests for all the semi-public methods if(has("ie") <= 7){ try{ document.execCommand("BackgroundImageCache", false, true); }catch(e){ // sane browsers don't have cache "issues" } } // ============================= // DOM Functions // ============================= // the result object var dom = { // summary: // This module defines the core dojo DOM API. }; if(has("ie")){ dom.byId = function(id, doc){ if(typeof id != "string"){ return id || null; } var _d = doc || win.doc, te = id && _d.getElementById(id); // attributes.id.value is better than just id in case the // user has a name=id inside a form if(te && (te.attributes.id.value == id || te.id == id)){ return te; }else{ var eles = _d.all[id]; if(!eles || eles.nodeName){ eles = [eles]; } // if more than 1, choose first with the correct id var i = 0; while((te = eles[i++])){ if((te.attributes && te.attributes.id && te.attributes.id.value == id) || te.id == id){ return te; } } } return null; }; }else{ dom.byId = function(id, doc){ // inline'd type check. // be sure to return null per documentation, to match IE branch. return ((typeof id == "string") ? (doc || win.doc).getElementById(id) : id) || null; // DOMNode }; } /*===== dom.byId = function(id, doc){ // summary: // Returns DOM node with matching `id` attribute or falsy value (ex: null or undefined) // if not found. If `id` is a DomNode, this function is a no-op. // // id: String|DOMNode // A string to match an HTML id attribute or a reference to a DOM Node // // doc: Document? // Document to work in. Defaults to the current value of // dojo/_base/window.doc. Can be used to retrieve // node references from other documents. // // example: // Look up a node by ID: // | require(["dojo/dom"], function(dom){ // | var n = dom.byId("foo"); // | }); // // example: // Check if a node exists, and use it. // | require(["dojo/dom"], function(dom){ // | var n = dom.byId("bar"); // | if(n){ doStuff() ... } // | }); // // example: // Allow string or DomNode references to be passed to a custom function: // | require(["dojo/dom"], function(dom){ // | var foo = function(nodeOrId){ // | nodeOrId = dom.byId(nodeOrId); // | // ... more stuff // | } // | }); }; =====*/ // Test for DOMNode.contains() method, available everywhere except FF8- // and IE8-, where it's available in general, but not on document itself, // and also problems when either ancestor or node are text nodes. var doc = kernel.global["document"] || null; has.add("dom-contains", !!(doc && doc.contains)); dom.isDescendant = has("dom-contains") ? // FF9+, IE9+, webkit, opera, iOS, Android, Edge, etc. function(/*DOMNode|String*/ node, /*DOMNode|String*/ ancestor){ return !!( (ancestor = dom.byId(ancestor)) && ancestor.contains(dom.byId(node)) ); } : function(/*DOMNode|String*/ node, /*DOMNode|String*/ ancestor){ // summary: // Returns true if node is a descendant of ancestor // node: DOMNode|String // string id or node reference to test // ancestor: DOMNode|String // string id or node reference of potential parent to test against // // example: // Test is node id="bar" is a descendant of node id="foo" // | require(["dojo/dom"], function(dom){ // | if(dom.isDescendant("bar", "foo")){ ... } // | }); try{ node = dom.byId(node); ancestor = dom.byId(ancestor); while(node){ if(node == ancestor){ return true; // Boolean } node = node.parentNode; } }catch(e){ /* squelch, return false */ } return false; // Boolean }; // TODO: do we need setSelectable in the base? // Add feature test for user-select CSS property // (currently known to work in all but IE < 10 and Opera) // TODO: The user-select CSS property as of May 2014 is no longer part of // any CSS specification. In IE, -ms-user-select does not do the same thing // as the unselectable attribute on elements; namely, dijit Editor buttons // do not properly prevent the content of the editable content frame from // unblurring. As a result, the -ms- prefixed version is omitted here. has.add("css-user-select", function(global, doc, element){ // Avoid exception when dom.js is loaded in non-browser environments if(!element){ return false; } var style = element.style; var prefixes = ["Khtml", "O", "Moz", "Webkit"], i = prefixes.length, name = "userSelect", prefix; // Iterate prefixes from most to least likely do{ if(typeof style[name] !== "undefined"){ // Supported; return property name return name; } }while(i-- && (name = prefixes[i] + "UserSelect")); // Not supported if we didn't return before now return false; }); /*===== dom.setSelectable = function(node, selectable){ // summary: // Enable or disable selection on a node // node: DOMNode|String // id or reference to node // selectable: Boolean // state to put the node in. false indicates unselectable, true // allows selection. // example: // Make the node id="bar" unselectable // | require(["dojo/dom"], function(dom){ // | dom.setSelectable("bar"); // | }); // example: // Make the node id="bar" selectable // | require(["dojo/dom"], function(dom){ // | dom.setSelectable("bar", true); // | }); }; =====*/ var cssUserSelect = has("css-user-select"); dom.setSelectable = cssUserSelect ? function(node, selectable){ // css-user-select returns a (possibly vendor-prefixed) CSS property name dom.byId(node).style[cssUserSelect] = selectable ? "" : "none"; } : function(node, selectable){ node = dom.byId(node); // (IE < 10 / Opera) Fall back to setting/removing the // unselectable attribute on the element and all its children var nodes = node.getElementsByTagName("*"), i = nodes.length; if(selectable){ node.removeAttribute("unselectable"); while(i--){ nodes[i].removeAttribute("unselectable"); } }else{ node.setAttribute("unselectable", "on"); while(i--){ nodes[i].setAttribute("unselectable", "on"); } } }; return dom; }); }, 'dojo/_base/window':function(){ define(["./kernel", "./lang", "../sniff"], function(dojo, lang, has){ // module: // dojo/_base/window var ret = { // summary: // API to save/set/restore the global/document scope. global: dojo.global, /*===== global: { // summary: // Alias for the current window. 'global' can be modified // for temporary context shifting. See also withGlobal(). // description: // Use this rather than referring to 'window' to ensure your code runs // correctly in managed contexts. }, =====*/ doc: dojo.global["document"] || null, /*===== doc: { // summary: // Alias for the current document. 'doc' can be modified // for temporary context shifting. See also withDoc(). // description: // Use this rather than referring to 'window.document' to ensure your code runs // correctly in managed contexts. // example: // | n.appendChild(dojo.doc.createElement('div')); }, =====*/ body: function(/*Document?*/ doc){ // summary: // Return the body element of the specified document or of dojo/_base/window::doc. // example: // | win.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(). doc = doc || dojo.doc; return doc.body || doc.getElementsByTagName("body")[0]; // Node }, 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 = ret.global = globalObject; dojo.doc = ret.doc = globalDocument; }, withGlobal: function( /*Object*/ globalObject, /*Function*/ callback, /*Object?*/ thisObject, /*Array?*/ cbArguments){ // summary: // Invoke callback with globalObject as dojo.global and // globalObject.document as dojo.doc. // description: // Invoke callback with globalObject as dojo.global and // globalObject.document as dojo.doc. If provided, globalObject // will be executed in the context of object thisObject // When callback() returns or throws an error, the dojo.global // and dojo.doc will be restored to its previous state. var oldGlob = dojo.global; try{ dojo.global = ret.global = globalObject; return ret.withDoc.call(null, globalObject.document, callback, thisObject, cbArguments); }finally{ dojo.global = ret.global = oldGlob; } }, withDoc: function( /*DocumentElement*/ documentObject, /*Function*/ callback, /*Object?*/ thisObject, /*Array?*/ cbArguments){ // summary: // Invoke callback with documentObject as dojo/_base/window::doc. // description: // Invoke callback with documentObject as dojo/_base/window::doc. If provided, // callback will be executed in the context of object thisObject // When callback() returns or throws an error, the dojo/_base/window::doc will // be restored to its previous state. var oldDoc = ret.doc, oldQ = has("quirks"), oldIE = has("ie"), isIE, mode, pwin; try{ dojo.doc = ret.doc = documentObject; // update dojo.isQuirks and the value of the has feature "quirks". // remove setting dojo.isQuirks and dojo.isIE for 2.0 dojo.isQuirks = has.add("quirks", dojo.doc.compatMode == "BackCompat", true, true); // no need to check for QuirksMode which was Opera 7 only if(has("ie")){ if((pwin = documentObject.parentWindow) && pwin.navigator){ // re-run IE detection logic and update dojo.isIE / has("ie") // (the only time parentWindow/navigator wouldn't exist is if we were not // passed an actual legitimate document object) isIE = parseFloat(pwin.navigator.appVersion.split("MSIE ")[1]) || undefined; mode = documentObject.documentMode; if(mode && mode != 5 && Math.floor(isIE) != mode){ isIE = mode; } dojo.isIE = has.add("ie", isIE, true, true); } } if(thisObject && typeof callback == "string"){ callback = thisObject[callback]; } return callback.apply(thisObject, cbArguments || []); }finally{ dojo.doc = ret.doc = oldDoc; dojo.isQuirks = has.add("quirks", oldQ, true, true); dojo.isIE = has.add("ie", oldIE, true, true); } } }; 1 && lang.mixin(dojo, ret); return ret; }); }, 'dojo/dom-form':function(){ define(["./_base/lang", "./dom", "./io-query", "./json"], function(lang, dom, ioq, json){ // module: // dojo/dom-form function setValue(/*Object*/ obj, /*String*/ name, /*String*/ value){ // summary: // For the named property in object, set the value. If a value // already exists and it is a string, convert the value to be an // array of values. // Skip it if there is no value if(value === null){ return; } var val = obj[name]; if(typeof val == "string"){ // inline'd type check obj[name] = [val, value]; }else if(lang.isArray(val)){ val.push(value); }else{ obj[name] = value; } } var exclude = "file|submit|image|reset|button"; var form = { // summary: // This module defines form-processing functions. fieldToObject: function fieldToObject(/*DOMNode|String*/ inputNode){ // summary: // Serialize a form field to a JavaScript object. // description: // Returns the value encoded in a form field as // as a string or an array of strings. Disabled form elements // and unchecked radio and checkboxes are skipped. Multi-select // elements are returned as an array of string values. // inputNode: DOMNode|String // returns: Object var ret = null; inputNode = dom.byId(inputNode); if(inputNode){ var _in = inputNode.name, type = (inputNode.type || "").toLowerCase(); if(_in && type && !inputNode.disabled){ if(type == "radio" || type == "checkbox"){ if(inputNode.checked){ ret = inputNode.value; } }else if(inputNode.multiple){ ret = []; var nodes = [inputNode.firstChild]; while(nodes.length){ for(var node = nodes.pop(); node; node = node.nextSibling){ if(node.nodeType == 1 && node.tagName.toLowerCase() == "option"){ if(node.selected){ ret.push(node.value); } }else{ if(node.nextSibling){ nodes.push(node.nextSibling); } if(node.firstChild){ nodes.push(node.firstChild); } break; } } } }else{ ret = inputNode.value; } } } return ret; // Object }, toObject: function formToObject(/*DOMNode|String*/ formNode){ // summary: // Serialize a form node to a JavaScript object. // description: // Returns the values encoded in an HTML form as // string properties in an object which it then returns. Disabled form // elements, buttons, and other non-value form elements are skipped. // Multi-select elements are returned as an array of string values. // formNode: DOMNode|String // example: // This form: // |
// | // | // | // | // |
// // yields this object structure as the result of a call to // formToObject(): // // | { // | blah: "blah", // | multi: [ // | "thud", // | "thonk" // | ] // | }; var ret = {}, elems = dom.byId(formNode).elements; for(var i = 0, l = elems.length; i < l; ++i){ var item = elems[i], _in = item.name, type = (item.type || "").toLowerCase(); if(_in && type && exclude.indexOf(type) < 0 && !item.disabled){ setValue(ret, _in, form.fieldToObject(item)); if(type == "image"){ ret[_in + ".x"] = ret[_in + ".y"] = ret[_in].x = ret[_in].y = 0; } } } return ret; // Object }, toQuery: function formToQuery(/*DOMNode|String*/ formNode){ // summary: // Returns a URL-encoded string representing the form passed as either a // node or string ID identifying the form to serialize // formNode: DOMNode|String // returns: String return ioq.objectToQuery(form.toObject(formNode)); // String }, toJson: function formToJson(/*DOMNode|String*/ formNode, /*Boolean?*/ prettyPrint){ // summary: // Create a serialized JSON string from a form node or string // ID identifying the form to serialize // formNode: DOMNode|String // prettyPrint: Boolean? // returns: String return json.stringify(form.toObject(formNode), null, prettyPrint ? 4 : 0); // String } }; return form; }); }, 'dojo/_base/Deferred':function(){ define([ "./kernel", "../Deferred", "../promise/Promise", "../errors/CancelError", "../has", "./lang", "../when" ], function(dojo, NewDeferred, Promise, CancelError, has, lang, when){ // module: // dojo/_base/Deferred var mutator = function(){}; var freeze = Object.freeze || function(){}; // A deferred provides an API for creating and resolving a promise. var Deferred = dojo.Deferred = function(/*Function?*/ canceller){ // summary: // Deprecated. This module defines the legacy dojo/_base/Deferred API. // New code should use dojo/Deferred instead. // description: // The Deferred API is based on the concept of promises that provide a // generic interface into the eventual completion of an asynchronous action. // The motivation for promises fundamentally is about creating a // separation of concerns that allows one to achieve the same type of // call patterns and logical data flow in asynchronous code as can be // achieved in synchronous code. Promises allows one // to be able to call a function purely with arguments needed for // execution, without conflating the call with concerns of whether it is // sync or async. One shouldn't need to alter a call's arguments if the // implementation switches from sync to async (or vice versa). By having // async functions return promises, the concerns of making the call are // separated from the concerns of asynchronous interaction (which are // handled by the promise). // // The Deferred is a type of promise that provides methods for fulfilling the // promise with a successful result or an error. The most important method for // working with Dojo's promises is the then() method, which follows the // CommonJS proposed promise API. An example of using a Dojo promise: // // | var resultingPromise = someAsyncOperation.then(function(result){ // | ... handle result ... // | }, // | function(error){ // | ... handle error ... // | }); // // The .then() call returns a new promise that represents the result of the // execution of the callback. The callbacks will never affect the original promises value. // // The Deferred instances also provide the following functions for backwards compatibility: // // - addCallback(handler) // - addErrback(handler) // - callback(result) // - errback(result) // // Callbacks are allowed to return promises 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 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 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).then(null, 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 synchronous 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 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).then(null, function(){ // | promptUserToRecover(); // | }); // // Note that the caller doesn't have to change his code at all to // handle the asynchronous case. var result, finished, canceled, fired, isError, head, nextListener; var promise = (this.promise = new Promise()); function complete(value){ if(finished){ throw new Error("This deferred has already been resolved"); } result = value; finished = true; notify(); } function notify(){ var mutated; while(!mutated && nextListener){ var listener = nextListener; nextListener = nextListener.next; if((mutated = (listener.progress == mutator))){ // assignment and check finished = false; } var func = (isError ? listener.error : listener.resolved); if(has("config-useDeferredInstrumentation")){ if(isError && NewDeferred.instrumentRejected){ NewDeferred.instrumentRejected(result, !!func); } } if(func){ try{ var newResult = func(result); if (newResult && typeof newResult.then === "function"){ newResult.then(lang.hitch(listener.deferred, "resolve"), lang.hitch(listener.deferred, "reject"), lang.hitch(listener.deferred, "progress")); continue; } var unchanged = mutated && newResult === undefined; if(mutated && !unchanged){ isError = newResult instanceof Error; } listener.deferred[unchanged && isError ? "reject" : "resolve"](unchanged ? result : newResult); }catch(e){ listener.deferred.reject(e); } }else{ if(isError){ listener.deferred.reject(result); }else{ listener.deferred.resolve(result); } } } } this.isResolved = promise.isResolved = function(){ // summary: // Checks whether the deferred has been resolved. // returns: Boolean return fired == 0; }; this.isRejected = promise.isRejected = function(){ // summary: // Checks whether the deferred has been rejected. // returns: Boolean return fired == 1; }; this.isFulfilled = promise.isFulfilled = function(){ // summary: // Checks whether the deferred has been resolved or rejected. // returns: Boolean return fired >= 0; }; this.isCanceled = promise.isCanceled = function(){ // summary: // Checks whether the deferred has been canceled. // returns: Boolean return canceled; }; // calling resolve will resolve the promise this.resolve = this.callback = function(value){ // summary: // Fulfills the Deferred instance successfully with the provide value this.fired = fired = 0; this.results = [value, null]; complete(value); }; // calling error will indicate that the promise failed this.reject = this.errback = function(error){ // summary: // Fulfills the Deferred instance as an error with the provided error isError = true; this.fired = fired = 1; if(has("config-useDeferredInstrumentation")){ if(NewDeferred.instrumentRejected){ NewDeferred.instrumentRejected(error, !!nextListener); } } complete(error); this.results = [null, error]; }; // call progress to provide updates on the progress on the completion of the promise this.progress = function(update){ // summary: // Send progress events to all listeners var listener = nextListener; while(listener){ var progress = listener.progress; progress && progress(update); listener = listener.next; } }; this.addCallbacks = function(callback, errback){ // summary: // Adds callback and error callback for this deferred instance. // callback: Function? // The callback attached to this deferred object. // errback: Function? // The error callback attached to this deferred object. // returns: // Returns this deferred object. this.then(callback, errback, mutator); return this; // Deferred }; // provide the implementation of the promise promise.then = this.then = function(/*Function?*/resolvedCallback, /*Function?*/errorCallback, /*Function?*/progressCallback){ // summary: // Adds a fulfilledHandler, errorHandler, and progressHandler to be called for // completion of a promise. The fulfilledHandler is called when the promise // is fulfilled. The errorHandler is called when a promise fails. The // progressHandler is called for progress events. All arguments are optional // and non-function values are ignored. The progressHandler is not only an // optional argument, but progress events are purely optional. Promise // providers are not required to ever create progress events. // // This function will return a new promise that is fulfilled when the given // fulfilledHandler or errorHandler callback is finished. This allows promise // operations to be chained together. The value returned from the callback // handler is the fulfillment value for the returned promise. If the callback // throws an error, the returned promise will be moved to failed state. // // returns: // Returns a new promise that represents the result of the // execution of the callback. The callbacks will never affect the original promises value. // example: // An example of using a CommonJS compliant promise: // | asyncComputeTheAnswerToEverything(). // | then(addTwo). // | then(printResult, onError); // | >44 // var returnDeferred = progressCallback == mutator ? this : new Deferred(promise.cancel); var listener = { resolved: resolvedCallback, error: errorCallback, progress: progressCallback, deferred: returnDeferred }; if(nextListener){ head = head.next = listener; } else{ nextListener = head = listener; } if(finished){ notify(); } return returnDeferred.promise; // Promise }; var deferred = this; promise.cancel = this.cancel = function(){ // summary: // Cancels the asynchronous operation if(!finished){ var error = canceller && canceller(deferred); if(!finished){ if (!(error instanceof Error)){ error = new CancelError(error); } error.log = false; deferred.reject(error); } } canceled = true; }; freeze(promise); }; lang.extend(Deferred, { addCallback: function(/*Function*/ callback){ // summary: // Adds successful callback for this deferred instance. // returns: // Returns this deferred object. return this.addCallbacks(lang.hitch.apply(dojo, arguments)); // Deferred }, addErrback: function(/*Function*/ errback){ // summary: // Adds error callback for this deferred instance. // returns: // Returns this deferred object. return this.addCallbacks(null, lang.hitch.apply(dojo, arguments)); // Deferred }, addBoth: function(/*Function*/ callback){ // summary: // Add handler as both successful callback and error callback for this deferred instance. // returns: // Returns this deferred object. var enclosed = lang.hitch.apply(dojo, arguments); return this.addCallbacks(enclosed, enclosed); // Deferred }, fired: -1 }); Deferred.when = dojo.when = when; return Deferred; }); }, 'dojo/Deferred':function(){ define([ "./has", "./_base/lang", "./errors/CancelError", "./promise/Promise", "./promise/instrumentation" ], function(has, lang, CancelError, Promise, instrumentation){ "use strict"; // module: // dojo/Deferred var PROGRESS = 0, RESOLVED = 1, REJECTED = 2; var FULFILLED_ERROR_MESSAGE = "This deferred has already been fulfilled."; var freezeObject = Object.freeze || function(){}; var signalWaiting = function(waiting, type, result, rejection, deferred){ if( 1 ){ if(type === REJECTED && Deferred.instrumentRejected && waiting.length === 0){ Deferred.instrumentRejected(result, false, rejection, deferred); } } for(var i = 0; i < waiting.length; i++){ signalListener(waiting[i], type, result, rejection); } }; var signalListener = function(listener, type, result, rejection){ var func = listener[type]; var deferred = listener.deferred; if(func){ try{ var newResult = func(result); if(type === PROGRESS){ if(typeof newResult !== "undefined"){ signalDeferred(deferred, type, newResult); } }else{ if(newResult && typeof newResult.then === "function"){ listener.cancel = newResult.cancel; newResult.then( // Only make resolvers if they're actually going to be used makeDeferredSignaler(deferred, RESOLVED), makeDeferredSignaler(deferred, REJECTED), makeDeferredSignaler(deferred, PROGRESS)); return; } signalDeferred(deferred, RESOLVED, newResult); } }catch(error){ signalDeferred(deferred, REJECTED, error); } }else{ signalDeferred(deferred, type, result); } if( 1 ){ if(type === REJECTED && Deferred.instrumentRejected){ Deferred.instrumentRejected(result, !!func, rejection, deferred.promise); } } }; var makeDeferredSignaler = function(deferred, type){ return function(value){ signalDeferred(deferred, type, value); }; }; var signalDeferred = function(deferred, type, result){ if(!deferred.isCanceled()){ switch(type){ case PROGRESS: deferred.progress(result); break; case RESOLVED: deferred.resolve(result); break; case REJECTED: deferred.reject(result); break; } } }; var Deferred = function(canceler){ // summary: // Creates a new deferred. This API is preferred over // `dojo/_base/Deferred`. // description: // Creates a new deferred, as an abstraction over (primarily) // asynchronous operations. The deferred is the private interface // that should not be returned to calling code. That's what the // `promise` is for. See `dojo/promise/Promise`. // canceler: Function? // Will be invoked if the deferred is canceled. The canceler // receives the reason the deferred was canceled as its argument. // The deferred is rejected with its return value, or a new // `dojo/errors/CancelError` instance. // promise: dojo/promise/Promise // The public promise object that clients can add callbacks to. var promise = this.promise = new Promise(); var deferred = this; var fulfilled, result, rejection; var canceled = false; var waiting = []; if( 1 && Error.captureStackTrace){ Error.captureStackTrace(deferred, Deferred); Error.captureStackTrace(promise, Deferred); } this.isResolved = promise.isResolved = function(){ // summary: // Checks whether the deferred has been resolved. // returns: Boolean return fulfilled === RESOLVED; }; this.isRejected = promise.isRejected = function(){ // summary: // Checks whether the deferred has been rejected. // returns: Boolean return fulfilled === REJECTED; }; this.isFulfilled = promise.isFulfilled = function(){ // summary: // Checks whether the deferred has been resolved or rejected. // returns: Boolean return !!fulfilled; }; this.isCanceled = promise.isCanceled = function(){ // summary: // Checks whether the deferred has been canceled. // returns: Boolean return canceled; }; this.progress = function(update, strict){ // summary: // Emit a progress update on the deferred. // description: // Emit a progress update on the deferred. Progress updates // can be used to communicate updates about the asynchronous // operation before it has finished. // update: any // The progress update. Passed to progbacks. // strict: Boolean? // If strict, will throw an error if the deferred has already // been fulfilled and consequently no progress can be emitted. // returns: dojo/promise/Promise // Returns the original promise for the deferred. if(!fulfilled){ signalWaiting(waiting, PROGRESS, update, null, deferred); return promise; }else if(strict === true){ throw new Error(FULFILLED_ERROR_MESSAGE); }else{ return promise; } }; this.resolve = function(value, strict){ // summary: // Resolve the deferred. // description: // Resolve the deferred, putting it in a success state. // value: any // The result of the deferred. Passed to callbacks. // strict: Boolean? // If strict, will throw an error if the deferred has already // been fulfilled and consequently cannot be resolved. // returns: dojo/promise/Promise // Returns the original promise for the deferred. if(!fulfilled){ // Set fulfilled, store value. After signaling waiting listeners unset // waiting. signalWaiting(waiting, fulfilled = RESOLVED, result = value, null, deferred); waiting = null; return promise; }else if(strict === true){ throw new Error(FULFILLED_ERROR_MESSAGE); }else{ return promise; } }; var reject = this.reject = function(error, strict){ // summary: // Reject the deferred. // description: // Reject the deferred, putting it in an error state. // error: any // The error result of the deferred. Passed to errbacks. // strict: Boolean? // If strict, will throw an error if the deferred has already // been fulfilled and consequently cannot be rejected. // returns: dojo/promise/Promise // Returns the original promise for the deferred. if(!fulfilled){ if( 1 && Error.captureStackTrace){ Error.captureStackTrace(rejection = {}, reject); } signalWaiting(waiting, fulfilled = REJECTED, result = error, rejection, deferred); waiting = null; return promise; }else if(strict === true){ throw new Error(FULFILLED_ERROR_MESSAGE); }else{ return promise; } }; this.then = promise.then = function(callback, errback, progback){ // summary: // Add new callbacks to the deferred. // description: // Add new callbacks to the deferred. Callbacks can be added // before or after the deferred is fulfilled. // callback: Function? // Callback to be invoked when the promise is resolved. // Receives the resolution value. // errback: Function? // Callback to be invoked when the promise is rejected. // Receives the rejection error. // progback: Function? // Callback to be invoked when the promise emits a progress // update. Receives the progress update. // returns: dojo/promise/Promise // Returns a new promise for the result of the callback(s). // This can be used for chaining many asynchronous operations. var listener = [progback, callback, errback]; // Ensure we cancel the promise we're waiting for, or if callback/errback // have returned a promise, cancel that one. listener.cancel = promise.cancel; listener.deferred = new Deferred(function(reason){ // Check whether cancel is really available, returned promises are not // required to expose `cancel` return listener.cancel && listener.cancel(reason); }); if(fulfilled && !waiting){ signalListener(listener, fulfilled, result, rejection); }else{ waiting.push(listener); } return listener.deferred.promise; }; this.cancel = promise.cancel = function(reason, strict){ // summary: // Inform the deferred it may cancel its asynchronous operation. // description: // Inform the deferred it may cancel its asynchronous operation. // The deferred's (optional) canceler is invoked and the // deferred will be left in a rejected state. Can affect other // promises that originate with the same deferred. // reason: any // A message that may be sent to the deferred's canceler, // explaining why it's being canceled. // strict: Boolean? // If strict, will throw an error if the deferred has already // been fulfilled and consequently cannot be canceled. // returns: any // Returns the rejection reason if the deferred was canceled // normally. if(!fulfilled){ // Cancel can be called even after the deferred is fulfilled if(canceler){ var returnedReason = canceler(reason); reason = typeof returnedReason === "undefined" ? reason : returnedReason; } canceled = true; if(!fulfilled){ // Allow canceler to provide its own reason, but fall back to a CancelError if(typeof reason === "undefined"){ reason = new CancelError(); } reject(reason); return reason; }else if(fulfilled === REJECTED && result === reason){ return reason; } }else if(strict === true){ throw new Error(FULFILLED_ERROR_MESSAGE); } }; freezeObject(promise); }; Deferred.prototype.toString = function(){ // returns: String // Returns `[object Deferred]`. return "[object Deferred]"; }; if(instrumentation){ instrumentation(Deferred); } return Deferred; }); }, 'dojo/errors/CancelError':function(){ define(["./create"], function(create){ // module: // dojo/errors/CancelError /*===== return function(){ // summary: // Default error if a promise is canceled without a reason. }; =====*/ return create("CancelError", null, null, { dojoType: "cancel", log: false }); }); }, 'dojo/errors/create':function(){ define(["../_base/lang"], function(lang){ return function(name, ctor, base, props){ base = base || Error; var ErrorCtor = function(message){ if(base === Error){ if(Error.captureStackTrace){ Error.captureStackTrace(this, ErrorCtor); } // Error.call() operates on the returned error // object rather than operating on |this| var err = Error.call(this, message), prop; // Copy own properties from err to |this| for(prop in err){ if(err.hasOwnProperty(prop)){ this[prop] = err[prop]; } } // messsage is non-enumerable in ES5 this.message = message; // stack is non-enumerable in at least Firefox this.stack = err.stack; }else{ base.apply(this, arguments); } if(ctor){ ctor.apply(this, arguments); } }; ErrorCtor.prototype = lang.delegate(base.prototype, props); ErrorCtor.prototype.name = name; ErrorCtor.prototype.constructor = ErrorCtor; return ErrorCtor; }; }); }, 'dojo/promise/Promise':function(){ define([ "../_base/lang" ], function(lang){ "use strict"; // module: // dojo/promise/Promise function throwAbstract(){ throw new TypeError("abstract"); } return lang.extend(function Promise(){ // summary: // The public interface to a deferred. // description: // The public interface to a deferred. All promises in Dojo are // instances of this class. }, { then: function(callback, errback, progback){ // summary: // Add new callbacks to the promise. // description: // Add new callbacks to the deferred. Callbacks can be added // before or after the deferred is fulfilled. // callback: Function? // Callback to be invoked when the promise is resolved. // Receives the resolution value. // errback: Function? // Callback to be invoked when the promise is rejected. // Receives the rejection error. // progback: Function? // Callback to be invoked when the promise emits a progress // update. Receives the progress update. // returns: dojo/promise/Promise // Returns a new promise for the result of the callback(s). // This can be used for chaining many asynchronous operations. throwAbstract(); }, cancel: function(reason, strict){ // summary: // Inform the deferred it may cancel its asynchronous operation. // description: // Inform the deferred it may cancel its asynchronous operation. // The deferred's (optional) canceler is invoked and the // deferred will be left in a rejected state. Can affect other // promises that originate with the same deferred. // reason: any // A message that may be sent to the deferred's canceler, // explaining why it's being canceled. // strict: Boolean? // If strict, will throw an error if the deferred has already // been fulfilled and consequently cannot be canceled. // returns: any // Returns the rejection reason if the deferred was canceled // normally. throwAbstract(); }, isResolved: function(){ // summary: // Checks whether the promise has been resolved. // returns: Boolean throwAbstract(); }, isRejected: function(){ // summary: // Checks whether the promise has been rejected. // returns: Boolean throwAbstract(); }, isFulfilled: function(){ // summary: // Checks whether the promise has been resolved or rejected. // returns: Boolean throwAbstract(); }, isCanceled: function(){ // summary: // Checks whether the promise has been canceled. // returns: Boolean throwAbstract(); }, "finally": function(callback) { // summary: // Add a callback to the promise that will fire whether it // resolves or rejects. // description: // Conforms to ES2018's `Promise.prototype.finally`. // Add a callback to the promise that will fire whether it // resolves or rejects. No value is passed to the callback. // Returns a promise that reflects the state of the original promise, // with two exceptions: // - If the callback return a promise, the outer promise will wait // until the returned promise is resolved, then it will resolve // with the original value. // - If the callback throws an exception or returns a promise that // is rejected (or rejects later), the outer promise will reject // with the inner promise's rejection reason. // callback: Function? // Callback to be invoked when the promise is resolved // or rejected. Doesn't receive any value. // returns: dojo/promise/Promise // Returns a new promise that reflects the state of the original promise, // with two small exceptions (see description). // return this.then(function (value){ var valueOrPromise = callback(); if (valueOrPromise && typeof valueOrPromise.then === "function"){ return valueOrPromise.then(function (){ return value; }); } return value; }, function(reason) { var valueOrPromise = callback(); if (valueOrPromise && typeof valueOrPromise.then === "function"){ return valueOrPromise.then(function (){ throw reason; }); } throw reason; }); }, always: function(callbackOrErrback){ // summary: // Add a callback to be invoked when the promise is resolved // or rejected. // callbackOrErrback: Function? // A function that is used both as a callback and errback. // returns: dojo/promise/Promise // Returns a new promise for the result of the callback/errback. return this.then(callbackOrErrback, callbackOrErrback); }, "catch": function(errback){ // summary: // Add new errbacks to the promise. Follows ECMA specification naming. // errback: Function? // Callback to be invoked when the promise is rejected. // returns: dojo/promise/Promise // Returns a new promise for the result of the errback. return this.then(null, errback); }, otherwise: function(errback){ // summary: // Add new errbacks to the promise. // errback: Function? // Callback to be invoked when the promise is rejected. // returns: dojo/promise/Promise // Returns a new promise for the result of the errback. return this.then(null, errback); }, trace: function(){ return this; }, traceRejected: function(){ return this; }, toString: function(){ // returns: string // Returns `[object Promise]`. return "[object Promise]"; } }); }); }, 'dojo/promise/instrumentation':function(){ define([ "./tracer", "../has", "../_base/lang", "../_base/array" ], function(tracer, has, lang, arrayUtil){ has.add("config-useDeferredInstrumentation", "report-unhandled-rejections"); function logError(error, rejection, deferred){ if(error && error.log === false){ return; } var stack = ""; if(error && error.stack){ stack += error.stack; } if(rejection && rejection.stack){ stack += "\n ----------------------------------------\n rejected" + rejection.stack.split("\n").slice(1).join("\n").replace(/^\s+/, " "); } if(deferred && deferred.stack){ stack += "\n ----------------------------------------\n" + deferred.stack; } console.error(error, stack); } function reportRejections(error, handled, rejection, deferred){ if(!handled){ logError(error, rejection, deferred); } } var errors = []; var activeTimeout = false; var unhandledWait = 1000; function trackUnhandledRejections(error, handled, rejection, deferred){ // try to find the existing tracking object if(!arrayUtil.some(errors, function(obj){ if(obj.error === error){ // found the tracking object for this error if(handled){ // if handled, update the state obj.handled = true; } return true; } })){ // no tracking object has been setup, create one errors.push({ error: error, rejection: rejection, handled: handled, deferred: deferred, timestamp: new Date().getTime() }); } if(!activeTimeout){ activeTimeout = setTimeout(logRejected, unhandledWait); } } function logRejected(){ var now = new Date().getTime(); var reportBefore = now - unhandledWait; errors = arrayUtil.filter(errors, function(obj){ // only report the error if we have waited long enough and // it hasn't been handled if(obj.timestamp < reportBefore){ if(!obj.handled){ logError(obj.error, obj.rejection, obj.deferred); } return false; } return true; }); if(errors.length){ activeTimeout = setTimeout(logRejected, errors[0].timestamp + unhandledWait - now); }else{ activeTimeout = false; } } return function(Deferred){ // summary: // Initialize instrumentation for the Deferred class. // description: // Initialize instrumentation for the Deferred class. // Done automatically by `dojo/Deferred` if the // `deferredInstrumentation` and `useDeferredInstrumentation` // config options are set. // // Sets up `dojo/promise/tracer` to log to the console. // // Sets up instrumentation of rejected deferreds so unhandled // errors are logged to the console. var usage = has("config-useDeferredInstrumentation"); if(usage){ tracer.on("resolved", lang.hitch(console, "log", "resolved")); tracer.on("rejected", lang.hitch(console, "log", "rejected")); tracer.on("progress", lang.hitch(console, "log", "progress")); var args = []; if(typeof usage === "string"){ args = usage.split(","); usage = args.shift(); } if(usage === "report-rejections"){ Deferred.instrumentRejected = reportRejections; }else if(usage === "report-unhandled-rejections" || usage === true || usage === 1){ Deferred.instrumentRejected = trackUnhandledRejections; unhandledWait = parseInt(args[0], 10) || unhandledWait; }else{ throw new Error("Unsupported instrumentation usage <" + usage + ">"); } } }; }); }, 'dojo/promise/tracer':function(){ define([ "../_base/lang", "./Promise", "../Evented" ], function(lang, Promise, Evented){ "use strict"; // module: // dojo/promise/tracer /*===== return { // summary: // Trace promise fulfillment. // description: // Trace promise fulfillment. Calling `.trace()` or `.traceError()` on a // promise enables tracing. Will emit `resolved`, `rejected` or `progress` // events. on: function(type, listener){ // summary: // Subscribe to traces. // description: // See `dojo/Evented#on()`. // type: String // `resolved`, `rejected`, or `progress` // listener: Function // The listener is passed the traced value and any arguments // that were used with the `.trace()` call. } }; =====*/ var evented = new Evented; var emit = evented.emit; evented.emit = null; // Emit events asynchronously since they should not change the promise state. function emitAsync(args){ setTimeout(function(){ emit.apply(evented, args); }, 0); } Promise.prototype.trace = function(){ // summary: // Trace the promise. // description: // Tracing allows you to transparently log progress, // resolution and rejection of promises, without affecting the // promise itself. Any arguments passed to `trace()` are // emitted in trace events. See `dojo/promise/tracer` on how // to handle traces. // returns: dojo/promise/Promise // The promise instance `trace()` is called on. var args = lang._toArray(arguments); this.then( function(value){ emitAsync(["resolved", value].concat(args)); }, function(error){ emitAsync(["rejected", error].concat(args)); }, function(update){ emitAsync(["progress", update].concat(args)); } ); return this; }; Promise.prototype.traceRejected = function(){ // summary: // Trace rejection of the promise. // description: // Tracing allows you to transparently log progress, // resolution and rejection of promises, without affecting the // promise itself. Any arguments passed to `trace()` are // emitted in trace events. See `dojo/promise/tracer` on how // to handle traces. // returns: dojo/promise/Promise // The promise instance `traceRejected()` is called on. var args = lang._toArray(arguments); this.otherwise(function(error){ emitAsync(["rejected", error].concat(args)); }); return this; }; return evented; }); }, 'dojo/Evented':function(){ define(["./aspect", "./on"], function(aspect, on){ // module: // dojo/Evented "use strict"; var after = aspect.after; function Evented(){ // summary: // A class that can be used as a mixin or base class, // to add on() and emit() methods to a class // for listening for events and emitting events: // example: // | define(["dojo/Evented", "dojo/_base/declare", "dojo/Stateful" // | ], function(Evented, declare, Stateful){ // | var EventedStateful = declare([Evented, Stateful], {...}); // | var instance = new EventedStateful(); // | instance.on("open", function(event){ // | ... do something with event // | }); // | // | instance.emit("open", {name:"some event", ...}); } Evented.prototype = { on: function(type, listener){ return on.parse(this, type, listener, function(target, type){ return after(target, 'on' + type, listener, true); }); }, emit: function(type, event){ var args = [this]; args.push.apply(args, arguments); return on.emit.apply(on, args); } }; return Evented; }); }, 'dojo/aspect':function(){ define([], function(){ // module: // dojo/aspect "use strict"; var undefined; function advise(dispatcher, type, advice, receiveArguments){ var previous = dispatcher[type]; var around = type == "around"; var signal; if(around){ var advised = advice(function(){ return previous.advice(this, arguments); }); signal = { remove: function(){ if(advised){ advised = dispatcher = advice = null; } }, advice: function(target, args){ return advised ? advised.apply(target, args) : // called the advised function previous.advice(target, args); // cancelled, skip to next one } }; }else{ // create the remove handler signal = { remove: function(){ if(signal.advice){ var previous = signal.previous; var next = signal.next; if(!next && !previous){ delete dispatcher[type]; }else{ if(previous){ previous.next = next; }else{ dispatcher[type] = next; } if(next){ next.previous = previous; } } // remove the advice to signal that this signal has been removed dispatcher = advice = signal.advice = null; } }, id: dispatcher.nextId++, advice: advice, receiveArguments: receiveArguments }; } if(previous && !around){ if(type == "after"){ // add the listener to the end of the list // note that we had to change this loop a little bit to workaround a bizarre IE10 JIT bug while(previous.next && (previous = previous.next)){} previous.next = signal; signal.previous = previous; }else if(type == "before"){ // add to beginning dispatcher[type] = signal; signal.next = previous; previous.previous = signal; } }else{ // around or first one just replaces dispatcher[type] = signal; } return signal; } function aspect(type){ return function(target, methodName, advice, receiveArguments){ var existing = target[methodName], dispatcher; if(!existing || existing.target != target){ // no dispatcher in place target[methodName] = dispatcher = function(){ var executionId = dispatcher.nextId; // before advice var args = arguments; var before = dispatcher.before; while(before){ if(before.advice){ args = before.advice.apply(this, args) || args; } before = before.next; } // around advice if(dispatcher.around){ var results = dispatcher.around.advice(this, args); } // after advice var after = dispatcher.after; while(after && after.id < executionId){ if(after.advice){ if(after.receiveArguments){ var newResults = after.advice.apply(this, args); // change the return value only if a new value was returned results = newResults === undefined ? results : newResults; }else{ results = after.advice.call(this, results, args); } } after = after.next; } return results; }; if(existing){ dispatcher.around = {advice: function(target, args){ return existing.apply(target, args); }}; } dispatcher.target = target; dispatcher.nextId = dispatcher.nextId || 0; } var results = advise((dispatcher || existing), type, advice, receiveArguments); advice = null; return results; }; } // TODOC: after/before/around return object var after = aspect("after"); /*===== after = function(target, methodName, advice, receiveArguments){ // summary: // The "after" export of the aspect module is a function that can be used to attach // "after" advice to a method. This function will be executed after the original method // is executed. By default the function will be called with a single argument, the return // value of the original method, or the the return value of the last executed advice (if a previous one exists). // The fourth (optional) argument can be set to true to so the function receives the original // arguments (from when the original method was called) rather than the return value. // If there are multiple "after" advisors, they are executed in the order they were registered. // target: Object // This is the target object // methodName: String // This is the name of the method to attach to. // advice: Function // This is function to be called after the original method // receiveArguments: Boolean? // If this is set to true, the advice function receives the original arguments (from when the original mehtod // was called) rather than the return value of the original/previous method. // returns: // A signal object that can be used to cancel the advice. If remove() is called on this signal object, it will // stop the advice function from being executed. }; =====*/ var before = aspect("before"); /*===== before = function(target, methodName, advice){ // summary: // The "before" export of the aspect module is a function that can be used to attach // "before" advice to a method. This function will be executed before the original method // is executed. This function will be called with the arguments used to call the method. // This function may optionally return an array as the new arguments to use to call // the original method (or the previous, next-to-execute before advice, if one exists). // If the before method doesn't return anything (returns undefined) the original arguments // will be preserved. // If there are multiple "before" advisors, they are executed in the reverse order they were registered. // target: Object // This is the target object // methodName: String // This is the name of the method to attach to. // advice: Function // This is function to be called before the original method }; =====*/ var around = aspect("around"); /*===== around = function(target, methodName, advice){ // summary: // The "around" export of the aspect module is a function that can be used to attach // "around" advice to a method. The advisor function is immediately executed when // the around() is called, is passed a single argument that is a function that can be // called to continue execution of the original method (or the next around advisor). // The advisor function should return a function, and this function will be called whenever // the method is called. It will be called with the arguments used to call the method. // Whatever this function returns will be returned as the result of the method call (unless after advise changes it). // example: // If there are multiple "around" advisors, the most recent one is executed first, // which can then delegate to the next one and so on. For example: // | around(obj, "foo", function(originalFoo){ // | return function(){ // | var start = new Date().getTime(); // | var results = originalFoo.apply(this, arguments); // call the original // | var end = new Date().getTime(); // | console.log("foo execution took " + (end - start) + " ms"); // | return results; // | }; // | }); // target: Object // This is the target object // methodName: String // This is the name of the method to attach to. // advice: Function // This is function to be called around the original method }; =====*/ return { // summary: // provides aspect oriented programming functionality, allowing for // one to add before, around, or after advice on existing methods. // example: // | define(["dojo/aspect"], function(aspect){ // | var signal = aspect.after(targetObject, "methodName", function(someArgument){ // | this will be called when targetObject.methodName() is called, after the original function is called // | }); // // example: // The returned signal object can be used to cancel the advice. // | signal.remove(); // this will stop the advice from being executed anymore // | aspect.before(targetObject, "methodName", function(someArgument){ // | // this will be called when targetObject.methodName() is called, before the original function is called // | }); before: before, around: around, after: after }; }); }, 'dojo/on':function(){ define(["./has!dom-addeventlistener?:./aspect", "./_base/kernel", "./sniff"], function(aspect, dojo, has){ "use strict"; if( 1 ){ // check to make sure we are in a browser, this module should work anywhere var major = window.ScriptEngineMajorVersion; has.add("jscript", major && (major() + ScriptEngineMinorVersion() / 10)); has.add("event-orientationchange", has("touch") && !has("android")); // TODO: how do we detect this? has.add("event-stopimmediatepropagation", window.Event && !!window.Event.prototype && !!window.Event.prototype.stopImmediatePropagation); has.add("event-focusin", function(global, doc, element){ return 'onfocusin' in element; }); if(has("touch")){ has.add("touch-can-modify-event-delegate", function(){ // This feature test checks whether deleting a property of an event delegate works // for a touch-enabled device. If it works, event delegation can be used as fallback // for browsers such as Safari in older iOS where deleting properties of the original // event does not work. var EventDelegate = function(){}; EventDelegate.prototype = document.createEvent("MouseEvents"); // original event // Attempt to modify a property of an event delegate and check if // it succeeds. Depending on browsers and on whether dojo/on's // strict mode is stripped in a Dojo build, there are 3 known behaviors: // it may either succeed, or raise an error, or fail to set the property // without raising an error. try{ var eventDelegate = new EventDelegate; eventDelegate.target = null; return eventDelegate.target === null; }catch(e){ return false; // cannot use event delegation } }); } } var on = function(target, type, listener, dontFix){ // summary: // A function that provides core event listening functionality. With this function // you can provide a target, event type, and listener to be notified of // future matching events that are fired. // target: Element|Object // This is the target object or DOM element that to receive events from // type: String|Function // This is the name of the event to listen for or an extension event type. // listener: Function // This is the function that should be called when the event fires. // returns: Object // An object with a remove() method that can be used to stop listening for this // event. // description: // To listen for "click" events on a button node, we can do: // | define(["dojo/on"], function(on){ // | on(button, "click", clickHandler); // | ... // Evented JavaScript objects can also have their own events. // | var obj = new Evented; // | on(obj, "foo", fooHandler); // And then we could publish a "foo" event: // | on.emit(obj, "foo", {key: "value"}); // We can use extension events as well. For example, you could listen for a tap gesture: // | define(["dojo/on", "dojo/gesture/tap", function(on, tap){ // | on(button, tap, tapHandler); // | ... // which would trigger fooHandler. Note that for a simple object this is equivalent to calling: // | obj.onfoo({key:"value"}); // If you use on.emit on a DOM node, it will use native event dispatching when possible. if(typeof target.on == "function" && typeof type != "function" && !target.nodeType){ // delegate to the target's on() method, so it can handle it's own listening if it wants (unless it // is DOM node and we may be dealing with jQuery or Prototype's incompatible addition to the // Element prototype return target.on(type, listener); } // delegate to main listener code return on.parse(target, type, listener, addListener, dontFix, this); }; on.pausable = function(target, type, listener, dontFix){ // summary: // This function acts the same as on(), but with pausable functionality. The // returned signal object has pause() and resume() functions. Calling the // pause() method will cause the listener to not be called for future events. Calling the // resume() method will cause the listener to again be called for future events. var paused; var signal = on(target, type, function(){ if(!paused){ return listener.apply(this, arguments); } }, dontFix); signal.pause = function(){ paused = true; }; signal.resume = function(){ paused = false; }; return signal; }; on.once = function(target, type, listener, dontFix){ // summary: // This function acts the same as on(), but will only call the listener once. The // listener will be called for the first // event that takes place and then listener will automatically be removed. var signal = on(target, type, function(){ // remove this listener signal.remove(); // proceed to call the listener return listener.apply(this, arguments); }); return signal; }; on.parse = function(target, type, listener, addListener, dontFix, matchesTarget){ var events; if(type.call){ // event handler function // on(node, touch.press, touchListener); return type.call(matchesTarget, target, listener); } if(type instanceof Array){ // allow an array of event names (or event handler functions) events = type; }else if(type.indexOf(",") > -1){ // we allow comma delimited event names, so you can register for multiple events at once events = type.split(/\s*,\s*/); } if(events){ var handles = []; var i = 0; var eventName; while(eventName = events[i++]){ // intentional assignment handles.push(on.parse(target, eventName, listener, addListener, dontFix, matchesTarget)); } handles.remove = function(){ for(var i = 0; i < handles.length; i++){ handles[i].remove(); } }; return handles; } return addListener(target, type, listener, dontFix, matchesTarget); }; var touchEvents = /^touch/; function addListener(target, type, listener, dontFix, matchesTarget){ // event delegation: var selector = type.match(/(.*):(.*)/); // if we have a selector:event, the last one is interpreted as an event, and we use event delegation if(selector){ type = selector[2]; selector = selector[1]; // create the extension event for selectors and directly call it return on.selector(selector, type).call(matchesTarget, target, listener); } // test to see if it a touch event right now, so we don't have to do it every time it fires if(has("touch")){ if(touchEvents.test(type)){ // touch event, fix it listener = fixTouchListener(listener); } if(!has("event-orientationchange") && (type == "orientationchange")){ //"orientationchange" not supported <= Android 2.1, //but works through "resize" on window type = "resize"; target = window; listener = fixTouchListener(listener); } } if(addStopImmediate){ // add stopImmediatePropagation if it doesn't exist listener = addStopImmediate(listener); } // normal path, the target is |this| if(target.addEventListener){ // the target has addEventListener, which should be used if available (might or might not be a node, non-nodes can implement this method as well) // check for capture conversions var capture = type in captures, adjustedType = capture ? captures[type] : type; target.addEventListener(adjustedType, listener, capture); // create and return the signal return { remove: function(){ target.removeEventListener(adjustedType, listener, capture); } }; } type = "on" + type; if(fixAttach && target.attachEvent){ return fixAttach(target, type, listener); } throw new Error("Target must be an event emitter"); } on.matches = function(node, selector, context, children, matchesTarget) { // summary: // Check if a node match the current selector within the constraint of a context // node: DOMNode // The node that originate the event // selector: String // The selector to check against // context: DOMNode // The context to search in. // children: Boolean // Indicates if children elements of the selector should be allowed. This defaults to // true // matchesTarget: Object|dojo/query? // An object with a property "matches" as a function. Default is dojo/query. // Matching DOMNodes will be done against this function // The function must return a Boolean. // It will have 3 arguments: "node", "selector" and "context" // True is expected if "node" is matching the current "selector" in the passed "context" // returns: DOMNode? // The matching node, if any. Else you get false // see if we have a valid matchesTarget or default to dojo/query matchesTarget = matchesTarget && (typeof matchesTarget.matches == "function") ? matchesTarget : dojo.query; children = children !== false; // there is a selector, so make sure it matches if(node.nodeType != 1){ // text node will fail in native match selector node = node.parentNode; } while(!matchesTarget.matches(node, selector, context)){ if(node == context || children === false || !(node = node.parentNode) || node.nodeType != 1){ // intentional assignment return false; } } return node; }; on.selector = function(selector, eventType, children){ // summary: // Creates a new extension event with event delegation. This is based on // the provided event type (can be extension event) that // only calls the listener when the CSS selector matches the target of the event. // // The application must require() an appropriate level of dojo/query to handle the selector. // selector: // The CSS selector to use for filter events and determine the |this| of the event listener. // eventType: // The event to listen for // children: // Indicates if children elements of the selector should be allowed. This defaults to // true // example: // | require(["dojo/on", "dojo/mouse", "dojo/query!css2"], function(on, mouse){ // | on(node, on.selector(".my-class", mouse.enter), handlerForMyHover); return function(target, listener){ // if the selector is function, use it to select the node, otherwise use the matches method var matchesTarget = typeof selector == "function" ? {matches: selector} : this, bubble = eventType.bubble; function select(eventTarget){ return on.matches(eventTarget, selector, target, children, matchesTarget); } if(bubble){ // the event type doesn't naturally bubble, but has a bubbling form, use that, and give it the selector so it can perform the select itself return on(target, bubble(select), listener); } // standard event delegation return on(target, eventType, function(event){ // call select to see if we match var eventTarget = select(event.target); // if it matches we call the listener if (eventTarget) { // We save the matching target into the event, so it can be accessed even when hitching (see #18355) event.selectorTarget = eventTarget; return listener.call(eventTarget, event); } }); }; }; function syntheticPreventDefault(){ this.cancelable = false; this.defaultPrevented = true; } function syntheticStopPropagation(){ this.bubbles = false; } var slice = [].slice, syntheticDispatch = on.emit = function(target, type, event){ // summary: // Fires an event on the target object. // target: // The target object to fire the event on. This can be a DOM element or a plain // JS object. If the target is a DOM element, native event emitting mechanisms // are used when possible. // type: // The event type name. You can emulate standard native events like "click" and // "mouseover" or create custom events like "open" or "finish". // event: // An object that provides the properties for the event. See https://developer.mozilla.org/en/DOM/event.initEvent // for some of the properties. These properties are copied to the event object. // Of particular importance are the cancelable and bubbles properties. The // cancelable property indicates whether or not the event has a default action // that can be cancelled. The event is cancelled by calling preventDefault() on // the event object. The bubbles property indicates whether or not the // event will bubble up the DOM tree. If bubbles is true, the event will be called // on the target and then each parent successively until the top of the tree // is reached or stopPropagation() is called. Both bubbles and cancelable // default to false. // returns: // If the event is cancelable and the event is not cancelled, // emit will return true. If the event is cancelable and the event is cancelled, // emit will return false. // details: // Note that this is designed to emit events for listeners registered through // dojo/on. It should actually work with any event listener except those // added through IE's attachEvent (IE8 and below's non-W3C event emitting // doesn't support custom event types). It should work with all events registered // through dojo/on. Also note that the emit method does do any default // action, it only returns a value to indicate if the default action should take // place. For example, emitting a keypress event would not cause a character // to appear in a textbox. // example: // To fire our own click event // | require(["dojo/on", "dojo/dom" // | ], function(on, dom){ // | on.emit(dom.byId("button"), "click", { // | cancelable: true, // | bubbles: true, // | screenX: 33, // | screenY: 44 // | }); // We can also fire our own custom events: // | on.emit(dom.byId("slider"), "slide", { // | cancelable: true, // | bubbles: true, // | direction: "left-to-right" // | }); // | }); var args = slice.call(arguments, 2); var method = "on" + type; if("parentNode" in target){ // node (or node-like), create event controller methods var newEvent = args[0] = {}; for(var i in event){ newEvent[i] = event[i]; } newEvent.preventDefault = syntheticPreventDefault; newEvent.stopPropagation = syntheticStopPropagation; newEvent.target = target; newEvent.type = type; event = newEvent; } do{ // call any node which has a handler (note that ideally we would try/catch to simulate normal event propagation but that causes too much pain for debugging) target[method] && target[method].apply(target, args); // and then continue up the parent node chain if it is still bubbling (if started as bubbles and stopPropagation hasn't been called) }while(event && event.bubbles && (target = target.parentNode)); return event && event.cancelable && event; // if it is still true (was cancelable and was cancelled), return the event to indicate default action should happen }; var captures = has("event-focusin") ? {} : {focusin: "focus", focusout: "blur"}; if(!has("event-stopimmediatepropagation")){ var stopImmediatePropagation =function(){ this.immediatelyStopped = true; this.modified = true; // mark it as modified so the event will be cached in IE }; var addStopImmediate = function(listener){ return function(event){ if(!event.immediatelyStopped){// check to make sure it hasn't been stopped immediately event.stopImmediatePropagation = stopImmediatePropagation; return listener.apply(this, arguments); } }; }; } if(has("dom-addeventlistener")){ // emitter that works with native event handling on.emit = function(target, type, event){ if(target.dispatchEvent && document.createEvent){ // use the native event emitting mechanism if it is available on the target object // create a generic event // we could create branch into the different types of event constructors, but // that would be a lot of extra code, with little benefit that I can see, seems // best to use the generic constructor and copy properties over, making it // easy to have events look like the ones created with specific initializers var ownerDocument = target.ownerDocument || document; var nativeEvent = ownerDocument.createEvent("HTMLEvents"); nativeEvent.initEvent(type, !!event.bubbles, !!event.cancelable); // and copy all our properties over for(var i in event){ if(!(i in nativeEvent)){ nativeEvent[i] = event[i]; } } return target.dispatchEvent(nativeEvent) && nativeEvent; } return syntheticDispatch.apply(on, arguments); // emit for a non-node }; }else{ // no addEventListener, basically old IE event normalization on._fixEvent = function(evt, 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;} try{ if(lastEvent && evt.type == lastEvent.type && evt.srcElement == lastEvent.target){ // should be same event, reuse event object (so it can be augmented); // accessing evt.srcElement rather than evt.target since evt.target not set on IE until fixup below evt = lastEvent; } }catch(e){ // will occur on IE on lastEvent.type reference if lastEvent points to a previous event that already // finished bubbling, but the setTimeout() to clear lastEvent hasn't fired yet } if(!evt.target){ // check to see if it has been fixed yet evt.target = evt.srcElement; evt.currentTarget = (sender || evt.srcElement); if(evt.type == "mouseover"){ evt.relatedTarget = evt.fromElement; } if(evt.type == "mouseout"){ evt.relatedTarget = evt.toElement; } if(!evt.stopPropagation){ evt.stopPropagation = stopPropagation; evt.preventDefault = preventDefault; } 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; _setKeyChar(evt); break; } } return evt; }; var lastEvent, IESignal = function(handle){ this.handle = handle; }; IESignal.prototype.remove = function(){ delete _dojoIEListeners_[this.handle]; }; var fixListener = function(listener){ // this is a minimal function for closing on the previous listener with as few as variables as possible return function(evt){ evt = on._fixEvent(evt, this); var result = listener.call(this, evt); if(evt.modified){ // cache the last event and reuse it if we can if(!lastEvent){ setTimeout(function(){ lastEvent = null; }); } lastEvent = evt; } return result; }; }; var fixAttach = function(target, type, listener){ listener = fixListener(listener); if(((target.ownerDocument ? target.ownerDocument.parentWindow : target.parentWindow || target.window || window) != top || has("jscript") < 5.8) && !has("config-_allow_leaks")){ // IE will leak memory on certain handlers in frames (IE8 and earlier) and in unattached DOM nodes for JScript 5.7 and below. // Here we use global redirection to solve the memory leaks if(typeof _dojoIEListeners_ == "undefined"){ _dojoIEListeners_ = []; } var emitter = target[type]; if(!emitter || !emitter.listeners){ var oldListener = emitter; emitter = Function('event', 'var callee = arguments.callee; for(var i = 0; i 1){ return callback ? callback(valueOrPromise) : valueOrPromise; }else{ return new Deferred().resolve(valueOrPromise); } }else if(!nativePromise){ var deferred = new Deferred(valueOrPromise.cancel); valueOrPromise.then(deferred.resolve, deferred.reject, deferred.progress); valueOrPromise = deferred.promise; } if(callback || errback || progback){ return valueOrPromise.then(callback, errback, progback); } return valueOrPromise; }; }); }, 'dojo/_base/json':function(){ define(["./kernel", "../json"], function(dojo, json){ // module: // dojo/_base/json /*===== return { // summary: // This module defines the dojo JSON API. }; =====*/ dojo.fromJson = function(/*String*/ js){ // summary: // Parses a JavaScript expression and returns a JavaScript value. // description: // Throws for invalid JavaScript expressions. It does not use a strict JSON parser. It // always delegates to eval(). The content passed to this method must therefore come // from a trusted source. // It is recommend that you use dojo/json's parse function for an // implementation uses the (faster) native JSON parse when available. // js: // a string literal of a JavaScript expression, for instance: // `'{ "foo": [ "bar", 1, { "baz": "thud" } ] }'` return eval("(" + js + ")"); // Object }; /*===== dojo._escapeString = function(){ // summary: // Adds escape sequences for non-visual characters, double quote and // backslash and surrounds with double quotes to form a valid string // literal. }; =====*/ dojo._escapeString = json.stringify; // just delegate to json.stringify dojo.toJsonIndentStr = "\t"; dojo.toJson = function(/*Object*/ it, /*Boolean?*/ prettyPrint){ // 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 is recommend that you use dojo/json's stringify function for an lighter // and faster implementation that matches the native JSON API and uses the // native JSON serializer when available. // 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. // Note that in 1.6, toJson would serialize undefined, but this no longer supported // since it is not supported by native JSON serializer. // 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(). // Note that if native JSON support is available, it will be used for serialization, // and native implementations vary on the exact spacing used in pretty printing. // returns: // A JSON string serialization of the passed-in object. // example: // simple serialization of a trivial object // | var jsonStr = dojo.toJson({ howdy: "stranger!", isStrange: true }); // | doh.is('{"howdy":"stranger!","isStrange":true}', jsonStr); // example: // a custom serializer for an objects of a particular class: // | dojo.declare("Furby", null, { // | furbies: "are strange", // | furbyCount: 10, // | __json__: function(){ // | }, // | }); // use dojo/json return json.stringify(it, function(key, value){ if(value){ var tf = value.__json__||value.json; if(typeof tf == "function"){ return tf.call(value); } } return value; }, prettyPrint && dojo.toJsonIndentStr); // String }; return dojo; }); }, 'dojo/request/watch':function(){ define([ './util', '../errors/RequestTimeoutError', '../errors/CancelError', '../_base/array', '../_base/window', '../has!host-browser?dom-addeventlistener?:../on:' ], function(util, RequestTimeoutError, CancelError, array, win, on){ // avoid setting a timer per request. It degrades performance on IE // something fierece if we don't use unified loops. var _inFlightIntvl = null, _inFlight = []; function watchInFlight(){ // summary: // internal method that checks each inflight XMLHttpRequest to see // if it has completed or if the timeout situation applies. var now = +(new Date); // we need manual loop because we often modify _inFlight (and therefore 'i') while iterating for(var i = 0, dfd; i < _inFlight.length && (dfd = _inFlight[i]); i++){ var response = dfd.response, options = response.options; if((dfd.isCanceled && dfd.isCanceled()) || (dfd.isValid && !dfd.isValid(response))){ _inFlight.splice(i--, 1); watch._onAction && watch._onAction(); }else if(dfd.isReady && dfd.isReady(response)){ _inFlight.splice(i--, 1); dfd.handleResponse(response); watch._onAction && watch._onAction(); }else if(dfd.startTime){ // did we timeout? if(dfd.startTime + (options.timeout || 0) < now){ _inFlight.splice(i--, 1); // Cancel the request so the io module can do appropriate cleanup. dfd.cancel(new RequestTimeoutError('Timeout exceeded', response)); watch._onAction && watch._onAction(); } } } watch._onInFlight && watch._onInFlight(dfd); if(!_inFlight.length){ clearInterval(_inFlightIntvl); _inFlightIntvl = null; } } function watch(dfd){ // summary: // Watches the io request represented by dfd to see if it completes. // dfd: Deferred // The Deferred object to watch. // response: Object // The object used as the value of the request promise. // validCheck: Function // Function used to check if the IO request is still valid. Gets the dfd // object as its only argument. // ioCheck: Function // Function used to check if basic IO call worked. Gets the dfd // object as its only argument. // resHandle: Function // Function used to process response. Gets the dfd // object as its only argument. if(dfd.response.options.timeout){ dfd.startTime = +(new Date); } if(dfd.isFulfilled()){ // bail out if the deferred is already fulfilled return; } _inFlight.push(dfd); if(!_inFlightIntvl){ _inFlightIntvl = setInterval(watchInFlight, 50); } // handle sync requests separately from async: // http://bugs.dojotoolkit.org/ticket/8467 if(dfd.response.options.sync){ watchInFlight(); } } watch.cancelAll = function cancelAll(){ // summary: // Cancels all pending IO requests, regardless of IO type try{ array.forEach(_inFlight, function(dfd){ try{ dfd.cancel(new CancelError('All requests canceled.')); }catch(e){} }); }catch(e){} }; if(win && on && win.doc.attachEvent){ // Automatically call cancel all io calls on unload in IE // http://bugs.dojotoolkit.org/ticket/2357 on(win.global, 'unload', function(){ watch.cancelAll(); }); } return watch; }); }, 'dojo/request/util':function(){ define([ 'exports', '../errors/RequestError', '../errors/CancelError', '../Deferred', '../io-query', '../_base/array', '../_base/lang', '../promise/Promise', '../has' ], function(exports, RequestError, CancelError, Deferred, ioQuery, array, lang, Promise, has){ function isArrayBuffer(value) { return has('native-arraybuffer') && value instanceof ArrayBuffer } function isBlob(value) { return has('native-blob') && value instanceof Blob } function isElement(value) { if(typeof Element !== 'undefined') { //all other return value instanceof Element; } //IE<=7 return value.nodeType === 1; } function isFormData(value) { return has('native-formdata') && value instanceof FormData; } function shouldDeepCopy(value) { return value && typeof value === 'object' && !isFormData(value) && !isElement(value) && !isBlob(value) && !isArrayBuffer(value) } exports.deepCopy = function(target, source) { for (var name in source) { var tval = target[name], sval = source[name]; if (name !== '__proto__' && tval !== sval) { if (shouldDeepCopy(sval)) { if (Object.prototype.toString.call(sval) === '[object Date]') { // use this date test to handle crossing frame boundaries target[name] = new Date(sval); } else if (lang.isArray(sval)) { target[name] = exports.deepCopyArray(sval); } else { if (tval && typeof tval === 'object') { exports.deepCopy(tval, sval); } else { target[name] = exports.deepCopy({}, sval); } } } else { target[name] = sval; } } } return target; }; exports.deepCopyArray = function(source) { var clonedArray = []; for (var i = 0, l = source.length; i < l; i++) { var svalItem = source[i]; if (typeof svalItem === 'object') { clonedArray.push(exports.deepCopy({}, svalItem)); } else { clonedArray.push(svalItem); } } return clonedArray; }; exports.deepCreate = function deepCreate(source, properties){ properties = properties || {}; var target = lang.delegate(source), name, value; for(name in source){ value = source[name]; if(value && typeof value === 'object'){ target[name] = exports.deepCreate(value, properties[name]); } } return exports.deepCopy(target, properties); }; var freeze = Object.freeze || function(obj){ return obj; }; function okHandler(response){ return freeze(response); } function dataHandler (response) { return response.data !== undefined ? response.data : response.text; } exports.deferred = function deferred(response, cancel, isValid, isReady, handleResponse, last){ var def = new Deferred(function(reason){ cancel && cancel(def, response); if(!reason || !(reason instanceof RequestError) && !(reason instanceof CancelError)){ return new CancelError('Request canceled', response); } return reason; }); def.response = response; def.isValid = isValid; def.isReady = isReady; def.handleResponse = handleResponse; function errHandler(error){ error.response = response; throw error; } var responsePromise = def.then(okHandler).otherwise(errHandler); if(exports.notify){ responsePromise.then( lang.hitch(exports.notify, 'emit', 'load'), lang.hitch(exports.notify, 'emit', 'error') ); } var dataPromise = responsePromise.then(dataHandler); // http://bugs.dojotoolkit.org/ticket/16794 // The following works around a leak in IE9 through the // prototype using lang.delegate on dataPromise and // assigning the result a property with a reference to // responsePromise. var promise = new Promise(); for (var prop in dataPromise) { if (dataPromise.hasOwnProperty(prop)) { promise[prop] = dataPromise[prop]; } } promise.response = responsePromise; freeze(promise); // End leak fix if(last){ def.then(function(response){ last.call(def, response); }, function(error){ last.call(def, response, error); }); } def.promise = promise; def.then = promise.then; return def; }; exports.addCommonMethods = function addCommonMethods(provider, methods){ array.forEach(methods||['GET', 'POST', 'PUT', 'DELETE'], function(method){ provider[(method === 'DELETE' ? 'DEL' : method).toLowerCase()] = function(url, options){ options = lang.delegate(options||{}); options.method = method; return provider(url, options); }; }); }; exports.parseArgs = function parseArgs(url, options, skipData){ var data = options.data, query = options.query; if(data && !skipData){ if(typeof data === 'object' && (!(has('native-xhr2')) || !(isArrayBuffer(data) || isBlob(data) ))){ options.data = ioQuery.objectToQuery(data); } } if(query){ if(typeof query === 'object'){ query = ioQuery.objectToQuery(query); } if(options.preventCache){ query += (query ? '&' : '') + 'request.preventCache=' + (+(new Date)); } }else if(options.preventCache){ query = 'request.preventCache=' + (+(new Date)); } if(url && query){ url += (~url.indexOf('?') ? '&' : '?') + query; } return { url: url, options: options, getHeader: function(headerName){ return null; } }; }; exports.checkStatus = function(stat){ stat = stat || 0; return (stat >= 200 && stat < 300) || // allow any 2XX response code stat === 304 || // or, get it out of the cache stat === 1223 || // or, Internet Explorer mangled the status code !stat; // or, we're Titanium/browser chrome/chrome extension requesting a local file }; }); }, 'dojo/errors/RequestError':function(){ define(['./create'], function(create){ // module: // dojo/errors/RequestError /*===== return function(){ // summary: // TODOC }; =====*/ return create("RequestError", function(message, response){ this.response = response; }); }); }, 'dojo/errors/RequestTimeoutError':function(){ define(['./create', './RequestError'], function(create, RequestError){ // module: // dojo/errors/RequestTimeoutError /*===== return function(){ // summary: // TODOC }; =====*/ return create("RequestTimeoutError", null, RequestError, { dojoType: "timeout" }); }); }, 'dojo/request/xhr':function(){ define([ '../errors/RequestError', './watch', './handlers', './util', '../has'/*=====, '../request', '../_base/declare' =====*/ ], function(RequestError, watch, handlers, util, has/*=====, request, declare =====*/){ has.add('native-xhr', function(){ // if true, the environment has a native XHR implementation return typeof XMLHttpRequest !== 'undefined'; }); has.add('dojo-force-activex-xhr', function(){ return has('activex') && window.location.protocol === 'file:'; }); has.add('native-xhr2', function(){ if(!has('native-xhr') || has('dojo-force-activex-xhr')){ return; } var x = new XMLHttpRequest(); return typeof x['addEventListener'] !== 'undefined' && (typeof opera === 'undefined' || typeof x['upload'] !== 'undefined'); }); has.add('native-formdata', function(){ // if true, the environment has a native FormData implementation return typeof FormData !== 'undefined'; }); has.add('native-blob', function(){ // if true, the environment has a native Blob implementation return typeof Blob !== 'undefined'; }); has.add('native-arraybuffer', function(){ // if true, the environment has a native ArrayBuffer implementation return typeof ArrayBuffer !== 'undefined'; }); has.add('native-response-type', function(){ return has('native-xhr') && typeof new XMLHttpRequest().responseType !== 'undefined'; }); has.add('native-xhr2-blob', function(){ if(!has('native-response-type')){ return; } var x = new XMLHttpRequest(); // The URL used here does not have to be reachable as the XHR's `send` method is never called. // It does need to be parsable/resolvable in all cases, so it should be an absolute URL. // XMLHttpRequest within a Worker created from a Blob does not support relative URL paths. x.open('GET', 'https://dojotoolkit.org/', true); x.responseType = 'blob'; // will not be set if unsupported var responseType = x.responseType; x.abort(); return responseType === 'blob'; }); // Google Chrome doesn't support "json" response type // up to version 30, so it's intentionally not included here var nativeResponseTypes = { 'blob': has('native-xhr2-blob') ? 'blob' : 'arraybuffer', 'document': 'document', 'arraybuffer': 'arraybuffer' }; function handleResponse(response, error){ var _xhr = response.xhr; response.status = response.xhr.status; try { // Firefox throws an error when trying to access // xhr.responseText if response isn't text response.text = _xhr.responseText; } catch (e) {} if(response.options.handleAs === 'xml'){ response.data = _xhr.responseXML; } var handleError; if(error){ this.reject(error); }else{ try{ handlers(response); }catch(e){ handleError = e; } if(util.checkStatus(_xhr.status)){ if(!handleError){ this.resolve(response); }else{ this.reject(handleError); } }else{ if(!handleError){ error = new RequestError('Unable to load ' + response.url + ' status: ' + _xhr.status, response); this.reject(error); }else{ error = new RequestError('Unable to load ' + response.url + ' status: ' + _xhr.status + ' and an error in handleAs: transformation of response', response); this.reject(error); } } } } var isValid, isReady, addListeners, cancel; if(has('native-xhr2')){ // Any platform with XHR2 will only use the watch mechanism for timeout. isValid = function(response){ // summary: // Check to see if the request should be taken out of the watch queue return !this.isFulfilled(); }; cancel = function(dfd, response){ // summary: // Canceler for deferred response.xhr.abort(); }; addListeners = function(_xhr, dfd, response, uploadProgress){ // summary: // Adds event listeners to the XMLHttpRequest object function onLoad(evt){ dfd.handleResponse(response); } function onError(evt){ var _xhr = evt.target; var error = new RequestError('Unable to load ' + response.url + ' status: ' + _xhr.status, response); dfd.handleResponse(response, error); } function onProgress(transferType, evt){ response.transferType = transferType; if(evt.lengthComputable){ response.loaded = evt.loaded; response.total = evt.total; dfd.progress(response); } else if(response.xhr.readyState === 3){ response.loaded = ('loaded' in evt) ? evt.loaded : evt.position; dfd.progress(response); } } function onDownloadProgress(evt) { return onProgress('download', evt); } function onUploadProgress(evt) { return onProgress('upload', evt); } _xhr.addEventListener('load', onLoad, false); _xhr.addEventListener('error', onError, false); _xhr.addEventListener('progress', onDownloadProgress, false); if (uploadProgress && _xhr.upload) { _xhr.upload.addEventListener('progress', onUploadProgress, false); } return function(){ _xhr.removeEventListener('load', onLoad, false); _xhr.removeEventListener('error', onError, false); _xhr.removeEventListener('progress', onDownloadProgress, false); _xhr.upload.removeEventListener('progress', onUploadProgress, false); _xhr = null; }; }; }else{ isValid = function(response){ return response.xhr.readyState; //boolean }; isReady = function(response){ return 4 === response.xhr.readyState; //boolean }; cancel = function(dfd, response){ // summary: // canceller function for util.deferred call. var xhr = response.xhr; var _at = typeof xhr.abort; if(_at === 'function' || _at === 'object' || _at === 'unknown'){ xhr.abort(); } }; } function getHeader(headerName){ return this.xhr.getResponseHeader(headerName); } var undefined, defaultOptions = { data: null, query: null, sync: false, method: 'GET' }; function xhr(url, options, returnDeferred){ var isFormData = has('native-formdata') && options && options.data && options.data instanceof FormData; var response = util.parseArgs( url, util.deepCreate(defaultOptions, options), isFormData ); url = response.url; options = response.options; var hasNoData = !options.data && options.method !== 'POST' && options.method !== 'PUT'; if(has('ie') <= 10){ // older IE breaks point 9 in http://www.w3.org/TR/XMLHttpRequest/#the-open()-method and sends fragment, so strip it url = url.split('#')[0]; } var remover, last = function(){ remover && remover(); }; //Make the Deferred object for this xhr request. var dfd = util.deferred( response, cancel, isValid, isReady, handleResponse, last ); var _xhr = response.xhr = xhr._create(); if(!_xhr){ // If XHR factory somehow returns nothings, // cancel the deferred. dfd.cancel(new RequestError('XHR was not created')); return returnDeferred ? dfd : dfd.promise; } response.getHeader = getHeader; if(addListeners){ remover = addListeners(_xhr, dfd, response, options.uploadProgress); } // IE11 treats data: undefined different than other browsers var data = typeof(options.data) === 'undefined' ? null : options.data, async = !options.sync, method = options.method; try{ // IE6 won't let you call apply() on the native function. _xhr.open(method, url, async, options.user || undefined, options.password || undefined); if(options.withCredentials){ _xhr.withCredentials = options.withCredentials; } if(has('native-response-type') && options.handleAs in nativeResponseTypes) { _xhr.responseType = nativeResponseTypes[options.handleAs]; } var headers = options.headers, contentType = (isFormData || hasNoData) ? false : 'application/x-www-form-urlencoded'; if(headers){ for(var hdr in headers){ if(hdr.toLowerCase() === 'content-type'){ contentType = headers[hdr]; }else if(headers[hdr]){ //Only add header if it has a value. This allows for instance, skipping //insertion of X-Requested-With by specifying empty value. _xhr.setRequestHeader(hdr, headers[hdr]); } } } if(contentType && contentType !== false){ _xhr.setRequestHeader('Content-Type', contentType); } if(!headers || !('X-Requested-With' in headers)){ _xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); } if(util.notify){ util.notify.emit('send', response, dfd.promise.cancel); } _xhr.send(data); }catch(e){ dfd.reject(e); } watch(dfd); _xhr = null; return returnDeferred ? dfd : dfd.promise; } /*===== xhr = function(url, options){ // summary: // Sends a request using XMLHttpRequest with the given URL and options. // url: String // URL to request // options: dojo/request/xhr.__Options? // Options for the request. // returns: dojo/request.__Promise }; xhr.__BaseOptions = declare(request.__BaseOptions, { // sync: Boolean? // Whether to make a synchronous request or not. Default // is `false` (asynchronous). // data: String|Object|FormData? // Data to transfer. This is ignored for GET and DELETE // requests. // headers: Object? // Headers to use for the request. // user: String? // Username to use during the request. // password: String? // Password to use during the request. // withCredentials: Boolean? // For cross-site requests, whether to send credentials // or not. // uploadProgress: Boolean? // Upload progress events cause preflighted requests. This // option enables upload progress event support but also // causes all requests to be preflighted. }); xhr.__MethodOptions = declare(null, { // method: String? // The HTTP method to use to make the request. Must be // uppercase. Default is `"GET"`. }); xhr.__Options = declare([xhr.__BaseOptions, xhr.__MethodOptions]); xhr.get = function(url, options){ // summary: // Send an HTTP GET request using XMLHttpRequest with the given URL and options. // url: String // URL to request // options: dojo/request/xhr.__BaseOptions? // Options for the request. // returns: dojo/request.__Promise }; xhr.post = function(url, options){ // summary: // Send an HTTP POST request using XMLHttpRequest with the given URL and options. // url: String // URL to request // options: dojo/request/xhr.__BaseOptions? // Options for the request. // returns: dojo/request.__Promise }; xhr.put = function(url, options){ // summary: // Send an HTTP PUT request using XMLHttpRequest with the given URL and options. // url: String // URL to request // options: dojo/request/xhr.__BaseOptions? // Options for the request. // returns: dojo/request.__Promise }; xhr.del = function(url, options){ // summary: // Send an HTTP DELETE request using XMLHttpRequest with the given URL and options. // url: String // URL to request // options: dojo/request/xhr.__BaseOptions? // Options for the request. // returns: dojo/request.__Promise }; =====*/ xhr._create = function(){ // summary: // does the work of portably generating a new XMLHTTPRequest object. throw new Error('XMLHTTP not available'); }; if(has('native-xhr') && !has('dojo-force-activex-xhr')){ xhr._create = function(){ return new XMLHttpRequest(); }; }else if(has('activex')){ try{ new ActiveXObject('Msxml2.XMLHTTP'); xhr._create = function(){ return new ActiveXObject('Msxml2.XMLHTTP'); }; }catch(e){ try{ new ActiveXObject('Microsoft.XMLHTTP'); xhr._create = function(){ return new ActiveXObject('Microsoft.XMLHTTP'); }; }catch(e){} } } util.addCommonMethods(xhr); return xhr; }); }, 'dojo/request/handlers':function(){ define([ '../json', '../_base/kernel', '../_base/array', '../has', '../selector/_loader' // only included for has() qsa tests ], function(JSON, kernel, array, has){ has.add('activex', typeof ActiveXObject !== 'undefined'); has.add('dom-parser', function(global){ return 'DOMParser' in global; }); var handleXML; if(has('activex')){ // GUIDs obtained from http://msdn.microsoft.com/en-us/library/ms757837(VS.85).aspx var dp = [ 'Msxml2.DOMDocument.6.0', 'Msxml2.DOMDocument.4.0', 'MSXML2.DOMDocument.3.0', 'MSXML.DOMDocument' // 2.0 ]; var lastParser; handleXML = function(response){ var result = response.data; var text = response.text; if(result && has('dom-qsa2.1') && !result.querySelectorAll && has('dom-parser')){ // http://bugs.dojotoolkit.org/ticket/15631 // IE9 supports a CSS3 querySelectorAll implementation, but the DOM implementation // returned by IE9 xhr.responseXML does not. Manually create the XML DOM to gain // the fuller-featured implementation and avoid bugs caused by the inconsistency result = new DOMParser().parseFromString(text, 'application/xml'); } function createDocument(p) { try{ var dom = new ActiveXObject(p); dom.async = false; dom.loadXML(text); result = dom; lastParser = p; }catch(e){ return false; } return true; } if(!result || !result.documentElement){ // The creation of an ActiveX object is expensive, so we cache the // parser type to avoid trying all parser types each time we handle a // document. There is some concern that some parser types might fail // depending on the document being parsed. If parsing using the cached // parser type fails, we do the more expensive operation of finding one // that works for the given document. // https://bugs.dojotoolkit.org/ticket/15246 if(!lastParser || !createDocument(lastParser)) { array.some(dp, createDocument); } } return result; }; } var handleNativeResponse = function(response) { if(!has('native-xhr2-blob') && response.options.handleAs === 'blob' && typeof Blob !== 'undefined'){ return new Blob([ response.xhr.response ], { type: response.xhr.getResponseHeader('Content-Type') }); } return response.xhr.response; } var handlers = { 'javascript': function(response){ return kernel.eval(response.text || ''); }, 'json': function(response){ return JSON.parse(response.text || null); }, 'xml': handleXML, 'blob': handleNativeResponse, 'arraybuffer': handleNativeResponse, 'document': handleNativeResponse }; function handle(response){ var handler = handlers[response.options.handleAs]; response.data = handler ? handler(response) : (response.data || response.text); return response; } handle.register = function(name, handler){ handlers[name] = handler; }; return handle; }); }, 'dojo/selector/_loader':function(){ define(["../has", "require"], function(has, require){ "use strict"; if (typeof document !== "undefined") { var testDiv = document.createElement("div"); has.add("dom-qsa2.1", !!testDiv.querySelectorAll); has.add("dom-qsa3", function(){ // test to see if we have a reasonable native selector engine available try{ testDiv.innerHTML = "

"; // test kind of from sizzle // Safari can't handle uppercase or unicode characters when // in quirks mode, IE8 can't handle pseudos like :empty return testDiv.querySelectorAll(".TEST:empty").length == 1; }catch(e){} }); } var fullEngine; var acme = "./acme", lite = "./lite"; return { // summary: // This module handles loading the appropriate selector engine for the given browser load: function(id, parentRequire, loaded, config){ if (config && config.isBuild) { //Indicate that the optimizer should not wait //for this resource any more and complete optimization. //This resource will be resolved dynamically during //run time in the web browser. loaded(); return; } var req = require; // here we implement the default logic for choosing a selector engine id = id == "default" ? has("config-selectorEngine") || "css3" : id; id = id == "css2" || id == "lite" ? lite : id == "css2.1" ? has("dom-qsa2.1") ? lite : acme : id == "css3" ? has("dom-qsa3") ? lite : acme : id == "acme" ? acme : (req = parentRequire) && id; if(id.charAt(id.length-1) == '?'){ id = id.substring(0,id.length - 1); var optionalLoad = true; } // the query engine is optional, only load it if a native one is not available or existing one has not been loaded if(optionalLoad && (has("dom-compliant-qsa") || fullEngine)){ return loaded(fullEngine); } // load the referenced selector engine req([id], function(engine){ if(id != "./lite"){ fullEngine = engine; } loaded(engine); }); } }; }); }, 'dojo/main':function(){ define([ "./_base/kernel", // kernel.isAsync "./has", "require", "./sniff", "./_base/lang", "./_base/array", "./_base/config", "./ready", "./_base/declare", "./_base/connect", "./_base/Deferred", "./_base/json", "./_base/Color", "./has!dojo-firebug?./_firebug/firebug", "./_base/browser", "./_base/loader" ], function(kernel, has, require, sniff, lang, array, config, ready){ // module: // dojo/main // summary: // This is the package main module for the dojo package; it loads dojo base appropriate for the execution environment. // Load code to fix IE's console if(config.isDebug){ require(["./_firebug/firebug"]); } // dojoConfig.require is deprecated; use the loader configuration property deps 1 || has.add("dojo-config-require", 1); if( 1 ){ var deps= config.require; if(deps){ // config.require may be dot notation deps= array.map(lang.isArray(deps) ? deps : [deps], function(item){ return item.replace(/\./g, "/"); }); if(kernel.isAsync){ require(deps); }else{ // this is a bit janky; in 1.6- dojo is defined before these requires are applied; but in 1.7+ // dojo isn't defined until returning from this module; this is only a problem in sync mode // since we're in sync mode, we know we've got our loader with its priority ready queue ready(1, function(){require(deps);}); } } } return kernel; }); }, 'dojo/ready':function(){ define(["./_base/kernel", "./has", "require", "./domReady", "./_base/lang"], function(dojo, has, require, domReady, lang){ // module: // dojo/ready // note: // This module should be unnecessary in dojo 2.0 var // truthy if DOMContentLoaded or better (e.g., window.onload fired) has been achieved isDomReady = 0, // The queue of functions waiting to execute as soon as dojo.ready conditions satisfied loadQ = [], // prevent recursion in onLoad onLoadRecursiveGuard = 0, handleDomReady = function(){ isDomReady = 1; dojo._postLoad = dojo.config.afterOnLoad = true; onEvent(); }, onEvent = function(){ // Called when some state changes: // - dom ready // - dojo/domReady has finished processing everything in its queue // - task added to loadQ // - require() has finished loading all currently requested modules // // Run the functions queued with dojo.ready if appropriate. //guard against recursions into this function if(onLoadRecursiveGuard){ return; } onLoadRecursiveGuard = 1; // Run tasks in queue if require() is finished loading modules, the dom is ready, and there are no // pending tasks registered via domReady(). // The last step is necessary so that a user defined dojo.ready() callback is delayed until after the // domReady() calls inside of dojo. Failure can be seen on dijit/tests/robot/Dialog_ally.html on IE8 // because the dijit/focus.js domReady() callback doesn't execute until after the test starts running. while(isDomReady && (!domReady || domReady._Q.length == 0) && (require.idle ? require.idle() : true) && loadQ.length){ var f = loadQ.shift(); try{ f(); }catch(e){ // force the dojo.js on("error") handler do display the message e.info = e.message; if(require.signal){ require.signal("error", e); }else{ throw e; } } } onLoadRecursiveGuard = 0; }; // Check if we should run the next queue operation whenever require() finishes loading modules or domReady // finishes processing it's queue. require.on && require.on("idle", onEvent); if(domReady){ domReady._onQEmpty = onEvent; } var ready = dojo.ready = dojo.addOnLoad = function(priority, context, callback){ // summary: // Add a function to execute on DOM content loaded and all requested modules have arrived and been evaluated. // In most cases, the `domReady` plug-in should suffice and this method should not be needed. // // When called in a non-browser environment, just checks that all requested modules have arrived and been // evaluated. // priority: Integer? // The order in which to exec this callback relative to other callbacks, defaults to 1000 // context: Object?|Function // The context in which to run execute callback, or a callback if not using context // callback: Function? // The function to execute. // // example: // Simple DOM and Modules ready syntax // | require(["dojo/ready"], function(ready){ // | ready(function(){ alert("Dom ready!"); }); // | }); // // example: // Using a priority // | require(["dojo/ready"], function(ready){ // | ready(2, function(){ alert("low priority ready!"); }) // | }); // // example: // Using context // | require(["dojo/ready"], function(ready){ // | ready(foo, function(){ // | // in here, this == foo // | }); // | }); // // example: // Using dojo/hitch style args: // | require(["dojo/ready"], function(ready){ // | var foo = { dojoReady: function(){ console.warn(this, "dojo dom and modules ready."); } }; // | ready(foo, "dojoReady"); // | }); var hitchArgs = lang._toArray(arguments); if(typeof priority != "number"){ callback = context; context = priority; priority = 1000; }else{ hitchArgs.shift(); } callback = callback ? lang.hitch.apply(dojo, hitchArgs) : function(){ context(); }; callback.priority = priority; for(var i = 0; i < loadQ.length && priority >= loadQ[i].priority; i++){} loadQ.splice(i, 0, callback); onEvent(); }; 1 || has.add("dojo-config-addOnLoad", 1); if( 1 ){ var dca = dojo.config.addOnLoad; if(dca){ ready[(lang.isArray(dca) ? "apply" : "call")](dojo, dca); } } if( 1 && dojo.config.parseOnLoad && !dojo.isAsync){ ready(99, function(){ if(!dojo.parser){ dojo.deprecated("Add explicit require(['dojo/parser']);", "", "2.0"); require(["dojo/parser"]); } }); } if(domReady){ domReady(handleDomReady); }else{ handleDomReady(); } return ready; }); }, 'dojo/domReady':function(){ define(['./global', './has'], function(global, has){ var doc = document, readyStates = { 'loaded': 1, 'complete': 1 }, fixReadyState = typeof doc.readyState != "string", ready = !!readyStates[doc.readyState], readyQ = [], recursiveGuard; function domReady(callback){ // summary: // Plugin to delay require()/define() callback from firing until the DOM has finished loading. readyQ.push(callback); if(ready){ processQ(); } } domReady.load = function(id, req, load){ domReady(load); }; // Export queue so that ready() can check if it's empty or not. domReady._Q = readyQ; domReady._onQEmpty = function(){ // summary: // Private method overridden by dojo/ready, to notify when everything in the // domReady queue has been processed. Do not use directly. // Will be removed in 2.0, along with domReady._Q. }; // For FF <= 3.5 if(fixReadyState){ doc.readyState = "loading"; } function processQ(){ // Calls all functions in the queue in order, unless processQ() is already running, in which case just return if(recursiveGuard){ return; } recursiveGuard = true; while(readyQ.length){ try{ (readyQ.shift())(doc); }catch(err){ console.error(err, "in domReady callback", err.stack); } } recursiveGuard = false; // Notification for dojo/ready. Remove for 2.0. // Note that this could add more tasks to the ready queue. domReady._onQEmpty(); } if(!ready){ var tests = [], detectReady = function(evt){ evt = evt || global.event; if(ready || (evt.type == "readystatechange" && !readyStates[doc.readyState])){ return; } // For FF <= 3.5 if(fixReadyState){ doc.readyState = "complete"; } ready = 1; processQ(); }, on = function(node, event){ node.addEventListener(event, detectReady, false); readyQ.push(function(){ node.removeEventListener(event, detectReady, false); }); }; if(!has("dom-addeventlistener")){ on = function(node, event){ event = "on" + event; node.attachEvent(event, detectReady); readyQ.push(function(){ node.detachEvent(event, detectReady); }); }; var div = doc.createElement("div"); try{ if(div.doScroll && global.frameElement === null){ // the doScroll test is only useful if we're in the top-most frame tests.push(function(){ // Derived with permission from Diego Perini's IEContentLoaded // http://javascript.nwbox.com/IEContentLoaded/ try{ div.doScroll("left"); return 1; }catch(e){} }); } }catch(e){} } on(doc, "DOMContentLoaded"); on(global, "load"); if("onreadystatechange" in doc){ on(doc, "readystatechange"); }else if(!fixReadyState){ // if the ready state property exists and there's // no readystatechange event, poll for the state // to change tests.push(function(){ return readyStates[doc.readyState]; }); } if(tests.length){ var poller = function(){ if(ready){ return; } var i = tests.length; while(i--){ if(tests[i]()){ detectReady("poller"); return; } } setTimeout(poller, 30); }; poller(); } } return domReady; }); }, 'dojo/_base/declare':function(){ define(["./kernel", "../has", "./lang"], function(dojo, has, lang){ // module: // dojo/_base/declare var mix = lang.mixin, op = Object.prototype, opts = op.toString, xtor, counter = 0, cname = "constructor"; if(!has("csp-restrictions")){ // 'new Function()' is preferable when available since it does not create a closure xtor = new Function; }else{ xtor = function(){}; } function err(msg, cls){ throw new Error("declare" + (cls ? " " + cls : "") + ": " + msg); } // C3 Method Resolution Order (see http://www.python.org/download/releases/2.3/mro/) function c3mro(bases, className){ var result = [], roots = [{cls: 0, refs: []}], nameMap = {}, clsCount = 1, l = bases.length, i = 0, j, lin, base, top, proto, rec, name, refs; // build a list of bases naming them if needed for(; i < l; ++i){ base = bases[i]; if(!base){ err("mixin #" + i + " is unknown. Did you use dojo.require to pull it in?", className); }else if(opts.call(base) != "[object Function]"){ err("mixin #" + i + " is not a callable constructor.", className); } lin = base._meta ? base._meta.bases : [base]; top = 0; // add bases to the name map for(j = lin.length - 1; j >= 0; --j){ proto = lin[j].prototype; if(!proto.hasOwnProperty("declaredClass")){ proto.declaredClass = "uniqName_" + (counter++); } name = proto.declaredClass; if(!nameMap.hasOwnProperty(name)){ nameMap[name] = {count: 0, refs: [], cls: lin[j]}; ++clsCount; } rec = nameMap[name]; if(top && top !== rec){ rec.refs.push(top); ++top.count; } top = rec; } ++top.count; roots[0].refs.push(top); } // remove classes without external references recursively while(roots.length){ top = roots.pop(); result.push(top.cls); --clsCount; // optimization: follow a single-linked chain while(refs = top.refs, refs.length == 1){ top = refs[0]; if(!top || --top.count){ // branch or end of chain => do not end to roots top = 0; break; } result.push(top.cls); --clsCount; } if(top){ // branch for(i = 0, l = refs.length; i < l; ++i){ top = refs[i]; if(!--top.count){ roots.push(top); } } } } if(clsCount){ err("can't build consistent linearization", className); } // calculate the superclass offset base = bases[0]; result[0] = base ? base._meta && base === result[result.length - base._meta.bases.length] ? base._meta.bases.length : 1 : 0; return result; } function inherited(args, a, f, g){ var name, chains, bases, caller, meta, base, proto, opf, pos, cache = this._inherited = this._inherited || {}; // crack arguments if(typeof args === "string"){ name = args; args = a; a = f; f = g; } if(typeof args === "function"){ // support strict mode caller = args; args = a; a = f; }else{ try{ caller = args.callee; }catch (e){ if(e instanceof TypeError){ // caller was defined in a strict-mode context err("strict mode inherited() requires the caller function to be passed before arguments", this.declaredClass); }else{ throw e; } } } name = name || caller.nom; if(!name){ err("can't deduce a name to call inherited()", this.declaredClass); } f = g = 0; meta = this.constructor._meta; bases = meta.bases; pos = cache.p; if(name != cname){ // method if(cache.c !== caller){ // cache bust pos = 0; base = bases[0]; meta = base._meta; if(meta.hidden[name] !== caller){ // error detection chains = meta.chains; if(chains && typeof chains[name] == "string"){ err("calling chained method with inherited: " + name, this.declaredClass); } // find caller do{ meta = base._meta; proto = base.prototype; if(meta && (proto[name] === caller && proto.hasOwnProperty(name) || meta.hidden[name] === caller)){ break; } }while(base = bases[++pos]); // intentional assignment pos = base ? pos : -1; } } // find next base = bases[++pos]; if(base){ proto = base.prototype; if(base._meta && proto.hasOwnProperty(name)){ f = proto[name]; }else{ opf = op[name]; do{ proto = base.prototype; f = proto[name]; if(f && (base._meta ? proto.hasOwnProperty(name) : f !== opf)){ break; } }while(base = bases[++pos]); // intentional assignment } } f = base && f || op[name]; }else{ // constructor if(cache.c !== caller){ // cache bust pos = 0; meta = bases[0]._meta; if(meta && meta.ctor !== caller){ // error detection chains = meta.chains; if(!chains || chains.constructor !== "manual"){ err("calling chained constructor with inherited", this.declaredClass); } // find caller while(base = bases[++pos]){ // intentional assignment meta = base._meta; if(meta && meta.ctor === caller){ break; } } pos = base ? pos : -1; } } // find next while(base = bases[++pos]){ // intentional assignment meta = base._meta; f = meta ? meta.ctor : base; if(f){ break; } } f = base && f; } // cache the found super method cache.c = f; cache.p = pos; // now we have the result if(f){ return a === true ? f : f.apply(this, a || args); } // intentionally no return if a super method was not found } function getInherited(name, args, a){ if(typeof name === "string"){ if (typeof args === "function") { return this.__inherited(name, args, a, true); } return this.__inherited(name, args, true); } else if (typeof name === "function") { return this.__inherited(name, args, true); } return this.__inherited(name, true); } function inherited__debug(args, a1, a2, a3){ var f = this.getInherited(args, a1, a2); if(f){ return f.apply(this, a3 || a2 || a1 || args); } // intentionally no return if a super method was not found } var inheritedImpl = dojo.config.isDebug ? inherited__debug : inherited; // emulation of "instanceof" function isInstanceOf(cls){ var bases = this.constructor._meta.bases; for(var i = 0, l = bases.length; i < l; ++i){ if(bases[i] === cls){ return true; } } return this instanceof cls; } function mixOwn(target, source){ // add props adding metadata for incoming functions skipping a constructor for(var name in source){ if(name != cname && source.hasOwnProperty(name)){ target[name] = source[name]; } } if(has("bug-for-in-skips-shadowed")){ for(var extraNames= lang._extraNames, i= extraNames.length; i;){ name = extraNames[--i]; if(name != cname && source.hasOwnProperty(name)){ target[name] = source[name]; } } } } // implementation of safe mixin function function safeMixin(target, source){ // summary: // Mix in properties skipping a constructor and decorating functions // like it is done by declare(). // target: Object // Target object to accept new properties. // source: Object // Source object for new properties. // description: // This function is used to mix in properties like lang.mixin does, // but it skips a constructor property and decorates functions like // declare() does. // // It is meant to be used with classes and objects produced with // declare. Functions mixed in with dojo.safeMixin can use // this.inherited() like normal methods. // // This function is used to implement extend() method of a constructor // produced with declare(). // // example: // | var A = declare(null, { // | m1: function(){ // | console.log("A.m1"); // | }, // | m2: function(){ // | console.log("A.m2"); // | } // | }); // | var B = declare(A, { // | m1: function(){ // | this.inherited(arguments); // | console.log("B.m1"); // | } // | }); // | B.extend({ // | m2: function(){ // | this.inherited(arguments); // | console.log("B.m2"); // | } // | }); // | var x = new B(); // | dojo.safeMixin(x, { // | m1: function(){ // | this.inherited(arguments); // | console.log("X.m1"); // | }, // | m2: function(){ // | this.inherited(arguments); // | console.log("X.m2"); // | } // | }); // | x.m2(); // | // prints: // | // A.m1 // | // B.m1 // | // X.m1 var name, t; // add props adding metadata for incoming functions skipping a constructor for(name in source){ t = source[name]; if((t !== op[name] || !(name in op)) && name != cname){ if(opts.call(t) == "[object Function]"){ // non-trivial function method => attach its name t.nom = name; } target[name] = t; } } if(has("bug-for-in-skips-shadowed") && source){ for(var extraNames= lang._extraNames, i= extraNames.length; i;){ name = extraNames[--i]; t = source[name]; if((t !== op[name] || !(name in op)) && name != cname){ if(opts.call(t) == "[object Function]"){ // non-trivial function method => attach its name t.nom = name; } target[name] = t; } } } return target; } function extend(source){ declare.safeMixin(this.prototype, source); return this; } function createSubclass(mixins, props){ // crack parameters if(!(mixins instanceof Array || typeof mixins === 'function')){ props = mixins; mixins = undefined; } props = props || {}; mixins = mixins || []; return declare([this].concat(mixins), props); } // chained constructor compatible with the legacy declare() function chainedConstructor(bases, ctorSpecial){ return function(){ var a = arguments, args = a, a0 = a[0], f, i, m, l = bases.length, preArgs; if(!(this instanceof a.callee)){ // not called via new, so force it return applyNew(a); } //this._inherited = {}; // perform the shaman's rituals of the original declare() // 1) call two types of the preamble if(ctorSpecial && (a0 && a0.preamble || this.preamble)){ // full blown ritual preArgs = new Array(bases.length); // prepare parameters preArgs[0] = a; for(i = 0;;){ // process the preamble of the 1st argument a0 = a[0]; if(a0){ f = a0.preamble; if(f){ a = f.apply(this, a) || a; } } // process the preamble of this class f = bases[i].prototype; f = f.hasOwnProperty("preamble") && f.preamble; if(f){ a = f.apply(this, a) || a; } // one peculiarity of the preamble: // it is called if it is not needed, // e.g., there is no constructor to call // let's watch for the last constructor // (see ticket #9795) if(++i == l){ break; } preArgs[i] = a; } } // 2) call all non-trivial constructors using prepared arguments for(i = l - 1; i >= 0; --i){ f = bases[i]; m = f._meta; f = m ? m.ctor : f; if(f){ f.apply(this, preArgs ? preArgs[i] : a); } } // 3) continue the original ritual: call the postscript f = this.postscript; if(f){ f.apply(this, args); } }; } // chained constructor compatible with the legacy declare() function singleConstructor(ctor, ctorSpecial){ return function(){ var a = arguments, t = a, a0 = a[0], f; if(!(this instanceof a.callee)){ // not called via new, so force it return applyNew(a); } //this._inherited = {}; // perform the shaman's rituals of the original declare() // 1) call two types of the preamble if(ctorSpecial){ // full blown ritual if(a0){ // process the preamble of the 1st argument f = a0.preamble; if(f){ t = f.apply(this, t) || t; } } f = this.preamble; if(f){ // process the preamble of this class f.apply(this, t); // one peculiarity of the preamble: // it is called even if it is not needed, // e.g., there is no constructor to call // let's watch for the last constructor // (see ticket #9795) } } // 2) call a constructor if(ctor){ ctor.apply(this, a); } // 3) continue the original ritual: call the postscript f = this.postscript; if(f){ f.apply(this, a); } }; } // plain vanilla constructor (can use inherited() to call its base constructor) function simpleConstructor(bases){ return function(){ var a = arguments, i = 0, f, m; if(!(this instanceof a.callee)){ // not called via new, so force it return applyNew(a); } //this._inherited = {}; // perform the shaman's rituals of the original declare() // 1) do not call the preamble // 2) call the top constructor (it can use this.inherited()) for(; f = bases[i]; ++i){ // intentional assignment m = f._meta; f = m ? m.ctor : f; if(f){ f.apply(this, a); break; } } // 3) call the postscript f = this.postscript; if(f){ f.apply(this, a); } }; } function chain(name, bases, reversed){ return function(){ var b, m, f, i = 0, step = 1; if(reversed){ i = bases.length - 1; step = -1; } for(; b = bases[i]; i += step){ // intentional assignment m = b._meta; f = (m ? m.hidden : b.prototype)[name]; if(f){ f.apply(this, arguments); } } }; } // forceNew(ctor) // return a new object that inherits from ctor.prototype but // without actually running ctor on the object. function forceNew(ctor){ // create object with correct prototype using a do-nothing // constructor xtor.prototype = ctor.prototype; var t = new xtor; xtor.prototype = null; // clean up return t; } // applyNew(args) // just like 'new ctor()' except that the constructor and its arguments come // from args, which must be an array or an arguments object function applyNew(args){ // create an object with ctor's prototype but without // calling ctor on it. var ctor = args.callee, t = forceNew(ctor); // execute the real constructor on the new object ctor.apply(t, args); return t; } function declare(className, superclass, props){ // summary: // Create a feature-rich constructor from compact notation. // className: String? // The optional name of the constructor (loosely, a "class") // stored in the "declaredClass" property in the created prototype. // It will be used as a global name for a created constructor. // superclass: Function|Function[] // May be null, a Function, or an Array of Functions. This argument // specifies a list of bases (the left-most one is the most deepest // base). // props: Object // An object whose properties are copied to the created prototype. // Add an instance-initialization function by making it a property // named "constructor". // returns: dojo/_base/declare.__DeclareCreatedObject // New constructor function. // description: // Create a constructor using a compact notation for inheritance and // prototype extension. // // 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. // // Ancestors can be compound classes created by this version of // declare(). In complex cases all base classes are going to be // linearized according to C3 MRO algorithm // (see http://www.python.org/download/releases/2.3/mro/ for more // details). // // "className" is cached in "declaredClass" property of the new class, // if it was supplied. The immediate super class will be cached in // "superclass" property of the new class. // // Methods in "props" will be copied and modified: "nom" property // (the declared name of the method) will be added to all copied // functions to help identify them for the internal machinery. Be // very careful, while reusing methods: if you use the same // function under different names, it can produce errors in some // cases. // // It is possible to use constructors created "manually" (without // declare()) as bases. They will be called as usual during the // creation of an instance, their methods will be chained, and even // called by "this.inherited()". // // Special property "-chains-" governs how to chain methods. It is // a dictionary, which uses method names as keys, and hint strings // as values. If a hint string is "after", this method will be // called after methods of its base classes. If a hint string is // "before", this method will be called before methods of its base // classes. // // If "constructor" is not mentioned in "-chains-" property, it will // be chained using the legacy mode: using "after" chaining, // calling preamble() method before each constructor, if available, // and calling postscript() after all constructors were executed. // If the hint is "after", it is chained as a regular method, but // postscript() will be called after the chain of constructors. // "constructor" cannot be chained "before", but it allows // a special hint string: "manual", which means that constructors // are not going to be chained in any way, and programmer will call // them manually using this.inherited(). In the latter case // postscript() will be called after the construction. // // All chaining hints are "inherited" from base classes and // potentially can be overridden. Be very careful when overriding // hints! Make sure that all chained methods can work in a proposed // manner of chaining. // // Once a method was chained, it is impossible to unchain it. The // only exception is "constructor". You don't need to define a // method in order to supply a chaining hint. // // If a method is chained, it cannot use this.inherited() because // all other methods in the hierarchy will be called automatically. // // Usually constructors and initializers of any kind are chained // using "after" and destructors of any kind are chained as // "before". Note that chaining assumes that chained methods do not // return any value: any returned value will be discarded. // // example: // | 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(); // | } // | }); // // example: // | var MyBase = declare(null, { // | // constructor, properties, and methods go here // | // ... // | }); // | var MyClass1 = declare(MyBase, { // | // constructor, properties, and methods go here // | // ... // | }); // | var MyClass2 = declare(MyBase, { // | // constructor, properties, and methods go here // | // ... // | }); // | var MyDiamond = declare([MyClass1, MyClass2], { // | // constructor, properties, and methods go here // | // ... // | }); // // example: // | var F = function(){ console.log("raw constructor"); }; // | F.prototype.method = function(){ // | console.log("raw method"); // | }; // | var A = declare(F, { // | constructor: function(){ // | console.log("A.constructor"); // | }, // | method: function(){ // | console.log("before calling F.method..."); // | this.inherited(arguments); // | console.log("...back in A"); // | } // | }); // | new A().method(); // | // will print: // | // raw constructor // | // A.constructor // | // before calling F.method... // | // raw method // | // ...back in A // // example: // | var A = declare(null, { // | "-chains-": { // | destroy: "before" // | } // | }); // | var B = declare(A, { // | constructor: function(){ // | console.log("B.constructor"); // | }, // | destroy: function(){ // | console.log("B.destroy"); // | } // | }); // | var C = declare(B, { // | constructor: function(){ // | console.log("C.constructor"); // | }, // | destroy: function(){ // | console.log("C.destroy"); // | } // | }); // | new C().destroy(); // | // prints: // | // B.constructor // | // C.constructor // | // C.destroy // | // B.destroy // // example: // | var A = declare(null, { // | "-chains-": { // | constructor: "manual" // | } // | }); // | var B = declare(A, { // | constructor: function(){ // | // ... // | // call the base constructor with new parameters // | this.inherited(arguments, [1, 2, 3]); // | // ... // | } // | }); // // example: // | var A = declare(null, { // | "-chains-": { // | m1: "before" // | }, // | m1: function(){ // | console.log("A.m1"); // | }, // | m2: function(){ // | console.log("A.m2"); // | } // | }); // | var B = declare(A, { // | "-chains-": { // | m2: "after" // | }, // | m1: function(){ // | console.log("B.m1"); // | }, // | m2: function(){ // | console.log("B.m2"); // | } // | }); // | var x = new B(); // | x.m1(); // | // prints: // | // B.m1 // | // A.m1 // | x.m2(); // | // prints: // | // A.m2 // | // B.m2 // crack parameters if(typeof className != "string"){ props = superclass; superclass = className; className = ""; } props = props || {}; var proto, i, t, ctor, name, bases, chains, mixins = 1, parents = superclass; // build a prototype if(opts.call(superclass) == "[object Array]"){ // C3 MRO bases = c3mro(superclass, className); t = bases[0]; mixins = bases.length - t; superclass = bases[mixins]; }else{ bases = [0]; if(superclass){ if(opts.call(superclass) == "[object Function]"){ t = superclass._meta; bases = bases.concat(t ? t.bases : superclass); }else{ err("base class is not a callable constructor.", className); } }else if(superclass !== null){ err("unknown base class. Did you use dojo.require to pull it in?", className); } } if(superclass){ for(i = mixins - 1;; --i){ proto = forceNew(superclass); if(!i){ // stop if nothing to add (the last base) break; } // mix in properties t = bases[i]; (t._meta ? mixOwn : mix)(proto, t.prototype); // chain in new constructor if (has("csp-restrictions")) { ctor = function () {}; } else { ctor = new Function; } ctor.superclass = superclass; ctor.prototype = proto; superclass = proto.constructor = ctor; } }else{ proto = {}; } // add all properties declare.safeMixin(proto, props); // add constructor t = props.constructor; if(t !== op.constructor){ t.nom = cname; proto.constructor = t; } // collect chains and flags for(i = mixins - 1; i; --i){ // intentional assignment t = bases[i]._meta; if(t && t.chains){ chains = mix(chains || {}, t.chains); } } if(proto["-chains-"]){ chains = mix(chains || {}, proto["-chains-"]); } if(superclass && superclass.prototype && superclass.prototype["-chains-"]) { chains = mix(chains || {}, superclass.prototype["-chains-"]); } // build ctor t = !chains || !chains.hasOwnProperty(cname); bases[0] = ctor = (chains && chains.constructor === "manual") ? simpleConstructor(bases) : (bases.length == 1 ? singleConstructor(props.constructor, t) : chainedConstructor(bases, t)); // add meta information to the constructor ctor._meta = {bases: bases, hidden: props, chains: chains, parents: parents, ctor: props.constructor}; ctor.superclass = superclass && superclass.prototype; ctor.extend = extend; ctor.createSubclass = createSubclass; ctor.prototype = proto; proto.constructor = ctor; // add "standard" methods to the prototype proto.getInherited = getInherited; proto.isInstanceOf = isInstanceOf; proto.inherited = inheritedImpl; proto.__inherited = inherited; // add name if specified if(className){ proto.declaredClass = className; lang.setObject(className, ctor); } // build chains and add them to the prototype if(chains){ for(name in chains){ if(proto[name] && typeof chains[name] == "string" && name != cname){ t = proto[name] = chain(name, bases, chains[name] === "after"); t.nom = name; } } } // chained methods do not return values // no need to chain "invisible" functions return ctor; // Function } /*===== declare.__DeclareCreatedObject = { // summary: // dojo/_base/declare() returns a constructor `C`. `new C()` returns an Object with the following // methods, in addition to the methods and properties specified via the arguments passed to declare(). inherited: function(name, caller, args, newArgs){ // summary: // Calls a super method. // name: String? // The optional method name. Should be the same as the caller's // name. Usually "name" is specified in complex dynamic cases, when // the calling method was dynamically added, undecorated by // declare(), and it cannot be determined. // caller: Function? // The reference to the calling function. Required only if the // call to "this.inherited" occurs from within strict-mode code. // If the caller is omitted within strict-mode code, an error will // be thrown. // The best way to obtain a reference to the calling function is to // use a named function expression (i.e. place a function name // after the "function" keyword and before the open paren, as in // "function fn(a, b)"). If the function is parsed as an expression // and not a statement (i.e. it's not by itself on its own line), // the function name will only be accessible as an identifier from // within the body of the function. // args: Arguments // The caller supply this argument, which should be the original // "arguments". // newArgs: Object? // If "true", the found function will be returned without // executing it. // If Array, it will be used to call a super method. Otherwise // "args" will be used. // returns: // Whatever is returned by a super method, or a super method itself, // if "true" was specified as newArgs. // description: // This method is used inside method of classes produced with // declare() to call a super method (next in the chain). It is // used for manually controlled chaining. Consider using the regular // chaining, because it is faster. Use "this.inherited()" only in // complex cases. // // This method cannot me called from automatically chained // constructors including the case of a special (legacy) // constructor chaining. It cannot be called from chained methods. // // If "this.inherited()" cannot find the next-in-chain method, it // does nothing and returns "undefined". The last method in chain // can be a default method implemented in Object, which will be // called last. // // If "name" is specified, it is assumed that the method that // received "args" is the parent method for this call. It is looked // up in the chain list and if it is found the next-in-chain method // is called. If it is not found, the first-in-chain method is // called. // // If "name" is not specified, it will be derived from the calling // method (using a methoid property "nom"). // // example: // | var B = declare(A, { // | method1: function(a, b, c){ // | this.inherited(arguments); // | }, // | method2: function(a, b){ // | return this.inherited(arguments, [a + b]); // | } // | }); // | // next method is not in the chain list because it is added // | // manually after the class was created. // | B.prototype.method3 = function(){ // | console.log("This is a dynamically-added method."); // | this.inherited("method3", arguments); // | }; // example: // | var B = declare(A, { // | method: function(a, b){ // | var super = this.inherited(arguments, true); // | // ... // | if(!super){ // | console.log("there is no super method"); // | return 0; // | } // | return super.apply(this, arguments); // | } // | }); // example: // | "use strict"; // | // class is defined in strict-mode code, // | // so caller must be passed before arguments. // | var B = declare(A, { // | // using a named function expression with "fn" as the name. // | method: function fn(a, b) { // | this.inherited(fn, arguments); // | } // | }); return {}; // Object }, getInherited: function(name, caller, args){ // summary: // Returns a super method. // name: String? // The optional method name. Should be the same as the caller's // name. Usually "name" is specified in complex dynamic cases, when // the calling method was dynamically added, undecorated by // declare(), and it cannot be determined. // caller: Function? // The caller function. This is required when running in // strict-mode code. A reference to the caller function // can be obtained by using a named function expression // (e.g. function fn(a,b) {...}). // args: Arguments // The caller supply this argument, which should be the original // "arguments". // returns: // Returns a super method (Function) or "undefined". // description: // This method is a convenience method for "this.inherited()". // It uses the same algorithm but instead of executing a super // method, it returns it, or "undefined" if not found. // // example: // | var B = declare(A, { // | method: function(a, b){ // | var super = this.getInherited(arguments); // | // ... // | if(!super){ // | console.log("there is no super method"); // | return 0; // | } // | return super.apply(this, arguments); // | } // | }); // example: // | "use strict;" // first line of function or file // | //... // | var B = declare(A, { // | // Using a named function expression with "fn" as the name, // | // since we're in strict mode. // | method: function fn(a, b){ // | var super = this.getInherited(fn, arguments); // | if(super){ // | return super.apply(this, arguments); // | } // | } // | }); return {}; // Object }, isInstanceOf: function(cls){ // summary: // Checks the inheritance chain to see if it is inherited from this // class. // cls: Function // Class constructor. // returns: // "true", if this object is inherited from this class, "false" // otherwise. // description: // This method is used with instances of classes produced with // declare() to determine of they support a certain interface or // not. It models "instanceof" operator. // // example: // | var A = declare(null, { // | // constructor, properties, and methods go here // | // ... // | }); // | var B = declare(null, { // | // constructor, properties, and methods go here // | // ... // | }); // | var C = declare([A, B], { // | // constructor, properties, and methods go here // | // ... // | }); // | var D = declare(A, { // | // constructor, properties, and methods go here // | // ... // | }); // | // | var a = new A(), b = new B(), c = new C(), d = new D(); // | // | console.log(a.isInstanceOf(A)); // true // | console.log(b.isInstanceOf(A)); // false // | console.log(c.isInstanceOf(A)); // true // | console.log(d.isInstanceOf(A)); // true // | // | console.log(a.isInstanceOf(B)); // false // | console.log(b.isInstanceOf(B)); // true // | console.log(c.isInstanceOf(B)); // true // | console.log(d.isInstanceOf(B)); // false // | // | console.log(a.isInstanceOf(C)); // false // | console.log(b.isInstanceOf(C)); // false // | console.log(c.isInstanceOf(C)); // true // | console.log(d.isInstanceOf(C)); // false // | // | console.log(a.isInstanceOf(D)); // false // | console.log(b.isInstanceOf(D)); // false // | console.log(c.isInstanceOf(D)); // false // | console.log(d.isInstanceOf(D)); // true return {}; // Object }, extend: function(source){ // summary: // Adds all properties and methods of source to constructor's // prototype, making them available to all instances created with // constructor. This method is specific to constructors created with // declare(). // source: Object // Source object which properties are going to be copied to the // constructor's prototype. // description: // Adds source properties to the constructor's prototype. It can // override existing properties. // // This method is similar to dojo.extend function, but it is specific // to constructors produced by declare(). It is implemented // using dojo.safeMixin, and it skips a constructor property, // and properly decorates copied functions. // // example: // | var A = declare(null, { // | m1: function(){}, // | s1: "Popokatepetl" // | }); // | A.extend({ // | m1: function(){}, // | m2: function(){}, // | f1: true, // | d1: 42 // | }); }, createSubclass: function(mixins, props){ // summary: // Create a subclass of the declared class from a list of base classes. // mixins: Function[] // Specifies a list of bases (the left-most one is the most deepest // base). // props: Object? // An optional object whose properties are copied to the created prototype. // returns: dojo/_base/declare.__DeclareCreatedObject // New constructor function. // description: // Create a constructor using a compact notation for inheritance and // prototype extension. // // 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. // // example: // | var A = declare(null, { // | m1: function(){}, // | s1: "bar" // | }); // | var B = declare(null, { // | m2: function(){}, // | s2: "foo" // | }); // | var C = declare(null, { // | }); // | var D1 = A.createSubclass([B, C], { // | m1: function(){}, // | d1: 42 // | }); // | var d1 = new D1(); // | // | // this is equivalent to: // | var D2 = declare([A, B, C], { // | m1: function(){}, // | d1: 42 // | }); // | var d2 = new D2(); } }; =====*/ // For back-compat, remove for 2.0 dojo.safeMixin = declare.safeMixin = safeMixin; dojo.declare = declare; return declare; }); }, 'dojo/_base/connect':function(){ define(["./kernel", "../on", "../topic", "../aspect", "./event", "../mouse", "./sniff", "./lang", "../keys"], function(dojo, on, hub, aspect, eventModule, mouse, has, lang){ // module: // dojo/_base/connect has.add("events-keypress-typed", function(){ // keypresses should only occur a printable character is hit var testKeyEvent = {charCode: 0}; try{ testKeyEvent = document.createEvent("KeyboardEvent"); (testKeyEvent.initKeyboardEvent || testKeyEvent.initKeyEvent).call(testKeyEvent, "keypress", true, true, null, false, false, false, false, 9, 3); }catch(e){} return testKeyEvent.charCode == 0 && !has("opera"); }); function connect_(obj, event, context, method, dontFix){ method = lang.hitch(context, method); if(!obj || !(obj.addEventListener || obj.attachEvent)){ // it is a not a DOM node and we are using the dojo.connect style of treating a // method like an event, must go right to aspect return aspect.after(obj || dojo.global, event, method, true); } if(typeof event == "string" && event.substring(0, 2) == "on"){ event = event.substring(2); } if(!obj){ obj = dojo.global; } if(!dontFix){ switch(event){ // dojo.connect has special handling for these event types case "keypress": event = keypress; break; case "mouseenter": event = mouse.enter; break; case "mouseleave": event = mouse.leave; break; } } return on(obj, event, method, dontFix); } var _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, 229:113 }; var evtCopyKey = has("mac") ? "metaKey" : "ctrlKey"; var _synthesizeEvent = function(evt, props){ var faux = lang.mixin({}, evt, props); setKeyChar(faux); // FIXME: would prefer to use lang.hitch: lang.hitch(evt, evt.preventDefault); // but it throws an error when preventDefault is invoked on Safari // does Event.preventDefault not support "apply" on Safari? faux.preventDefault = function(){ evt.preventDefault(); }; faux.stopPropagation = function(){ evt.stopPropagation(); }; return faux; }; function setKeyChar(evt){ evt.keyChar = evt.charCode ? String.fromCharCode(evt.charCode) : ''; evt.charOrCode = evt.keyChar || evt.keyCode; } var keypress; if(has("events-keypress-typed")){ // this emulates Firefox's keypress behavior where every keydown can correspond to a keypress 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; } }; keypress = function(object, listener){ var keydownSignal = on(object, "keydown", function(evt){ // 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||!has("ie")) && (k<48||k>90) && (k<96||k>111) && (k<186||k>192) && (k<219||k>222) && k!=229; // 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 listener.call(evt.currentTarget, evt); // 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 = _punctMap[c] || c; // map other problematic CTRL combinations to ASCII } } // simulate a keypress event var faux = _synthesizeEvent(evt, {type: 'keypress', faux: true, charCode: c}); listener.call(evt.currentTarget, faux); if(has("ie")){ _trySetKeyCode(evt, faux.keyCode); } } }); var keypressSignal = on(object, "keypress", function(evt){ var c = evt.charCode; c = c>=32 ? c : 0; evt = _synthesizeEvent(evt, {charCode: c, faux: true}); return listener.call(this, evt); }); return { remove: function(){ keydownSignal.remove(); keypressSignal.remove(); } }; }; }else{ if(has("opera")){ keypress = function(object, listener){ return on(object, "keypress", function(evt){ var c = evt.which; if(c==3){ c=99; // Mozilla maps CTRL-BREAK to CTRL-c } // can't trap some keys at all, like INSERT and DELETE // there is no differentiating info between DELETE and ".", or INSERT and "-" c = c<32 && !evt.shiftKey ? 0 : c; if(evt.ctrlKey && !evt.shiftKey && c>=65 && c<=90){ // lowercase CTRL-[A-Z] keys c += 32; } return listener.call(this, _synthesizeEvent(evt, { charCode: c })); }); }; }else{ keypress = function(object, listener){ return on(object, "keypress", function(evt){ setKeyChar(evt); return listener.call(this, evt); }); }; } } var connect = { // summary: // This module defines the dojo.connect API. // This modules also provides keyboard event handling helpers. // This module exports an extension event for emulating Firefox's keypress handling. // However, this extension event exists primarily for backwards compatibility and // is not recommended. WebKit and IE uses an alternate keypress handling (only // firing for printable characters, to distinguish from keydown events), and most // consider the WebKit/IE behavior more desirable. _keypress:keypress, connect:function(obj, event, context, method, dontFix){ // summary: // `dojo.connect` is a deprecated event handling and delegation method in // Dojo. It allows one function to "listen in" on the execution of // any other, triggering the second whenever the first is called. Many // listeners may be attached to a function, and source functions may // be either regular function calls or DOM events. // // description: // Connects listeners to actions, so that after event fires, a // listener is called with the same arguments passed to the original // function. // // Since `dojo.connect` allows the source of events to be either a // "regular" JavaScript function or a DOM event, it provides a uniform // interface for listening to all the types of events that an // application is likely to deal with though a single, unified // interface. DOM programmers may want to think of it as // "addEventListener for everything and anything". // // When setting up a connection, the `event` parameter must be a // string that is the name of the method/event to be listened for. If // `obj` is null, `kernel.global` is assumed, meaning that connections // to global methods are supported but also that you may inadvertently // connect to a global by passing an incorrect object name or invalid // reference. // // `dojo.connect` generally is forgiving. If you pass the name of a // function or method that does not yet exist on `obj`, connect will // not fail, but will instead set up a stub method. Similarly, null // arguments may simply be omitted such that fewer than 4 arguments // may be required to set up a connection See the examples for details. // // The return value is a handle that is needed to // remove this connection with `dojo.disconnect`. // // obj: Object? // The source object for the event function. // Defaults to `kernel.global` if null. // If obj is a DOM node, the connection is delegated // to the DOM event manager (unless dontFix is true). // // event: String // String name of the event function in obj. // I.e. identifies a property `obj[event]`. // // context: Object|null // 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, // kernel.global is used. // // method: String|Function // 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: Boolean? // 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 omitted args.push(typeof a[0] == "string" ? 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(typeof a1 == "string" || typeof a1 == "function" ? a[i++] : null, a[i++]); // absorb any additional arguments for(var l=a.length; i= 0){ s.width = w + u; } if(h >= 0){ s.height = h + u; } } function isButtonTag(/*DomNode*/ node){ // summary: // True if the node is BUTTON or INPUT.type="button". return node.tagName.toLowerCase() == "button" || node.tagName.toLowerCase() == "input" && (node.getAttribute("type") || "").toLowerCase() == "button"; // boolean } function usesBorderBox(/*DomNode*/ node){ // summary: // True if the node uses border-box layout. // We could test the computed style of node to see if a particular box // has been specified, but there are details and we choose not to bother. // TABLE and BUTTON (and INPUT type=button) are always border-box by default. // If you have assigned a different box to either one via CSS then // box functions will break. return geom.boxModel == "border-box" || node.tagName.toLowerCase() == "table" || isButtonTag(node); // boolean } function getBoundingClientRect(/*DomNode*/ node) { // summary: // Gets the bounding client rectangle for a dom node. // node: DOMNode // This will return the result of node.getBoundingClientRect if node is in the dom, and // {x:0, y:0, width:0, height:0, top:0, right:0, bottom:0, left:0} if it throws an error or the node is not on the dom // This will handle when IE throws an error or Edge returns an empty object when node is not on the dom var retEmpty = { x: 0, y: 0, width: 0, height: 0, top: 0, right: 0, bottom: 0, left: 0 }, ret; try { ret = node.getBoundingClientRect(); } catch (e) { // IE throws an Unspecified Error if the node is not in the dom. Handle this by returning an object with 0 values return retEmpty; } // Edge returns an empty object if the node is not in the dom. Handle this by returning an object with 0 values if (typeof ret.left === "undefined") { return retEmpty; } return ret; } geom.setContentSize = function setContentSize(/*DomNode*/ node, /*Object*/ box, /*Object*/ computedStyle){ // summary: // Sets the size of the node's contents, irrespective of margins, // padding, or borders. // node: DOMNode // box: Object // hash with optional "w", and "h" properties for "width", and "height" // respectively. All specified properties should have numeric values in whole pixels. // computedStyle: Object? // This parameter accepts computed styles object. // If this parameter is omitted, the functions will call // dojo/dom-style.getComputedStyle to get one. It is a better way, calling // dojo/dom-style.getComputedStyle once, and then pass the reference to this // computedStyle parameter. Wherever possible, reuse the returned // object of dojo/dom-style.getComputedStyle(). node = dom.byId(node); var w = box.w, h = box.h; if(usesBorderBox(node)){ var pb = geom.getPadBorderExtents(node, computedStyle); if(w >= 0){ w += pb.w; } if(h >= 0){ h += pb.h; } } setBox(node, NaN, NaN, w, h); }; var nilExtents = {l: 0, t: 0, w: 0, h: 0}; geom.setMarginBox = function setMarginBox(/*DomNode*/ node, /*Object*/ box, /*Object*/ computedStyle){ // summary: // sets the size of the node's margin box and placement // (left/top), irrespective of box model. Think of it as a // passthrough to setBox that handles box-model vagaries for // you. // node: DOMNode // box: Object // hash with optional "l", "t", "w", and "h" properties for "left", "right", "width", and "height" // respectively. All specified properties should have numeric values in whole pixels. // computedStyle: Object? // This parameter accepts computed styles object. // If this parameter is omitted, the functions will call // dojo/dom-style.getComputedStyle to get one. It is a better way, calling // dojo/dom-style.getComputedStyle once, and then pass the reference to this // computedStyle parameter. Wherever possible, reuse the returned // object of dojo/dom-style.getComputedStyle(). node = dom.byId(node); var s = computedStyle || style.getComputedStyle(node), w = box.w, h = box.h, // Some elements have special padding, margin, and box-model settings. // To use box functions you may need to set padding, margin explicitly. // Controlling box-model is harder, in a pinch you might set dojo/dom-geometry.boxModel. pb = usesBorderBox(node) ? nilExtents : geom.getPadBorderExtents(node, s), mb = geom.getMarginExtents(node, s); if(has("webkit")){ // on Safari (3.1.2), button nodes with no explicit size have a default margin // setting an explicit size eliminates the margin. // We have to swizzle the width to get correct margin reading. if(isButtonTag(node)){ var ns = node.style; if(w >= 0 && !ns.width){ ns.width = "4px"; } if(h >= 0 && !ns.height){ ns.height = "4px"; } } } if(w >= 0){ w = Math.max(w - pb.w - mb.w, 0); } if(h >= 0){ h = Math.max(h - pb.h - mb.h, 0); } setBox(node, box.l, box.t, w, h); }; // ============================= // Positioning // ============================= geom.isBodyLtr = function isBodyLtr(/*Document?*/ doc){ // summary: // Returns true if the current language is left-to-right, and false otherwise. // doc: Document? // Optional document to query. If unspecified, use win.doc. // returns: Boolean doc = doc || win.doc; return (win.body(doc).dir || doc.documentElement.dir || "ltr").toLowerCase() == "ltr"; // Boolean }; geom.docScroll = function docScroll(/*Document?*/ doc){ // summary: // Returns an object with {node, x, y} with corresponding offsets. // doc: Document? // Optional document to query. If unspecified, use win.doc. // returns: Object doc = doc || win.doc; var node = doc.parentWindow || doc.defaultView; // use UI window, not dojo.global window. TODO: use dojo/window::get() except for circular dependency problem return "pageXOffset" in node ? {x: node.pageXOffset, y: node.pageYOffset } : (node = has("quirks") ? win.body(doc) : doc.documentElement) && {x: geom.fixIeBiDiScrollLeft(node.scrollLeft || 0, doc), y: node.scrollTop || 0 }; }; geom.getIeDocumentElementOffset = function(/*Document?*/ doc){ // summary: // Deprecated method previously used for IE6-IE7. Now, just returns `{x:0, y:0}`. return { x: 0, y: 0 }; }; geom.fixIeBiDiScrollLeft = function fixIeBiDiScrollLeft(/*Integer*/ scrollLeft, /*Document?*/ doc){ // summary: // In RTL direction, scrollLeft should be a negative value, but IE // returns a positive one. All codes using documentElement.scrollLeft // must call this function to fix this error, otherwise the position // will offset to right when there is a horizontal scrollbar. // scrollLeft: Number // doc: Document? // Optional document to query. If unspecified, use win.doc. // returns: Number // In RTL direction, scrollLeft should be a negative value, but IE // returns a positive one. All codes using documentElement.scrollLeft // must call this function to fix this error, otherwise the position // will offset to right when there is a horizontal scrollbar. doc = doc || win.doc; var ie = has("ie"); if(ie && !geom.isBodyLtr(doc)){ var qk = has("quirks"), de = qk ? win.body(doc) : doc.documentElement, pwin = win.global; // TODO: use winUtils.get(doc) after resolving circular dependency b/w dom-geometry.js and dojo/window.js if(ie == 6 && !qk && pwin.frameElement && de.scrollHeight > de.clientHeight){ scrollLeft += de.clientLeft; // workaround ie6+strict+rtl+iframe+vertical-scrollbar bug where clientWidth is too small by clientLeft pixels } return (ie < 8 || qk) ? (scrollLeft + de.clientWidth - de.scrollWidth) : -scrollLeft; // Integer } return scrollLeft; // Integer }; geom.position = function(/*DomNode*/ node, /*Boolean?*/ includeScroll){ // summary: // Gets the position and size of the passed element relative to // the viewport (if includeScroll==false), or relative to the // document root (if includeScroll==true). // // description: // Returns an object of the form: // `{ x: 100, y: 300, w: 20, h: 15 }`. // If includeScroll==true, the x and y values will include any // document offsets that may affect the position relative to the // viewport. // Uses the border-box model (inclusive of border and padding but // not margin). Does not act as a setter. // node: DOMNode|String // includeScroll: Boolean? // returns: Object node = dom.byId(node); var db = win.body(node.ownerDocument), ret= getBoundingClientRect(node); ret = {x: ret.left, y: ret.top, w: ret.right - ret.left, h: ret.bottom - ret.top}; if(has("ie") < 9){ // fixes the position in IE, quirks mode ret.x -= (has("quirks") ? db.clientLeft + db.offsetLeft : 0); ret.y -= (has("quirks") ? db.clientTop + db.offsetTop : 0); } // account for document scrolling // if offsetParent is used, ret value already includes scroll position // so we may have to actually remove that value if !includeScroll if(includeScroll){ var scroll = geom.docScroll(node.ownerDocument); ret.x += scroll.x; ret.y += scroll.y; } return ret; // Object }; // random "private" functions wildly used throughout the toolkit geom.getMarginSize = function getMarginSize(/*DomNode*/ node, /*Object*/ computedStyle){ // summary: // returns an object that encodes the width and height of // the node's margin box // node: DOMNode|String // computedStyle: Object? // This parameter accepts computed styles object. // If this parameter is omitted, the functions will call // dojo/dom-style.getComputedStyle to get one. It is a better way, calling // dojo/dom-style.getComputedStyle once, and then pass the reference to this // computedStyle parameter. Wherever possible, reuse the returned // object of dojo/dom-style.getComputedStyle(). node = dom.byId(node); var me = geom.getMarginExtents(node, computedStyle || style.getComputedStyle(node)); var size = getBoundingClientRect(node); return { w: (size.right - size.left) + me.w, h: (size.bottom - size.top) + me.h }; }; geom.normalizeEvent = function(event){ // summary: // Normalizes the geometry of a DOM event, normalizing the pageX, pageY, // offsetX, offsetY, layerX, and layerX properties // event: Object if(!("layerX" in event)){ event.layerX = event.offsetX; event.layerY = event.offsetY; } if(!("pageX" in event)){ // FIXME: scroll position query is duped from dojo/_base/html to // avoid dependency on that entire module. Now that HTML is in // Base, we should convert back to something similar there. var se = event.target; var doc = (se && se.ownerDocument) || document; // DO NOT replace the following to use dojo/_base/window.body(), in IE, document.documentElement should be used // here rather than document.body var docBody = has("quirks") ? doc.body : doc.documentElement; event.pageX = event.clientX + geom.fixIeBiDiScrollLeft(docBody.scrollLeft || 0, doc); event.pageY = event.clientY + (docBody.scrollTop || 0); } }; // TODO: evaluate separate getters/setters for position and sizes? return geom; }); }, 'dojo/dom-style':function(){ define(["./sniff", "./dom", "./_base/window"], function(has, dom, win){ // module: // dojo/dom-style // ============================= // Style Functions // ============================= // getComputedStyle drives most of the style code. // Wherever possible, reuse the returned object. // // API functions below that need to access computed styles accept an // optional computedStyle parameter. // If this parameter is omitted, the functions will call getComputedStyle themselves. // This way, calling code can access computedStyle once, and then pass the reference to // multiple API functions. // Although we normally eschew argument validation at this // level, here we test argument 'node' for (duck)type, // by testing nodeType, ecause 'document' is the 'parentNode' of 'body' // it is frequently sent to this function even // though it is not Element. var getComputedStyle, style = { // summary: // This module defines the core dojo DOM style API. }; if(has("webkit")){ getComputedStyle = function(/*DomNode*/ node){ var s; if(node.nodeType == 1){ var dv = node.ownerDocument.defaultView; s = dv.getComputedStyle(node, null); if(!s && node.style){ node.style.display = ""; s = dv.getComputedStyle(node, null); } } return s || {}; }; }else if(has("ie") && (has("ie") < 9 || has("quirks"))){ getComputedStyle = function(node){ // IE (as of 7) doesn't expose Element like sane browsers // currentStyle can be null on IE8! return node.nodeType == 1 /* ELEMENT_NODE*/ && node.currentStyle ? node.currentStyle : {}; }; }else{ getComputedStyle = function(node){ if(node.nodeType === 1 /* ELEMENT_NODE*/){ var dv = node.ownerDocument.defaultView, w = dv.opener ? dv : win.global.window; return w.getComputedStyle(node, null); } return {}; }; } style.getComputedStyle = getComputedStyle; /*===== style.getComputedStyle = function(node){ // summary: // Returns a "computed style" object. // // description: // Gets a "computed style" object which can be used to gather // information about the current state of the rendered node. // // Note that this may behave differently on different browsers. // Values may have different formats and value encodings across // browsers. // // Note also that this method is expensive. Wherever possible, // reuse the returned object. // // Use the dojo/dom-style.get() method for more consistent (pixelized) // return values. // // node: DOMNode // A reference to a DOM node. Does NOT support taking an // ID string for speed reasons. // example: // | require(["dojo/dom-style", "dojo/dom"], function(domStyle, dom){ // | domStyle.getComputedStyle(dom.byId('foo')).borderWidth; // | }); // // example: // Reusing the returned object, avoiding multiple lookups: // | require(["dojo/dom-style", "dojo/dom"], function(domStyle, dom){ // | var cs = domStyle.getComputedStyle(dom.byId("someNode")); // | var w = cs.width, h = cs.height; // | }); return; // CSS2Properties }; =====*/ var toPixel; if(!has("ie")){ toPixel = function(element, value){ // style values can be floats, client code may want // to round for integer pixels. return parseFloat(value) || 0; }; }else{ toPixel = function(element, avalue){ if(!avalue){ return 0; } // on IE7, medium is usually 4 pixels if(avalue == "medium"){ return 4; } // style values can be floats, client code may // want to round this value for integer pixels. if(avalue.slice && avalue.slice(-2) == 'px'){ return parseFloat(avalue); } var s = element.style, rs = element.runtimeStyle, cs = element.currentStyle, sLeft = s.left, rsLeft = rs.left; rs.left = cs.left; try{ // 'avalue' may be incompatible with style.left, which can cause IE to throw // this has been observed for border widths using "thin", "medium", "thick" constants // those particular constants could be trapped by a lookup // but perhaps there are more s.left = avalue; avalue = s.pixelLeft; }catch(e){ avalue = 0; } s.left = sLeft; rs.left = rsLeft; return avalue; }; } style.toPixelValue = toPixel; /*===== style.toPixelValue = function(node, value){ // summary: // converts style value to pixels on IE or return a numeric value. // node: DOMNode // value: String // returns: Number }; =====*/ // FIXME: there opacity quirks on FF that we haven't ported over. Hrm. var astr = "DXImageTransform.Microsoft.Alpha"; var af = function(n, f){ try{ return n.filters.item(astr); }catch(e){ return f ? {} : null; } }; var _getOpacity = has("ie") < 9 || (has("ie") < 10 && has("quirks")) ? function(node){ try{ return af(node).Opacity / 100; // Number }catch(e){ return 1; // Number } } : function(node){ return getComputedStyle(node).opacity; }; var _setOpacity = has("ie") < 9 || (has("ie") < 10 && has("quirks")) ? function(/*DomNode*/ node, /*Number*/ opacity){ if(opacity === ""){ opacity = 1; } var ov = opacity * 100, fullyOpaque = opacity === 1; // on IE7 Alpha(Filter opacity=100) makes text look fuzzy so disable it altogether (bug #2661), // but still update the opacity value so we can get a correct reading if it is read later: // af(node, 1).Enabled = !fullyOpaque; if(fullyOpaque){ node.style.zoom = ""; if(af(node)){ node.style.filter = node.style.filter.replace( new RegExp("\\s*progid:" + astr + "\\([^\\)]+?\\)", "i"), ""); } }else{ node.style.zoom = 1; if(af(node)){ af(node, 1).Opacity = ov; }else{ node.style.filter += " progid:" + astr + "(Opacity=" + ov + ")"; } af(node, 1).Enabled = true; } if(node.tagName.toLowerCase() == "tr"){ for(var td = node.firstChild; td; td = td.nextSibling){ if(td.tagName.toLowerCase() == "td"){ _setOpacity(td, opacity); } } } return opacity; } : function(node, opacity){ return node.style.opacity = opacity; }; var _pixelNamesCache = { left: true, top: true }; var _pixelRegExp = /margin|padding|width|height|max|min|offset/; // |border function _toStyleValue(node, type, value){ //TODO: should we really be doing string case conversion here? Should we cache it? Need to profile! type = type.toLowerCase(); // Adjustments for IE and Edge if(value == "auto"){ if(type == "height"){ return node.offsetHeight; } if(type == "width"){ return node.offsetWidth; } } if(type == "fontweight"){ switch(value){ case 700: return "bold"; case 400: default: return "normal"; } } if(!(type in _pixelNamesCache)){ _pixelNamesCache[type] = _pixelRegExp.test(type); } return _pixelNamesCache[type] ? toPixel(node, value) : value; } var _floatAliases = {cssFloat: 1, styleFloat: 1, "float": 1}; // public API style.get = function getStyle(/*DOMNode|String*/ node, /*String?*/ name){ // summary: // Accesses styles on a node. // description: // Getting the style value uses the computed style for the node, so the value // will be a calculated value, not just the immediate node.style value. // Also when getting values, use specific style names, // like "borderBottomWidth" instead of "border" since compound values like // "border" are not necessarily reflected as expected. // If you want to get node dimensions, use `dojo/dom-geometry.getMarginBox()`, // `dojo/dom-geometry.getContentBox()` or `dojo/dom-geometry.getPosition()`. // node: DOMNode|String // id or reference to node to get style for // name: String? // the style property to get // example: // Passing only an ID or node returns the computed style object of // the node: // | require(["dojo/dom-style", "dojo/dom"], function(domStyle, dom){ // | domStyle.get("thinger"); // | }); // example: // Passing a node and a style property returns the current // normalized, computed value for that property: // | require(["dojo/dom-style", "dojo/dom"], function(domStyle, dom){ // | domStyle.get("thinger", "opacity"); // 1 by default // | }); var n = dom.byId(node), l = arguments.length, op = (name == "opacity"); if(l == 2 && op){ return _getOpacity(n); } name = _floatAliases[name] ? "cssFloat" in n.style ? "cssFloat" : "styleFloat" : name; var s = style.getComputedStyle(n); return (l == 1) ? s : _toStyleValue(n, name, s[name] || n.style[name]); /* CSS2Properties||String||Number */ }; style.set = function setStyle(/*DOMNode|String*/ node, /*String|Object*/ name, /*String?*/ value){ // summary: // Sets styles on a node. // node: DOMNode|String // id or reference to node to set style for // name: String|Object // the style property to set in DOM-accessor format // ("borderWidth", not "border-width") or an object with key/value // pairs suitable for setting each property. // value: String? // If passed, sets value on the node for style, handling // cross-browser concerns. When setting a pixel value, // be sure to include "px" in the value. For instance, top: "200px". // Otherwise, in some cases, some browsers will not apply the style. // // example: // Passing a node, a style property, and a value changes the // current display of the node and returns the new computed value // | require(["dojo/dom-style"], function(domStyle){ // | domStyle.set("thinger", "opacity", 0.5); // == 0.5 // | }); // // example: // Passing a node, an object-style style property sets each of the values in turn and returns the computed style object of the node: // | require(["dojo/dom-style"], function(domStyle){ // | domStyle.set("thinger", { // | "opacity": 0.5, // | "border": "3px solid black", // | "height": "300px" // | }); // | }); // // example: // When the CSS style property is hyphenated, the JavaScript property is camelCased. // font-size becomes fontSize, and so on. // | require(["dojo/dom-style", "dojo/dom"], function(domStyle, dom){ // | domStyle.set("thinger",{ // | fontSize:"14pt", // | letterSpacing:"1.2em" // | }); // | }); // // example: // dojo/NodeList implements .style() using the same syntax, omitting the "node" parameter, calling // dojo/dom-style.get() on every element of the list. See: `dojo/query` and `dojo/NodeList` // | require(["dojo/dom-style", "dojo/query", "dojo/NodeList-dom"], // | function(domStyle, query){ // | query(".someClassName").style("visibility","hidden"); // | // or // | query("#baz > div").style({ // | opacity:0.75, // | fontSize:"13pt" // | }); // | }); var n = dom.byId(node), l = arguments.length, op = (name == "opacity"); name = _floatAliases[name] ? "cssFloat" in n.style ? "cssFloat" : "styleFloat" : name; if(l == 3){ return op ? _setOpacity(n, value) : n.style[name] = value; // Number } for(var x in name){ style.set(node, x, name[x]); } return style.getComputedStyle(n); }; return style; }); }, 'dojo/mouse':function(){ define(["./_base/kernel", "./on", "./has", "./dom", "./_base/window"], function(dojo, on, has, dom, win){ // module: // dojo/mouse has.add("dom-quirks", win.doc && win.doc.compatMode == "BackCompat"); has.add("events-mouseenter", win.doc && "onmouseenter" in win.doc.createElement("div")); has.add("events-mousewheel", win.doc && 'onmousewheel' in win.doc); var mouseButtons; if((has("dom-quirks") && has("ie")) || !has("dom-addeventlistener")){ mouseButtons = { LEFT: 1, MIDDLE: 4, RIGHT: 2, // helper functions isButton: function(e, button){ return e.button & button; }, isLeft: function(e){ return e.button & 1; }, isMiddle: function(e){ return e.button & 4; }, isRight: function(e){ return e.button & 2; } }; }else{ mouseButtons = { LEFT: 0, MIDDLE: 1, RIGHT: 2, // helper functions isButton: function(e, button){ return e.button == button; }, isLeft: function(e){ return e.button == 0; }, isMiddle: function(e){ return e.button == 1; }, isRight: function(e){ return e.button == 2; } }; } dojo.mouseButtons = mouseButtons; /*===== dojo.mouseButtons = { // LEFT: Number // Numeric value of the left mouse button for the platform. LEFT: 0, // MIDDLE: Number // Numeric value of the middle mouse button for the platform. MIDDLE: 1, // RIGHT: Number // Numeric value of the right mouse button for the platform. RIGHT: 2, isButton: function(e, button){ // summary: // Checks an event object for a pressed button // e: Event // Event object to examine // button: Number // The button value (example: dojo.mouseButton.LEFT) return e.button == button; // Boolean }, isLeft: function(e){ // summary: // Checks an event object for the pressed left button // e: Event // Event object to examine return e.button == 0; // Boolean }, isMiddle: function(e){ // summary: // Checks an event object for the pressed middle button // e: Event // Event object to examine return e.button == 1; // Boolean }, isRight: function(e){ // summary: // Checks an event object for the pressed right button // e: Event // Event object to examine return e.button == 2; // Boolean } }; =====*/ function eventHandler(type, selectHandler){ // emulation of mouseenter/leave with mouseover/out using descendant checking var handler = function(node, listener){ return on(node, type, function(evt){ if(selectHandler){ return selectHandler(evt, listener); } if(!dom.isDescendant(evt.relatedTarget, node)){ return listener.call(this, evt); } }); }; handler.bubble = function(select){ return eventHandler(type, function(evt, listener){ // using a selector, use the select function to determine if the mouse moved inside the selector and was previously outside the selector var target = select(evt.target); var relatedTarget = evt.relatedTarget; if(target && (target != (relatedTarget && relatedTarget.nodeType == 1 && select(relatedTarget)))){ return listener.call(target, evt); } }); }; return handler; } var wheel; if(has("events-mousewheel")){ wheel = 'mousewheel'; }else{ //firefox wheel = function(node, listener){ return on(node, 'DOMMouseScroll', function(evt){ evt.wheelDelta = -evt.detail; listener.call(this, evt); }); }; } return { // summary: // This module provide mouse event handling utility functions and exports // mouseenter and mouseleave event emulation. // example: // To use these events, you register a mouseenter like this: // | define(["dojo/on", "dojo/mouse"], function(on, mouse){ // | on(targetNode, mouse.enter, function(event){ // | dojo.addClass(targetNode, "highlighted"); // | }); // | on(targetNode, mouse.leave, function(event){ // | dojo.removeClass(targetNode, "highlighted"); // | }); _eventHandler: eventHandler, // for dojo/touch // enter: Synthetic Event // This is an extension event for the mouseenter that IE provides, emulating the // behavior on other browsers. enter: eventHandler("mouseover"), // leave: Synthetic Event // This is an extension event for the mouseleave that IE provides, emulating the // behavior on other browsers. leave: eventHandler("mouseout"), // wheel: Normalized Mouse Wheel Event // This is an extension event for the mousewheel that non-Mozilla browsers provide, // emulating the behavior on Mozilla based browsers. wheel: wheel, isLeft: mouseButtons.isLeft, /*===== isLeft: function(){ // summary: // Test an event object (from a mousedown event) to see if the left button was pressed. }, =====*/ isMiddle: mouseButtons.isMiddle, /*===== isMiddle: function(){ // summary: // Test an event object (from a mousedown event) to see if the middle button was pressed. }, =====*/ isRight: mouseButtons.isRight /*===== , isRight: function(){ // summary: // Test an event object (from a mousedown event) to see if the right button was pressed. } =====*/ }; }); }, 'dojo/keys':function(){ define(["./_base/kernel", "./sniff"], function(dojo, has){ // module: // dojo/keys return dojo.keys = { // summary: // Definitions for common key values. Client code should test keyCode against these named constants, // as the actual codes can vary by browser. BACKSPACE: 8, TAB: 9, CLEAR: 12, ENTER: 13, SHIFT: 16, CTRL: 17, ALT: 18, META: has("webkit") ? 91 : 224, // the apple key on macs 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, UP_DPAD: 175, DOWN_DPAD: 176, LEFT_DPAD: 177, RIGHT_DPAD: 178, // virtual key mapping copyKey: has("mac") && !has("air") ? (has("safari") ? 91 : 224 ) : 17 }; }); }, 'dojo/_base/Color':function(){ define(["./kernel", "./lang", "./array", "./config"], function(dojo, lang, ArrayUtil, config){ var 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 `Color` object // and creates a new Color instance to work from. // // example: // Work with a Color instance: // | require(["dojo/_base/color"], function(Color){ // | var c = new Color(); // | c.setColor([0,0,0]); // black // | var hex = c.toHex(); // #000000 // | }); // // example: // Work with a node's color: // | // | require(["dojo/_base/color", "dojo/dom-style"], function(Color, domStyle){ // | var color = domStyle("someNode", "backgroundColor"); // | var n = new Color(color); // | // adjust the color some // | n.r *= .5; // | console.log(n.toString()); // rgb(128, 255, 255); // | }); if(color){ this.setColor(color); } }; // FIXME: // there's got to be a more space-efficient way to encode or discover // these!! Use hex? Color.named = { // summary: // Dictionary list of all CSS named colors, by name. Values are 3-item arrays with corresponding RG and B values. "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], "transparent": config.transparentColor || [0,0,0,0] }; lang.extend(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 `Color` object // and sets this color instance to that value. // // example: // | require(["dojo/_base/color"], function(Color){ // | var c = new Color(); // no color // | c.setColor("#ededed"); // greyish // | }); if(lang.isString(color)){ Color.fromString(color, this); }else if(lang.isArray(color)){ Color.fromArray(color, this); }else{ this._set(color.r, color.g, color.b, color.a); if(!(color instanceof Color)){ this.sanitize(); } } return this; // Color }, sanitize: function(){ // summary: // Ensures the object has correct attributes // description: // the default implementation does nothing, include dojo.colors to // augment it with real checks return this; // Color }, toRgb: function(){ // summary: // Returns 3 component array of rgb values // example: // | require(["dojo/_base/color"], function(Color){ // | var c = new Color("#000000"); // | console.log(c.toRgb()); // [0,0,0] // | }); var t = this; return [t.r, t.g, t.b]; // Array }, toRgba: function(){ // summary: // Returns a 4 component array of rgba values from the color // represented by this object. var t = this; return [t.r, t.g, t.b, t.a]; // Array }, toHex: function(){ // summary: // Returns a CSS color string in hexadecimal representation // example: // | require(["dojo/_base/color"], function(Color){ // | console.log(new Color([0,0,0]).toHex()); // #000000 // | }); var arr = ArrayUtil.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 // example: // | require(["dojo/_base/color"], function(Color){ // | var c = new Color("#FFF").toCss(); // | console.log(c); // rgb('255','255','255') // | }); 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 } }); Color.blendColors = dojo.blendColors = function( /*Color*/ start, /*Color*/ end, /*Number*/ weight, /*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 Color object for the result var t = obj || new Color(); t.r = Math.round(start.r + (end.r - start.r) * weight); t.g = Math.round(start.g + (end.g - start.g) * weight); t.b = Math.round(start.b + (end.b - start.b) * weight); t.a = start.a + (end.a - start.a) * weight; return t.sanitize(); // Color }; Color.fromRgb = dojo.colorFromRgb = function(/*String*/ color, /*Color?*/ obj){ // summary: // Returns a `Color` instance from a string of the form // "rgb(...)" or "rgba(...)". Optionally accepts a `Color` // object to update with the parsed value and return instead of // creating a new object. // returns: // A Color object. If obj is passed, it will be the return value. var m = color.toLowerCase().match(/^rgba?\(([\s\.,0-9]+)\)/); return m && Color.fromArray(m[1].split(/\s*,\s*/), obj); // Color }; Color.fromHex = dojo.colorFromHex = function(/*String*/ color, /*Color?*/ obj){ // summary: // Converts a hex string with a '#' prefix to a color object. // Supports 12-bit #rgb shorthand. Optionally accepts a // `Color` object to update with the parsed value. // // returns: // A Color object. If obj is passed, it will be the return value. // // example: // | require(["dojo/_base/color"], function(Color){ // | var thing = new Color().fromHex("#ededed"); // grey, longhand // | var thing2 = new Color().fromHex("#000"); // black, shorthand // | }); var t = obj || new Color(), bits = (color.length == 4) ? 4 : 8, mask = (1 << bits) - 1; color = Number("0x" + color.substr(1)); if(isNaN(color)){ return null; // Color } ArrayUtil.forEach(["b", "g", "r"], function(x){ var c = color & mask; color >>= bits; t[x] = bits == 4 ? 17 * c : c; }); t.a = 1; return t; // Color }; Color.fromArray = dojo.colorFromArray = function(/*Array*/ a, /*Color?*/ obj){ // summary: // Builds a `Color` from a 3 or 4 element array, mapping each // element in sequence to the rgb(a) values of the color. // example: // | require(["dojo/_base/color"], function(Color){ // | var myColor = new Color().fromArray([237,237,237,0.5]); // grey, 50% alpha // | }); // returns: // A Color object. If obj is passed, it will be the return value. var t = obj || new 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(); // Color }; Color.fromString = dojo.colorFromString = function(/*String*/ str, /*Color?*/ obj){ // summary: // Parses `str` for a color value. Accepts hex, rgb, and rgba // style color values. // 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 Color object. If obj is passed, it will be the return value. var a = Color.named[str]; return a && Color.fromArray(a, obj) || Color.fromRgb(str, obj) || Color.fromHex(str, obj); // Color }; return Color; }); }, 'dojo/_base/browser':function(){ if(require.has){ require.has.add("config-selectorEngine", "acme"); } define([ "../ready", "./kernel", "./connect", // until we decide if connect is going back into non-browser environments "./unload", "./window", "./event", "./html", "./NodeList", "../query", "./xhr", "./fx"], function(dojo){ // module: // dojo/_base/browser /*===== return { // summary: // This module causes the browser-only base modules to be loaded. }; =====*/ return dojo; }); }, 'dojo/_base/unload':function(){ define(["./kernel", "./lang", "../on"], function(dojo, lang, on){ // module: // dojo/unload var win = window; var unload = { // summary: // This module contains the document and window unload detection API. // This module is deprecated. Use on(window, "unload", func) // and on(window, "beforeunload", func) instead. addOnWindowUnload: function(/*Object|Function?*/ obj, /*String|Function?*/ functionName){ // summary: // Registers a function to be triggered when window.onunload fires. // Deprecated, use on(window, "unload", lang.hitch(obj, functionName)) instead. // description: // The first time that addOnWindowUnload is called Dojo // will register a page listener to trigger your unload // handler with. Note that registering these handlers may // destroy "fastback" page caching in browsers that support // it. Be careful trying to modify the DOM or access // JavaScript properties during this phase of page unloading: // they may not always be available. Consider // addOnUnload() if you need to modify the DOM or do // heavy JavaScript work since it fires at the equivalent of // the page's "onbeforeunload" event. // example: // | var afunc = function() {console.log("global function");}; // | require(["dojo/_base/unload"], function(unload) { // | var foo = {bar: function(){ console.log("bar unloading...");}, // | data: "mydata"}; // | unload.addOnWindowUnload(afunc); // | unload.addOnWindowUnload(foo, "bar"); // | unload.addOnWindowUnload(foo, function(){console.log("", this.data);}); // | }); if (!dojo.windowUnloaded){ on(win, "unload", (dojo.windowUnloaded = function(){ // summary: // signal fired by impending window destruction. You may use // dojo.addOnWindowUnload() to register a listener for this // event. NOTE: if you wish to dojo.connect() to this method // to perform page/application cleanup, be aware that this // event WILL NOT fire if no handler has been registered with // addOnWindowUnload(). This behavior started in Dojo 1.3. // Previous versions always triggered windowUnloaded(). See // addOnWindowUnload for more info. })); } on(win, "unload", lang.hitch(obj, functionName)); }, addOnUnload: function(/*Object?|Function?*/ obj, /*String|Function?*/ functionName){ // summary: // Registers a function to be triggered when the page unloads. // Deprecated, use on(window, "beforeunload", lang.hitch(obj, functionName)) instead. // description: // The first time that addOnUnload is called Dojo will // register a page listener to trigger your unload handler // with. // // In a browser environment, the functions will be triggered // during the window.onbeforeunload event. Be careful of doing // too much work in an unload handler. onbeforeunload can be // triggered if a link to download a file is clicked, or if // the link is a javascript: link. In these cases, the // onbeforeunload event fires, but the document is not // actually destroyed. So be careful about doing destructive // operations in a dojo.addOnUnload callback. // // Further note that calling dojo.addOnUnload will prevent // browsers from using a "fast back" cache to make page // loading via back button instantaneous. // example: // | var afunc = function() {console.log("global function");}; // | require(["dojo/_base/unload"], function(unload) { // | var foo = {bar: function(){ console.log("bar unloading...");}, // | data: "mydata"}; // | unload.addOnUnload(afunc); // | unload.addOnUnload(foo, "bar"); // | unload.addOnUnload(foo, function(){console.log("", this.data);}); // | }); on(win, "beforeunload", lang.hitch(obj, functionName)); } }; dojo.addOnWindowUnload = unload.addOnWindowUnload; dojo.addOnUnload = unload.addOnUnload; return unload; }); }, 'dojo/_base/html':function(){ define(["./kernel", "../dom", "../dom-style", "../dom-attr", "../dom-prop", "../dom-class", "../dom-construct", "../dom-geometry"], function(dojo, dom, style, attr, prop, cls, ctr, geom){ // module: // dojo/dom /*===== return { // summary: // This module is a stub for the core dojo DOM API. }; =====*/ // mix-in dom dojo.byId = dom.byId; dojo.isDescendant = dom.isDescendant; dojo.setSelectable = dom.setSelectable; // mix-in dom-attr dojo.getAttr = attr.get; dojo.setAttr = attr.set; dojo.hasAttr = attr.has; dojo.removeAttr = attr.remove; dojo.getNodeProp = attr.getNodeProp; dojo.attr = function(node, name, value){ // summary: // Gets or sets an attribute on an HTML element. // description: // Handles normalized getting and setting of attributes on DOM // Nodes. If 2 arguments are passed, and a the second argument is a // string, acts as a getter. // // If a third argument is passed, or if the second argument is a // map of attributes, acts as a setter. // // When passing functions as values, note that they will not be // directly assigned to slots on the node, but rather the default // behavior will be removed and the new behavior will be added // using `dojo.connect()`, meaning that event handler properties // will be normalized and that some caveats with regards to // non-standard behaviors for onsubmit apply. Namely that you // should cancel form submission using `dojo.stopEvent()` on the // passed event object instead of returning a boolean value from // the handler itself. // node: DOMNode|String // id or reference to the element to get or set the attribute on // name: String|Object // the name of the attribute to get or set. // value: String? // The value to set for the attribute // returns: // when used as a getter, the value of the requested attribute // or null if that attribute does not have a specified or // default value; // // when used as a setter, the DOM node // // example: // | // get the current value of the "foo" attribute on a node // | dojo.attr(dojo.byId("nodeId"), "foo"); // | // or we can just pass the id: // | dojo.attr("nodeId", "foo"); // // example: // | // use attr() to set the tab index // | dojo.attr("nodeId", "tabIndex", 3); // | // // example: // Set multiple values at once, including event handlers: // | dojo.attr("formId", { // | "foo": "bar", // | "tabIndex": -1, // | "method": "POST", // | "onsubmit": function(e){ // | // stop submitting the form. Note that the IE behavior // | // of returning true or false will have no effect here // | // since our handler is connect()ed to the built-in // | // onsubmit behavior and so we need to use // | // dojo.stopEvent() to ensure that the submission // | // doesn't proceed. // | dojo.stopEvent(e); // | // | // submit the form with Ajax // | dojo.xhrPost({ form: "formId" }); // | } // | }); // // example: // Style is s special case: Only set with an object hash of styles // | dojo.attr("someNode",{ // | id:"bar", // | style:{ // | width:"200px", height:"100px", color:"#000" // | } // | }); // // example: // Again, only set style as an object hash of styles: // | var obj = { color:"#fff", backgroundColor:"#000" }; // | dojo.attr("someNode", "style", obj); // | // | // though shorter to use `dojo.style()` in this case: // | dojo.style("someNode", obj); if(arguments.length == 2){ return attr[typeof name == "string" ? "get" : "set"](node, name); } return attr.set(node, name, value); }; // mix-in dom-class dojo.hasClass = cls.contains; dojo.addClass = cls.add; dojo.removeClass = cls.remove; dojo.toggleClass = cls.toggle; dojo.replaceClass = cls.replace; // mix-in dom-construct dojo._toDom = dojo.toDom = ctr.toDom; dojo.place = ctr.place; dojo.create = ctr.create; dojo.empty = function(node){ ctr.empty(node); }; dojo._destroyElement = dojo.destroy = function(node){ ctr.destroy(node); }; // mix-in dom-geometry dojo._getPadExtents = dojo.getPadExtents = geom.getPadExtents; dojo._getBorderExtents = dojo.getBorderExtents = geom.getBorderExtents; dojo._getPadBorderExtents = dojo.getPadBorderExtents = geom.getPadBorderExtents; dojo._getMarginExtents = dojo.getMarginExtents = geom.getMarginExtents; dojo._getMarginSize = dojo.getMarginSize = geom.getMarginSize; dojo._getMarginBox = dojo.getMarginBox = geom.getMarginBox; dojo.setMarginBox = geom.setMarginBox; dojo._getContentBox = dojo.getContentBox = geom.getContentBox; dojo.setContentSize = geom.setContentSize; dojo._isBodyLtr = dojo.isBodyLtr = geom.isBodyLtr; dojo._docScroll = dojo.docScroll = geom.docScroll; dojo._getIeDocumentElementOffset = dojo.getIeDocumentElementOffset = geom.getIeDocumentElementOffset; dojo._fixIeBiDiScrollLeft = dojo.fixIeBiDiScrollLeft = geom.fixIeBiDiScrollLeft; dojo.position = geom.position; dojo.marginBox = function marginBox(/*DomNode|String*/node, /*Object?*/box){ // summary: // Getter/setter for the margin-box of node. // description: // Getter/setter for the margin-box of node. // Returns an object in the expected format of box (regardless // if box is passed). The object might look like: // `{ l: 50, t: 200, w: 300: h: 150 }` // for a node offset from its parent 50px to the left, 200px from // the top with a margin width of 300px and a margin-height of // 150px. // node: // id or reference to DOM Node to get/set box for // box: // If passed, denotes that dojo.marginBox() should // update/set the margin box for node. Box is an object in the // above format. All properties are optional if passed. // example: // Retrieve the margin box of a passed node // | var box = dojo.marginBox("someNodeId"); // | console.dir(box); // // example: // Set a node's margin box to the size of another node // | var box = dojo.marginBox("someNodeId"); // | dojo.marginBox("someOtherNode", box); return box ? geom.setMarginBox(node, box) : geom.getMarginBox(node); // Object }; dojo.contentBox = function contentBox(/*DomNode|String*/node, /*Object?*/box){ // summary: // Getter/setter for the content-box of node. // description: // Returns an object in the expected format of box (regardless if box is passed). // The object might look like: // `{ l: 50, t: 200, w: 300: h: 150 }` // for a node offset from its parent 50px to the left, 200px from // the top with a content width of 300px and a content-height of // 150px. Note that the content box may have a much larger border // or margin box, depending on the box model currently in use and // CSS values set/inherited for node. // While the getter will return top and left values, the // setter only accepts setting the width and height. // node: // id or reference to DOM Node to get/set box for // box: // If passed, denotes that dojo.contentBox() should // update/set the content box for node. Box is an object in the // above format, but only w (width) and h (height) are supported. // All properties are optional if passed. return box ? geom.setContentSize(node, box) : geom.getContentBox(node); // Object }; dojo.coords = function(/*DomNode|String*/node, /*Boolean?*/includeScroll){ // summary: // Deprecated: Use position() for border-box x/y/w/h // or marginBox() for margin-box w/h/l/t. // // Returns an object that measures margin-box (w)idth/(h)eight // and absolute position x/y of the border-box. Also returned // is computed (l)eft and (t)op values in pixels from the // node's offsetParent as returned from marginBox(). // Return value will be in the form: //| { l: 50, t: 200, w: 300: h: 150, x: 100, y: 300 } // Does not act as a setter. If includeScroll is passed, the x and // y params are affected as one would expect in dojo.position(). dojo.deprecated("dojo.coords()", "Use dojo.position() or dojo.marginBox()."); node = dom.byId(node); var s = style.getComputedStyle(node), mb = geom.getMarginBox(node, s); var abs = geom.position(node, includeScroll); mb.x = abs.x; mb.y = abs.y; return mb; // Object }; // mix-in dom-prop dojo.getProp = prop.get; dojo.setProp = prop.set; dojo.prop = function(/*DomNode|String*/node, /*String|Object*/name, /*String?*/value){ // summary: // Gets or sets a property on an HTML element. // description: // Handles normalized getting and setting of properties on DOM // Nodes. If 2 arguments are passed, and a the second argument is a // string, acts as a getter. // // If a third argument is passed, or if the second argument is a // map of attributes, acts as a setter. // // When passing functions as values, note that they will not be // directly assigned to slots on the node, but rather the default // behavior will be removed and the new behavior will be added // using `dojo.connect()`, meaning that event handler properties // will be normalized and that some caveats with regards to // non-standard behaviors for onsubmit apply. Namely that you // should cancel form submission using `dojo.stopEvent()` on the // passed event object instead of returning a boolean value from // the handler itself. // node: // id or reference to the element to get or set the property on // name: // the name of the property to get or set. // value: // The value to set for the property // returns: // when used as a getter, the value of the requested property // or null if that attribute does not have a specified or // default value; // // when used as a setter, the DOM node // // example: // | // get the current value of the "foo" property on a node // | dojo.prop(dojo.byId("nodeId"), "foo"); // | // or we can just pass the id: // | dojo.prop("nodeId", "foo"); // // example: // | // use prop() to set the tab index // | dojo.prop("nodeId", "tabIndex", 3); // | // // example: // Set multiple values at once, including event handlers: // | dojo.prop("formId", { // | "foo": "bar", // | "tabIndex": -1, // | "method": "POST", // | "onsubmit": function(e){ // | // stop submitting the form. Note that the IE behavior // | // of returning true or false will have no effect here // | // since our handler is connect()ed to the built-in // | // onsubmit behavior and so we need to use // | // dojo.stopEvent() to ensure that the submission // | // doesn't proceed. // | dojo.stopEvent(e); // | // | // submit the form with Ajax // | dojo.xhrPost({ form: "formId" }); // | } // | }); // // example: // Style is s special case: Only set with an object hash of styles // | dojo.prop("someNode",{ // | id:"bar", // | style:{ // | width:"200px", height:"100px", color:"#000" // | } // | }); // // example: // Again, only set style as an object hash of styles: // | var obj = { color:"#fff", backgroundColor:"#000" }; // | dojo.prop("someNode", "style", obj); // | // | // though shorter to use `dojo.style()` in this case: // | dojo.style("someNode", obj); if(arguments.length == 2){ return prop[typeof name == "string" ? "get" : "set"](node, name); } // setter return prop.set(node, name, value); }; // mix-in dom-style dojo.getStyle = style.get; dojo.setStyle = style.set; dojo.getComputedStyle = style.getComputedStyle; dojo.__toPixelValue = dojo.toPixelValue = style.toPixelValue; dojo.style = function(node, name, value){ // summary: // Accesses styles on a node. If 2 arguments are // passed, acts as a getter. If 3 arguments are passed, acts // as a setter. // description: // Getting the style value uses the computed style for the node, so the value // will be a calculated value, not just the immediate node.style value. // Also when getting values, use specific style names, // like "borderBottomWidth" instead of "border" since compound values like // "border" are not necessarily reflected as expected. // If you want to get node dimensions, use `dojo.marginBox()`, // `dojo.contentBox()` or `dojo.position()`. // node: DOMNode|String // id or reference to node to get/set style for // name: String|Object? // the style property to set in DOM-accessor format // ("borderWidth", not "border-width") or an object with key/value // pairs suitable for setting each property. // value: String? // If passed, sets value on the node for style, handling // cross-browser concerns. When setting a pixel value, // be sure to include "px" in the value. For instance, top: "200px". // Otherwise, in some cases, some browsers will not apply the style. // returns: // when used as a getter, return the computed style of the node if passing in an ID or node, // or return the normalized, computed value for the property when passing in a node and a style property // example: // Passing only an ID or node returns the computed style object of // the node: // | dojo.style("thinger"); // example: // Passing a node and a style property returns the current // normalized, computed value for that property: // | dojo.style("thinger", "opacity"); // 1 by default // // example: // Passing a node, a style property, and a value changes the // current display of the node and returns the new computed value // | dojo.style("thinger", "opacity", 0.5); // == 0.5 // // example: // Passing a node, an object-style style property sets each of the values in turn and returns the computed style object of the node: // | dojo.style("thinger", { // | "opacity": 0.5, // | "border": "3px solid black", // | "height": "300px" // | }); // // example: // When the CSS style property is hyphenated, the JavaScript property is camelCased. // font-size becomes fontSize, and so on. // | dojo.style("thinger",{ // | fontSize:"14pt", // | letterSpacing:"1.2em" // | }); // // example: // dojo/NodeList implements .style() using the same syntax, omitting the "node" parameter, calling // dojo.style() on every element of the list. See: `dojo/query` and `dojo/NodeList` // | dojo.query(".someClassName").style("visibility","hidden"); // | // or // | dojo.query("#baz > div").style({ // | opacity:0.75, // | fontSize:"13pt" // | }); switch(arguments.length){ case 1: return style.get(node); case 2: return style[typeof name == "string" ? "get" : "set"](node, name); } // setter return style.set(node, name, value); }; return dojo; }); }, 'dojo/dom-attr':function(){ define(["exports", "./sniff", "./_base/lang", "./dom", "./dom-style", "./dom-prop"], function(exports, has, lang, dom, style, prop){ // module: // dojo/dom-attr // summary: // This module defines the core dojo DOM attributes API. // TODOC: summary not showing up in output see https://github.com/csnover/js-doc-parse/issues/42 // ============================= // Element attribute Functions // ============================= // This module will be obsolete soon. Use dojo/prop instead. // dojo/dom-attr.get() should conform to http://www.w3.org/TR/DOM-Level-2-Core/ // attribute-related functions (to be obsolete soon) var forcePropNames = { innerHTML: 1, textContent:1, className: 1, htmlFor: has("ie") ? 1 : 0, value: 1 }, attrNames = { // original attribute names classname: "class", htmlfor: "for", // for IE tabindex: "tabIndex", readonly: "readOnly" }; function _hasAttr(node, name){ var attr = node.getAttributeNode && node.getAttributeNode(name); return !!attr && attr.specified; // Boolean } // There is a difference in the presence of certain properties and their default values // between browsers. For example, on IE "disabled" is present on all elements, // but it is value is "false"; "tabIndex" of
returns 0 by default on IE, yet other browsers // can return -1. exports.has = function hasAttr(/*DOMNode|String*/ node, /*String*/ name){ // summary: // Returns true if the requested attribute is specified on the // given element, and false otherwise. // node: DOMNode|String // id or reference to the element to check // name: String // the name of the attribute // returns: Boolean // true if the requested attribute is specified on the // given element, and false otherwise var lc = name.toLowerCase(); return !!forcePropNames[prop.names[lc] || name] || _hasAttr(dom.byId(node), attrNames[lc] || name); // Boolean }; exports.get = function getAttr(/*DOMNode|String*/ node, /*String*/ name){ // summary: // Gets an attribute on an HTML element. // description: // Handles normalized getting of attributes on DOM Nodes. // node: DOMNode|String // id or reference to the element to get the attribute on // name: String // the name of the attribute to get. // returns: // the value of the requested attribute or null if that attribute does not have a specified or // default value; // // example: // | // get the current value of the "foo" attribute on a node // | require(["dojo/dom-attr", "dojo/dom"], function(domAttr, dom){ // | domAttr.get(dom.byId("nodeId"), "foo"); // | // or we can just pass the id: // | domAttr.get("nodeId", "foo"); // | }); // | node = dom.byId(node); var lc = name.toLowerCase(), propName = prop.names[lc] || name, forceProp = forcePropNames[propName], value = node[propName]; // should we access this attribute via a property or via getAttribute()? if(forceProp && typeof value != "undefined"){ // node's property return value; // Anything } if(propName == "textContent"){ return prop.get(node, propName); } if(propName != "href" && (typeof value == "boolean" || lang.isFunction(value))){ // node's property return value; // Anything } // node's attribute // we need _hasAttr() here to guard against IE returning a default value var attrName = attrNames[lc] || name; return _hasAttr(node, attrName) ? node.getAttribute(attrName) : null; // Anything }; exports.set = function setAttr(/*DOMNode|String*/ node, /*String|Object*/ name, /*String?*/ value){ // summary: // Sets an attribute on an HTML element. // description: // Handles normalized setting of attributes on DOM Nodes. // // When passing functions as values, note that they will not be // directly assigned to slots on the node, but rather the default // behavior will be removed and the new behavior will be added // using `dojo.connect()`, meaning that event handler properties // will be normalized and that some caveats with regards to // non-standard behaviors for onsubmit apply. Namely that you // should cancel form submission using `dojo.stopEvent()` on the // passed event object instead of returning a boolean value from // the handler itself. // node: DOMNode|String // id or reference to the element to set the attribute on // name: String|Object // the name of the attribute to set, or a hash of key-value pairs to set. // value: String? // the value to set for the attribute, if the name is a string. // returns: // the DOM node // // example: // | // use attr() to set the tab index // | require(["dojo/dom-attr"], function(domAttr){ // | domAttr.set("nodeId", "tabIndex", 3); // | }); // // example: // Set multiple values at once, including event handlers: // | require(["dojo/dom-attr"], // | function(domAttr){ // | domAttr.set("formId", { // | "foo": "bar", // | "tabIndex": -1, // | "method": "POST" // | } // | }); node = dom.byId(node); if(arguments.length == 2){ // inline'd type check // the object form of setter: the 2nd argument is a dictionary for(var x in name){ exports.set(node, x, name[x]); } return node; // DomNode } var lc = name.toLowerCase(), propName = prop.names[lc] || name, forceProp = forcePropNames[propName]; if(propName == "style" && typeof value != "string"){ // inline'd type check // special case: setting a style style.set(node, value); return node; // DomNode } if(forceProp || typeof value == "boolean" || lang.isFunction(value)){ return prop.set(node, name, value); } // node's attribute node.setAttribute(attrNames[lc] || name, value); return node; // DomNode }; exports.remove = function removeAttr(/*DOMNode|String*/ node, /*String*/ name){ // summary: // Removes an attribute from an HTML element. // node: DOMNode|String // id or reference to the element to remove the attribute from // name: String // the name of the attribute to remove dom.byId(node).removeAttribute(attrNames[name.toLowerCase()] || name); }; exports.getNodeProp = function getNodeProp(/*DomNode|String*/ node, /*String*/ name){ // summary: // Returns an effective value of a property or an attribute. // node: DOMNode|String // id or reference to the element to remove the attribute from // name: String // the name of the attribute // returns: // the value of the attribute node = dom.byId(node); var lc = name.toLowerCase(), propName = prop.names[lc] || name; if((propName in node) && propName != "href"){ // node's property return node[propName]; // Anything } // node's attribute var attrName = attrNames[lc] || name; return _hasAttr(node, attrName) ? node.getAttribute(attrName) : null; // Anything }; }); }, 'dojo/dom-prop':function(){ define(["exports", "./_base/kernel", "./sniff", "./_base/lang", "./dom", "./dom-style", "./dom-construct", "./_base/connect"], function(exports, dojo, has, lang, dom, style, ctr, conn){ // module: // dojo/dom-prop // summary: // This module defines the core dojo DOM properties API. // TODOC: summary not showing up in output, see https://github.com/csnover/js-doc-parse/issues/42 // ============================= // Element properties Functions // ============================= // helper to connect events var _evtHdlrMap = {}, _ctr = 1, _attrId = dojo._scopeName + "attrid"; has.add('dom-textContent', function (global, doc, element) { return 'textContent' in element; }); exports.names = { // properties renamed to avoid clashes with reserved words "class": "className", "for": "htmlFor", // properties written as camelCase tabindex: "tabIndex", readonly: "readOnly", colspan: "colSpan", frameborder: "frameBorder", rowspan: "rowSpan", textcontent: "textContent", valuetype: "valueType" }; function getText(/*DOMNode*/node){ // summary: // recursion method for get('textContent') to use. Gets text value for a node. // description: // Juse uses nodedValue so things like
tags do not end up in // the text as any sort of line return. var text = "", ch = node.childNodes; for(var i = 0, n; n = ch[i]; i++){ //Skip comments. if(n.nodeType != 8){ if(n.nodeType == 1){ text += getText(n); }else{ text += n.nodeValue; } } } return text; } exports.get = function getProp(/*DOMNode|String*/ node, /*String*/ name){ // summary: // Gets a property on an HTML element. // description: // Handles normalized getting of properties on DOM nodes. // // node: DOMNode|String // id or reference to the element to get the property on // name: String // the name of the property to get. // returns: // the value of the requested property or its default value // // example: // | // get the current value of the "foo" property on a node // | require(["dojo/dom-prop", "dojo/dom"], function(domProp, dom){ // | domProp.get(dom.byId("nodeId"), "foo"); // | // or we can just pass the id: // | domProp.get("nodeId", "foo"); // | }); node = dom.byId(node); var lc = name.toLowerCase(), propName = exports.names[lc] || name; if(propName == "textContent" && !has("dom-textContent")){ return getText(node); } return node[propName]; // Anything }; exports.set = function setProp(/*DOMNode|String*/ node, /*String|Object*/ name, /*String?*/ value){ // summary: // Sets a property on an HTML element. // description: // Handles normalized setting of properties on DOM nodes. // // When passing functions as values, note that they will not be // directly assigned to slots on the node, but rather the default // behavior will be removed and the new behavior will be added // using `dojo.connect()`, meaning that event handler properties // will be normalized and that some caveats with regards to // non-standard behaviors for onsubmit apply. Namely that you // should cancel form submission using `dojo.stopEvent()` on the // passed event object instead of returning a boolean value from // the handler itself. // node: DOMNode|String // id or reference to the element to set the property on // name: String|Object // the name of the property to set, or a hash object to set // multiple properties at once. // value: String? // The value to set for the property // returns: // the DOM node // // example: // | // use prop() to set the tab index // | require(["dojo/dom-prop"], function(domProp){ // | domProp.set("nodeId", "tabIndex", 3); // | }); // // example: // Set multiple values at once, including event handlers: // | require(["dojo/dom-prop"], function(domProp){ // | domProp.set("formId", { // | "foo": "bar", // | "tabIndex": -1, // | "method": "POST", // | }); // | }); node = dom.byId(node); var l = arguments.length; if(l == 2 && typeof name != "string"){ // inline'd type check // the object form of setter: the 2nd argument is a dictionary for(var x in name){ exports.set(node, x, name[x]); } return node; // DomNode } var lc = name.toLowerCase(), propName = exports.names[lc] || name; if(propName == "style" && typeof value != "string"){ // inline'd type check // special case: setting a style style.set(node, value); return node; // DomNode } if(propName == "innerHTML"){ // special case: assigning HTML // the hash lists elements with read-only innerHTML on IE if(has("ie") && node.tagName.toLowerCase() in {col: 1, colgroup: 1, table: 1, tbody: 1, tfoot: 1, thead: 1, tr: 1, title: 1}){ ctr.empty(node); node.appendChild(ctr.toDom(value, node.ownerDocument)); }else{ node[propName] = value; } return node; // DomNode } if(propName == "textContent" && !has("dom-textContent")) { ctr.empty(node); node.appendChild(node.ownerDocument.createTextNode(value)); return node; } if(lang.isFunction(value)){ // special case: assigning an event handler // clobber if we can var attrId = node[_attrId]; if(!attrId){ attrId = _ctr++; node[_attrId] = attrId; } if(!_evtHdlrMap[attrId]){ _evtHdlrMap[attrId] = {}; } var h = _evtHdlrMap[attrId][propName]; if(h){ //h.remove(); conn.disconnect(h); }else{ try{ delete node[propName]; }catch(e){} } // ensure that event objects are normalized, etc. if(value){ //_evtHdlrMap[attrId][propName] = on(node, propName, value); _evtHdlrMap[attrId][propName] = conn.connect(node, propName, value); }else{ node[propName] = null; } return node; // DomNode } node[propName] = value; return node; // DomNode }; }); }, 'dojo/dom-construct':function(){ define(["exports", "./_base/kernel", "./sniff", "./_base/window", "./dom", "./dom-attr"], function(exports, dojo, has, win, dom, attr){ // module: // dojo/dom-construct // summary: // This module defines the core dojo DOM construction API. // TODOC: summary not showing up in output, see https://github.com/csnover/js-doc-parse/issues/42 // support stuff for toDom() var tagWrap = { option: ["select"], tbody: ["table"], thead: ["table"], tfoot: ["table"], tr: ["table", "tbody"], td: ["table", "tbody", "tr"], th: ["table", "thead", "tr"], legend: ["fieldset"], caption: ["table"], colgroup: ["table"], col: ["table", "colgroup"], li: ["ul"] }, reTag = /<\s*([\w\:]+)/, masterNode = {}, masterNum = 0, masterName = "__" + dojo._scopeName + "ToDomId"; // generate start/end tag strings to use // for the injection for each special tag wrap case. for(var param in tagWrap){ if(tagWrap.hasOwnProperty(param)){ var tw = tagWrap[param]; tw.pre = param == "option" ? '