if(!dojo._hasResource["dojox.lang.functional.lambda"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. dojo._hasResource["dojox.lang.functional.lambda"] = true; dojo.provide("dojox.lang.functional.lambda"); // This module adds high-level functions and related constructs: // - anonymous functions built from the string // Acknoledgements: // - lambda() is based on work by Oliver Steele // (http://osteele.com/sources/javascript/functional/functional.js) // which was published under MIT License // Notes: // - lambda() produces functions, which after the compilation step are // as fast as regular JS functions (at least theoretically). // Lambda input values: // - returns functions unchanged // - converts strings to functions // - converts arrays to a functional composition (function(){ var df = dojox.lang.functional; // split() is augmented on IE6 to ensure the uniform behavior var split = "ab".split(/a*/).length > 1 ? String.prototype.split : function(sep){ var r = this.split.call(this, sep), m = sep.exec(this); if(m && m.index == 0){ r.unshift(""); } return r; }; var lambda = function(/*String*/ s){ var args = [], sects = split.call(s, /\s*->\s*/m); if(sects.length > 1){ while(sects.length){ s = sects.pop(); args = sects.pop().split(/\s*,\s*|\s+/m); if(sects.length){ sects.push("(function(" + args + "){return (" + s + ")})"); } } }else if(s.match(/\b_\b/)){ args = ["_"]; }else{ var l = s.match(/^\s*(?:[+*\/%&|\^\.=<>]|!=)/m), r = s.match(/[+\-*\/%&|\^\.=<>!]\s*$/m); if(l || r){ if(l){ args.push("$1"); s = "$1" + s; } if(r){ args.push("$2"); s = s + "$2"; } }else{ // the point of the long regex below is to exclude all well-known // lower-case words from the list of potential arguments var vars = s. replace(/(?:\b[A-Z]|\.[a-zA-Z_$])[a-zA-Z_$\d]*|[a-zA-Z_$][a-zA-Z_$\d]*:|this|true|false|null|undefined|typeof|instanceof|in|delete|new|void|arguments|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|escape|eval|isFinite|isNaN|parseFloat|parseInt|unescape|dojo|dijit|dojox|window|document|'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*"/g, ""). match(/([a-z_$][a-z_$\d]*)/gi) || []; var t = {}; dojo.forEach(vars, function(v){ if(!(v in t)){ args.push(v); t[v] = 1; } }); } } return {args: args, body: "return (" + s + ");"}; // Object }; var compose = function(/*Array*/ a){ return a.length ? function(){ var i = a.length - 1, x = df.lambda(a[i]).apply(this, arguments); for(--i; i >= 0; --i){ x = df.lambda(a[i]).call(this, x); } return x; } : // identity function(x){ return x; }; }; dojo.mixin(df, { // lambda buildLambda: function(/*String*/ s){ // summary: builds a function from a snippet, returns a string, // which represents the function. // description: This method returns a textual representation of a function // built from the snippet. It is meant to be evaled in the proper context, // so local variables can be pulled from the environment. s = lambda(s); return "function(" + s.args.join(",") + "){" + s.body + "}"; // String }, lambda: function(/*Function|String|Array*/ s){ // summary: builds a function from a snippet, or array (composing), returns // a function object; functions are passed through unmodified. // description: This method is used to normalize a functional representation // (a text snippet, an array, or a function) to a function object. if(typeof s == "function"){ return s; } if(s instanceof Array){ return compose(s); } s = lambda(s); return new Function(s.args, s.body); // Function } }); })(); }