You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@struts.apache.org by mu...@apache.org on 2007/08/25 01:47:38 UTC
svn commit: r569576 [3/10] - in
/struts/struts2/trunk/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo:
./ src/ src/animation/ src/cal/ src/charting/ src/charting/svg/
src/charting/vml/ src/collections/ src/crypto/ src/data/ src/data/core...
Modified: struts/struts2/trunk/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/dojo.js.uncompressed.js
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/dojo.js.uncompressed.js?rev=569576&r1=569575&r2=569576&view=diff
==============================================================================
--- struts/struts2/trunk/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/dojo.js.uncompressed.js (original)
+++ struts/struts2/trunk/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/dojo.js.uncompressed.js Fri Aug 24 16:47:20 2007
@@ -99,8 +99,8 @@
//TODOC: HOW TO DOC THIS?
dojo.version = {
// summary: version number of this instance of dojo.
- major: 0, minor: 4, patch: 2, flag: "",
- revision: Number("$Rev: 7616 $".match(/[0-9]+/)[0]),
+ major: 0, minor: 4, patch: 3, flag: "",
+ revision: Number("$Rev: 8617 $".match(/[0-9]+/)[0]),
toString: function(){
with(dojo.version){
return major + "." + minor + "." + patch + flag + " (" + revision + ")"; // String
@@ -1390,8 +1390,10 @@
return true;
}
+ dojo.hostenv._djInitFired = false;
// BEGIN DOMContentLoaded, from Dean Edwards (http://dean.edwards.name/weblog/2006/06/again/)
function dj_load_init(e){
+ dojo.hostenv._djInitFired = true;
// allow multiple calls, only first one will take effect
// A bug in khtml calls events callbacks for document for event which isnt supported
// for example a created contextmenu event calls DOMContentLoaded, workaround
@@ -1658,6 +1660,78 @@
dojo.requireIf(djConfig["debugAtAllCosts"] && !window.widget && !djConfig["useXDomain"], "dojo.browser_debug");
dojo.requireIf(djConfig["debugAtAllCosts"] && !window.widget && djConfig["useXDomain"], "dojo.browser_debug_xd");
+dojo.provide("dojo.string.common");
+
+dojo.string.trim = function(/* string */str, /* integer? */wh){
+ // summary
+ // Trim whitespace from str. If wh > 0, trim from start, if wh < 0, trim from end, else both
+ if(!str.replace){ return str; }
+ if(!str.length){ return str; }
+ var re = (wh > 0) ? (/^\s+/) : (wh < 0) ? (/\s+$/) : (/^\s+|\s+$/g);
+ return str.replace(re, ""); // string
+}
+
+dojo.string.trimStart = function(/* string */str) {
+ // summary
+ // Trim whitespace at the beginning of 'str'
+ return dojo.string.trim(str, 1); // string
+}
+
+dojo.string.trimEnd = function(/* string */str) {
+ // summary
+ // Trim whitespace at the end of 'str'
+ return dojo.string.trim(str, -1);
+}
+
+dojo.string.repeat = function(/* string */str, /* integer */count, /* string? */separator) {
+ // summary
+ // Return 'str' repeated 'count' times, optionally placing 'separator' between each rep
+ var out = "";
+ for(var i = 0; i < count; i++) {
+ out += str;
+ if(separator && i < count - 1) {
+ out += separator;
+ }
+ }
+ return out; // string
+}
+
+dojo.string.pad = function(/* string */str, /* integer */len/*=2*/, /* string */ c/*='0'*/, /* integer */dir/*=1*/) {
+ // summary
+ // Pad 'str' to guarantee that it is at least 'len' length with the character 'c' at either the
+ // start (dir=1) or end (dir=-1) of the string
+ var out = String(str);
+ if(!c) {
+ c = '0';
+ }
+ if(!dir) {
+ dir = 1;
+ }
+ while(out.length < len) {
+ if(dir > 0) {
+ out = c + out;
+ } else {
+ out += c;
+ }
+ }
+ return out; // string
+}
+
+dojo.string.padLeft = function(/* string */str, /* integer */len, /* string */c) {
+ // summary
+ // same as dojo.string.pad(str, len, c, 1)
+ return dojo.string.pad(str, len, c, 1); // string
+}
+
+dojo.string.padRight = function(/* string */str, /* integer */len, /* string */c) {
+ // summary
+ // same as dojo.string.pad(str, len, c, -1)
+ return dojo.string.pad(str, len, c, -1); // string
+}
+
+dojo.provide("dojo.string");
+
+
dojo.provide("dojo.lang.common");
dojo.lang.inherits = function(/*Function*/subclass, /*Function*/superclass){
@@ -1902,364 +1976,91 @@
// end Crockford functions
-dojo.provide("dojo.lang.array");
+dojo.provide("dojo.lang.extras");
-// FIXME: Is this worthless since you can do: if(name in obj)
-// is this the right place for this?
+dojo.lang.setTimeout = function(/*Function*/func, /*int*/delay /*, ...*/){
+ // summary:
+ // Sets a timeout in milliseconds to execute a function in a given
+ // context with optional arguments.
+ // usage:
+ // dojo.lang.setTimeout(Object context, function func, number delay[, arg1[, ...]]);
+ // dojo.lang.setTimeout(function func, number delay[, arg1[, ...]]);
-dojo.lang.mixin(dojo.lang, {
- has: function(/*Object*/obj, /*String*/name){
- // summary: is there a property with the passed name in obj?
- try{
- return typeof obj[name] != "undefined"; // Boolean
- }catch(e){ return false; } // Boolean
- },
+ var context = window, argsStart = 2;
+ if(!dojo.lang.isFunction(func)){
+ context = func;
+ func = delay;
+ delay = arguments[2];
+ argsStart++;
+ }
- isEmpty: function(/*Object*/obj){
- // summary:
- // can be used to determine if the passed object is "empty". In
- // the case of array-like objects, the length, property is
- // examined, but for other types of objects iteration is used to
- // examine the iterable "surface area" to determine if any
- // non-prototypal properties have been assigned. This iteration is
- // prototype-extension safe.
- if(dojo.lang.isObject(obj)){
- var tmp = {};
- var count = 0;
- for(var x in obj){
- if(obj[x] && (!tmp[x])){
- count++;
- break;
- }
- }
- return count == 0; // boolean
- }else if(dojo.lang.isArrayLike(obj) || dojo.lang.isString(obj)){
- return obj.length == 0; // boolean
- }
- },
+ if(dojo.lang.isString(func)){
+ func = context[func];
+ }
+
+ var args = [];
+ for (var i = argsStart; i < arguments.length; i++){
+ args.push(arguments[i]);
+ }
+ return dojo.global().setTimeout(function(){ func.apply(context, args); }, delay); // int
+}
- map: function(/*Array*/arr, /*Object|Function*/obj, /*Function?*/unary_func){
- // summary:
- // returns a new array constituded from the return values of
- // passing each element of arr into unary_func. The obj parameter
- // may be passed to enable the passed function to be called in
- // that scope. In environments that support JavaScript 1.6, this
- // function is a passthrough to the built-in map() function
- // provided by Array instances. For details on this, see:
- // http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:map
- // examples:
- // dojo.lang.map([1, 2, 3, 4], function(item){ return item+1 });
- // // returns [2, 3, 4, 5]
- var isString = dojo.lang.isString(arr);
- if(isString){
- // arr: String
- arr = arr.split("");
- }
- if(dojo.lang.isFunction(obj)&&(!unary_func)){
- unary_func = obj;
- obj = dj_global;
- }else if(dojo.lang.isFunction(obj) && unary_func){
- // ff 1.5 compat
- var tmpObj = obj;
- obj = unary_func;
- unary_func = tmpObj;
+dojo.lang.clearTimeout = function(/*int*/timer){
+ // summary: clears timer by number from the execution queue
+
+ // FIXME:
+ // why do we have this function? It's not portable outside of browser
+ // environments and it's a stupid wrapper on something that browsers
+ // provide anyway.
+ dojo.global().clearTimeout(timer);
+}
+
+dojo.lang.getNameInObj = function(/*Object*/ns, /*unknown*/item){
+ // summary:
+ // looks for a value in the object ns with a value matching item and
+ // returns the property name
+ // ns: if null, dj_global is used
+ // item: value to return a name for
+ if(!ns){ ns = dj_global; }
+
+ for(var x in ns){
+ if(ns[x] === item){
+ return new String(x); // String
}
- if(Array.map){
- var outArr = Array.map(arr, unary_func, obj);
- }else{
- var outArr = [];
- for(var i=0;i<arr.length;++i){
- outArr.push(unary_func.call(obj, arr[i]));
+ }
+ return null; // null
+}
+
+dojo.lang.shallowCopy = function(/*Object*/obj, /*Boolean?*/deep){
+ // summary:
+ // copies object obj one level deep, or full depth if deep is true
+ var i, ret;
+
+ if(obj === null){ /*obj: null*/ return null; } // null
+
+ if(dojo.lang.isObject(obj)){
+ // obj: Object
+ ret = new obj.constructor();
+ for(i in obj){
+ if(dojo.lang.isUndefined(ret[i])){
+ ret[i] = deep ? dojo.lang.shallowCopy(obj[i], deep) : obj[i];
}
}
- if(isString) {
- return outArr.join(""); // String
- } else {
- return outArr; // Array
+ }else if(dojo.lang.isArray(obj)){
+ // obj: Array
+ ret = [];
+ for(i=0; i<obj.length; i++){
+ ret[i] = deep ? dojo.lang.shallowCopy(obj[i], deep) : obj[i];
}
- },
+ }else{
+ // obj: Object
+ ret = obj;
+ }
- reduce: function(/*Array*/arr, initialValue, /*Object|Function*/obj, /*Function*/binary_func){
- // summary:
- // similar to Python's builtin reduce() function. The result of
- // the previous computation is passed as the first argument to
- // binary_func along with the next value from arr. The result of
- // this call is used along with the subsequent value from arr, and
- // this continues until arr is exhausted. The return value is the
- // last result. The "obj" and "initialValue" parameters may be
- // safely omitted and the order of obj and binary_func may be
- // reversed. The default order of the obj and binary_func argument
- // will probably be reversed in a future release, and this call
- // order is supported today.
- // examples:
- // dojo.lang.reduce([1, 2, 3, 4], function(last, next){ return last+next});
- // returns 10
- var reducedValue = initialValue;
- if(arguments.length == 2){
- binary_func = initialValue;
- reducedValue = arr[0];
- arr = arr.slice(1);
- }else if(arguments.length == 3){
- if(dojo.lang.isFunction(obj)){
- binary_func = obj;
- obj = null;
- }
- }else{
- // un-fsck the default order
- // FIXME:
- // could be wrong for some strange function object cases. Not
- // sure how to test for them.
- if(dojo.lang.isFunction(obj)){
- var tmp = binary_func;
- binary_func = obj;
- obj = tmp;
- }
- }
-
- var ob = obj || dj_global;
- dojo.lang.map(arr,
- function(val){
- reducedValue = binary_func.call(ob, reducedValue, val);
- }
- );
- return reducedValue;
- },
-
- forEach: function(/*Array*/anArray, /*Function*/callback, /*Object?*/thisObject){
- // summary:
- // for every item in anArray, call callback with that item as its
- // only parameter. Return values are ignored. This funciton
- // corresponds (and wraps) the JavaScript 1.6 forEach method. For
- // more details, see:
- // http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:forEach
- if(dojo.lang.isString(anArray)){
- // anArray: String
- anArray = anArray.split("");
- }
- if(Array.forEach){
- Array.forEach(anArray, callback, thisObject);
- }else{
- // FIXME: there are several ways of handilng thisObject. Is dj_global always the default context?
- if(!thisObject){
- thisObject=dj_global;
- }
- for(var i=0,l=anArray.length; i<l; i++){
- callback.call(thisObject, anArray[i], i, anArray);
- }
- }
- },
-
- _everyOrSome: function(/*Boolean*/every, /*Array*/arr, /*Function*/callback, /*Object?*/thisObject){
- if(dojo.lang.isString(arr)){
- //arr: String
- arr = arr.split("");
- }
- if(Array.every){
- return Array[ every ? "every" : "some" ](arr, callback, thisObject);
- }else{
- if(!thisObject){
- thisObject = dj_global;
- }
- for(var i=0,l=arr.length; i<l; i++){
- var result = callback.call(thisObject, arr[i], i, arr);
- if(every && !result){
- return false; // Boolean
- }else if((!every)&&(result)){
- return true; // Boolean
- }
- }
- return Boolean(every); // Boolean
- }
- },
-
- every: function(/*Array*/arr, /*Function*/callback, /*Object?*/thisObject){
- // summary:
- // determines whether or not every item in the array satisfies the
- // condition implemented by callback. thisObject may be used to
- // scope the call to callback. The function signature is derived
- // from the JavaScript 1.6 Array.every() function. More
- // information on this can be found here:
- // http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:every
- // examples:
- // dojo.lang.every([1, 2, 3, 4], function(item){ return item>1; });
- // // returns false
- // dojo.lang.every([1, 2, 3, 4], function(item){ return item>0; });
- // // returns true
- return this._everyOrSome(true, arr, callback, thisObject); // Boolean
- },
-
- some: function(/*Array*/arr, /*Function*/callback, /*Object?*/thisObject){
- // summary:
- // determines whether or not any item in the array satisfies the
- // condition implemented by callback. thisObject may be used to
- // scope the call to callback. The function signature is derived
- // from the JavaScript 1.6 Array.some() function. More
- // information on this can be found here:
- // http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:some
- // examples:
- // dojo.lang.some([1, 2, 3, 4], function(item){ return item>1; });
- // // returns true
- // dojo.lang.some([1, 2, 3, 4], function(item){ return item<1; });
- // // returns false
- return this._everyOrSome(false, arr, callback, thisObject); // Boolean
- },
-
- filter: function(/*Array*/arr, /*Function*/callback, /*Object?*/thisObject){
- // summary:
- // returns a new Array with those items from arr that match the
- // condition implemented by callback.thisObject may be used to
- // scope the call to callback. The function signature is derived
- // from the JavaScript 1.6 Array.filter() function, although
- // special accomidation is made in our implementation for strings.
- // More information on the JS 1.6 API can be found here:
- // http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:filter
- // examples:
- // dojo.lang.some([1, 2, 3, 4], function(item){ return item>1; });
- // // returns [2, 3, 4]
- var isString = dojo.lang.isString(arr);
- if(isString){ /*arr: String*/arr = arr.split(""); }
- var outArr;
- if(Array.filter){
- outArr = Array.filter(arr, callback, thisObject);
- }else{
- if(!thisObject){
- if(arguments.length >= 3){ dojo.raise("thisObject doesn't exist!"); }
- thisObject = dj_global;
- }
-
- outArr = [];
- for(var i = 0; i < arr.length; i++){
- if(callback.call(thisObject, arr[i], i, arr)){
- outArr.push(arr[i]);
- }
- }
- }
- if(isString){
- return outArr.join(""); // String
- } else {
- return outArr; // Array
- }
- },
-
- unnest: function(/* ... */){
- // summary:
- // Creates a 1-D array out of all the arguments passed,
- // unravelling any array-like objects in the process
- // usage:
- // unnest(1, 2, 3) ==> [1, 2, 3]
- // unnest(1, [2, [3], [[[4]]]]) ==> [1, 2, 3, 4]
-
- var out = [];
- for(var i = 0; i < arguments.length; i++){
- if(dojo.lang.isArrayLike(arguments[i])){
- var add = dojo.lang.unnest.apply(this, arguments[i]);
- out = out.concat(add);
- }else{
- out.push(arguments[i]);
- }
- }
- return out; // Array
- },
-
- toArray: function(/*Object*/arrayLike, /*Number*/startOffset){
- // summary:
- // Converts an array-like object (i.e. arguments, DOMCollection)
- // to an array. Returns a new Array object.
- var array = [];
- for(var i = startOffset||0; i < arrayLike.length; i++){
- array.push(arrayLike[i]);
- }
- return array; // Array
- }
-});
-
-dojo.provide("dojo.lang.extras");
-
-
-
-dojo.lang.setTimeout = function(/*Function*/func, /*int*/delay /*, ...*/){
- // summary:
- // Sets a timeout in milliseconds to execute a function in a given
- // context with optional arguments.
- // usage:
- // dojo.lang.setTimeout(Object context, function func, number delay[, arg1[, ...]]);
- // dojo.lang.setTimeout(function func, number delay[, arg1[, ...]]);
-
- var context = window, argsStart = 2;
- if(!dojo.lang.isFunction(func)){
- context = func;
- func = delay;
- delay = arguments[2];
- argsStart++;
- }
-
- if(dojo.lang.isString(func)){
- func = context[func];
- }
-
- var args = [];
- for (var i = argsStart; i < arguments.length; i++){
- args.push(arguments[i]);
- }
- return dojo.global().setTimeout(function(){ func.apply(context, args); }, delay); // int
-}
-
-dojo.lang.clearTimeout = function(/*int*/timer){
- // summary: clears timer by number from the execution queue
-
- // FIXME:
- // why do we have this function? It's not portable outside of browser
- // environments and it's a stupid wrapper on something that browsers
- // provide anyway.
- dojo.global().clearTimeout(timer);
-}
-
-dojo.lang.getNameInObj = function(/*Object*/ns, /*unknown*/item){
- // summary:
- // looks for a value in the object ns with a value matching item and
- // returns the property name
- // ns: if null, dj_global is used
- // item: value to return a name for
- if(!ns){ ns = dj_global; }
-
- for(var x in ns){
- if(ns[x] === item){
- return new String(x); // String
- }
- }
- return null; // null
-}
-
-dojo.lang.shallowCopy = function(/*Object*/obj, /*Boolean?*/deep){
- // summary:
- // copies object obj one level deep, or full depth if deep is true
- var i, ret;
-
- if(obj === null){ /*obj: null*/ return null; } // null
-
- if(dojo.lang.isObject(obj)){
- // obj: Object
- ret = new obj.constructor();
- for(i in obj){
- if(dojo.lang.isUndefined(ret[i])){
- ret[i] = deep ? dojo.lang.shallowCopy(obj[i], deep) : obj[i];
- }
- }
- }else if(dojo.lang.isArray(obj)){
- // obj: Array
- ret = [];
- for(i=0; i<obj.length; i++){
- ret[i] = deep ? dojo.lang.shallowCopy(obj[i], deep) : obj[i];
- }
- }else{
- // obj: Object
- ret = obj;
- }
-
- return ret; // Object
-}
+ return ret; // Object
+}
dojo.lang.firstValued = function(/* ... */){
// summary: Return the first argument that isn't undefined
@@ -2309,4781 +2110,5364 @@
}
}
-dojo.provide("dojo.lang.declare");
-
-
+dojo.provide("dojo.io.common");
-dojo.lang.declare = function( /*String*/ className,
- /*Function|Array*/ superclass,
- /*Function?*/ init,
- /*Object|Array*/ props){
- /*
- * summary: Create a feature-rich constructor with a compact notation
- * className: the name of the constructor (loosely, a "class")
- * superclass:
- * may be a Function, or an Array of Functions. If "superclass" is an
- * array, the first element is used as the prototypical ancestor and
- * any following Functions become mixin ancestors.
- * init: an initializer function
- * props:
- * an object (or array of objects) whose properties are copied to the
- * created prototype
- * description:
- * Create a constructor using a compact notation for inheritance and
- * prototype extension. "superclass" argument may be a Function, or an
- * array of Functions.
- *
- * If "superclass" is an array, the first element is used as the
- * prototypical ancestor and any following Functions become mixin
- * ancestors.
- *
- * All "superclass(es)" must be Functions (not mere Objects).
- *
- * Using mixin ancestors provides a type of multiple inheritance.
- * Mixin ancestors prototypical properties are copied to the subclass,
- * and any inializater/constructor is invoked.
- *
- * Properties of object "props" are copied to the constructor
- * prototype. If "props" is an array, properties of each object in the
- * array are copied to the constructor prototype.
- *
- * name of the class ("className" argument) is stored in
- * "declaredClass" property
- *
- * Initializer functions are called when an object is instantiated
- * from this constructor.
- *
- * Aliased as "dojo.declare"
- *
- * Usage:
- *
- * dojo.declare("my.classes.bar", my.classes.foo,
- * function(){
- * // initialization function
- * this.myComplicatedObject = new ReallyComplicatedObject();
- * },
- * { // properties to be added to the class prototype
- * someValue: 2,
- * someMethod: function(){
- * doStuff();
- * }
- * }
- * );
- *
- */
- if((dojo.lang.isFunction(props))||((!props)&&(!dojo.lang.isFunction(init)))){
- // parameter juggling to support omitting init param (also allows
- // reordering init and props arguments)
- var temp = props;
- props = init;
- init = temp;
- }
- var mixins = [ ];
- if(dojo.lang.isArray(superclass)){
- mixins = superclass;
- superclass = mixins.shift();
- }
- if(!init){
- init = dojo.evalObjPath(className, false);
- if((init)&&(!dojo.lang.isFunction(init))){ init = null };
- }
- var ctor = dojo.lang.declare._makeConstructor();
- var scp = (superclass ? superclass.prototype : null);
- if(scp){
- scp.prototyping = true;
- ctor.prototype = new superclass();
- scp.prototyping = false;
- }
- ctor.superclass = scp;
- ctor.mixins = mixins;
- for(var i=0,l=mixins.length; i<l; i++){
- dojo.lang.extend(ctor, mixins[i].prototype);
- }
- ctor.prototype.initializer = null;
- ctor.prototype.declaredClass = className;
- if(dojo.lang.isArray(props)){
- dojo.lang.extend.apply(dojo.lang, [ctor].concat(props));
- }else{
- dojo.lang.extend(ctor, (props)||{});
- }
- dojo.lang.extend(ctor, dojo.lang.declare._common);
- ctor.prototype.constructor = ctor;
- ctor.prototype.initializer = (ctor.prototype.initializer)||(init)||(function(){});
- var created = dojo.parseObjPath(className, null, true);
- created.obj[created.prop] = ctor;
- return ctor; // Function
-}
-
-dojo.lang.declare._makeConstructor = function(){
- return function(){
- // get the generational context (which object [or prototype] should be constructed)
- var self = this._getPropContext();
- var s = self.constructor.superclass;
- if((s)&&(s.constructor)){
- if(s.constructor==arguments.callee){
- // if this constructor is invoked directly (my.ancestor.call(this))
- this._inherited("constructor", arguments);
- }else{
- this._contextMethod(s, "constructor", arguments);
- }
- }
- var ms = (self.constructor.mixins)||([]);
- for(var i=0, m; (m=ms[i]); i++) {
- (((m.prototype)&&(m.prototype.initializer))||(m)).apply(this, arguments);
- }
- if((!this.prototyping)&&(self.initializer)){
- self.initializer.apply(this, arguments);
- }
- }
-}
-dojo.lang.declare._common = {
- _getPropContext: function(){ return (this.___proto||this); },
- // caches ptype context and calls method on it
- _contextMethod: function(ptype, method, args){
- var result, stack = this.___proto;
- this.___proto = ptype;
- try { result = ptype[method].apply(this,(args||[])); }
- catch(e) { throw e; }
- finally { this.___proto = stack; }
- return result;
- },
- _inherited: function(prop, args){
- // summary:
- // Searches backward thru prototype chain to find nearest
- // ancestral instance of prop. Internal use only.
- var p = this._getPropContext();
- do{
- if((!p.constructor)||(!p.constructor.superclass)){ return; }
- p = p.constructor.superclass;
- }while(!(prop in p));
- return (dojo.lang.isFunction(p[prop]) ? this._contextMethod(p, prop, args) : p[prop]);
- },
- inherited: function(prop, args){
- dojo.deprecated("'inherited' method is dangerous, do not up-call! 'inherited' is slated for removal in 0.5; name your super class (or use superclass property) instead.", "0.5");
- this._inherited(prop, args);
+/******************************************************************************
+ * Notes about dojo.io design:
+ *
+ * The dojo.io.* package has the unenviable task of making a lot of different
+ * types of I/O feel natural, despite a universal lack of good (or even
+ * reasonable!) I/O capability in the host environment. So lets pin this down
+ * a little bit further.
+ *
+ * Rhino:
+ * perhaps the best situation anywhere. Access to Java classes allows you
+ * to do anything one might want in terms of I/O, both synchronously and
+ * async. Can open TCP sockets and perform low-latency client/server
+ * interactions. HTTP transport is available through Java HTTP client and
+ * server classes. Wish it were always this easy.
+ *
+ * xpcshell:
+ * XPCOM for I/O.
+ *
+ * spidermonkey:
+ * S.O.L.
+ *
+ * Browsers:
+ * Browsers generally do not provide any useable filesystem access. We are
+ * therefore limited to HTTP for moving information to and from Dojo
+ * instances living in a browser.
+ *
+ * XMLHTTP:
+ * Sync or async, allows reading of arbitrary text files (including
+ * JS, which can then be eval()'d), writing requires server
+ * cooperation and is limited to HTTP mechanisms (POST and GET).
+ *
+ * <iframe> hacks:
+ * iframe document hacks allow browsers to communicate asynchronously
+ * with a server via HTTP POST and GET operations. With significant
+ * effort and server cooperation, low-latency data transit between
+ * client and server can be acheived via iframe mechanisms (repubsub).
+ *
+ * SVG:
+ * Adobe's SVG viewer implements helpful primitives for XML-based
+ * requests, but receipt of arbitrary text data seems unlikely w/o
+ * <![CDATA[]]> sections.
+ *
+ *
+ * A discussion between Dylan, Mark, Tom, and Alex helped to lay down a lot
+ * the IO API interface. A transcript of it can be found at:
+ * http://dojotoolkit.org/viewcvs/viewcvs.py/documents/irc/irc_io_api_log.txt?rev=307&view=auto
+ *
+ * Also referenced in the design of the API was the DOM 3 L&S spec:
+ * http://www.w3.org/TR/2004/REC-DOM-Level-3-LS-20040407/load-save.html
+ ******************************************************************************/
+
+// a map of the available transport options. Transports should add themselves
+// by calling add(name)
+dojo.io.transports = [];
+dojo.io.hdlrFuncNames = [ "load", "error", "timeout" ]; // we're omitting a progress() event for now
+
+dojo.io.Request = function(/*String*/ url, /*String*/ mimetype, /*String*/ transport, /*String or Boolean*/ changeUrl){
+// summary:
+// Constructs a Request object that is used by dojo.io.bind().
+// description:
+// dojo.io.bind() will create one of these for you if
+// you call dojo.io.bind() with an plain object containing the bind parameters.
+// This method can either take the arguments specified, or an Object containing all of the parameters that you
+// want to use to create the dojo.io.Request (similar to how dojo.io.bind() is called.
+// The named parameters to this constructor represent the minimum set of parameters need
+ if((arguments.length == 1)&&(arguments[0].constructor == Object)){
+ this.fromKwArgs(arguments[0]);
+ }else{
+ this.url = url;
+ if(mimetype){ this.mimetype = mimetype; }
+ if(transport){ this.transport = transport; }
+ if(arguments.length >= 4){ this.changeUrl = changeUrl; }
}
}
-dojo.declare = dojo.lang.declare;
+dojo.lang.extend(dojo.io.Request, {
-dojo.provide("dojo.lang.func");
+ /** The URL to hit */
+ url: "",
+
+ /** The mime type used to interrpret the response body */
+ mimetype: "text/plain",
+
+ /** The HTTP method to use */
+ method: "GET",
+
+ /** An Object containing key-value pairs to be included with the request */
+ content: undefined, // Object
+
+ /** The transport medium to use */
+ transport: undefined, // String
+
+ /** If defined the URL of the page is physically changed */
+ changeUrl: undefined, // String
+
+ /** A form node to use in the request */
+ formNode: undefined, // HTMLFormElement
+
+ /** Whether the request should be made synchronously */
+ sync: false,
+
+ bindSuccess: false,
+ /** Cache/look for the request in the cache before attempting to request?
+ * NOTE: this isn't a browser cache, this is internal and would only cache in-page
+ */
+ useCache: false,
-dojo.lang.hitch = function(/*Object*/thisObject, /*Function|String*/method){
- // summary:
- // Returns a function that will only ever execute in the a given scope
- // (thisObject). This allows for easy use of object member functions
- // in callbacks and other places in which the "this" keyword may
- // otherwise not reference the expected scope. Note that the order of
- // arguments may be reversed in a future version.
- // thisObject: the scope to run the method in
- // method:
- // a function to be "bound" to thisObject or the name of the method in
- // thisObject to be used as the basis for the binding
- // usage:
- // dojo.lang.hitch(foo, "bar")(); // runs foo.bar() in the scope of foo
- // dojo.lang.hitch(foo, myFunction); // returns a function that runs myFunction in the scope of foo
+ /** Prevent the browser from caching this by adding a query string argument to the URL */
+ preventCache: false,
- // FIXME:
- // should this be extended to "fixate" arguments in a manner similar
- // to dojo.lang.curry, but without the default execution of curry()?
- var fcn = (dojo.lang.isString(method) ? thisObject[method] : method) || function(){};
- return function(){
- return fcn.apply(thisObject, arguments); // Function
- };
-}
+ jsonFilter: function(value){
+ if( (this.mimetype == "text/json-comment-filtered")||
+ (this.mimetype == "application/json-comment-filtered")
+ ){
+ var cStartIdx = value.indexOf("\/*");
+ var cEndIdx = value.lastIndexOf("*\/");
+ if((cStartIdx == -1)||(cEndIdx == -1)){
+ dojo.debug("your JSON wasn't comment filtered!"); // FIXME: throw exception instead?
+ return "";
+ }
+ return value.substring(cStartIdx+2, cEndIdx);
+ }
+ dojo.debug("please consider using a mimetype of text/json-comment-filtered to avoid potential security issues with JSON endpoints");
+ return value;
+ },
+
+ // events stuff
+ load: function(/*String*/type, /*Object*/data, /*Object*/transportImplementation, /*Object*/kwArgs){
+ // summary:
+ // Called on successful completion of a bind.
+ // type: String
+ // A string with value "load"
+ // data: Object
+ // The object representing the result of the bind. The actual structure
+ // of the data object will depend on the mimetype that was given to bind
+ // in the bind arguments.
+ // transportImplementation: Object
+ // The object that implements a particular transport. Structure is depedent
+ // on the transport. For XMLHTTPTransport (dojo.io.BrowserIO), it will be the
+ // XMLHttpRequest object from the browser.
+ // kwArgs: Object
+ // Object that contains the request parameters that were given to the
+ // bind call. Useful for storing and retrieving state from when bind
+ // was called.
+ },
+ error: function(/*String*/type, /*Object*/error, /*Object*/transportImplementation, /*Object*/kwArgs){
+ // summary:
+ // Called when there is an error with a bind.
+ // type: String
+ // A string with value "error"
+ // error: Object
+ // The error object. Should be a dojo.io.Error object, but not guaranteed.
+ // transportImplementation: Object
+ // The object that implements a particular transport. Structure is depedent
+ // on the transport. For XMLHTTPTransport (dojo.io.BrowserIO), it will be the
+ // XMLHttpRequest object from the browser.
+ // kwArgs: Object
+ // Object that contains the request parameters that were given to the
+ // bind call. Useful for storing and retrieving state from when bind
+ // was called.
+ },
+ timeout: function(/*String*/type, /*Object*/empty, /*Object*/transportImplementation, /*Object*/kwArgs){
+ // summary:
+ // Called when there is an error with a bind. Only implemented in certain transports at this time.
+ // type: String
+ // A string with value "timeout"
+ // empty: Object
+ // Should be null. Just a spacer argument so that load, error, timeout and handle have the
+ // same signatures.
+ // transportImplementation: Object
+ // The object that implements a particular transport. Structure is depedent
+ // on the transport. For XMLHTTPTransport (dojo.io.BrowserIO), it will be the
+ // XMLHttpRequest object from the browser. May be null for the timeout case for
+ // some transports.
+ // kwArgs: Object
+ // Object that contains the request parameters that were given to the
+ // bind call. Useful for storing and retrieving state from when bind
+ // was called.
+ },
+ handle: function(/*String*/type, /*Object*/data, /*Object*/transportImplementation, /*Object*/kwArgs){
+ // summary:
+ // The handle method can be defined instead of defining separate load, error and timeout
+ // callbacks.
+ // type: String
+ // A string with the type of callback: "load", "error", or "timeout".
+ // data: Object
+ // See the above callbacks for what this parameter could be.
+ // transportImplementation: Object
+ // The object that implements a particular transport. Structure is depedent
+ // on the transport. For XMLHTTPTransport (dojo.io.BrowserIO), it will be the
+ // XMLHttpRequest object from the browser.
+ // kwArgs: Object
+ // Object that contains the request parameters that were given to the
+ // bind call. Useful for storing and retrieving state from when bind
+ // was called.
+ },
-dojo.lang.anonCtr = 0;
-dojo.lang.anon = {};
+ //FIXME: change IframeIO.js to use timeouts?
+ // The number of seconds to wait until firing a timeout callback.
+ // If it is zero, that means, don't do a timeout check.
+ timeoutSeconds: 0,
+
+ // the abort method needs to be filled in by the transport that accepts the
+ // bind() request
+ abort: function(){ },
+
+ // backButton: function(){ },
+ // forwardButton: function(){ },
-dojo.lang.nameAnonFunc = function(/*Function*/anonFuncPtr, /*Object*/thisObj, /*Boolean*/searchForNames){
- // summary:
- // Creates a reference to anonFuncPtr in thisObj with a completely
- // unique name. The new name is returned as a String. If
- // searchForNames is true, an effort will be made to locate an
- // existing reference to anonFuncPtr in thisObj, and if one is found,
- // the existing name will be returned instead. The default is for
- // searchForNames to be false.
- var nso = (thisObj|| dojo.lang.anon);
- if( (searchForNames) ||
- ((dj_global["djConfig"])&&(djConfig["slowAnonFuncLookups"] == true)) ){
- for(var x in nso){
- try{
- if(nso[x] === anonFuncPtr){
- return x;
- }
- }catch(e){} // window.external fails in IE embedded in Eclipse (Eclipse bug #151165)
+ fromKwArgs: function(/*Object*/ kwArgs){
+ // summary:
+ // Creates a dojo.io.Request from a simple object (kwArgs object).
+
+ // normalize args
+ if(kwArgs["url"]){ kwArgs.url = kwArgs.url.toString(); }
+ if(kwArgs["formNode"]) { kwArgs.formNode = dojo.byId(kwArgs.formNode); }
+ if(!kwArgs["method"] && kwArgs["formNode"] && kwArgs["formNode"].method) {
+ kwArgs.method = kwArgs["formNode"].method;
}
- }
- var ret = "__"+dojo.lang.anonCtr++;
- while(typeof nso[ret] != "undefined"){
- ret = "__"+dojo.lang.anonCtr++;
- }
- nso[ret] = anonFuncPtr;
- return ret; // String
-}
+
+ // backwards compatibility
+ if(!kwArgs["handle"] && kwArgs["handler"]){ kwArgs.handle = kwArgs.handler; }
+ if(!kwArgs["load"] && kwArgs["loaded"]){ kwArgs.load = kwArgs.loaded; }
+ if(!kwArgs["changeUrl"] && kwArgs["changeURL"]) { kwArgs.changeUrl = kwArgs.changeURL; }
-dojo.lang.forward = function(funcName){
- // summary:
- // Returns a function that forwards a method call to
- // this.funcName(...). Unlike dojo.lang.hitch(), the "this" scope is
- // not fixed on a single object. Ported from MochiKit.
- return function(){
- return this[funcName].apply(this, arguments);
- }; // Function
-}
-
-dojo.lang.curry = function(thisObj, func /* args ... */){
- // summary:
- // similar to the curry() method found in many functional programming
- // environments, this function returns an "argument accumulator"
- // function, bound to a particular scope, and "primed" with a variable
- // number of arguments. The curry method is unique in that it returns
- // a function that may return other "partial" function which can be
- // called repeatedly. New functions are returned until the arity of
- // the original function is reached, at which point the underlying
- // function (func) is called in the scope thisObj with all of the
- // accumulated arguments (plus any extras) in positional order.
- // examples:
- // assuming a function defined like this:
- // var foo = {
- // bar: function(arg1, arg2, arg3){
- // dojo.debug.apply(dojo, arguments);
- // }
- // };
- //
- // dojo.lang.curry() can be used most simply in this way:
- //
- // tmp = dojo.lang.curry(foo, foo.bar, "arg one", "thinger");
- // tmp("blah", "this is superfluous");
- // // debugs: "arg one thinger blah this is superfluous"
- // tmp("blah");
- // // debugs: "arg one thinger blah"
- // tmp();
- // // returns a function exactly like tmp that expects one argument
- //
- // other intermittent functions could be created until the 3
- // positional arguments are filled:
- //
- // tmp = dojo.lang.curry(foo, foo.bar, "arg one");
- // tmp2 = tmp("arg two");
- // tmp2("blah blah");
- // // debugs: "arg one arg two blah blah"
- // tmp2("oy");
- // // debugs: "arg one arg two oy"
- //
- // curry() can also be used to call the function if enough arguments
- // are passed in the initial invocation:
- //
- // dojo.lang.curry(foo, foo.bar, "one", "two", "three", "four");
- // // debugs: "one two three four"
- // dojo.lang.curry(foo, foo.bar, "one", "two", "three");
- // // debugs: "one two three"
+ // encoding fun!
+ kwArgs.encoding = dojo.lang.firstValued(kwArgs["encoding"], djConfig["bindEncoding"], "");
+ kwArgs.sendTransport = dojo.lang.firstValued(kwArgs["sendTransport"], djConfig["ioSendTransport"], false);
- // FIXME: the order of func and thisObj should be changed!!!
- var outerArgs = [];
- thisObj = thisObj||dj_global;
- if(dojo.lang.isString(func)){
- func = thisObj[func];
- }
- for(var x=2; x<arguments.length; x++){
- outerArgs.push(arguments[x]);
- }
- // since the event system replaces the original function with a new
- // join-point runner with an arity of 0, we check to see if it's left us
- // any clues about the original arity in lieu of the function's actual
- // length property
- var ecount = (func["__preJoinArity"]||func.length) - outerArgs.length;
- // borrowed from svend tofte
- function gather(nextArgs, innerArgs, expected){
- var texpected = expected;
- var totalArgs = innerArgs.slice(0); // copy
- for(var x=0; x<nextArgs.length; x++){
- totalArgs.push(nextArgs[x]);
- }
- // check the list of provided nextArgs to see if it, plus the
- // number of innerArgs already supplied, meets the total
- // expected.
- expected = expected-nextArgs.length;
- if(expected<=0){
- var res = func.apply(thisObj, totalArgs);
- expected = texpected;
- return res;
- }else{
- return function(){
- return gather(arguments,// check to see if we've been run
- // with enough args
- totalArgs, // a copy
- expected); // how many more do we need to run?;
- };
+ var isFunction = dojo.lang.isFunction;
+ for(var x=0; x<dojo.io.hdlrFuncNames.length; x++){
+ var fn = dojo.io.hdlrFuncNames[x];
+ if(kwArgs[fn] && isFunction(kwArgs[fn])){ continue; }
+ if(kwArgs["handle"] && isFunction(kwArgs["handle"])){
+ kwArgs[fn] = kwArgs.handle;
+ }
+ // handler is aliased above, shouldn't need this check
+ /* else if(dojo.lang.isObject(kwArgs.handler)){
+ if(isFunction(kwArgs.handler[fn])){
+ kwArgs[fn] = kwArgs.handler[fn]||kwArgs.handler["handle"]||function(){};
+ }
+ }*/
}
+ dojo.lang.mixin(this, kwArgs);
}
- return gather([], outerArgs, ecount);
+
+});
+
+dojo.io.Error = function(/*String*/ msg, /*String*/ type, /*Number*/num){
+ // summary:
+ // Constructs an object representing a bind error.
+ this.message = msg;
+ this.type = type || "unknown"; // must be one of "io", "parse", "unknown"
+ this.number = num || 0; // per-substrate error number, not normalized
}
-dojo.lang.curryArguments = function(/*Object*/thisObj, /*Function*/func, /*Array*/args, /*Integer, optional*/offset){
+dojo.io.transports.addTransport = function(/*String*/name){
// summary:
- // similar to dojo.lang.curry(), except that a list of arguments to
- // start the curry with may be provided as an array instead of as
- // positional arguments. An offset may be specified from the 0 index
- // to skip some elements in args.
- var targs = [];
- var x = offset||0;
- for(x=offset; x<args.length; x++){
- targs.push(args[x]); // ensure that it's an arr
- }
- return dojo.lang.curry.apply(dojo.lang, [thisObj, func].concat(targs));
+ // Used to register transports that can support bind calls.
+ this.push(name);
+ // FIXME: do we need to handle things that aren't direct children of the
+ // dojo.io module? (say, dojo.io.foo.fooTransport?)
+ this[name] = dojo.io[name];
}
-dojo.lang.tryThese = function(/*...*/){
+// binding interface, the various implementations register their capabilities
+// and the bind() method dispatches
+dojo.io.bind = function(/*dojo.io.Request or Object*/request){
// summary:
- // executes each function argument in turn, returning the return value
- // from the first one which does not throw an exception in execution.
- // Any number of functions may be passed.
- for(var x=0; x<arguments.length; x++){
+ // Binding interface for IO. Loading different IO transports, like
+ // dojo.io.BrowserIO or dojo.io.IframeIO, will register with bind
+ // to handle particular types of bind calls.
+ // request: Object
+ // Object containing bind arguments. This object is converted to
+ // a dojo.io.Request object, and that request object is the return
+ // value for this method.
+ if(!(request instanceof dojo.io.Request)){
try{
- if(typeof arguments[x] == "function"){
- var ret = (arguments[x]());
- if(ret){
- return ret;
- }
+ request = new dojo.io.Request(request);
+ }catch(e){ dojo.debug(e); }
+ }
+
+ // if the request asks for a particular implementation, use it
+ var tsName = "";
+ if(request["transport"]){
+ tsName = request["transport"];
+ if(!this[tsName]){
+ dojo.io.sendBindError(request, "No dojo.io.bind() transport with name '"
+ + request["transport"] + "'.");
+ return request; //dojo.io.Request
+ }
+ if(!this[tsName].canHandle(request)){
+ dojo.io.sendBindError(request, "dojo.io.bind() transport with name '"
+ + request["transport"] + "' cannot handle this type of request.");
+ return request; //dojo.io.Request
+ }
+ }else{
+ // otherwise we do our best to auto-detect what available transports
+ // will handle
+ for(var x=0; x<dojo.io.transports.length; x++){
+ var tmp = dojo.io.transports[x];
+ if((this[tmp])&&(this[tmp].canHandle(request))){
+ tsName = tmp;
+ break;
}
- }catch(e){
- dojo.debug(e);
+ }
+ if(tsName == ""){
+ dojo.io.sendBindError(request, "None of the loaded transports for dojo.io.bind()"
+ + " can handle the request.");
+ return request; //dojo.io.Request
}
}
+ this[tsName].bind(request);
+ request.bindSuccess = true;
+ return request; //dojo.io.Request
}
-dojo.lang.delayThese = function(/*Array*/farr, /*Function, optional*/cb, /*Integer*/delay, /*Function, optional*/onend){
+dojo.io.sendBindError = function(/* Object */request, /* String */message){
// summary:
- // executes a series of functions contained in farr, but spaces out
- // calls to each function by the millisecond delay provided. If cb is
- // provided, it will be called directly after each item in farr is
- // called and if onend is passed, it will be called when all items
- // have completed executing.
+ // Used internally by dojo.io.bind() to return/raise a bind error.
- /**
- * alternate: (array funcArray, function callback, function onend)
- * alternate: (array funcArray, function callback)
- * alternate: (array funcArray)
- */
- if(!farr.length){
- if(typeof onend == "function"){
- onend();
- }
- return;
- }
- if((typeof delay == "undefined")&&(typeof cb == "number")){
- delay = cb;
- cb = function(){};
- }else if(!cb){
- cb = function(){};
- if(!delay){ delay = 0; }
+ //Need to be careful since not all hostenvs support setTimeout.
+ if((typeof request.error == "function" || typeof request.handle == "function")
+ && (typeof setTimeout == "function" || typeof setTimeout == "object")){
+ var errorObject = new dojo.io.Error(message);
+ setTimeout(function(){
+ request[(typeof request.error == "function") ? "error" : "handle"]("error", errorObject, null, request);
+ }, 50);
+ }else{
+ dojo.raise(message);
}
- setTimeout(function(){
- (farr.shift())();
- cb();
- dojo.lang.delayThese(farr, cb, delay, onend);
- }, delay);
}
-dojo.provide("dojo.event.common");
-
-
-
+dojo.io.queueBind = function(/*dojo.io.Request or Object*/request){
+ // summary:
+ // queueBind will use dojo.io.bind() but guarantee that only one bind
+ // call is handled at a time.
+ // description:
+ // If queueBind is called while a bind call
+ // is in process, it will queue up the other calls to bind and call them
+ // in order as bind calls complete.
+ // request: Object
+ // Same sort of request object as used for dojo.io.bind().
+ if(!(request instanceof dojo.io.Request)){
+ try{
+ request = new dojo.io.Request(request);
+ }catch(e){ dojo.debug(e); }
+ }
+ // make sure we get called if/when we get a response
+ var oldLoad = request.load;
+ request.load = function(){
+ dojo.io._queueBindInFlight = false;
+ var ret = oldLoad.apply(this, arguments);
+ dojo.io._dispatchNextQueueBind();
+ return ret;
+ }
-// TODO: connection filter functions
-// these are functions that accept a method invocation (like around
-// advice) and return a boolean based on it. That value determines
-// whether or not the connection proceeds. It could "feel" like around
-// advice for those who know what it is (calling proceed() or not),
-// but I think presenting it as a "filter" and/or calling it with the
-// function args and not the MethodInvocation might make it more
-// palletable to "normal" users than around-advice currently is
-// TODO: execution scope mangling
-// YUI's event facility by default executes listeners in the context
-// of the source object. This is very odd, but should probably be
-// supported as an option (both for the source and for the dest). It
-// can be thought of as a connection-specific hitch().
-// TODO: more resiliency for 4+ arguments to connect()
-
-dojo.event = new function(){
- this._canTimeout = dojo.lang.isFunction(dj_global["setTimeout"])||dojo.lang.isAlien(dj_global["setTimeout"]);
-
- // FIXME: where should we put this method (not here!)?
- function interpolateArgs(args, searchForNames){
- var dl = dojo.lang;
- var ao = {
- srcObj: dj_global,
- srcFunc: null,
- adviceObj: dj_global,
- adviceFunc: null,
- aroundObj: null,
- aroundFunc: null,
- adviceType: (args.length>2) ? args[0] : "after",
- precedence: "last",
- once: false,
- delay: null,
- rate: 0,
- adviceMsg: false,
- maxCalls: -1
- };
+ var oldErr = request.error;
+ request.error = function(){
+ dojo.io._queueBindInFlight = false;
+ var ret = oldErr.apply(this, arguments);
+ dojo.io._dispatchNextQueueBind();
+ return ret;
+ }
- switch(args.length){
- case 0: return;
- case 1: return;
- case 2:
- ao.srcFunc = args[0];
- ao.adviceFunc = args[1];
- break;
- case 3:
- if((dl.isObject(args[0]))&&(dl.isString(args[1]))&&(dl.isString(args[2]))){
- ao.adviceType = "after";
- ao.srcObj = args[0];
- ao.srcFunc = args[1];
- ao.adviceFunc = args[2];
- }else if((dl.isString(args[1]))&&(dl.isString(args[2]))){
- ao.srcFunc = args[1];
- ao.adviceFunc = args[2];
- }else if((dl.isObject(args[0]))&&(dl.isString(args[1]))&&(dl.isFunction(args[2]))){
- ao.adviceType = "after";
- ao.srcObj = args[0];
- ao.srcFunc = args[1];
- var tmpName = dl.nameAnonFunc(args[2], ao.adviceObj, searchForNames);
- ao.adviceFunc = tmpName;
- }else if((dl.isFunction(args[0]))&&(dl.isObject(args[1]))&&(dl.isString(args[2]))){
- ao.adviceType = "after";
- ao.srcObj = dj_global;
- var tmpName = dl.nameAnonFunc(args[0], ao.srcObj, searchForNames);
- ao.srcFunc = tmpName;
- ao.adviceObj = args[1];
- ao.adviceFunc = args[2];
- }
- break;
- case 4:
- if((dl.isObject(args[0]))&&(dl.isObject(args[2]))){
- // we can assume that we've got an old-style "connect" from
- // the sigslot school of event attachment. We therefore
- // assume after-advice.
- ao.adviceType = "after";
- ao.srcObj = args[0];
- ao.srcFunc = args[1];
- ao.adviceObj = args[2];
- ao.adviceFunc = args[3];
- }else if((dl.isString(args[0]))&&(dl.isString(args[1]))&&(dl.isObject(args[2]))){
- ao.adviceType = args[0];
- ao.srcObj = dj_global;
- ao.srcFunc = args[1];
- ao.adviceObj = args[2];
- ao.adviceFunc = args[3];
- }else if((dl.isString(args[0]))&&(dl.isFunction(args[1]))&&(dl.isObject(args[2]))){
- ao.adviceType = args[0];
- ao.srcObj = dj_global;
- var tmpName = dl.nameAnonFunc(args[1], dj_global, searchForNames);
- ao.srcFunc = tmpName;
- ao.adviceObj = args[2];
- ao.adviceFunc = args[3];
- }else if((dl.isString(args[0]))&&(dl.isObject(args[1]))&&(dl.isString(args[2]))&&(dl.isFunction(args[3]))){
- ao.srcObj = args[1];
- ao.srcFunc = args[2];
- var tmpName = dl.nameAnonFunc(args[3], dj_global, searchForNames);
- ao.adviceObj = dj_global;
- ao.adviceFunc = tmpName;
- }else if(dl.isObject(args[1])){
- ao.srcObj = args[1];
- ao.srcFunc = args[2];
- ao.adviceObj = dj_global;
- ao.adviceFunc = args[3];
- }else if(dl.isObject(args[2])){
- ao.srcObj = dj_global;
- ao.srcFunc = args[1];
- ao.adviceObj = args[2];
- ao.adviceFunc = args[3];
- }else{
- ao.srcObj = ao.adviceObj = ao.aroundObj = dj_global;
- ao.srcFunc = args[1];
- ao.adviceFunc = args[2];
- ao.aroundFunc = args[3];
- }
- break;
- case 6:
- ao.srcObj = args[1];
- ao.srcFunc = args[2];
- ao.adviceObj = args[3]
- ao.adviceFunc = args[4];
- ao.aroundFunc = args[5];
- ao.aroundObj = dj_global;
- break;
- default:
- ao.srcObj = args[1];
- ao.srcFunc = args[2];
- ao.adviceObj = args[3]
- ao.adviceFunc = args[4];
- ao.aroundObj = args[5];
- ao.aroundFunc = args[6];
- ao.once = args[7];
- ao.delay = args[8];
- ao.rate = args[9];
- ao.adviceMsg = args[10];
- ao.maxCalls = (!isNaN(parseInt(args[11]))) ? args[11] : -1;
- break;
- }
+ dojo.io._bindQueue.push(request);
+ dojo.io._dispatchNextQueueBind();
+ return request; //dojo.io.Request
+}
- if(dl.isFunction(ao.aroundFunc)){
- var tmpName = dl.nameAnonFunc(ao.aroundFunc, ao.aroundObj, searchForNames);
- ao.aroundFunc = tmpName;
+dojo.io._dispatchNextQueueBind = function(){
+ // summary:
+ // Private method used by dojo.io.queueBind().
+ if(!dojo.io._queueBindInFlight){
+ dojo.io._queueBindInFlight = true;
+ if(dojo.io._bindQueue.length > 0){
+ dojo.io.bind(dojo.io._bindQueue.shift());
+ }else{
+ dojo.io._queueBindInFlight = false;
}
+ }
+}
+dojo.io._bindQueue = [];
+dojo.io._queueBindInFlight = false;
- if(dl.isFunction(ao.srcFunc)){
- ao.srcFunc = dl.getNameInObj(ao.srcObj, ao.srcFunc);
+dojo.io.argsFromMap = function(/*Object*/map, /*String?*/encoding, /*String?*/last){
+ // summary:
+ // Converts name/values pairs in the map object to an URL-encoded string
+ // with format of name1=value1&name2=value2...
+ // map: Object
+ // Object that has the contains the names and values.
+ // encoding: String?
+ // String to specify how to encode the name and value. If the encoding string
+ // contains "utf" (case-insensitive), then encodeURIComponent is used. Otherwise
+ // dojo.string.encodeAscii is used.
+ // last: String?
+ // The last parameter in the list. Helps with final string formatting?
+ var enc = /utf/i.test(encoding||"") ? encodeURIComponent : dojo.string.encodeAscii;
+ var mapped = [];
+ var control = new Object();
+ for(var name in map){
+ var domap = function(elt){
+ var val = enc(name)+"="+enc(elt);
+ mapped[(last == name) ? "push" : "unshift"](val);
}
-
- if(dl.isFunction(ao.adviceFunc)){
- ao.adviceFunc = dl.getNameInObj(ao.adviceObj, ao.adviceFunc);
+ if(!control[name]){
+ var value = map[name];
+ // FIXME: should be isArrayLike?
+ if (dojo.lang.isArray(value)){
+ dojo.lang.forEach(value, domap);
+ }else{
+ domap(value);
+ }
}
+ }
+ return mapped.join("&"); //String
+}
- if((ao.aroundObj)&&(dl.isFunction(ao.aroundFunc))){
- ao.aroundFunc = dl.getNameInObj(ao.aroundObj, ao.aroundFunc);
- }
+dojo.io.setIFrameSrc = function(/*DOMNode*/ iframe, /*String*/ src, /*Boolean*/ replace){
+ //summary:
+ // Sets the URL that is loaded in an IFrame. The replace parameter indicates whether
+ // location.replace() should be used when changing the location of the iframe.
+ try{
+ var r = dojo.render.html;
+ // dojo.debug(iframe);
+ if(!replace){
+ if(r.safari){
+ iframe.location = src;
+ }else{
+ frames[iframe.name].location = src;
+ }
+ }else{
+ // Fun with DOM 0 incompatibilities!
+ var idoc;
+ if(r.ie){
+ idoc = iframe.contentWindow.document;
+ }else if(r.safari){
+ idoc = iframe.document;
+ }else{ // if(r.moz){
+ idoc = iframe.contentWindow;
+ }
- if(!ao.srcObj){
- dojo.raise("bad srcObj for srcFunc: "+ao.srcFunc);
- }
- if(!ao.adviceObj){
- dojo.raise("bad adviceObj for adviceFunc: "+ao.adviceFunc);
+ //For Safari (at least 2.0.3) and Opera, if the iframe
+ //has just been created but it doesn't have content
+ //yet, then iframe.document may be null. In that case,
+ //use iframe.location and return.
+ if(!idoc){
+ iframe.location = src;
+ return;
+ }else{
+ idoc.location.replace(src);
+ }
}
-
- if(!ao.adviceFunc){
- dojo.debug("bad adviceFunc for srcFunc: "+ao.srcFunc);
- dojo.debugShallow(ao);
- }
-
- return ao;
+ }catch(e){
+ dojo.debug(e);
+ dojo.debug("setIFrameSrc: "+e);
}
+}
- this.connect = function(/*...*/){
- // summary:
- // dojo.event.connect is the glue that holds most Dojo-based
- // applications together. Most combinations of arguments are
- // supported, with the connect() method attempting to disambiguate
- // the implied types of positional parameters. The following will
- // all work:
- // dojo.event.connect("globalFunctionName1", "globalFunctionName2");
- // dojo.event.connect(functionReference1, functionReference2);
- // dojo.event.connect("globalFunctionName1", functionReference2);
- // dojo.event.connect(functionReference1, "globalFunctionName2");
- // dojo.event.connect(scope1, "functionName1", "globalFunctionName2");
- // dojo.event.connect("globalFunctionName1", scope2, "functionName2");
- // dojo.event.connect(scope1, "functionName1", scope2, "functionName2");
- // dojo.event.connect("after", scope1, "functionName1", scope2, "functionName2");
- // dojo.event.connect("before", scope1, "functionName1", scope2, "functionName2");
- // dojo.event.connect("around", scope1, "functionName1",
- // scope2, "functionName2",
- // aroundFunctionReference);
- // dojo.event.connect("around", scope1, "functionName1",
- // scope2, "functionName2",
- // scope3, "aroundFunctionName");
- // dojo.event.connect("before-around", scope1, "functionName1",
- // scope2, "functionName2",
- // aroundFunctionReference);
- // dojo.event.connect("after-around", scope1, "functionName1",
- // scope2, "functionName2",
- // aroundFunctionReference);
- // dojo.event.connect("after-around", scope1, "functionName1",
- // scope2, "functionName2",
- // scope3, "aroundFunctionName");
- // dojo.event.connect("around", scope1, "functionName1",
- // scope2, "functionName2",
- // scope3, "aroundFunctionName", true, 30);
- // dojo.event.connect("around", scope1, "functionName1",
- // scope2, "functionName2",
- // scope3, "aroundFunctionName", null, null, 10);
- // adviceType:
- // Optional. String. One of "before", "after", "around",
- // "before-around", or "after-around". FIXME
- // srcObj:
- // the scope in which to locate/execute the named srcFunc. Along
- // with srcFunc, this creates a way to dereference the function to
- // call. So if the function in question is "foo.bar", the
- // srcObj/srcFunc pair would be foo and "bar", where "bar" is a
- // string and foo is an object reference.
- // srcFunc:
- // the name of the function to connect to. When it is executed,
- // the listener being registered with this call will be called.
- // The adviceType defines the call order between the source and
- // the target functions.
- // adviceObj:
- // the scope in which to locate/execute the named adviceFunc.
- // adviceFunc:
- // the name of the function being conected to srcObj.srcFunc
- // aroundObj:
- // the scope in which to locate/execute the named aroundFunc.
- // aroundFunc:
- // the name of, or a reference to, the function that will be used
- // to mediate the advice call. Around advice requires a special
- // unary function that will be passed a "MethodInvocation" object.
- // These objects have several important properties, namely:
- // - args
- // a mutable array of arguments to be passed into the
- // wrapped function
- // - proceed
- // a function that "continues" the invocation. The result
- // of this function is the return of the wrapped function.
- // You can then manipulate this return before passing it
- // back out (or take further action based on it).
- // once:
- // boolean that determines whether or not this connect() will
- // create a new connection if an identical connect() has already
- // been made. Defaults to "false".
- // delay:
- // an optional delay (in ms), as an integer, for dispatch of a
- // listener after the source has been fired.
- // rate:
- // an optional rate throttling parameter (integer, in ms). When
- // specified, this particular connection will not fire more than
- // once in the interval specified by the rate
- // adviceMsg:
- // boolean. Should the listener have all the parameters passed in
- // as a single argument?
-
- /*
- ao.adviceType = args[0];
- ao.srcObj = args[1];
- ao.srcFunc = args[2];
- ao.adviceObj = args[3]
- ao.adviceFunc = args[4];
- ao.aroundObj = args[5];
- ao.aroundFunc = args[6];
- ao.once = args[7];
- ao.delay = args[8];
- ao.rate = args[9];
- ao.adviceMsg = args[10];
- ao.maxCalls = args[11];
- */
- if(arguments.length == 1){
- var ao = arguments[0];
- }else{
- var ao = interpolateArgs(arguments, true);
+/*
+dojo.io.sampleTranport = new function(){
+ this.canHandle = function(kwArgs){
+ // canHandle just tells dojo.io.bind() if this is a good transport to
+ // use for the particular type of request.
+ if(
+ (
+ (kwArgs["mimetype"] == "text/plain") ||
+ (kwArgs["mimetype"] == "text/html") ||
+ (kwArgs["mimetype"] == "text/javascript")
+ )&&(
+ (kwArgs["method"] == "get") ||
+ ( (kwArgs["method"] == "post") && (!kwArgs["formNode"]) )
+ )
+ ){
+ return true;
}
- /*
- if(dojo.lang.isString(ao.srcFunc) && (ao.srcFunc.toLowerCase() == "onkey") ){
- if(dojo.render.html.ie){
- ao.srcFunc = "onkeydown";
- this.connect(ao);
+
+ return false;
+ }
+
+ this.bind = function(kwArgs){
+ var hdlrObj = {};
+
+ // set up a handler object
+ for(var x=0; x<dojo.io.hdlrFuncNames.length; x++){
+ var fn = dojo.io.hdlrFuncNames[x];
+ if(typeof kwArgs.handler == "object"){
+ if(typeof kwArgs.handler[fn] == "function"){
+ hdlrObj[fn] = kwArgs.handler[fn]||kwArgs.handler["handle"];
+ }
+ }else if(typeof kwArgs[fn] == "function"){
+ hdlrObj[fn] = kwArgs[fn];
+ }else{
+ hdlrObj[fn] = kwArgs["handle"]||function(){};
}
- ao.srcFunc = "onkeypress";
}
- */
- if(dojo.lang.isArray(ao.srcObj) && ao.srcObj!=""){
- var tmpAO = {};
- for(var x in ao){
- tmpAO[x] = ao[x];
+ // build a handler function that calls back to the handler obj
+ var hdlrFunc = function(evt){
+ if(evt.type == "onload"){
+ hdlrObj.load("load", evt.data, evt);
+ }else if(evt.type == "onerr"){
+ var errObj = new dojo.io.Error("sampleTransport Error: "+evt.msg);
+ hdlrObj.error("error", errObj);
}
- var mjps = [];
- dojo.lang.forEach(ao.srcObj, function(src){
- if((dojo.render.html.capable)&&(dojo.lang.isString(src))){
- src = dojo.byId(src);
- // dojo.debug(src);
- }
- tmpAO.srcObj = src;
- // dojo.debug(tmpAO.srcObj, tmpAO.srcFunc);
- // dojo.debug(tmpAO.adviceObj, tmpAO.adviceFunc);
- mjps.push(dojo.event.connect.call(dojo.event, tmpAO));
- });
- return mjps;
}
- // FIXME: just doing a "getForMethod()" seems to be enough to put this into infinite recursion!!
- var mjp = dojo.event.MethodJoinPoint.getForMethod(ao.srcObj, ao.srcFunc);
- if(ao.adviceFunc){
- var mjp2 = dojo.event.MethodJoinPoint.getForMethod(ao.adviceObj, ao.adviceFunc);
- }
+ // the sample transport would attach the hdlrFunc() when sending the
+ // request down the pipe at this point
+ var tgtURL = kwArgs.url+"?"+dojo.io.argsFromMap(kwArgs.content);
+ // sampleTransport.sendRequest(tgtURL, hdlrFunc);
+ }
- mjp.kwAddAdvice(ao);
+ dojo.io.transports.addTransport("sampleTranport");
+}
+*/
- // advanced users might want to fsck w/ the join point manually
- return mjp; // a MethodJoinPoint object
- }
+dojo.provide("dojo.lang.array");
- this.log = function(/*object or funcName*/ a1, /*funcName*/ a2){
- // summary:
- // a function that will wrap and log all calls to the specified
- // a1.a2() function. If only a1 is passed, it'll be used as a
- // function or function name on the global context. Logging will
- // be sent to dojo.debug
- // a1:
- // if a2 is passed, this should be an object. If not, it can be a
- // function or function name.
- // a2:
- // a function name
- var kwArgs;
- if((arguments.length == 1)&&(typeof a1 == "object")){
- kwArgs = a1;
- }else{
- kwArgs = {
- srcObj: a1,
- srcFunc: a2
- };
- }
- kwArgs.adviceFunc = function(){
- var argsStr = [];
- for(var x=0; x<arguments.length; x++){
- argsStr.push(arguments[x]);
- }
- dojo.debug("("+kwArgs.srcObj+")."+kwArgs.srcFunc, ":", argsStr.join(", "));
- };
- this.kwConnect(kwArgs);
- }
- this.connectBefore = function(){
- // summary:
- // takes the same parameters as dojo.event.connect(), except that
- // the advice type will always be "before"
- var args = ["before"];
- for(var i = 0; i < arguments.length; i++){ args.push(arguments[i]); }
- return this.connect.apply(this, args); // a MethodJoinPoint object
- }
- this.connectAround = function(){
- // summary:
- // takes the same parameters as dojo.event.connect(), except that
- // the advice type will always be "around"
- var args = ["around"];
- for(var i = 0; i < arguments.length; i++){ args.push(arguments[i]); }
- return this.connect.apply(this, args); // a MethodJoinPoint object
- }
+// FIXME: Is this worthless since you can do: if(name in obj)
+// is this the right place for this?
- this.connectOnce = function(){
- // summary:
- // takes the same parameters as dojo.event.connect(), except that
- // the "once" flag will always be set to "true"
- var ao = interpolateArgs(arguments, true);
- ao.once = true;
- return this.connect(ao); // a MethodJoinPoint object
- }
+dojo.lang.mixin(dojo.lang, {
+ has: function(/*Object*/obj, /*String*/name){
+ // summary: is there a property with the passed name in obj?
+ try{
+ return typeof obj[name] != "undefined"; // Boolean
+ }catch(e){ return false; } // Boolean
+ },
- this.connectRunOnce = function(){
+ isEmpty: function(/*Object*/obj){
// summary:
- // takes the same parameters as dojo.event.connect(), except that
- // the "maxCalls" flag will always be set to 1
- var ao = interpolateArgs(arguments, true);
- ao.maxCalls = 1;
- return this.connect(ao); // a MethodJoinPoint object
- }
-
- this._kwConnectImpl = function(kwArgs, disconnect){
- var fn = (disconnect) ? "disconnect" : "connect";
- if(typeof kwArgs["srcFunc"] == "function"){
- kwArgs.srcObj = kwArgs["srcObj"]||dj_global;
- var tmpName = dojo.lang.nameAnonFunc(kwArgs.srcFunc, kwArgs.srcObj, true);
- kwArgs.srcFunc = tmpName;
- }
- if(typeof kwArgs["adviceFunc"] == "function"){
- kwArgs.adviceObj = kwArgs["adviceObj"]||dj_global;
- var tmpName = dojo.lang.nameAnonFunc(kwArgs.adviceFunc, kwArgs.adviceObj, true);
- kwArgs.adviceFunc = tmpName;
+ // can be used to determine if the passed object is "empty". In
+ // the case of array-like objects, the length, property is
+ // examined, but for other types of objects iteration is used to
+ // examine the iterable "surface area" to determine if any
+ // non-prototypal properties have been assigned. This iteration is
+ // prototype-extension safe.
+ if(dojo.lang.isObject(obj)){
+ var tmp = {};
+ var count = 0;
+ for(var x in obj){
+ if(obj[x] && (!tmp[x])){
+ count++;
+ break;
+ }
+ }
+ return count == 0; // boolean
+ }else if(dojo.lang.isArrayLike(obj) || dojo.lang.isString(obj)){
+ return obj.length == 0; // boolean
}
- kwArgs.srcObj = kwArgs["srcObj"]||dj_global;
- kwArgs.adviceObj = kwArgs["adviceObj"]||kwArgs["targetObj"]||dj_global;
- kwArgs.adviceFunc = kwArgs["adviceFunc"]||kwArgs["targetFunc"];
- // pass kwargs to avoid unrolling/repacking
- return dojo.event[fn](kwArgs);
- }
+ },
- this.kwConnect = function(/*Object*/ kwArgs){
+ map: function(/*Array*/arr, /*Object|Function*/obj, /*Function?*/unary_func){
// summary:
- // A version of dojo.event.connect() that takes a map of named
- // parameters instead of the positional parameters that
- // dojo.event.connect() uses. For many advanced connection types,
- // this can be a much more readable (and potentially faster)
- // alternative.
- // kwArgs:
- // An object that can have the following properties:
- // - adviceType
- // - srcObj
- // - srcFunc
- // - adviceObj
- // - adviceFunc
- // - aroundObj
- // - aroundFunc
- // - once
- // - delay
- // - rate
- // - adviceMsg
- // As with connect, only srcFunc and adviceFunc are generally
- // required
+ // returns a new array constituded from the return values of
+ // passing each element of arr into unary_func. The obj parameter
+ // may be passed to enable the passed function to be called in
+ // that scope. In environments that support JavaScript 1.6, this
+ // function is a passthrough to the built-in map() function
+ // provided by Array instances. For details on this, see:
+ // http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:map
+ // examples:
+ // dojo.lang.map([1, 2, 3, 4], function(item){ return item+1 });
+ // // returns [2, 3, 4, 5]
+ var isString = dojo.lang.isString(arr);
+ if(isString){
+ // arr: String
+ arr = arr.split("");
+ }
+ if(dojo.lang.isFunction(obj)&&(!unary_func)){
+ unary_func = obj;
+ obj = dj_global;
+ }else if(dojo.lang.isFunction(obj) && unary_func){
+ // ff 1.5 compat
+ var tmpObj = obj;
+ obj = unary_func;
+ unary_func = tmpObj;
+ }
+ if(Array.map){
+ var outArr = Array.map(arr, unary_func, obj);
+ }else{
+ var outArr = [];
+ for(var i=0;i<arr.length;++i){
+ outArr.push(unary_func.call(obj, arr[i]));
+ }
+ }
+ if(isString) {
+ return outArr.join(""); // String
+ } else {
+ return outArr; // Array
+ }
+ },
- return this._kwConnectImpl(kwArgs, false); // a MethodJoinPoint object
+ reduce: function(/*Array*/arr, initialValue, /*Object|Function*/obj, /*Function*/binary_func){
+ // summary:
+ // similar to Python's builtin reduce() function. The result of
+ // the previous computation is passed as the first argument to
+ // binary_func along with the next value from arr. The result of
+ // this call is used along with the subsequent value from arr, and
+ // this continues until arr is exhausted. The return value is the
+ // last result. The "obj" and "initialValue" parameters may be
+ // safely omitted and the order of obj and binary_func may be
+ // reversed. The default order of the obj and binary_func argument
+ // will probably be reversed in a future release, and this call
+ // order is supported today.
+ // examples:
+ // dojo.lang.reduce([1, 2, 3, 4], function(last, next){ return last+next});
+ // returns 10
+ var reducedValue = initialValue;
+ if(arguments.length == 2){
+ binary_func = initialValue;
+ reducedValue = arr[0];
+ arr = arr.slice(1);
+ }else if(arguments.length == 3){
+ if(dojo.lang.isFunction(obj)){
+ binary_func = obj;
+ obj = null;
+ }
+ }else{
+ // un-fsck the default order
+ // FIXME:
+ // could be wrong for some strange function object cases. Not
+ // sure how to test for them.
+ if(dojo.lang.isFunction(obj)){
+ var tmp = binary_func;
+ binary_func = obj;
+ obj = tmp;
+ }
+ }
- }
+ var ob = obj || dj_global;
+ dojo.lang.map(arr,
+ function(val){
+ reducedValue = binary_func.call(ob, reducedValue, val);
+ }
+ );
+ return reducedValue;
+ },
- this.disconnect = function(){
+ forEach: function(/*Array*/anArray, /*Function*/callback, /*Object?*/thisObject){
// summary:
- // Takes the same parameters as dojo.event.connect() but destroys
- // an existing connection instead of building a new one. For
- // multiple identical connections, multiple disconnect() calls
- // will unroll one each time it's called.
- if(arguments.length == 1){
- var ao = arguments[0];
+ // for every item in anArray, call callback with that item as its
+ // only parameter. Return values are ignored. This funciton
+ // corresponds (and wraps) the JavaScript 1.6 forEach method. For
+ // more details, see:
+ // http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:forEach
+ if(dojo.lang.isString(anArray)){
+ // anArray: String
+ anArray = anArray.split("");
+ }
+ if(Array.forEach){
+ Array.forEach(anArray, callback, thisObject);
}else{
- var ao = interpolateArgs(arguments, true);
+ // FIXME: there are several ways of handilng thisObject. Is dj_global always the default context?
+ if(!thisObject){
+ thisObject=dj_global;
+ }
+ for(var i=0,l=anArray.length; i<l; i++){
+ callback.call(thisObject, anArray[i], i, anArray);
+ }
}
- if(!ao.adviceFunc){ return; } // nothing to disconnect
- if(dojo.lang.isString(ao.srcFunc) && (ao.srcFunc.toLowerCase() == "onkey") ){
- if(dojo.render.html.ie){
- ao.srcFunc = "onkeydown";
- this.disconnect(ao);
+ },
+
+ _everyOrSome: function(/*Boolean*/every, /*Array*/arr, /*Function*/callback, /*Object?*/thisObject){
+ if(dojo.lang.isString(arr)){
+ //arr: String
+ arr = arr.split("");
+ }
+ if(Array.every){
+ return Array[ every ? "every" : "some" ](arr, callback, thisObject);
+ }else{
+ if(!thisObject){
+ thisObject = dj_global;
}
- ao.srcFunc = "onkeypress";
+ for(var i=0,l=arr.length; i<l; i++){
+ var result = callback.call(thisObject, arr[i], i, arr);
+ if(every && !result){
+ return false; // Boolean
+ }else if((!every)&&(result)){
+ return true; // Boolean
+ }
+ }
+ return Boolean(every); // Boolean
}
- if(!ao.srcObj[ao.srcFunc]){ return null; } // prevent un-necessaray joinpoint creation
- var mjp = dojo.event.MethodJoinPoint.getForMethod(ao.srcObj, ao.srcFunc, true);
- mjp.removeAdvice(ao.adviceObj, ao.adviceFunc, ao.adviceType, ao.once); // a MethodJoinPoint object
- return mjp;
- }
+ },
- this.kwDisconnect = function(kwArgs){
+ every: function(/*Array*/arr, /*Function*/callback, /*Object?*/thisObject){
// summary:
- // Takes the same parameters as dojo.event.kwConnect() but
- // destroys an existing connection instead of building a new one.
- return this._kwConnectImpl(kwArgs, true);
- }
-}
+ // determines whether or not every item in the array satisfies the
+ // condition implemented by callback. thisObject may be used to
+ // scope the call to callback. The function signature is derived
+ // from the JavaScript 1.6 Array.every() function. More
+ // information on this can be found here:
+ // http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:every
+ // examples:
+ // dojo.lang.every([1, 2, 3, 4], function(item){ return item>1; });
+ // // returns false
+ // dojo.lang.every([1, 2, 3, 4], function(item){ return item>0; });
+ // // returns true
+ return this._everyOrSome(true, arr, callback, thisObject); // Boolean
+ },
-// exactly one of these is created whenever a method with a joint point is run,
-// if there is at least one 'around' advice.
-dojo.event.MethodInvocation = function(/*dojo.event.MethodJoinPoint*/join_point, /*Object*/obj, /*Array*/args){
- // summary:
- // a class the models the call into a function. This is used under the
- // covers for all method invocations on both ends of a
- // connect()-wrapped function dispatch. This allows us to "pickle"
- // calls, such as in the case of around advice.
- // join_point:
- // a dojo.event.MethodJoinPoint object that represents a connection
- // obj:
- // the scope the call will execute in
- // args:
- // an array of parameters that will get passed to the callee
- this.jp_ = join_point;
- this.object = obj;
- this.args = [];
- // make sure we don't lock into a mutable object which can change under us.
- // It's ok if the individual items change, though.
- for(var x=0; x<args.length; x++){
- this.args[x] = args[x];
- }
- // the index of the 'around' that is currently being executed.
- this.around_index = -1;
-}
+ some: function(/*Array*/arr, /*Function*/callback, /*Object?*/thisObject){
+ // summary:
+ // determines whether or not any item in the array satisfies the
+ // condition implemented by callback. thisObject may be used to
+ // scope the call to callback. The function signature is derived
+ // from the JavaScript 1.6 Array.some() function. More
+ // information on this can be found here:
+ // http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:some
+ // examples:
+ // dojo.lang.some([1, 2, 3, 4], function(item){ return item>1; });
+ // // returns true
+ // dojo.lang.some([1, 2, 3, 4], function(item){ return item<1; });
+ // // returns false
+ return this._everyOrSome(false, arr, callback, thisObject); // Boolean
+ },
-dojo.event.MethodInvocation.prototype.proceed = function(){
- // summary:
- // proceed with the method call that's represented by this invocation
- // object
- this.around_index++;
- if(this.around_index >= this.jp_.around.length){
- return this.jp_.object[this.jp_.methodname].apply(this.jp_.object, this.args);
- // return this.jp_.run_before_after(this.object, this.args);
- }else{
- var ti = this.jp_.around[this.around_index];
- var mobj = ti[0]||dj_global;
- var meth = ti[1];
- return mobj[meth].call(mobj, this);
- }
-}
-
-
-dojo.event.MethodJoinPoint = function(/*Object*/obj, /*String*/funcName){
- this.object = obj||dj_global;
- this.methodname = funcName;
- this.methodfunc = this.object[funcName];
- this.squelch = false;
- // this.before = [];
- // this.after = [];
- // this.around = [];
-}
-
-dojo.event.MethodJoinPoint.getForMethod = function(/*Object*/obj, /*String*/funcName){
- // summary:
- // "static" class function for returning a MethodJoinPoint from a
- // scoped function. If one doesn't exist, one is created.
- // obj:
- // the scope to search for the function in
- // funcName:
- // the name of the function to return a MethodJoinPoint for
- if(!obj){ obj = dj_global; }
- var ofn = obj[funcName];
- if(!ofn){
- // supply a do-nothing method implementation
- ofn = obj[funcName] = function(){};
- if(!obj[funcName]){
- // e.g. cannot add to inbuilt objects in IE6
- dojo.raise("Cannot set do-nothing method on that object "+funcName);
- }
- }else if((typeof ofn != "function")&&(!dojo.lang.isFunction(ofn))&&(!dojo.lang.isAlien(ofn))){
- // FIXME: should we throw an exception here instead?
- return null;
- }
- // we hide our joinpoint instance in obj[funcName + '$joinpoint']
- var jpname = funcName + "$joinpoint";
- var jpfuncname = funcName + "$joinpoint$method";
- var joinpoint = obj[jpname];
- if(!joinpoint){
- var isNode = false;
- if(dojo.event["browser"]){
- if( (obj["attachEvent"])||
- (obj["nodeType"])||
- (obj["addEventListener"]) ){
- isNode = true;
- dojo.event.browser.addClobberNodeAttrs(obj, [jpname, jpfuncname, funcName]);
+ filter: function(/*Array*/arr, /*Function*/callback, /*Object?*/thisObject){
+ // summary:
+ // returns a new Array with those items from arr that match the
+ // condition implemented by callback.thisObject may be used to
+ // scope the call to callback. The function signature is derived
+ // from the JavaScript 1.6 Array.filter() function, although
+ // special accomidation is made in our implementation for strings.
+ // More information on the JS 1.6 API can be found here:
+ // http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:filter
+ // examples:
+ // dojo.lang.some([1, 2, 3, 4], function(item){ return item>1; });
+ // // returns [2, 3, 4]
+ var isString = dojo.lang.isString(arr);
+ if(isString){ /*arr: String*/arr = arr.split(""); }
+ var outArr;
+ if(Array.filter){
+ outArr = Array.filter(arr, callback, thisObject);
+ }else{
+ if(!thisObject){
+ if(arguments.length >= 3){ dojo.raise("thisObject doesn't exist!"); }
+ thisObject = dj_global;
}
- }
- var origArity = ofn.length;
- obj[jpfuncname] = ofn;
- // joinpoint = obj[jpname] = new dojo.event.MethodJoinPoint(obj, funcName);
- joinpoint = obj[jpname] = new dojo.event.MethodJoinPoint(obj, jpfuncname);
- if(!isNode){
- obj[funcName] = function(){
- // var args = [];
- // for(var x=0; x<arguments.length; x++){
- // args.push(arguments[x]);
- // }
- // return joinpoint.run.apply(joinpoint, args);
- return joinpoint.run.apply(joinpoint, arguments);
+ outArr = [];
+ for(var i = 0; i < arr.length; i++){
+ if(callback.call(thisObject, arr[i], i, arr)){
+ outArr.push(arr[i]);
+ }
}
- }else{
- obj[funcName] = function(){
- var args = [];
+ }
+ if(isString){
+ return outArr.join(""); // String
+ } else {
+ return outArr; // Array
+ }
+ },
- if(!arguments.length){
- var evt = null;
- try{
- if(obj.ownerDocument){
- evt = obj.ownerDocument.parentWindow.event;
- }else if(obj.documentElement){
- evt = obj.documentElement.ownerDocument.parentWindow.event;
- }else if(obj.event){ //obj is a window
- evt = obj.event;
- }else{
- evt = window.event;
- }
- }catch(e){
- evt = window.event;
- }
+ unnest: function(/* ... */){
+ // summary:
+ // Creates a 1-D array out of all the arguments passed,
+ // unravelling any array-like objects in the process
+ // usage:
+ // unnest(1, 2, 3) ==> [1, 2, 3]
+ // unnest(1, [2, [3], [[[4]]]]) ==> [1, 2, 3, 4]
- if(evt){
- args.push(dojo.event.browser.fixEvent(evt, this));
- }
- }else{
- for(var x=0; x<arguments.length; x++){
- if((x==0)&&(dojo.event.browser.isEvent(arguments[x]))){
- args.push(dojo.event.browser.fixEvent(arguments[x], this));
- }else{
- args.push(arguments[x]);
- }
- }
- }
- // return joinpoint.run.apply(joinpoint, arguments);
- return joinpoint.run.apply(joinpoint, args);
+ var out = [];
+ for(var i = 0; i < arguments.length; i++){
+ if(dojo.lang.isArrayLike(arguments[i])){
+ var add = dojo.lang.unnest.apply(this, arguments[i]);
+ out = out.concat(add);
+ }else{
+ out.push(arguments[i]);
}
}
- obj[funcName].__preJoinArity = origArity;
- }
- return joinpoint; // dojo.event.MethodJoinPoint
-}
+ return out; // Array
+ },
-dojo.lang.extend(dojo.event.MethodJoinPoint, {
- squelch: false,
+ toArray: function(/*Object*/arrayLike, /*Number*/startOffset){
+ // summary:
+ // Converts an array-like object (i.e. arguments, DOMCollection)
+ // to an array. Returns a new Array object.
+ var array = [];
+ for(var i = startOffset||0; i < arrayLike.length; i++){
+ array.push(arrayLike[i]);
+ }
+ return array; // Array
+ }
+});
- unintercept: function(){
- // summary:
- // destroy the connection to all listeners that may have been
- // registered on this joinpoint
- this.object[this.methodname] = this.methodfunc;
- this.before = [];
- this.after = [];
- this.around = [];
- },
+dojo.provide("dojo.lang.func");
- disconnect: dojo.lang.forward("unintercept"),
- run: function(){
- // summary:
- // execute the connection represented by this join point. The
- // arguments passed to run() will be passed to the function and
- // its listeners.
- var obj = this.object||dj_global;
- var args = arguments;
+dojo.lang.hitch = function(/*Object*/thisObject, /*Function|String*/method /*, ...*/){
+ // summary:
+ // Returns a function that will only ever execute in the a given scope
+ // (thisObject). This allows for easy use of object member functions
+ // in callbacks and other places in which the "this" keyword may
+ // otherwise not reference the expected scope. Any number of default
+ // positional arguments may be passed as parameters beyond "method".
+ // Each of these values will be used to "placehold" (similar to curry)
+ // for the hitched function. Note that the order of arguments may be
+ // reversed in a future version.
+ // thisObject: the scope to run the method in
+ // method:
+ // a function to be "bound" to thisObject or the name of the method in
+ // thisObject to be used as the basis for the binding
+ // usage:
+ // dojo.lang.hitch(foo, "bar")(); // runs foo.bar() in the scope of foo
+ // dojo.lang.hitch(foo, myFunction); // returns a function that runs myFunction in the scope of foo
- // optimization. We only compute once the array version of the arguments
- // pseudo-arr in order to prevent building it each time advice is unrolled.
- var aargs = [];
- for(var x=0; x<args.length; x++){
- aargs[x] = args[x];
+ var args = [];
+ for(var x=2; x<arguments.length; x++){
+ args.push(arguments[x]);
+ }
+ var fcn = (dojo.lang.isString(method) ? thisObject[method] : method) || function(){};
+ return function(){
+ var ta = args.concat([]); // make a copy
+ for(var x=0; x<arguments.length; x++){
+ ta.push(arguments[x]);
}
+ return fcn.apply(thisObject, ta); // Function
+ // return fcn.apply(thisObject, arguments); // Function
+ };
+}
- var unrollAdvice = function(marr){
- if(!marr){
- dojo.debug("Null argument to unrollAdvice()");
- return;
- }
-
- var callObj = marr[0]||dj_global;
- var callFunc = marr[1];
-
- if(!callObj[callFunc]){
- dojo.raise("function \"" + callFunc + "\" does not exist on \"" + callObj + "\"");
- }
-
- var aroundObj = marr[2]||dj_global;
- var aroundFunc = marr[3];
- var msg = marr[6];
- var maxCount = marr[7];
- if(maxCount > -1){
- if(maxCount == 0){
- return;
- }
- marr[7]--;
- }
- var undef;
+dojo.lang.anonCtr = 0;
+dojo.lang.anon = {};
- var to = {
- args: [],
- jp_: this,
- object: obj,
- proceed: function(){
- return callObj[callFunc].apply(callObj, to.args);
+dojo.lang.nameAnonFunc = function(/*Function*/anonFuncPtr, /*Object*/thisObj, /*Boolean*/searchForNames){
+ // summary:
+ // Creates a reference to anonFuncPtr in thisObj with a completely
+ // unique name. The new name is returned as a String. If
+ // searchForNames is true, an effort will be made to locate an
+ // existing reference to anonFuncPtr in thisObj, and if one is found,
+ // the existing name will be returned instead. The default is for
+ // searchForNames to be false.
+ var nso = (thisObj|| dojo.lang.anon);
+ if( (searchForNames) ||
+ ((dj_global["djConfig"])&&(djConfig["slowAnonFuncLookups"] == true)) ){
+ for(var x in nso){
+ try{
+ if(nso[x] === anonFuncPtr){
+ return x;
}
- };
- to.args = aargs;
-
- var delay = parseInt(marr[4]);
- var hasDelay = ((!isNaN(delay))&&(marr[4]!==null)&&(typeof marr[4] != "undefined"));
- if(marr[5]){
- var rate = parseInt(marr[5]);
- var cur = new Date();
- var timerSet = false;
- if((marr["last"])&&((cur-marr.last)<=rate)){
- if(dojo.event._canTimeout){
- if(marr["delayTimer"]){
- clearTimeout(marr.delayTimer);
- }
- var tod = parseInt(rate*2); // is rate*2 naive?
- var mcpy = dojo.lang.shallowCopy(marr);
- marr.delayTimer = setTimeout(function(){
- // FIXME: on IE at least, event objects from the
- // browser can go out of scope. How (or should?) we
- // deal with it?
- mcpy[5] = 0;
- unrollAdvice(mcpy);
- }, tod);
- }
- return;
- }else{
- marr.last = cur;
- }
- }
+ }catch(e){} // window.external fails in IE embedded in Eclipse (Eclipse bug #151165)
+ }
+ }
+ var ret = "__"+dojo.lang.anonCtr++;
+ while(typeof nso[ret] != "undefined"){
+ ret = "__"+dojo.lang.anonCtr++;
+ }
+ nso[ret] = anonFuncPtr;
+ return ret; // String
+}
- // FIXME: need to enforce rates for a connection here!
+dojo.lang.forward = function(funcName){
+ // summary:
+ // Returns a function that forwards a method call to
+ // this.funcName(...). Unlike dojo.lang.hitch(), the "this" scope is
+ // not fixed on a single object. Ported from MochiKit.
+ return function(){
+ return this[funcName].apply(this, arguments);
+ }; // Function
+}
- if(aroundFunc){
- // NOTE: around advice can't delay since we might otherwise depend
- // on execution order!
- aroundObj[aroundFunc].call(aroundObj, to);
- }else{
- // var tmjp = dojo.event.MethodJoinPoint.getForMethod(obj, methname);
- if((hasDelay)&&((dojo.render.html)||(dojo.render.svg))){ // FIXME: the render checks are grotty!
- dj_global["setTimeout"](function(){
- if(msg){
- callObj[callFunc].call(callObj, to);
- }else{
- callObj[callFunc].apply(callObj, args);
- }
- }, delay);
- }else{ // many environments can't support delay!
- if(msg){
- callObj[callFunc].call(callObj, to);
- }else{
- callObj[callFunc].apply(callObj, args);
- }
- }
- }
- };
+dojo.lang.curry = function(thisObj, func /* args ... */){
+ // summary:
+ // similar to the curry() method found in many functional programming
+ // environments, this function returns an "argument accumulator"
+ // function, bound to a particular scope, and "primed" with a variable
+ // number of arguments. The curry method is unique in that it returns
+ // a function that may return other "partial" function which can be
+ // called repeatedly. New functions are returned until the arity of
+ // the original function is reached, at which point the underlying
+ // function (func) is called in the scope thisObj with all of the
+ // accumulated arguments (plus any extras) in positional order.
+ // examples:
+ // assuming a function defined like this:
+ // var foo = {
+ // bar: function(arg1, arg2, arg3){
+ // dojo.debug.apply(dojo, arguments);
+ // }
+ // };
+ //
+ // dojo.lang.curry() can be used most simply in this way:
+ //
+ // tmp = dojo.lang.curry(foo, foo.bar, "arg one", "thinger");
+ // tmp("blah", "this is superfluous");
+ // // debugs: "arg one thinger blah this is superfluous"
+ // tmp("blah");
+ // // debugs: "arg one thinger blah"
+ // tmp();
+ // // returns a function exactly like tmp that expects one argument
+ //
+ // other intermittent functions could be created until the 3
+ // positional arguments are filled:
+ //
+ // tmp = dojo.lang.curry(foo, foo.bar, "arg one");
+ // tmp2 = tmp("arg two");
+ // tmp2("blah blah");
+ // // debugs: "arg one arg two blah blah"
+ // tmp2("oy");
+ // // debugs: "arg one arg two oy"
+ //
+ // curry() can also be used to call the function if enough arguments
+ // are passed in the initial invocation:
+ //
+ // dojo.lang.curry(foo, foo.bar, "one", "two", "three", "four");
+ // // debugs: "one two three four"
+ // dojo.lang.curry(foo, foo.bar, "one", "two", "three");
+ // // debugs: "one two three"
- var unRollSquelch = function(){
- if(this.squelch){
- try{
- return unrollAdvice.apply(this, arguments);
- }catch(e){
- dojo.debug(e);
- }
- }else{
- return unrollAdvice.apply(this, arguments);
- }
- };
- if((this["before"])&&(this.before.length>0)){
- // pass a cloned array, if this event disconnects this event forEach on this.before wont work
- dojo.lang.forEach(this.before.concat(new Array()), unRollSquelch);
+ // FIXME: the order of func and thisObj should be changed!!!
+ var outerArgs = [];
+ thisObj = thisObj||dj_global;
+ if(dojo.lang.isString(func)){
+ func = thisObj[func];
+ }
+ for(var x=2; x<arguments.length; x++){
+ outerArgs.push(arguments[x]);
+ }
+ // since the event system replaces the original function with a new
+ // join-point runner with an arity of 0, we check to see if it's left us
+ // any clues about the original arity in lieu of the function's actual
+ // length property
+ var ecount = (func["__preJoinArity"]||func.length) - outerArgs.length;
[... 8855 lines stripped ...]