0a5defa41670fcbf633a5883d22d486ef574c232.svn-base 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. if (!dojo._hasResource["dojo._base.lang"]) { // _hasResource checks added by
  2. // build. Do not use
  3. // _hasResource directly in your
  4. // code.
  5. dojo._hasResource["dojo._base.lang"] = true;
  6. dojo.provide("dojo._base.lang");
  7. // Crockford (ish) functions
  8. dojo.isString = function(/* anything */it) {
  9. // summary: Return true if it is a String
  10. return typeof it == "string" || it instanceof String; // Boolean
  11. }
  12. dojo.isArray = function(/* anything */it) {
  13. // summary: Return true if it is an Array
  14. return it && it instanceof Array || typeof it == "array"; // Boolean
  15. }
  16. /*
  17. * ===== dojo.isFunction = function(it){ // summary: Return true if it is a
  18. * Function // it: anything } =====
  19. */
  20. dojo.isFunction = (function() {
  21. var _isFunction = function(/* anything */it) {
  22. return typeof it == "function" || it instanceof Function; // Boolean
  23. };
  24. return dojo.isSafari ?
  25. // only slow this down w/ gratuitious casting in Safari since
  26. // it's what's b0rken
  27. function(/* anything */it) {
  28. if (typeof it == "function" && it == "[object NodeList]") {
  29. return false;
  30. }
  31. return _isFunction(it); // Boolean
  32. }
  33. : _isFunction;
  34. })();
  35. dojo.isObject = function(/* anything */it) {
  36. // summary:
  37. // Returns true if it is a JavaScript object (or an Array, a Function or
  38. // null)
  39. return it !== undefined
  40. && (it === null || typeof it == "object" || dojo.isArray(it) || dojo
  41. .isFunction(it)); // Boolean
  42. }
  43. dojo.isArrayLike = function(/* anything */it) {
  44. // summary:
  45. // similar to dojo.isArray() but more permissive
  46. // description:
  47. // Doesn't strongly test for "arrayness". Instead, settles for "isn't
  48. // a string or number and has a length property". Arguments objects
  49. // and DOM collections will return true when passed to
  50. // dojo.isArrayLike(), but will return false when passed to
  51. // dojo.isArray().
  52. // return:
  53. // If it walks like a duck and quicks like a duck, return true
  54. var d = dojo;
  55. return it
  56. && it !== undefined
  57. &&
  58. // keep out built-in constructors (Number, String, ...) which
  59. // have length
  60. // properties
  61. !d.isString(it) && !d.isFunction(it)
  62. && !(it.tagName && it.tagName.toLowerCase() == 'form')
  63. && (d.isArray(it) || isFinite(it.length)); // Boolean
  64. }
  65. dojo.isAlien = function(/* anything */it) {
  66. // summary:
  67. // Returns true if it is a built-in function or some other kind of
  68. // oddball that *should* report as a function but doesn't
  69. return it && !dojo.isFunction(it)
  70. && /\{\s*\[native code\]\s*\}/.test(String(it)); // Boolean
  71. }
  72. dojo.extend = function(/* Object */constructor, /* Object... */props) {
  73. // summary:
  74. // Adds all properties and methods of props to constructor's
  75. // prototype, making them available to all instances created with
  76. // constructor.
  77. for (var i = 1, l = arguments.length; i < l; i++) {
  78. dojo._mixin(constructor.prototype, arguments[i]);
  79. }
  80. return constructor; // Object
  81. }
  82. dojo._hitchArgs = function(scope, method /* ,... */) {
  83. var pre = dojo._toArray(arguments, 2);
  84. var named = dojo.isString(method);
  85. return function() {
  86. // arrayify arguments
  87. var args = dojo._toArray(arguments);
  88. // locate our method
  89. var f = named ? (scope || dojo.global)[method] : method;
  90. // invoke with collected args
  91. return f && f.apply(scope || this, pre.concat(args)); // mixed
  92. } // Function
  93. }
  94. dojo.hitch = function(/* Object */scope, /* Function|String */method /* ,... */) {
  95. // summary:
  96. // Returns a function that will only ever execute in the a given scope.
  97. // This allows for easy use of object member functions
  98. // in callbacks and other places in which the "this" keyword may
  99. // otherwise not reference the expected scope.
  100. // Any number of default positional arguments may be passed as
  101. // parameters
  102. // beyond "method".
  103. // Each of these values will be used to "placehold" (similar to curry)
  104. // for the hitched function.
  105. // scope:
  106. // The scope to use when method executes. If method is a string,
  107. // scope is also the object containing method.
  108. // method:
  109. // A function to be hitched to scope, or the name of the method in
  110. // scope to be hitched.
  111. // example:
  112. // | dojo.hitch(foo, "bar")();
  113. // runs foo.bar() in the scope of foo
  114. // example:
  115. // | dojo.hitch(foo, myFunction);
  116. // returns a function that runs myFunction in the scope of foo
  117. if (arguments.length > 2) {
  118. return dojo._hitchArgs.apply(dojo, arguments); // Function
  119. }
  120. if (!method) {
  121. method = scope;
  122. scope = null;
  123. }
  124. if (dojo.isString(method)) {
  125. scope = scope || dojo.global;
  126. if (!scope[method]) {
  127. throw (['dojo.hitch: scope["', method, '"] is null (scope="',
  128. scope, '")'].join(''));
  129. }
  130. return function() {
  131. return scope[method].apply(scope, arguments || []);
  132. }; // Function
  133. }
  134. return !scope ? method : function() {
  135. return method.apply(scope, arguments || []);
  136. }; // Function
  137. }
  138. /*
  139. * ===== dojo.delegate = function(obj, props){ // summary: // returns a new
  140. * object which "looks" to obj for properties which it // does not have a
  141. * value for. Optionally takes a bag of properties to // seed the returned
  142. * object with initially. // description: // This is a small implementaton
  143. * of the Boodman/Crockford delegation // pattern in JavaScript. An
  144. * intermediate object constructor mediates // the prototype chain for the
  145. * returned object, using it to delegate // down to obj for property lookup
  146. * when object-local lookup fails. // This can be thought of similarly to
  147. * ES4's "wrap", save that it does // not act on types but rather on pure
  148. * objects. // obj: // The object to delegate to for properties not found
  149. * directly on the // return object or in props. // props: // an object
  150. * containing properties to assign to the returned object // returns: // an
  151. * Object of anonymous type // example: // | var foo = { bar: "baz" }; // |
  152. * var thinger = dojo.delegate(foo, { thud: "xyzzy"}); // | thinger.bar ==
  153. * "baz"; // delegated to foo // | foo.xyzzy == undefined; // by definition // |
  154. * thinger.xyzzy == "xyzzy"; // mixed in from props // | foo.bar = "thonk"; // |
  155. * thinger.bar == "thonk"; // still delegated to foo's bar } =====
  156. */
  157. dojo.delegate = dojo._delegate = function(obj, props) {
  158. // boodman/crockford delegation
  159. function TMP() {
  160. };
  161. TMP.prototype = obj;
  162. var tmp = new TMP();
  163. if (props) {
  164. dojo.mixin(tmp, props);
  165. }
  166. return tmp; // Object
  167. }
  168. dojo.partial = function(/* Function|String */method /* , ... */) {
  169. // summary:
  170. // similar to hitch() except that the scope object is left to be
  171. // whatever the execution context eventually becomes.
  172. // description:
  173. // Calling dojo.partial is the functional equivalent of calling:
  174. // | dojo.hitch(null, funcName, ...);
  175. var arr = [null];
  176. return dojo.hitch.apply(dojo, arr.concat(dojo._toArray(arguments))); // Function
  177. }
  178. dojo._toArray = function(/* Object */obj, /* Number? */offset, /* Array? */
  179. startWith) {
  180. // summary:
  181. // Converts an array-like object (i.e. arguments, DOMCollection)
  182. // to an array. Returns a new Array object.
  183. // obj:
  184. // the object to "arrayify". We expect the object to have, at a
  185. // minimum, a length property which corresponds to integer-indexed
  186. // properties.
  187. // offset:
  188. // the location in obj to start iterating from. Defaults to 0. Optional.
  189. // startWith:
  190. // An array to pack with the properties of obj. If provided,
  191. // properties in obj are appended at the end of startWith and
  192. // startWith is the returned array.
  193. var arr = startWith || [];
  194. for (var x = offset || 0; x < obj.length; x++) {
  195. arr.push(obj[x]);
  196. }
  197. return arr; // Array
  198. }
  199. dojo.clone = function(/* anything */o) {
  200. // summary:
  201. // Clones objects (including DOM nodes) and all children.
  202. // Warning: do not clone cyclic structures.
  203. if (!o) {
  204. return o;
  205. }
  206. if (dojo.isArray(o)) {
  207. var r = [];
  208. for (var i = 0; i < o.length; ++i) {
  209. r.push(dojo.clone(o[i]));
  210. }
  211. return r; // Array
  212. }
  213. if (!dojo.isObject(o)) {
  214. return o; /* anything */
  215. }
  216. if (o.nodeType && o.cloneNode) { // isNode
  217. return o.cloneNode(true); // Node
  218. }
  219. if (o instanceof Date) {
  220. return new Date(o.getTime()); // Date
  221. }
  222. // Generic objects
  223. var r = new o.constructor(); // specific to dojo.declare()'d classes!
  224. for (var i in o) {
  225. if (!(i in r) || r[i] != o[i]) {
  226. r[i] = dojo.clone(o[i]);
  227. }
  228. }
  229. return r; // Object
  230. }
  231. dojo.trim = function(/* String */str) {
  232. // summary:
  233. // trims whitespaces from both sides of the string
  234. // description:
  235. // This version of trim() was selected for inclusion into the base due
  236. // to its compact size and relatively good performance (see Steven
  237. // Levithan's blog:
  238. // http://blog.stevenlevithan.com/archives/faster-trim-javascript).
  239. // The fastest but longest version of this function is located at
  240. // dojo.string.trim()
  241. return str.replace(/^\s\s*/, '').replace(/\s\s*$/, ''); // String
  242. }
  243. }