From b31aae372e4b9af3b52be6636b0dd7b6b02cf054 Mon Sep 17 00:00:00 2001 From: Rawld Gill Date: Wed, 20 Jul 2011 09:44:32 +0000 Subject: [PATCH] refactored set/getObject, mixin, exists from dojo/_base/kernel to dojo/_base/lang; further loader and kernel cleanup and minifying; refs #13484; !strict git-svn-id: http://svn.dojotoolkit.org/src/dojo/trunk@25850 560b804f-0ae3-0310-86f3-f6aa0a117693 --- NodeList-data.js | 2 +- NodeList-fx.js | 2 +- Stateful.js | 4 +- _base/Color.js | 8 +- _base/NodeList.js | 10 +- _base/array.js | 4 +- _base/browser.js | 2 - _base/config.js | 78 +- _base/configNode.js | 43 +- _base/configRhino.js | 34 +- _base/connect.js | 22 +- _base/declare.js | 12 +- _base/fx.js | 4 +- _base/kernel.js | 369 ++----- _base/lang.js | 990 +++++++++++------- _base/loader.js | 19 +- _base/sniff.js | 93 +- _base/xhr.js | 4 +- cldr/supplemental.js | 4 +- colors.js | 8 +- currency.js | 6 +- date.js | 4 +- date/locale.js | 8 +- date/stamp.js | 4 +- dojo.js | 525 +++++----- i18n.js | 2 +- number.js | 6 +- parser.js | 16 +- regexp.js | 4 +- store/Observable.js | 6 +- store/util/QueryResults.js | 8 +- string.js | 8 +- tests/_base/loader/config-sniff-djConfig.html | 4 +- tests/_base/loader/config-sniff.html | 4 +- tests/_base/loader/config.html | 24 +- tests/_base/loader/configApi.html | 13 +- tests/_base/loader/xdomain/xdomain.html | 7 +- window.js | 4 +- 38 files changed, 1162 insertions(+), 1203 deletions(-) diff --git a/NodeList-data.js b/NodeList-data.js index 88f403f541..f941d9ca1d 100644 --- a/NodeList-data.js +++ b/NodeList-data.js @@ -118,7 +118,7 @@ define([ }else{ // must be a setter, mix `value` into data hash // API discrepency: using object as setter works here - r = dojo._mixin(dataCache[pid], key); + r = lang.mixin(dataCache[pid], key); } return r; // Object|Anything|Nothing diff --git a/NodeList-fx.js b/NodeList-fx.js index 030d106371..6768effbaf 100644 --- a/NodeList-fx.js +++ b/NodeList-fx.js @@ -20,7 +20,7 @@ lang.extend(NodeList, { var a = dfx.combine( this.map(function(item){ var tmpArgs = { node: item }; - dojo.mixin(tmpArgs, args); + lang.mixin(tmpArgs, args); return obj[method](tmpArgs); }) ); diff --git a/Stateful.js b/Stateful.js index 6f1512677c..5ecbcaef02 100644 --- a/Stateful.js +++ b/Stateful.js @@ -1,4 +1,4 @@ -define(["./_base/kernel", "./_base/declare", "./_base/array"], function(dojo, declare) { +define(["./_base/kernel", "./_base/declare", "./_base/lang", "./_base/array"], function(dojo, declare, lang) { // module: // dojo/Stateful // summary: @@ -16,7 +16,7 @@ return dojo.declare("dojo.Stateful", null, { // | obj.set("foo","bar"); postscript: function(mixin){ if(mixin){ - dojo.mixin(this, mixin); + lang.mixin(this, mixin); } }, diff --git a/_base/Color.js b/_base/Color.js index c68ee8709f..f2f895f642 100644 --- a/_base/Color.js +++ b/_base/Color.js @@ -1,4 +1,4 @@ -define(["./kernel", "./array", "./lang"], function(dojo){ +define(["./kernel", "./lang", "./array"], function(dojo, lang){ dojo.Color = function(/*Array|String|Object*/ color){ // summary: @@ -22,10 +22,10 @@ define(["./kernel", "./array", "./lang"], function(dojo){ if(color){ this.setColor(color); } }; - /*===== - dojo.mixin(dojo.Color,{ + /*===== + lang.mixin(dojo.Color,{ named:{ - // summary: Dictionary list of all CSS named colors, by name. Values are 3-item arrays with corresponding RG and B values. + // summary: Dictionary list of all CSS named colors, by name. Values are 3-item arrays with corresponding RG and B values. } }); =====*/ diff --git a/_base/NodeList.js b/_base/NodeList.js index 7dea6b601b..8f43114c25 100644 --- a/_base/NodeList.js +++ b/_base/NodeList.js @@ -1,4 +1,4 @@ -define(["./kernel", "../on", "./lang", "./array", "./html"], function(dojo, on){ +define(["./kernel", "./lang", "../on", "./lang", "./array", "./html"], function(dojo, lang, on){ // module: // dojo/_base/NodeList // summary: @@ -25,7 +25,7 @@ define(["./kernel", "../on", "./lang", "./array", "./html"], function(dojo, on){ } var ctor = NodeListCtor || this._NodeListCtor || dojo._NodeListCtor; a.constructor = ctor; - dojo._mixin(a, ctor.prototype); + lang.mixin(a, ctor.prototype); a._NodeListCtor = ctor; return parent ? a._stash(parent) : a; }; @@ -244,7 +244,7 @@ define(["./kernel", "../on", "./lang", "./array", "./html"], function(dojo, on){ nlp.connect = adaptAsForEach(function(){ return dojo.connect.apply(this, arguments); }); - + dojo.extend(dojo.NodeList, { _normalize: function(/*String||Element||Object||NodeList*/content, /*DOMNode?*/refNode){ // summary: @@ -378,7 +378,7 @@ define(["./kernel", "../on", "./lang", "./array", "./html"], function(dojo, on){ // summary: // Listen for events on the nodes in the NodeList. Basic usage is: // | query(".my-class").on("click", listener); - // This supports event delegation by using selectors as the first argument with the event names as + // This supports event delegation by using selectors as the first argument with the event names as // pseudo selectors. For example: // | dojo.query("#my-list").on("li:click", listener); // This will listen for click events within
  • elements that are inside the #my-list element. @@ -935,7 +935,7 @@ define(["./kernel", "../on", "./lang", "./array", "./html"], function(dojo, on){ // example: // Grabs all buttons in the page and converts them to diji.form.Buttons. // | var buttons = dojo.query("button").instantiate("dijit.form.Button", {showLabel: true}); - var c = dojo.isFunction(declaredClass) ? declaredClass : dojo.getObject(declaredClass); + var c = dojo.isFunction(declaredClass) ? declaredClass : lang.getObject(declaredClass); properties = properties || {}; return this.forEach(function(node){ new c(properties, node); diff --git a/_base/array.js b/_base/array.js index 6b2b564c20..54252cf0a8 100644 --- a/_base/array.js +++ b/_base/array.js @@ -1,4 +1,4 @@ -define(["./kernel", "./lang"], function(dojo){ +define(["./kernel", "./lang"], function(dojo, lang){ // module: // dojo/_base/array // summary: @@ -25,7 +25,7 @@ define(["./kernel", "./lang"], function(dojo){ return every; // Boolean }; - dojo.mixin(dojo, { + lang.mixin(dojo, { indexOf: function( /*Array*/ array, /*Object*/ value, /*Integer?*/ fromIndex, diff --git a/_base/browser.js b/_base/browser.js index 0f34cac294..c367db7cea 100644 --- a/_base/browser.js +++ b/_base/browser.js @@ -19,5 +19,3 @@ define([ // This module causes the browser-only base modules to be loaded. return dojo; }); - - diff --git a/_base/config.js b/_base/config.js index 4f496e7038..69f5e73928 100644 --- a/_base/config.js +++ b/_base/config.js @@ -2,35 +2,61 @@ define(["../has", "require"], function(has, require){ // module: // dojo/_base/config // summary: - // This module processes the user configuration during bootstrap. + // 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-uniqe 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 + // | }); - has.add("dojo-sniff", - // inspect script elements for data-dojo-config during bootstrap - has("dom") ? 1 : 0 - ); - - var result = this.dojoConfig || this.djConfig || {}; - if(has("dom") && has("dojo-sniff") && !has("dojo-loader")){ - // if we're not under the dojo loader, then assume the user doesn't want to sniff the baseUrl from the loader (since it must already be set) - // notice this loop breaks on first match - for(var config, src, match, scripts = document.getElementsByTagName("script"), i = 0; i < scripts.length && !match; i++){ - if((src = scripts[i].getAttribute("src")) && (match = src.match(/(.*)\/?(dojo|require)\.js(\W|$)/i))){ - // see if there's a dojo configuration stuffed into the node - config = (scripts[i].getAttribute("data-dojo-config") || scripts[i].getAttribute("djConfig")); - if(config){ - config = eval("({ " + config + " })\r\n//@ sourceURL=dojo/config/data-dojo-config"); - for(var p in config){ - result[p] = config[p]; - } - } + var adviseHas = function(featureSet, prefix, booting){ + for(p in featureSet){ + has.add(prefix + p, featureSet[p], 0, booting); } + }, + result; + if(has("dojo-config-api")){ + // must be the dojo loader; take a shallow copy of require.rawConfig + var src = require.rawConfig, dest = {}, p; + for(p in src){ + dest[p] = src[p]; } + result = dest; + require.on("config", function(config){ + adviseHas(config, "config", 0); + adviseHas(config.has, "", 0); + }); }else{ - // if this is the dojo loader, then the aggregate of defaultConfig + (dojoConfig | djConfig | require) + sniffed config will be in require.rawConfig - var p, rawConfig = require.rawConfig || {}; - for(p in rawConfig){ - result[p] = rawConfig[p]; - } + result = has("dojo-loader") ? + // must be a built version of the dojo loader; all config stuffed in require.rawConfig + require.rawConfig : + // a foreign loader + this.dojoConfig || this.djConfig || {}; + adviseHas(result, "config", 1); + adviseHas(result.has, "", 1); } return result; }); @@ -43,7 +69,7 @@ define(["../has", "require"], function(has, require){ // Setting any of these variables *after* the library has loaded does // nothing at all. -// FIXME: can we document these on dojo.config object and explain they must be set via djConfig/dojoConfig global prior to loading dojo.js +// FIXME: can we document these on dojo.config object and explain they must be set via djConfig/dojoConfig global prior to loading dojo.js dojoConfig = { // summary: diff --git a/_base/configNode.js b/_base/configNode.js index 2302a7ac79..f78c0704eb 100644 --- a/_base/configNode.js +++ b/_base/configNode.js @@ -29,7 +29,6 @@ exports.config = function(config){ "dojo-inject-api":1, "dojo-timeout-api":0, "dojo-trace-api":1, - "dojo-loader-catches":1, "dojo-dom-ready-api":0, "dojo-publish-privates":1, "dojo-sniff":0, @@ -54,29 +53,31 @@ exports.config = function(config){ // TODO: really get the locale locale:"en-us", - debug: function(item){ - // define debug for console messages during dev instead of console.log - // (node's heavy async makes console.log confusing sometimes) - require("util").debug(item); - }, + loaderPatch: { + log:function(item){ + // define debug for console messages during dev instead of console.log + // (node's heavy async makes console.log confusing sometimes) + require("util").debug(item); + }, - eval: function(__text, __urlHint){ - return vm.runInThisContext(__text, __urlHint); - }, + eval: function(__text, __urlHint){ + return vm.runInThisContext(__text, __urlHint); + }, - injectUrl: function(url, callback){ - try{ - vm.runInThisContext(fs.readFileSync(url, "utf8"), url); - callback(); - }catch(e){ - console.log("failed to load resource (" + url + ")"); - console.log(e); - } - }, + injectUrl: function(url, callback){ + try{ + vm.runInThisContext(fs.readFileSync(url, "utf8"), url); + callback(); + }catch(e){ + this.require.log("failed to load resource (" + url + ")"); + this.require.log(e); + } + }, - getText: function(url, sync, onLoad){ - // TODO: implement async and http/https handling - onLoad(fs.readFileSync(url, "utf8")); + getText: function(url, sync, onLoad){ + // TODO: implement async and http/https handling + onLoad(fs.readFileSync(url, "utf8")); + } } }; for(p in nodeConfig){ diff --git a/_base/configRhino.js b/_base/configRhino.js index 62f8ab12ca..ec64759973 100644 --- a/_base/configRhino.js +++ b/_base/configRhino.js @@ -93,24 +93,26 @@ function rhinoDojoConfig(config, baseUrl, rhinoArgs){ timeout:0, locale:String(java.util.Locale.getDefault().toString().replace('_', '-').toLowerCase()), - injectUrl: function(url, callback){ - try{ - if(isLocal(url)){ - load(url); - }else{ - require.eval(readUrl(url, "UTF-8")); + loaderPatch:{ + injectUrl: function(url, callback){ + try{ + if(isLocal(url)){ + load(url); + }else{ + require.eval(readUrl(url, "UTF-8")); + } + callback(); + }catch(e){ + console.log("failed to load resource (" + url + ")"); + console.log(e); } - callback(); - }catch(e){ - console.log("failed to load resource (" + url + ")"); - console.log(e); - } - }, + }, - getText: function(url, sync, onLoad){ - // TODO: test https://bugzilla.mozilla.org/show_bug.cgi?id=471005; see v1.6 hostenv_rhino - // note: async mode not supported in rhino - onLoad(isLocal(url) ? readFile(url, "UTF-8") : readUrl(url, "UTF-8")); + getText: function(url, sync, onLoad){ + // TODO: test https://bugzilla.mozilla.org/show_bug.cgi?id=471005; see v1.6 hostenv_rhino + // note: async mode not supported in rhino + onLoad(isLocal(url) ? readFile(url, "UTF-8") : readUrl(url, "UTF-8")); + } } }; for(p in rhinoConfig){ diff --git a/_base/connect.js b/_base/connect.js index 6a2072ede0..ce85336072 100644 --- a/_base/connect.js +++ b/_base/connect.js @@ -1,4 +1,4 @@ -define(["./kernel", "../on", "../aspect", "./event", "../mouse", "../has", "./lang", "../keys"], function(dojo, on, aspect, eventModule, mouse, has){ +define(["./kernel", "../on", "../aspect", "./event", "../mouse", "../has", "./lang", "../keys"], function(dojo, on, aspect, eventModule, mouse, has, lang){ // module: // dojo/_base/connect // summary: @@ -23,7 +23,7 @@ function connect(obj, event, context, method, dontFix){ event = event.substring(2); }else 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 + // method like an event, must go right to aspect return aspect.after(obj || dojo.global, event, dojo.hitch(context, method), true); } if(!obj){ @@ -66,7 +66,7 @@ var evtCopyKey = dojo.isMac ? "metaKey" : "ctrlKey"; var _synthesizeEvent = function(evt, props){ - var faux = dojo.mixin({}, evt, props); + var faux = lang.mixin({}, evt, props); setKeyChar(faux); // FIXME: would prefer to use dojo.hitch: dojo.hitch(evt, evt.preventDefault); // but it throws an error when preventDefault is invoked on Safari @@ -152,7 +152,7 @@ if(has("events-keypress-typed")){ }); }; }else{ - keypress = function(object, listener){ + keypress = function(object, listener){ return on(object, "keypress", function(evt){ setKeyChar(evt); return listener.call(this, evt); @@ -263,7 +263,7 @@ return { // 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 @@ -275,8 +275,8 @@ return { for(var l=a.length; i 2){ - return dojo._hitchArgs.apply(dojo, arguments); // Function - } - if(!method){ - method = scope; - scope = null; - } - if(dojo.isString(method)){ - scope = scope || dojo.global; - if(!scope[method]){ throw(['dojo.hitch: scope["', method, '"] is null (scope="', scope, '")'].join('')); } - return function(){ return scope[method].apply(scope, arguments || []); }; // Function + + has.add("bug-for-in-skips-shadowed", function(){ + // if true, the for-in interator skips object properties that exist in Object's prototype (IE 6 - ?) + for(var i in {toString: 1}){ + return 0; } - return !scope ? method : function(){ return method.apply(scope, arguments || []); }; // Function - }; - - /*===== - dojo.delegate = function(obj, props){ - // summary: - // Returns a new object which "looks" to obj for properties which it - // does not have a value for. Optionally takes a bag of properties to - // seed the returned object with initially. - // description: - // This is a small implementaton of the Boodman/Crockford delegation - // pattern in JavaScript. An intermediate object constructor mediates - // the prototype chain for the returned object, using it to delegate - // down to obj for property lookup when object-local lookup fails. - // This can be thought of similarly to ES4's "wrap", save that it does - // not act on types but rather on pure objects. - // obj: - // The object to delegate to for properties not found directly on the - // return object or in props. - // props: - // an object containing properties to assign to the returned object - // returns: - // an Object of anonymous type - // example: - // | var foo = { bar: "baz" }; - // | var thinger = dojo.delegate(foo, { thud: "xyzzy"}); - // | thinger.bar == "baz"; // delegated to foo - // | foo.thud == undefined; // by definition - // | thinger.thud == "xyzzy"; // mixed in from props - // | foo.bar = "thonk"; - // | thinger.bar == "thonk"; // still delegated to foo's bar - } - =====*/ - - dojo.delegate = dojo._delegate = (function(){ - // boodman/crockford delegation w/ cornford optimization - function TMP(){} - return function(obj, props){ - TMP.prototype = obj; - var tmp = new TMP(); - TMP.prototype = null; - if(props){ - dojo._mixin(tmp, props); + return 1; + }); + + var empty = {}, + + _extraNames = has("bug-for-in-skips-shadowed") ? "hasOwnProperty.valueOf.isPrototypeOf.propertyIsEnumerable.toLocaleString.toString.constructor".split(".") : [], + + _extraLen = _extraNames.length, + + _mixin = function(/*Object*/ target, /*Object*/ source){ + // summary: + // Adds all properties and methods of source to target. This addition + // is "prototype extension safe", so that instances of objects + // will not pass along prototype defaults. + var name, s, i; + for(name in source){ + // the "tobj" condition avoid copying properties in "source" + // inherited from Object.prototype. For example, if target 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 target) || (target[name] !== s && (!(name in empty) || empty[name] !== s))){ + target[name] = s; + } } - return tmp; // Object - }; - })(); - - /*===== - dojo._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. - } - =====*/ - - var efficient = function(obj, offset, startWith){ - return (startWith||[]).concat(Array.prototype.slice.call(obj, offset||0)); - }; - - //>>excludeStart("webkitMobile", kwArgs.webkitMobile); - var slow = function(obj, offset, startWith){ - var arr = startWith||[]; - for(var x = offset || 0; x < obj.length; x++){ - arr.push(obj[x]); - } - return arr; - }; - //>>excludeEnd("webkitMobile"); - - dojo._toArray = - //>>excludeStart("webkitMobile", kwArgs.webkitMobile); - dojo.isIE ? function(obj){ - return ((obj.item) ? slow : efficient).apply(this, arguments); - } : - //>>excludeEnd("webkitMobile"); - efficient; - - dojo.partial = function(/*Function|String*/method /*, ...*/){ - // summary: - // similar to hitch() except that the scope object is left to be - // whatever the execution context eventually becomes. - // description: - // Calling dojo.partial is the functional equivalent of calling: - // | dojo.hitch(null, funcName, ...); - var arr = [ null ]; - return dojo.hitch.apply(dojo, arr.concat(dojo._toArray(arguments))); // Function - }; - - var empty= {}; - dojo.clone = function(/*anything*/ o){ - // summary: - // Clones objects (including DOM nodes) and all children. - // Warning: do not clone cyclic structures. - if(!o || typeof o != "object" || dojo.isFunction(o)){ - // null, undefined, any non-object, or function - return o; // anything - } - if(o.nodeType && "cloneNode" in o){ - // DOM Node - return o.cloneNode(true); // Node - } - if(o instanceof Date){ - // Date - return new Date(o.getTime()); // Date - } - if(o instanceof RegExp){ - // RegExp - return new RegExp(o); // RegExp - } - var r, i, l, s, name; - if(dojo.isArray(o)){ - // array - r = []; - for(i = 0, l = o.length; i < l; ++i){ - if(i in o){ - r.push(dojo.clone(o[i])); + + if(has("bug-for-in-skips-shadowed")){ + if(source){ + for(i = 0; i < _extraLen; ++i){ + name = _extraNames[i]; + s = source[name]; + if(!(name in target) || (target[name] !== s && (!(name in empty) || empty[name] !== s))){ + target[name] = s; + } + } } } -// we don't clone functions for performance reasons -// }else if(d.isFunction(o)){ -// // function -// r = function(){ return o.apply(this, arguments); }; - }else{ - // generic objects - r = o.constructor ? new o.constructor() : {}; - } - for(name in o){ - // the "tobj" condition avoid copying properties in "source" - // inherited from Object.prototype. For example, if target has a custom - // toString() method, don't overwrite it with the toString() method - // that source inherited from Object.prototype - s = o[name]; - if(!(name in r) || (r[name] !== s && (!(name in empty) || empty[name] !== s))){ - r[name] = dojo.clone(s); + + return target; // Object + }, + + mixin = function(/*Object*/obj, /*Object...*/props){ + // summary: + // Adds all properties and methods of props to obj and returns the + // (now modified) obj. + // description: + // `lang.mixin` can mix multiple source objects into a + // destination object which is then returned. Unlike regular + // `for...in` iteration, `lang.mixin` is also smart about avoiding + // extensions which other toolkits may unwisely add to the root + // object prototype + // obj: + // The object to mix properties into. Also the return value. + // props: + // One or more objects whose values are successively copied into + // obj. If more than one of these objects contain the same value, + // the one specified last in the function call will "win". + // example: + // make a shallow copy of an object + // | var copy = 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: + // | dojo.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(!obj){ obj = {}; } + for(var i = 1, l = arguments.length; i < l; i++){ + _mixin(obj, arguments[i]); + } + return obj; // Object + }, + + getProp = function(/*Array*/parts, /*Boolean*/create, /*Object*/context){ + var p, i = 0, dojoGlobal = dojo.global; + if(!context){ + if(!parts.length){ + return dojoGlobal; + }else{ + p = parts[i++]; + try{ + context = dojo.scopeMap[p] && dojo.scopeMap[p][1]; + }catch(e){} + context = context || (p in dojoGlobal ? dojoGlobal[p] : (create ? dojoGlobal[p] = {} : undefined)); + } + } + while(context && (p = parts[i++])){ + context = (p in context ? context[p] : (create ? context[p] = {} : undefined)); + } + return context; // mixed + }, + + setObject = function(/*String*/name, /*Object*/value, /*Object?*/context){ + // summary: + // Set a property from a dot-separated string, such as "A.B.C" + // description: + // Useful for longer api chains where you have to test each object in + // the chain, or when you have an object reference in string format. + // Objects are created as needed along `path`. Returns the passed + // value if setting is successful or `undefined` if not. + // name: + // Path to a property, in the form "A.B.C". + // context: + // Optional. Object to use as root of path. Defaults to + // `dojo.global`. + // example: + // set the value of `foo.bar.baz`, regardless of whether + // intermediate objects already exist: + // | 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(/*String*/name, /*Boolean?*/create, /*Object?*/context){ + // summary: + // Get a property from a dot-separated string, such as "A.B.C" + // description: + // Useful for longer api chains where you have to test each object in + // the chain, or when you have an object reference in string format. + // name: + // Path to an property, in the form "A.B.C". + // create: + // Optional. Defaults to `false`. If `true`, Objects will be + // created at any point along the 'path' that is undefined. + // context: + // Optional. Object to use as root of path. Defaults to + // 'dojo.global'. Null may be passed. + return getProp(name.split("."), create, context); // Object + }, + + exists = function(/*String*/name, /*Object?*/obj){ + // summary: + // determine if an object supports a given method + // description: + // useful for longer api chains where you have to test each object in + // the chain. Useful for object and method detection. + // name: + // Path to an object, in the form "A.B.C". + // obj: + // Object to use as root of path. Defaults to + // 'dojo.global'. Null may be passed. + // example: + // | // define an object + // | var foo = { + // | bar: { } + // | }; + // | + // | // search the global scope + // | 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 getObject(name, false, obj) !== undefined; // Boolean + }, + + opts = Object.prototype.toString, + + // Crockford (ish) functions + + isString = function(/*anything*/ it){ + // summary: + // Return true if it is a String + return (typeof it == "string" || it instanceof String); // Boolean + }, + + isArray = function(/*anything*/ it){ + // summary: + // Return true if it is an Array. + // Does not work on Arrays created in other windows. + return it && (it instanceof Array || typeof it == "array"); // Boolean + }, + + isFunction = function(/*anything*/ it){ + // summary: + // Return true if it is a Function + return opts.call(it) === "[object Function]"; + }, + + isObject = function(/*anything*/ it){ + // summary: + // Returns true if it is a JavaScript object (or an Array, a Function + // or null) + return it !== undefined && + (it === null || typeof it == "object" || isArray(it) || isFunction(it)); // Boolean + }, + + isArrayLike = function(/*anything*/ it){ + // summary: + // similar to dojo.isArray() but more permissive + // description: + // Doesn't strongly test for "arrayness". Instead, settles for "isn't + // a string or number and has a length property". Arguments objects + // and DOM collections will return true when passed to + // dojo.isArrayLike(), but will return false when passed to + // dojo.isArray(). + // returns: + // If it walks like a duck and quacks like a duck, return `true` + return it && it !== undefined && // Boolean + // keep out built-in constructors (Number, String, ...) which have length + // properties + !isString(it) && !isFunction(it) && + !(it.tagName && it.tagName.toLowerCase() == 'form') && + (isArray(it) || isFinite(it.length)); + }, + + isAlien = function(/*anything*/ it){ + // summary: + // Returns true if it is a built-in function or some other kind of + // oddball that *should* report as a function but doesn't + return it && !isFunction(it) && /\{\s*\[native code\]\s*\}/.test(String(it)); // Boolean + }, + + extend = function(/*Object*/ constructor, /*Object...*/ props){ + // summary: + // Adds all properties and methods of props to constructor's + // prototype, making them available to all instances created with + // constructor. + for(var i=1, l=arguments.length; i 2){ + return _hitchArgs.apply(dojo, arguments); // Function + } + if(!method){ + method = scope; + scope = null; + } + if(isString(method)){ + scope = scope || dojo.global; + if(!scope[method]){ throw(['dojo.hitch: scope["', method, '"] is null (scope="', scope, '")'].join('')); } + return function(){ return scope[method].apply(scope, arguments || []); }; // Function + } + return !scope ? method : function(){ return method.apply(scope, arguments || []); }; // Function + }, + + /*===== + dojo.delegate = function(obj, props){ + // summary: + // Returns a new object which "looks" to obj for properties which it + // does not have a value for. Optionally takes a bag of properties to + // seed the returned object with initially. + // description: + // This is a small implementaton of the Boodman/Crockford delegation + // pattern in JavaScript. An intermediate object constructor mediates + // the prototype chain for the returned object, using it to delegate + // down to obj for property lookup when object-local lookup fails. + // This can be thought of similarly to ES4's "wrap", save that it does + // not act on types but rather on pure objects. + // obj: + // The object to delegate to for properties not found directly on the + // return object or in props. + // props: + // an object containing properties to assign to the returned object + // returns: + // an Object of anonymous type + // example: + // | var foo = { bar: "baz" }; + // | var thinger = dojo.delegate(foo, { thud: "xyzzy"}); + // | thinger.bar == "baz"; // delegated to foo + // | foo.thud == undefined; // by definition + // | thinger.thud == "xyzzy"; // mixed in from props + // | foo.bar = "thonk"; + // | thinger.bar == "thonk"; // still delegated to foo's bar } - if(has("bug-for-in-skips-shadowed")){ - var extraNames = dojo._extraNames; - for(i = extraNames.length; i;){ - name = extraNames[--i]; + =====*/ + + 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){ + _mixin(tmp, props); + } + return tmp; // Object + }; + })(), + + /*===== + dojo._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. + } + =====*/ + + efficient = function(obj, offset, startWith){ + return (startWith||[]).concat(Array.prototype.slice.call(obj, offset||0)); + }, + + _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, + + partial = function(/*Function|String*/method /*, ...*/){ + // summary: + // similar to hitch() except that the scope object is left to be + // whatever the execution context eventually becomes. + // description: + // Calling dojo.partial is the functional equivalent of calling: + // | dojo.hitch(null, funcName, ...); + var arr = [ null ]; + return hitch.apply(dojo, arr.concat(_toArray(arguments))); // Function + }, + + clone = function(/*anything*/ o){ + // summary: + // Clones objects (including DOM nodes) and all children. + // Warning: do not clone cyclic structures. + if(!o || typeof o != "object" || isFunction(o)){ + // null, undefined, any non-object, or function + return o; // anything + } + if(o.nodeType && "cloneNode" in o){ + // DOM Node + return o.cloneNode(true); // Node + } + if(o instanceof Date){ + // Date + return new Date(o.getTime()); // Date + } + if(o instanceof RegExp){ + // RegExp + return new RegExp(o); // RegExp + } + var r, i, l, s, name; + if(isArray(o)){ + // array + r = []; + for(i = 0, l = o.length; i < l; ++i){ + if(i in o){ + r.push(clone(o[i])); + } + } + // we don't clone functions for performance reasons + // }else if(d.isFunction(o)){ + // // function + // r = function(){ return o.apply(this, arguments); }; + }else{ + // generic objects + r = o.constructor ? new o.constructor() : {}; + } + for(name in o){ + // the "tobj" condition avoid copying properties in "source" + // inherited from Object.prototype. For example, if target has a custom + // toString() method, don't overwrite it with the toString() method + // that source inherited from Object.prototype s = o[name]; if(!(name in r) || (r[name] !== s && (!(name in empty) || empty[name] !== s))){ - r[name] = s; // functions only, we don't clone them + r[name] = clone(s); + } + } + if(has("bug-for-in-skips-shadowed")){ + var extraNames = _extraNames; + for(i = extraNames.length; i;){ + name = extraNames[--i]; + s = o[name]; + if(!(name in r) || (r[name] !== s && (!(name in empty) || empty[name] !== s))){ + r[name] = s; // functions only, we don't clone them + } } } + return r; // Object + }, + + /*===== + dojo.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 + // dojo.string.trim() + return ""; // String } - return r; // Object - }; - - /*===== - dojo.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 - // dojo.string.trim() - return ""; // String - } - =====*/ - - dojo.trim = String.prototype.trim ? - function(str){ return str.trim(); } : - function(str){ return str.replace(/^\s\s*/, '').replace(/\s\s*$/, ''); }; - - /*===== - dojo.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: - // | dojo.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: - // | dojo.replace("Hello, {0} {2}!", - // | ["Robert", "X", "Cringely"]); - // | // returns: Hello, Robert Cringely! - // example: - // | // uses a function for substitutions: - // | function sum(a){ - // | var t = 0; - // | dojo.forEach(a, function(x){ t += x; }); - // | return t; - // | } - // | dojo.replace( - // | "{count} payments averaging {avg} USD per payment.", - // | dojo.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: - // | dojo.replace("Hello, ${0} ${2}!", - // | ["Robert", "X", "Cringely"], /\$\{([^\}]+)\}/g); - // | // returns: Hello, Robert Cringely! - return ""; // String - } - =====*/ - - var _pattern = /\{([^\}]+)\}/g; - dojo.replace = function(tmpl, map, pattern){ - return tmpl.replace(pattern || _pattern, dojo.isFunction(map) ? - map : function(_, k){ return dojo.getObject(k, false, map); }); - }; - - return { - isString: dojo.isString, - isArray: dojo.isArray, - isFunction: dojo.isFunction, - isObject: dojo.isObject, - isArrayLike: dojo.isArrayLike, - isAlien: dojo.isAlien, - extend: dojo.extend, - _hitchArgs: dojo._hitchArgs, - hitch: dojo.hitch, - delegate: dojo.delegate, - _toArray: dojo._toArray, - partial: dojo.partial, - clone: dojo.clone, - trim: dojo.trim, - replace: dojo.replace - }; + =====*/ + + trim = String.prototype.trim ? + function(str){ return str.trim(); } : + function(str){ return str.replace(/^\s\s*/, '').replace(/\s\s*$/, ''); }, + + /*===== + dojo.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: + // | dojo.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: + // | dojo.replace("Hello, {0} {2}!", + // | ["Robert", "X", "Cringely"]); + // | // returns: Hello, Robert Cringely! + // example: + // | // uses a function for substitutions: + // | function sum(a){ + // | var t = 0; + // | dojo.forEach(a, function(x){ t += x; }); + // | return t; + // | } + // | dojo.replace( + // | "{count} payments averaging {avg} USD per payment.", + // | dojo.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: + // | dojo.replace("Hello, ${0} ${2}!", + // | ["Robert", "X", "Cringely"], /\$\{([^\}]+)\}/g); + // | // returns: Hello, Robert Cringely! + return ""; // String + } + =====*/ + + _pattern = /\{([^\}]+)\}/g, + + replace = function(tmpl, map, pattern){ + return tmpl.replace(pattern || _pattern, isFunction(map) ? + map : function(_, k){ return getObject(k, false, map); }); + }, + + lang = { + _extraNames:_extraNames, + _mixin:_mixin, + mixin:mixin, + setObject:setObject, + getObject:getObject, + exists:exists, + isString: isString, + isArray: isArray, + isFunction: isFunction, + isObject: isObject, + isArrayLike: isArrayLike, + isAlien: isAlien, + extend: extend, + _hitchArgs: _hitchArgs, + hitch: hitch, + delegate: delegate, + _toArray: _toArray, + partial: partial, + clone: clone, + trim: trim, + replace: replace + }; + + has("dojo-1x-base") && mixin(dojo, lang); + return lang; }); diff --git a/_base/loader.js b/_base/loader.js index f62a392c9a..3896f5da3a 100644 --- a/_base/loader.js +++ b/_base/loader.js @@ -144,7 +144,7 @@ define(["./kernel", "../has", "require", "module", "./json", "./lang", "./array" // names:["dojo", "dijit", "dojox"], // def: function(){ // dojo.loadInit(function(){ - // var gfx = dojo.getObject("dojox.gfx", true); + // var gfx = lang.getObject("dojox.gfx", true); // // // // // code required to set gfx properties ommitted... @@ -165,7 +165,7 @@ define(["./kernel", "../has", "require", "module", "./json", "./lang", "./array" // dojo.require("dojox.gfx.matrix"); // dojo.require("dojox.gfx._base"); // dojo.require("dojox.gfx." + gfx.renderer); - // return dojo.getObject("dojo.gfx"); + // return lang.getObject("dojo.gfx"); // }); // })(); // @@ -232,7 +232,7 @@ define(["./kernel", "../has", "require", "module", "./json", "./lang", "./array" } bundle.def.apply(null, args); }catch(e){ - signal(errorListeners, [makeErrorToken("failedDojoLoadInit"), e]); + signal("error", [makeErrorToken("failedDojoLoadInit"), e]); }finally{ for(p in syncLoaderApi){ dojo[p] = hold[p]; @@ -444,9 +444,6 @@ define(["./kernel", "../has", "require", "module", "./json", "./lang", "./array" execQ = loaderVars.execQ, - errorListeners = - loaderVars.errorListeners, - fixupUrl = loaderVars.fixupUrl, @@ -473,14 +470,14 @@ define(["./kernel", "../has", "require", "module", "./json", "./lang", "./array" dojo.provide = function(mid){ var executingModule = syncExecStack[0], - module = dojo.mixin(getModule(slashName(mid), require.module), { + module = lang.mixin(getModule(slashName(mid), require.module), { executed:executing, - result:dojo.getObject(mid, true) + result:lang.getObject(mid, true) }); setArrived(module); if(executingModule){ (executingModule.provides || (executingModule.provides = [])).push(function(){ - module.result = dojo.getObject(mid); + module.result = lang.getObject(mid); delete module.provides; module.executed!==executed && finishExec(module); }); @@ -631,8 +628,8 @@ define(["./kernel", "../has", "require", "module", "./json", "./lang", "./array" }; var result = doRequire(moduleName); - if(has("config-publishRequireResult") && !dojo.exists(moduleName) && result!==undefined){ - dojo.setObject(moduleName, result); + if(has("config-publishRequireResult") && !lang.exists(moduleName) && result!==undefined){ + lang.setObject(moduleName, result); } return result; }; diff --git a/_base/sniff.js b/_base/sniff.js index f2592e7c08..d0e8f584d5 100644 --- a/_base/sniff.js +++ b/_base/sniff.js @@ -7,7 +7,11 @@ define(["./kernel", "../has"], function(dojo, has){ if(!has("host-browser")){ return has; } - var + + dojo.isBrowser = true, + dojo._name = "browser"; + + var hasAdd = has.add, n = navigator, dua = n.userAgent, dav = n.appVersion, @@ -101,18 +105,7 @@ define(["./kernel", "../has"], function(dojo, has){ }); =====*/ - dojo.isBrowser = true, - dojo._name = "browser"; - // fill in the rendering support information in dojo.render.* - if(dua.indexOf("Opera") >= 0){ - isOpera = tv; - // 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 - if(isOpera >= 9.8){ - isOpera = parseFloat(dua.split("Version/")[1]) || tv; - } - } if(dua.indexOf("AdobeAIR") >= 0){ isAIR = 1; } isKhtml = (dav.indexOf("Konqueror") >= 0) ? tv : 0; isWebKit = parseFloat(dua.split("WebKit/")[1]) || undefined; @@ -136,6 +129,15 @@ define(["./kernel", "../has"], function(dojo, has){ } if (!has("dojo-webkit")) { + if(dua.indexOf("Opera") >= 0){ + isOpera = tv; + // 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 + if(isOpera >= 9.8){ + isOpera = parseFloat(dua.split("Version/")[1]) || tv; + } + } + if(dua.indexOf("Gecko") >= 0 && !isKhtml && !isWebKit){ isMozilla = isMoz = tv; } @@ -156,59 +158,34 @@ define(["./kernel", "../has"], function(dojo, has){ isIE = mode; } } - - //Workaround to get local file loads of dojo to work on IE 7 - //by forcing to not use native xhr. - if(isIE && window.location.protocol === "file:"){ - //TODO: look at this with respect to v1.7 loader changes - dojo.config.ieForceActiveXXhr=true; - } } - dojo.locale = dojo.locale || (isIE ? n.userLanguage : n.language).toLowerCase(); isQuirks = document.compatMode == "BackCompat"; - has.add("opera", dojo.isOpera = isOpera); - has.add("air", dojo.isAIR = isAIR); - has.add("khtml", dojo.isKhtml = isKhtml); - has.add("webKit", dojo.isWebKit = isWebKit); - has.add("chrome", dojo.isChrome = isChrome); - has.add("mac", dojo.isMac = isMac ); - has.add("safari", dojo.isSafari = isSafari); - has.add("mozilla", dojo.isMozilla = dojo.isMoz = isMozilla ); - has.add("ie", dojo.isIE = isIE ); - has.add("ff", dojo.isFF = isFF); - has.add("quirks", dojo.isQuirks = isQuirks); - has.add("ios", dojo.isIos = isIos); + hasAdd("opera", dojo.isOpera = isOpera); + hasAdd("air", dojo.isAIR = isAIR); + hasAdd("khtml", dojo.isKhtml = isKhtml); + hasAdd("webKit", dojo.isWebKit = isWebKit); + hasAdd("chrome", dojo.isChrome = isChrome); + hasAdd("mac", dojo.isMac = isMac ); + hasAdd("safari", dojo.isSafari = isSafari); + hasAdd("mozilla", dojo.isMozilla = dojo.isMoz = isMozilla ); + hasAdd("ie", dojo.isIE = isIE ); + hasAdd("ff", dojo.isFF = isFF); + hasAdd("quirks", dojo.isQuirks = isQuirks); + hasAdd("ios", dojo.isIos = isIos); + + dojo.locale = dojo.locale || (isIE ? n.userLanguage : n.language).toLowerCase(); + dojo._isDocumentOk = function(http){ var stat = http.status || 0; - return (stat >= 200 && stat < 300) || // Boolean - stat == 304 || // allow any 2XX response code - stat == 1223 || // get it out of the cache - // Internet Explorer mangled the status code - !stat; // OR we're Titanium/browser chrome/chrome extension requesting a local file + stat = + (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 + return stat; // Boolean }; - has.add("vml", isIE); - if (has("vml")) { - // TODO: can this be moved to a more-appropriate module? - // TODO: can the try-catch be removed if we know that vml is supported? - try{ - (function(){ - document.namespaces.add("v", "urn:schemas-microsoft-com:vml"); - var vmlElems = ["*", "group", "roundrect", "oval", "shape", "rect", "imagedata", "path", "textpath", "text"], - i = 0, l = 1, s = document.createStyleSheet(); - if(isIE >= 8){ - i = 1; - l = vmlElems.length; - } - for(; i < l; ++i){ - s.addRule("v\\:" + vmlElems[i], "behavior:url(#default#VML); display:inline-block"); - } - })(); - }catch(e){} - } - return has; - }); \ No newline at end of file diff --git a/_base/xhr.js b/_base/xhr.js index ff3d521790..abdec8395e 100644 --- a/_base/xhr.js +++ b/_base/xhr.js @@ -1,4 +1,4 @@ -define(["./kernel", "./sniff", "require", "../on", "../io-query", "../dom-form", "./Deferred", "./json", "./lang"], function(dojo, has, require, on, ioq, domForm){ +define(["./kernel", "./sniff", "require", "../on", "../io-query", "../dom-form", "./Deferred", "./json", "./lang"], function(dojo, has, require, on, ioq, domForm, deferred, json, lang){ // module: // dojo/_base.xhr // summary: @@ -784,7 +784,7 @@ define(["./kernel", "./sniff", "require", "../on", "../io-query", "../dom-form", */ // Add aliases for static functions to dojo.xhr since dojo.xhr is what's returned from this module - dojo.mixin(dojo.xhr, { + lang.mixin(dojo.xhr, { _xhrObj: dojo._xhrObj, fieldToObject: dojo.fieldToObject, formToObject: dojo.formToObject, diff --git a/cldr/supplemental.js b/cldr/supplemental.js index d9ef0f5e9f..83088ae3be 100644 --- a/cldr/supplemental.js +++ b/cldr/supplemental.js @@ -1,10 +1,10 @@ -define(["../_base/kernel", "../i18n"], function(dojo) { +define(["../_base/kernel", "../_base/lang", "../i18n"], function(dojo, lang) { // module: // dojo/cldr/supplemental // summary: // TODOC -dojo.getObject("cldr.supplemental", true, dojo); +lang.getObject("cldr.supplemental", true, dojo); dojo.cldr.supplemental.getFirstDayOfWeek = function(/*String?*/locale){ // summary: Returns a zero-based index for first day of the week diff --git a/colors.js b/colors.js index b2199f8e0c..98d784deec 100644 --- a/colors.js +++ b/colors.js @@ -1,15 +1,15 @@ -define(["./_base/kernel", "./_base/Color", "./_base/array"], function(dojo) { +define(["./_base/kernel", "./_base/lang", "./_base/Color", "./_base/array"], function(dojo, lang) { // module: // dojo/colors // summary: // TODOC - dojo.getObject("colors", true, dojo); + lang.getObject("colors", true, dojo); //TODO: this module appears to break naming conventions /*===== - dojo.mixin(dojo, { + lang.mixin(dojo, { colors: { // summary: Color utilities, extending Base dojo.Color } @@ -94,7 +94,7 @@ define(["./_base/kernel", "./_base/Color", "./_base/array"], function(dojo) { }; // mixin all CSS3 named colors not already in _base, along with SVG 1.0 variant spellings - dojo.mixin(dojo.Color.named, { + lang.mixin(dojo.Color.named, { "aliceblue": [240,248,255], "antiquewhite": [250,235,215], "aquamarine": [127,255,212], diff --git a/currency.js b/currency.js index 718a554d4e..9d11d14018 100644 --- a/currency.js +++ b/currency.js @@ -1,10 +1,10 @@ -define(["./_base/kernel", "./_base/array", "./number", "./i18n", "./i18n!./cldr/nls/currency", "./cldr/monetary"], function(dojo) { +define(["./_base/kernel", "./_base/lang", "./_base/array", "./number", "./i18n", "./i18n!./cldr/nls/currency", "./cldr/monetary"], function(dojo, lang) { // module: // dojo/currency // summary: // TODOC -dojo.getObject("currency", true, dojo); +lang.getObject("currency", true, dojo); /*===== dojo.currency = { @@ -38,7 +38,7 @@ dojo.currency._mixInDefaults = function(options){ data.fractional = [true, false]; // Mixin with provided options - return dojo.mixin(data, options); + return lang.mixin(data, options); }; /*===== diff --git a/date.js b/date.js index d54b4700cb..f3571e890f 100644 --- a/date.js +++ b/date.js @@ -1,10 +1,10 @@ -define(["./_base/kernel"], function(dojo) { +define(["./_base/kernel", "./_base/lang"], function(dojo, lang) { // module: // dojo/date // summary: // TODOC -dojo.getObject("date", true, dojo); +lang.getObject("date", true, dojo); /*===== dojo.date = { diff --git a/date/locale.js b/date/locale.js index 49cffcf05e..0f1ca1b7a3 100644 --- a/date/locale.js +++ b/date/locale.js @@ -1,19 +1,19 @@ define([ "../_base/kernel", - "../_base/array", "../_base/lang", + "../_base/array", "../date", "../cldr/supplemental", "../regexp", "../string", "../i18n!../cldr/nls/gregorian" -], function(dojo) { +], function(dojo, lang, array) { // module: // dojo/date/locale // summary: // This modules defines dojo.date.locale, localization methods for Date. -dojo.getObject("date.locale", true, dojo); +lang.getObject("date.locale", true, dojo); // Localization methods for Date. Honor local customs using locale-dependent dojo.cldr data. @@ -598,7 +598,7 @@ dojo.date.locale._getGregorianBundle = function(/*String*/locale){ var gregorian = {}; dojo.forEach(_customFormats, function(desc){ var bundle = dojo.i18n.getLocalization(desc.pkg, desc.name, locale); - gregorian = dojo.mixin(gregorian, bundle); + gregorian = lang.mixin(gregorian, bundle); }, this); return gregorian; /*Object*/ }; diff --git a/date/stamp.js b/date/stamp.js index b876ce6c54..7168059b45 100644 --- a/date/stamp.js +++ b/date/stamp.js @@ -1,10 +1,10 @@ -define(["../_base/kernel", "../_base/array"], function(dojo) { +define(["../_base/kernel", "../_base/lang", "../_base/array"], function(dojo, lang) { // module: // dojo/date/stamp // summary: // TODOC -dojo.getObject("date.stamp", true, dojo); +lang.getObject("date.stamp", true, dojo); // Methods to convert dates to or from a wire (string) format using well-known conventions diff --git a/dojo.js b/dojo.js index 66ac84dbf5..12eb8c1516 100644 --- a/dojo.js +++ b/dojo.js @@ -147,9 +147,7 @@ // 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.nodeRequire = require; - // recompute userConfig because passed userConfig argument was wrong in node - userConfig = global.dojoConfig || global.djConfig || global.require || {}; + defaultConfig.loaderPatch.nodeRequire = require; } has.add("host-rhino", typeof load == "function" && (typeof Packages == "function" || typeof Packages == "object")); @@ -200,7 +198,7 @@ } if(has("dojo-sync-loader")){ - var legacyMode = req.legacyMode || 0, + var legacyMode = 0, sync = "sync", xd = "xd", syncExecStack = [], @@ -209,6 +207,37 @@ transformToAmd = noop, getXhr; + req.isXdUrl = noop; + req.initSyncLoader = function(dojoRequirePlugin_, checkDojoRequirePlugin_, transformToAmd_, isXdUrl_){ + if(!dojoRequirePlugin){ + dojoRequirePlugin = dojoRequirePlugin_; + checkDojoRequirePlugin = checkDojoRequirePlugin_; + transformToAmd = transformToAmd_; + req.isXdUrl = isXdUrl_; + } + return { + sync:sync, + xd:xd, + 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, + fixupUrl:fixupUrl, + getLegacyMode:function(){return legacyMode;} + }; + }; + if(has("dom")){ // in legacy sync mode, the loader needs a minimal XHR library to load dojo/_base/loader and ojo/_base/xhr; // when dojo/_base/loader pushes the sync loader machinery into the loader (via initSyncLoader), getText is @@ -259,135 +288,133 @@ } } - // lexical variables that hold key loader data structures; may be completely initialized by - // defaultConfig for optimized/built versions of the loader. - mix(req, defaultConfig); - delete req.packages; - var reqEval, paths, aliases, pathsMapProg, packs, packageMap, packageMapProg, modules, cache, cacheBust, pendingCacheInsert = {}; - if(has("dojo-auto-init")){ - paths = req.paths; - pathsMapProg = req.pathsMapProg; - packs = req.packs; - aliases = req.aliases; - packageMap = req.packageMap; - packageMapProg = req.packageMapProg; - modules = req.modules; - cache = req.cache; - cacheBust = req.cacheBust; - }else{ - // CommonJS paths - 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 - - aliases = - // a vector of pairs of regexs and second args to replace - [], - - packageMap = {}; - // map from package name to local-installed package name - - packageMapProg = []; - // list of (from-package, to-package, regex, length) derived from packageMap; - // a "program" to apply paths; see computeMapProg - - // A hash:(mid) --> (module-object). module objects are simple JavaScript objects with the - // following properties: - // - // 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 tranversing 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: (requested | arrived | nonmodule) 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 evalated. - // - // 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. - modules = {}; - - /// - // hash:(mid)-->(function) - /// - // Gives the contents of a cached resource; function should cause the same actions as if the given mid was downloaded - // and evaluated by the host environment - cache = {}; - - cacheBust = ""; - } - - + // + // loader eval + // var eval_ = // use the function constructor so our eval is scoped close to (but not in) in the global space with minimal pollution new Function("__text", 'return eval(__text);'); - reqEval = req.eval || + req.eval = function(text, hint){ return eval_(text + "\r\n////@ sourceURL=" + hint); }; - var listenerConnection= function(listener, queue){ - queue.push(listener); - this.l = listener; - this.q = queue; - }; - - listenerConnection.prototype.remove= function(){ - for(var queue = this.q, listener = this.l, i = 0; i (alias, actual) + = [], - // - // configuration machinery (with an optimized/built defaultConfig, this can be discarded) - // - if(has("dojo-config-api")){ - var configListeners = - // vector of registered listener functions for config changes - listenerQueues.config = [], + 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 + = {}, + + packageMap + // map from package name to local-installed package name + = {}, + + packageMapProg + // list of (from-package, to-package, regex, length) derived from packageMap; + // a "program" to apply paths; see computeMapProg + = [], + + 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 tranversing 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: (requested | arrived | nonmodule) 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 evalated. + // + // 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 + = "", - consumePendingCacheInsert = function(referenceModule){ + cache + // hash:(mid)-->(function) + // + // Gives the contents of a cached resource; function should cause the same actions as if the given mid was downloaded + // and evaluated by the host environment + = {}, + + 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) + = {}; + + if(has("dojo-config-api")){ + var consumePendingCacheInsert = function(referenceModule){ for(var p in pendingCacheInsert){ cache[getModuleInfo(p, referenceModule).mid] = pendingCacheInsert[p]; } @@ -434,6 +461,7 @@ } // allow paths to be specified in the package info + // TODO: this is not supported; remove mix(paths, packageInfo.paths); // now that we've got a fully-resolved package object, push it into the configuration @@ -441,50 +469,44 @@ packageMap[name] = name; }, - configVariableNames = {waitSeconds:1, cacheBust:1, baseUrl:1, locale:1, combo:1}, - config = function(config, booting){ - var p; - - // make sure baseUrl ends with a slash - if(config.baseUrl && !/\/$/.test(config.baseUrl)){ - config.baseUrl += "/"; - } - - for(p in config){ - if(configVariableNames[p]){ + for(var p in config){ + if(p=="waitSeconds"){ + req.waitms = (config[p] || 0) * 1000; + } + if(p=="cacheBust"){ + cacheBust = config[p] ? (new Date()).getTime() + "" : ""; + } + if(p=="baseUrl" || p=="combo"){ req[p] = config[p]; } + if(has("dojo-sync-loader") && 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 + 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]; has.add("config-"+p, config[p], 0, booting); } } - req.waitms = (req.waitSeconds || 0) * 1000; - - // TODO: this is from v1.6-; why do we need the toString and replace...can't the config be assumed correct? - cacheBust = ((req.cacheBust || "")+"").replace(/\W+/g,""); // make sure baseUrl exists if(!req.baseUrl){ req.baseUrl = "./"; } - - if(has("dojo-sync-loader")){ - // 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 - var mode = config.async; - if(mode!==undefined){ - req.legacyMode = legacyMode = (isString(mode) && /sync|legacyAsync/.test(mode) ? mode : (!mode ? "sync" : false)); - req.async = !legacyMode; - } + // make sure baseUrl ends with a slash + if(!/\/$/.test(req.baseUrl)){ + req.baseUrl += "/"; } - // now do the special work for has, packagePaths, packages, paths, deps, callback, and ready + // 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); @@ -500,9 +522,6 @@ }); } - // backcompat - config.modulePaths && !config.paths && (config.paths= config.modulePaths); - // push in any paths and recompute the internal pathmap // warning: this cann't be done until the package config is processed since packages may include path info computeMapProg(mix(paths, config.paths), pathsMapProg); @@ -519,31 +538,19 @@ computeMapProg(mix(packageMap, config.packageMap), packageMapProg); // push in any new cache values - if(config.cache){ consumePendingCacheInsert(); pendingCacheInsert = config.cache; pendingCacheInsert["*immediate"] && consumePendingCacheInsert(); } - - (function(deps, callback){ - var args = ((deps && deps.length) || callback) && [deps || [], callback || noop]; - if(booting){ - args && (req.bootRequire= args); - }else{ - args && req(args[0], args[1]); - } - })(config.deps, config.callback); - - signal(configListeners, [config, req.rawConfig]); + signal("config", [config, req.rawConfig]); }; // // execute the various sniffs // - var dojoSniffConfig = {}; if(has("dojo-sniff")){ for(var src, match, scripts = doc.getElementsByTagName("script"), i = 0; i < scripts.length && !match; i++){ if((src = scripts[i].getAttribute("src")) && (match = src.match(/(.*)\/?dojo\.js(\W|$)/i))){ @@ -553,7 +560,7 @@ // see if there's a dojo configuration stuffed into the node src = (scripts[i].getAttribute("data-dojo-config") || scripts[i].getAttribute("djConfig")); if(src){ - dojoSniffConfig = reqEval("({ " + src + " })", "data-dojo-config"); + dojoSniffConfig = req.eval("({ " + src + " })", "data-dojo-config"); } if(has("dojo-requirejs-api")){ var dataMain = scripts[i].getAttribute("data-main"); @@ -580,6 +587,20 @@ config(defaultConfig, 1); 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; + packageMap = defaultConfig.packageMap; + packageMapProg = defaultConfig.packageMapProg; + modules = defaultConfig.modules; + cache = defaultConfig.cache; + cacheBust = defaultConfig.cacheBust; + + // remember the default config for other processes (e.g., dojo/config) + req.rawConfig = defaultConfig; } // build the loader machinery iaw configuration, including has feature tests @@ -631,7 +652,7 @@ } // construct a synthetic module to control execution of the requestList, and, optionally, callback - syntheticMid = uid(); + syntheticMid = "require*" + uid(); module = mix(makeModuleInfo("", syntheticMid, 0, ""), { injected: arrived, deps: deps, @@ -736,7 +757,7 @@ makeModuleInfo = function(pid, mid, pack, url){ if(has("dojo-sync-loader")){ - var xd= isXdUrl(url); + 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}; @@ -888,7 +909,7 @@ has("dojo-sync-loader") && syncExecStack.shift(module); if(!ok){ module.result = factoryThrew; - signal(errorListeners, [factoryThrew, module]); + signal(error, [factoryThrew, module]); } } @@ -998,7 +1019,7 @@ checkCompleteGuard--; } if(execComplete()){ - signal(idleListeners, []); + signal("idle", []); } }; @@ -1082,7 +1103,7 @@ if(text===cached){ cache[module.mid].call(null); }else{ - reqEval(text, module.mid); + req.eval(text, module.mid); } }finally{ injectingCachedModule = 0; @@ -1202,13 +1223,13 @@ } }; - req.trace("loader-inject", ["xhr", legacyMode!=sync, module.mid, url]); + req.trace("loader-inject", ["xhr", module.mid, url, legacyMode!=sync]); var ok = 0; try{ req.getText(url, legacyMode!=sync, xhrCallback); ok = 1; }finally{ - !ok && signal(errorListeners, [makeErrorToken("xhrFailed"), module]); + !ok && signal(error, [makeErrorToken("xhrFailed"), module]); } return; } @@ -1224,7 +1245,7 @@ var mid = module.mid; if(module.injected === arrived){ - signal(errorListeners, [makeErrorToken("multipleDefine"), module]); + signal(error, [makeErrorToken("multipleDefine"), module]); return module; } mix(module, { @@ -1294,7 +1315,7 @@ clearTimer(); req.waitms && (timerId = setTimeout(function(){ clearTimer(); - signal(errorListeners, [makeErrorToken("timeout"), waiting]); + signal(error, [makeErrorToken("timeout"), waiting]); }, req.waitms)); }; } @@ -1304,7 +1325,7 @@ } if(has("dom") && (has("dojo-inject-api") || has("dojo-dom-ready-api"))){ - var on = function(node, eventName, ieEventName, handler){ + var domOn = function(node, eventName, ieEventName, handler){ // Add an event listener to a DOM node using the API appropriate for the current browser; // return a function that will disconnect the listener. if(!has("ie-event-behavior")){ @@ -1319,45 +1340,44 @@ }; } }, - windowOnLoadListener = on(window, "load", "onload", function(){ + windowOnLoadListener = domOn(window, "load", "onload", function(){ req.pageLoaded = 1; doc.readyState!="complete" && (doc.readyState = "complete"); windowOnLoadListener(); }); - } - if(has("dom") && has("dojo-inject-api")){ - // if the loader is on the page, there must be at least one script element - // getting its parent and then doing insertBefore solves the "Operation Aborted" - // error in IE from appending to a node that isn't properly closed; see - // dojo/tests/_base/loader/requirejs/simple-badbase.html for an example - var sibling = doc.getElementsByTagName("script")[0], - insertPoint= sibling.parentNode; - req.injectUrl = req.injectUrl || function(url, callback, owner){ - // insert a script element to the insert-point element with src=url; - // apply callback upon detecting the script has loaded. - - startTimer(); - var node = owner.node = doc.createElement("script"), - onLoad = function(e){ - e = e || window.event; - var node = e.target || e.srcElement; - if(e.type === "load" || /complete|loaded/.test(node.readyState)){ - disconnector(); - callback && callback(); - } - }, - disconnector = on(node, "load", "onreadystatechange", onLoad); - node.type = "text/javascript"; - node.charset = "utf-8"; - node.src = url; - insertPoint.insertBefore(node, sibling); - return node; - }; + if(has("dojo-inject-api")){ + // if the loader is on the page, there must be at least one script element + // getting its parent and then doing insertBefore solves the "Operation Aborted" + // error in IE from appending to a node that isn't properly closed; see + // dojo/tests/_base/loader/requirejs/simple-badbase.html for an example + var sibling = doc.getElementsByTagName("script")[0], + insertPoint= sibling.parentNode; + req.injectUrl = function(url, callback, owner){ + // insert a script element to the insert-point element with src=url; + // apply callback upon detecting the script has loaded. + + startTimer(); + var node = owner.node = doc.createElement("script"), + onLoad = function(e){ + e = e || window.event; + var node = e.target || e.srcElement; + if(e.type === "load" || /complete|loaded/.test(node.readyState)){ + disconnector(); + callback && callback(); + } + }, + disconnector = domOn(node, "load", "onreadystatechange", onLoad); + node.type = "text/javascript"; + node.charset = "utf-8"; + node.src = url; + insertPoint.insertBefore(node, sibling); + return node; + }; + } } if(has("dojo-log-api")){ - // if you want to replace the req.log API, pass in a default config and make has("dojo-log-api") falsy req.log = function(){ try{ for(var i = 0; i < arguments.length; i++){ @@ -1365,12 +1385,12 @@ } }catch(e){} }; + }else{ + req.log = noop; } - req.log && req.on("error", req.log); if(has("dojo-trace-api")){ - listenerQueues.trace= []; - var trace = function( + var trace = req.trace = function( group, // the trace group to which this application belongs args // the contents of the trace ){ @@ -1380,14 +1400,12 @@ // Sends the contents of args to the console iff (req.trace.on && req.trace[group]) if(trace.on && trace.group[group]){ - signal(listenerQueues.trace, [group, args]); - for(var text= group + ":" + args[0], i= 1; i>excludeStart("replaceLoaderConfig", kwArgs.replaceLoaderConfig); ( // userConfig - this.dojoConfig || this.djConfig || this.require || {}, + (function(){ + // make sure we're looking at global dojoConfig etc. + return this.dojoConfig || this.djConfig || this.require || {}; + })(), // default config { @@ -1609,7 +1604,7 @@ "config-tlmSiblingOfDojo":1, "dojo-sync-loader":1, "dojo-test-sniff":1, - "dojo-xdomain-test-api":1 + "dojo-1x-base":1 }, packages:[{ // note: like v1.6-, this bootstrap computes baseUrl to be the dojo directory @@ -1646,10 +1641,4 @@ async:0 } ); -(function(){ - // must use this.require to make this work in node.js - var require = this.require; - !require.async && require(["dojo"]); - require.bootRequire && require.apply(null, require.bootRequire); -})(); //>>excludeEnd("replaceLoaderConfig") diff --git a/i18n.js b/i18n.js index d785d28022..72fa4a8cda 100644 --- a/i18n.js +++ b/i18n.js @@ -74,7 +74,7 @@ define(["./_base/kernel", "require", "./has", "./_base/array", "./_base/lang", " availableLocales= getAvailableLocales(!root._v1x && root, locale, bundlePath, bundleName); require(availableLocales, function(){ for (var i= 1; i script[type^='dojo/']", node)); @@ -316,7 +316,7 @@ dojo.parser = new function(){ // map it to the JS namespace if that makes sense if(jsname){ - dojo.setObject(jsname, instance); + dlang.setObject(jsname, instance); } // process connections and startup functions @@ -547,7 +547,7 @@ dojo.parser = new function(){ }; // If dojoType/data-dojo-type specified, add to output array of nodes to instantiate - var ctor = type && (_ctorMap[type] || (_ctorMap[type] = dojo.getObject(type))), // note: won't find classes declared via dojo.Declaration + var ctor = type && (_ctorMap[type] || (_ctorMap[type] = dlang.getObject(type))), // note: won't find classes declared via dojo.Declaration childScripts = ctor && !ctor.prototype._noScript ? [] : null; //