1 | /*! |
---|
2 | * Ext JS Library 3.0.0 |
---|
3 | * Copyright(c) 2006-2009 Ext JS, LLC |
---|
4 | * licensing@extjs.com |
---|
5 | * http://www.extjs.com/license |
---|
6 | */ |
---|
7 | /** |
---|
8 | * @class Ext |
---|
9 | */ |
---|
10 | |
---|
11 | Ext.ns("Ext.grid", "Ext.dd", "Ext.tree", "Ext.form", "Ext.menu", |
---|
12 | "Ext.state", "Ext.layout", "Ext.app", "Ext.ux", "Ext.chart", "Ext.direct"); |
---|
13 | /** |
---|
14 | * Namespace alloted for extensions to the framework. |
---|
15 | * @property ux |
---|
16 | * @type Object |
---|
17 | */ |
---|
18 | |
---|
19 | Ext.apply(Ext, function(){ |
---|
20 | var E = Ext, idSeed = 0; |
---|
21 | |
---|
22 | return { |
---|
23 | /** |
---|
24 | * A reusable empty function |
---|
25 | * @property |
---|
26 | * @type Function |
---|
27 | */ |
---|
28 | emptyFn : function(){}, |
---|
29 | |
---|
30 | /** |
---|
31 | * URL to a 1x1 transparent gif image used by Ext to create inline icons with CSS background images. |
---|
32 | * In older versions of IE, this defaults to "http://extjs.com/s.gif" and you should change this to a URL on your server. |
---|
33 | * For other browsers it uses an inline data URL. |
---|
34 | * @type String |
---|
35 | */ |
---|
36 | BLANK_IMAGE_URL : Ext.isIE6 || Ext.isIE7 ? |
---|
37 | 'http:/' + '/extjs.com/s.gif' : |
---|
38 | 'data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==', |
---|
39 | |
---|
40 | extendX : function(supr, fn){ |
---|
41 | return Ext.extend(supr, fn(supr.prototype)); |
---|
42 | }, |
---|
43 | |
---|
44 | /** |
---|
45 | * Returns the current HTML document object as an {@link Ext.Element}. |
---|
46 | * @return Ext.Element The document |
---|
47 | */ |
---|
48 | getDoc : function(){ |
---|
49 | return Ext.get(document); |
---|
50 | }, |
---|
51 | |
---|
52 | /** |
---|
53 | * Returns true if the passed object is a JavaScript date object, otherwise false. |
---|
54 | * @param {Object} object The object to test |
---|
55 | * @return {Boolean} |
---|
56 | */ |
---|
57 | isDate : function(v){ |
---|
58 | return Object.prototype.toString.apply(v) === '[object Date]'; |
---|
59 | }, |
---|
60 | |
---|
61 | /** |
---|
62 | * Utility method for validating that a value is numeric, returning the specified default value if it is not. |
---|
63 | * @param {Mixed} value Should be a number, but any type will be handled appropriately |
---|
64 | * @param {Number} defaultValue The value to return if the original value is non-numeric |
---|
65 | * @return {Number} Value, if numeric, else defaultValue |
---|
66 | */ |
---|
67 | num : function(v, defaultValue){ |
---|
68 | v = Number(v === null || typeof v == 'boolean'? NaN : v); |
---|
69 | return isNaN(v)? defaultValue : v; |
---|
70 | }, |
---|
71 | |
---|
72 | /** |
---|
73 | * <p>Utility method for returning a default value if the passed value is empty.</p> |
---|
74 | * <p>The value is deemed to be empty if it is<div class="mdetail-params"><ul> |
---|
75 | * <li>null</li> |
---|
76 | * <li>undefined</li> |
---|
77 | * <li>an empty array</li> |
---|
78 | * <li>a zero length string (Unless the <tt>allowBlank</tt> parameter is <tt>true</tt>)</li> |
---|
79 | * </ul></div> |
---|
80 | * @param {Mixed} value The value to test |
---|
81 | * @param {Mixed} defaultValue The value to return if the original value is empty |
---|
82 | * @param {Boolean} allowBlank (optional) true to allow zero length strings to qualify as non-empty (defaults to false) |
---|
83 | * @return {Mixed} value, if non-empty, else defaultValue |
---|
84 | */ |
---|
85 | value : function(v, defaultValue, allowBlank){ |
---|
86 | return Ext.isEmpty(v, allowBlank) ? defaultValue : v; |
---|
87 | }, |
---|
88 | |
---|
89 | /** |
---|
90 | * Escapes the passed string for use in a regular expression |
---|
91 | * @param {String} str |
---|
92 | * @return {String} |
---|
93 | */ |
---|
94 | escapeRe : function(s) { |
---|
95 | return s.replace(/([.*+?^${}()|[\]\/\\])/g, "\\$1"); |
---|
96 | }, |
---|
97 | |
---|
98 | sequence : function(o, name, fn, scope){ |
---|
99 | o[name] = o[name].createSequence(fn, scope); |
---|
100 | }, |
---|
101 | |
---|
102 | /** |
---|
103 | * Applies event listeners to elements by selectors when the document is ready. |
---|
104 | * The event name is specified with an <tt>@</tt> suffix. |
---|
105 | * <pre><code> |
---|
106 | Ext.addBehaviors({ |
---|
107 | // add a listener for click on all anchors in element with id foo |
---|
108 | '#foo a@click' : function(e, t){ |
---|
109 | // do something |
---|
110 | }, |
---|
111 | |
---|
112 | // add the same listener to multiple selectors (separated by comma BEFORE the @) |
---|
113 | '#foo a, #bar span.some-class@mouseover' : function(){ |
---|
114 | // do something |
---|
115 | } |
---|
116 | }); |
---|
117 | * </code></pre> |
---|
118 | * @param {Object} obj The list of behaviors to apply |
---|
119 | */ |
---|
120 | addBehaviors : function(o){ |
---|
121 | if(!Ext.isReady){ |
---|
122 | Ext.onReady(function(){ |
---|
123 | Ext.addBehaviors(o); |
---|
124 | }); |
---|
125 | } else { |
---|
126 | var cache = {}, // simple cache for applying multiple behaviors to same selector does query multiple times |
---|
127 | parts, |
---|
128 | b, |
---|
129 | s; |
---|
130 | for (b in o) { |
---|
131 | if ((parts = b.split('@'))[1]) { // for Object prototype breakers |
---|
132 | s = parts[0]; |
---|
133 | if(!cache[s]){ |
---|
134 | cache[s] = Ext.select(s); |
---|
135 | } |
---|
136 | cache[s].on(parts[1], o[b]); |
---|
137 | } |
---|
138 | } |
---|
139 | cache = null; |
---|
140 | } |
---|
141 | }, |
---|
142 | |
---|
143 | |
---|
144 | // deprecated |
---|
145 | combine : function(){ |
---|
146 | var as = arguments, l = as.length, r = []; |
---|
147 | for(var i = 0; i < l; i++){ |
---|
148 | var a = as[i]; |
---|
149 | if(Ext.isArray(a)){ |
---|
150 | r = r.concat(a); |
---|
151 | }else if(a.length !== undefined && !a.substr){ |
---|
152 | r = r.concat(Array.prototype.slice.call(a, 0)); |
---|
153 | }else{ |
---|
154 | r.push(a); |
---|
155 | } |
---|
156 | } |
---|
157 | return r; |
---|
158 | }, |
---|
159 | |
---|
160 | /** |
---|
161 | * Copies a set of named properties fom the source object to the destination object. |
---|
162 | * <p>example:<pre><code> |
---|
163 | ImageComponent = Ext.extend(Ext.BoxComponent, { |
---|
164 | initComponent: function() { |
---|
165 | this.autoEl = { tag: 'img' }; |
---|
166 | MyComponent.superclass.initComponent.apply(this, arguments); |
---|
167 | this.initialBox = Ext.copyTo({}, this.initialConfig, 'x,y,width,height'); |
---|
168 | } |
---|
169 | }); |
---|
170 | * </code></pre> |
---|
171 | * @param {Object} The destination object. |
---|
172 | * @param {Object} The source object. |
---|
173 | * @param {Array/String} Either an Array of property names, or a comma-delimited list |
---|
174 | * of property names to copy. |
---|
175 | * @return {Object} The modified object. |
---|
176 | */ |
---|
177 | copyTo : function(dest, source, names){ |
---|
178 | if(typeof names == 'string'){ |
---|
179 | names = names.split(/[,;\s]/); |
---|
180 | } |
---|
181 | Ext.each(names, function(name){ |
---|
182 | if(source.hasOwnProperty(name)){ |
---|
183 | dest[name] = source[name]; |
---|
184 | } |
---|
185 | }, this); |
---|
186 | return dest; |
---|
187 | }, |
---|
188 | |
---|
189 | /** |
---|
190 | * Attempts to destroy any objects passed to it by removing all event listeners, removing them from the |
---|
191 | * DOM (if applicable) and calling their destroy functions (if available). This method is primarily |
---|
192 | * intended for arguments of type {@link Ext.Element} and {@link Ext.Component}, but any subclass of |
---|
193 | * {@link Ext.util.Observable} can be passed in. Any number of elements and/or components can be |
---|
194 | * passed into this function in a single call as separate arguments. |
---|
195 | * @param {Mixed} arg1 An {@link Ext.Element}, {@link Ext.Component}, or an Array of either of these to destroy |
---|
196 | * @param {Mixed} arg2 (optional) |
---|
197 | * @param {Mixed} etc... (optional) |
---|
198 | */ |
---|
199 | destroy : function(){ |
---|
200 | Ext.each(arguments, function(arg){ |
---|
201 | if(arg){ |
---|
202 | if(Ext.isArray(arg)){ |
---|
203 | this.destroy.apply(this, arg); |
---|
204 | }else if(Ext.isFunction(arg.destroy)){ |
---|
205 | arg.destroy(); |
---|
206 | }else if(arg.dom){ |
---|
207 | arg.remove(); |
---|
208 | } |
---|
209 | } |
---|
210 | }, this); |
---|
211 | }, |
---|
212 | |
---|
213 | /** |
---|
214 | * Attempts to destroy and then remove a set of named properties of the passed object. |
---|
215 | * @param {Object} o The object (most likely a Component) who's properties you wish to destroy. |
---|
216 | * @param {Mixed} arg1 The name of the property to destroy and remove from the object. |
---|
217 | * @param {Mixed} etc... More property names to destroy and remove. |
---|
218 | */ |
---|
219 | destroyMembers : function(o, arg1, arg2, etc){ |
---|
220 | for(var i = 1, a = arguments, len = a.length; i < len; i++) { |
---|
221 | Ext.destroy(o[a[i]]); |
---|
222 | delete o[a[i]]; |
---|
223 | } |
---|
224 | }, |
---|
225 | |
---|
226 | /** |
---|
227 | * Creates a copy of the passed Array with falsy values removed. |
---|
228 | * @param {Array/NodeList} arr The Array from which to remove falsy values. |
---|
229 | * @return {Array} The new, compressed Array. |
---|
230 | */ |
---|
231 | clean : function(arr){ |
---|
232 | var ret = []; |
---|
233 | Ext.each(arr, function(v){ |
---|
234 | if(!!v){ |
---|
235 | ret.push(v); |
---|
236 | } |
---|
237 | }); |
---|
238 | return ret; |
---|
239 | }, |
---|
240 | |
---|
241 | /** |
---|
242 | * Creates a copy of the passed Array, filtered to contain only unique values. |
---|
243 | * @param {Array} arr The Array to filter |
---|
244 | * @return {Array} The new Array containing unique values. |
---|
245 | */ |
---|
246 | unique : function(arr){ |
---|
247 | var ret = [], |
---|
248 | collect = {}; |
---|
249 | |
---|
250 | Ext.each(arr, function(v) { |
---|
251 | if(!collect[v]){ |
---|
252 | ret.push(v); |
---|
253 | } |
---|
254 | collect[v] = true; |
---|
255 | }); |
---|
256 | return ret; |
---|
257 | }, |
---|
258 | |
---|
259 | /** |
---|
260 | * Recursively flattens into 1-d Array. Injects Arrays inline. |
---|
261 | * @param {Array} arr The array to flatten |
---|
262 | * @return {Array} The new, flattened array. |
---|
263 | */ |
---|
264 | flatten : function(arr){ |
---|
265 | var worker = []; |
---|
266 | function rFlatten(a) { |
---|
267 | Ext.each(a, function(v) { |
---|
268 | if(Ext.isArray(v)){ |
---|
269 | rFlatten(v); |
---|
270 | }else{ |
---|
271 | worker.push(v); |
---|
272 | } |
---|
273 | }); |
---|
274 | return worker; |
---|
275 | } |
---|
276 | return rFlatten(arr); |
---|
277 | }, |
---|
278 | |
---|
279 | /** |
---|
280 | * Returns the minimum value in the Array. |
---|
281 | * @param {Array|NodeList} arr The Array from which to select the minimum value. |
---|
282 | * @param {Function} comp (optional) a function to perform the comparision which determines minimization. |
---|
283 | * If omitted the "<" operator will be used. Note: gt = 1; eq = 0; lt = -1 |
---|
284 | * @return {Object} The minimum value in the Array. |
---|
285 | */ |
---|
286 | min : function(arr, comp){ |
---|
287 | var ret = arr[0]; |
---|
288 | comp = comp || function(a,b){ return a < b ? -1 : 1; }; |
---|
289 | Ext.each(arr, function(v) { |
---|
290 | ret = comp(ret, v) == -1 ? ret : v; |
---|
291 | }); |
---|
292 | return ret; |
---|
293 | }, |
---|
294 | |
---|
295 | /** |
---|
296 | * Returns the maximum value in the Array |
---|
297 | * @param {Array|NodeList} arr The Array from which to select the maximum value. |
---|
298 | * @param {Function} comp (optional) a function to perform the comparision which determines maximization. |
---|
299 | * If omitted the ">" operator will be used. Note: gt = 1; eq = 0; lt = -1 |
---|
300 | * @return {Object} The maximum value in the Array. |
---|
301 | */ |
---|
302 | max : function(arr, comp){ |
---|
303 | var ret = arr[0]; |
---|
304 | comp = comp || function(a,b){ return a > b ? 1 : -1; }; |
---|
305 | Ext.each(arr, function(v) { |
---|
306 | ret = comp(ret, v) == 1 ? ret : v; |
---|
307 | }); |
---|
308 | return ret; |
---|
309 | }, |
---|
310 | |
---|
311 | /** |
---|
312 | * Calculates the mean of the Array |
---|
313 | * @param {Array} arr The Array to calculate the mean value of. |
---|
314 | * @return {Number} The mean. |
---|
315 | */ |
---|
316 | mean : function(arr){ |
---|
317 | return Ext.sum(arr) / arr.length; |
---|
318 | }, |
---|
319 | |
---|
320 | /** |
---|
321 | * Calculates the sum of the Array |
---|
322 | * @param {Array} arr The Array to calculate the sum value of. |
---|
323 | * @return {Number} The sum. |
---|
324 | */ |
---|
325 | sum : function(arr){ |
---|
326 | var ret = 0; |
---|
327 | Ext.each(arr, function(v) { |
---|
328 | ret += v; |
---|
329 | }); |
---|
330 | return ret; |
---|
331 | }, |
---|
332 | |
---|
333 | /** |
---|
334 | * Partitions the set into two sets: a true set and a false set. |
---|
335 | * Example: |
---|
336 | * Example2: |
---|
337 | * <pre><code> |
---|
338 | // Example 1: |
---|
339 | Ext.partition([true, false, true, true, false]); // [[true, true, true], [false, false]] |
---|
340 | |
---|
341 | // Example 2: |
---|
342 | Ext.partition( |
---|
343 | Ext.query("p"), |
---|
344 | function(val){ |
---|
345 | return val.className == "class1" |
---|
346 | } |
---|
347 | ); |
---|
348 | // true are those paragraph elements with a className of "class1", |
---|
349 | // false set are those that do not have that className. |
---|
350 | * </code></pre> |
---|
351 | * @param {Array|NodeList} arr The array to partition |
---|
352 | * @param {Function} truth (optional) a function to determine truth. If this is omitted the element |
---|
353 | * itself must be able to be evaluated for its truthfulness. |
---|
354 | * @return {Array} [true<Array>,false<Array>] |
---|
355 | */ |
---|
356 | partition : function(arr, truth){ |
---|
357 | var ret = [[],[]]; |
---|
358 | Ext.each(arr, function(v, i, a) { |
---|
359 | ret[ (truth && truth(v, i, a)) || (!truth && v) ? 0 : 1].push(v); |
---|
360 | }); |
---|
361 | return ret; |
---|
362 | }, |
---|
363 | |
---|
364 | /** |
---|
365 | * Invokes a method on each item in an Array. |
---|
366 | * <pre><code> |
---|
367 | // Example: |
---|
368 | Ext.invoke(Ext.query("p"), "getAttribute", "id"); |
---|
369 | // [el1.getAttribute("id"), el2.getAttribute("id"), ..., elN.getAttribute("id")] |
---|
370 | * </code></pre> |
---|
371 | * @param {Array|NodeList} arr The Array of items to invoke the method on. |
---|
372 | * @param {String} methodName The method name to invoke. |
---|
373 | * @param {Anything} ... Arguments to send into the method invocation. |
---|
374 | * @return {Array} The results of invoking the method on each item in the array. |
---|
375 | */ |
---|
376 | invoke : function(arr, methodName){ |
---|
377 | var ret = [], |
---|
378 | args = Array.prototype.slice.call(arguments, 2); |
---|
379 | Ext.each(arr, function(v,i) { |
---|
380 | if (v && typeof v[methodName] == "function") { |
---|
381 | ret.push(v[methodName].apply(v, args)); |
---|
382 | } else { |
---|
383 | ret.push(undefined); |
---|
384 | } |
---|
385 | }); |
---|
386 | return ret; |
---|
387 | }, |
---|
388 | |
---|
389 | /** |
---|
390 | * Plucks the value of a property from each item in the Array |
---|
391 | * <pre><code> |
---|
392 | // Example: |
---|
393 | Ext.pluck(Ext.query("p"), "className"); // [el1.className, el2.className, ..., elN.className] |
---|
394 | * </code></pre> |
---|
395 | * @param {Array|NodeList} arr The Array of items to pluck the value from. |
---|
396 | * @param {String} prop The property name to pluck from each element. |
---|
397 | * @return {Array} The value from each item in the Array. |
---|
398 | */ |
---|
399 | pluck : function(arr, prop){ |
---|
400 | var ret = []; |
---|
401 | Ext.each(arr, function(v) { |
---|
402 | ret.push( v[prop] ); |
---|
403 | }); |
---|
404 | return ret; |
---|
405 | }, |
---|
406 | |
---|
407 | /** |
---|
408 | * <p>Zips N sets together.</p> |
---|
409 | * <pre><code> |
---|
410 | // Example 1: |
---|
411 | Ext.zip([1,2,3],[4,5,6]); // [[1,4],[2,5],[3,6]] |
---|
412 | // Example 2: |
---|
413 | Ext.zip( |
---|
414 | [ "+", "-", "+"], |
---|
415 | [ 12, 10, 22], |
---|
416 | [ 43, 15, 96], |
---|
417 | function(a, b, c){ |
---|
418 | return "$" + a + "" + b + "." + c |
---|
419 | } |
---|
420 | ); // ["$+12.43", "$-10.15", "$+22.96"] |
---|
421 | * </code></pre> |
---|
422 | * @param {Arrays|NodeLists} arr This argument may be repeated. Array(s) to contribute values. |
---|
423 | * @param {Function} zipper (optional) The last item in the argument list. This will drive how the items are zipped together. |
---|
424 | * @return {Array} The zipped set. |
---|
425 | */ |
---|
426 | zip : function(){ |
---|
427 | var parts = Ext.partition(arguments, function( val ){ return !Ext.isFunction(val); }), |
---|
428 | arrs = parts[0], |
---|
429 | fn = parts[1][0], |
---|
430 | len = Ext.max(Ext.pluck(arrs, "length")), |
---|
431 | ret = []; |
---|
432 | |
---|
433 | for (var i = 0; i < len; i++) { |
---|
434 | ret[i] = []; |
---|
435 | if(fn){ |
---|
436 | ret[i] = fn.apply(fn, Ext.pluck(arrs, i)); |
---|
437 | }else{ |
---|
438 | for (var j = 0, aLen = arrs.length; j < aLen; j++){ |
---|
439 | ret[i].push( arrs[j][i] ); |
---|
440 | } |
---|
441 | } |
---|
442 | } |
---|
443 | return ret; |
---|
444 | }, |
---|
445 | |
---|
446 | /** |
---|
447 | * This is shorthand reference to {@link Ext.ComponentMgr#get}. |
---|
448 | * Looks up an existing {@link Ext.Component Component} by {@link Ext.Component#id id} |
---|
449 | * @param {String} id The component {@link Ext.Component#id id} |
---|
450 | * @return Ext.Component The Component, <tt>undefined</tt> if not found, or <tt>null</tt> if a |
---|
451 | * Class was found. |
---|
452 | */ |
---|
453 | getCmp : function(id){ |
---|
454 | return Ext.ComponentMgr.get(id); |
---|
455 | }, |
---|
456 | |
---|
457 | /** |
---|
458 | * By default, Ext intelligently decides whether floating elements should be shimmed. If you are using flash, |
---|
459 | * you may want to set this to true. |
---|
460 | * @type Boolean |
---|
461 | */ |
---|
462 | useShims: E.isIE6 || (E.isMac && E.isGecko2), |
---|
463 | |
---|
464 | // inpired by a similar function in mootools library |
---|
465 | /** |
---|
466 | * Returns the type of object that is passed in. If the object passed in is null or undefined it |
---|
467 | * return false otherwise it returns one of the following values:<div class="mdetail-params"><ul> |
---|
468 | * <li><b>string</b>: If the object passed is a string</li> |
---|
469 | * <li><b>number</b>: If the object passed is a number</li> |
---|
470 | * <li><b>boolean</b>: If the object passed is a boolean value</li> |
---|
471 | * <li><b>date</b>: If the object passed is a Date object</li> |
---|
472 | * <li><b>function</b>: If the object passed is a function reference</li> |
---|
473 | * <li><b>object</b>: If the object passed is an object</li> |
---|
474 | * <li><b>array</b>: If the object passed is an array</li> |
---|
475 | * <li><b>regexp</b>: If the object passed is a regular expression</li> |
---|
476 | * <li><b>element</b>: If the object passed is a DOM Element</li> |
---|
477 | * <li><b>nodelist</b>: If the object passed is a DOM NodeList</li> |
---|
478 | * <li><b>textnode</b>: If the object passed is a DOM text node and contains something other than whitespace</li> |
---|
479 | * <li><b>whitespace</b>: If the object passed is a DOM text node and contains only whitespace</li> |
---|
480 | * </ul></div> |
---|
481 | * @param {Mixed} object |
---|
482 | * @return {String} |
---|
483 | */ |
---|
484 | type : function(o){ |
---|
485 | if(o === undefined || o === null){ |
---|
486 | return false; |
---|
487 | } |
---|
488 | if(o.htmlElement){ |
---|
489 | return 'element'; |
---|
490 | } |
---|
491 | var t = typeof o; |
---|
492 | if(t == 'object' && o.nodeName) { |
---|
493 | switch(o.nodeType) { |
---|
494 | case 1: return 'element'; |
---|
495 | case 3: return (/\S/).test(o.nodeValue) ? 'textnode' : 'whitespace'; |
---|
496 | } |
---|
497 | } |
---|
498 | if(t == 'object' || t == 'function') { |
---|
499 | switch(o.constructor) { |
---|
500 | case Array: return 'array'; |
---|
501 | case RegExp: return 'regexp'; |
---|
502 | case Date: return 'date'; |
---|
503 | } |
---|
504 | if(typeof o.length == 'number' && typeof o.item == 'function') { |
---|
505 | return 'nodelist'; |
---|
506 | } |
---|
507 | } |
---|
508 | return t; |
---|
509 | }, |
---|
510 | |
---|
511 | intercept : function(o, name, fn, scope){ |
---|
512 | o[name] = o[name].createInterceptor(fn, scope); |
---|
513 | }, |
---|
514 | |
---|
515 | // internal |
---|
516 | callback : function(cb, scope, args, delay){ |
---|
517 | if(Ext.isFunction(cb)){ |
---|
518 | if(delay){ |
---|
519 | cb.defer(delay, scope, args || []); |
---|
520 | }else{ |
---|
521 | cb.apply(scope, args || []); |
---|
522 | } |
---|
523 | } |
---|
524 | } |
---|
525 | }; |
---|
526 | }()); |
---|
527 | |
---|
528 | /** |
---|
529 | * @class Function |
---|
530 | * These functions are available on every Function object (any JavaScript function). |
---|
531 | */ |
---|
532 | Ext.apply(Function.prototype, { |
---|
533 | /** |
---|
534 | * Create a combined function call sequence of the original function + the passed function. |
---|
535 | * The resulting function returns the results of the original function. |
---|
536 | * The passed fcn is called with the parameters of the original function. Example usage: |
---|
537 | * <pre><code> |
---|
538 | var sayHi = function(name){ |
---|
539 | alert('Hi, ' + name); |
---|
540 | } |
---|
541 | |
---|
542 | sayHi('Fred'); // alerts "Hi, Fred" |
---|
543 | |
---|
544 | var sayGoodbye = sayHi.createSequence(function(name){ |
---|
545 | alert('Bye, ' + name); |
---|
546 | }); |
---|
547 | |
---|
548 | sayGoodbye('Fred'); // both alerts show |
---|
549 | </code></pre> |
---|
550 | * @param {Function} fcn The function to sequence |
---|
551 | * @param {Object} scope (optional) The scope of the passed fcn (Defaults to scope of original function or window) |
---|
552 | * @return {Function} The new function |
---|
553 | */ |
---|
554 | createSequence : function(fcn, scope){ |
---|
555 | var method = this; |
---|
556 | return !Ext.isFunction(fcn) ? |
---|
557 | this : |
---|
558 | function(){ |
---|
559 | var retval = method.apply(this || window, arguments); |
---|
560 | fcn.apply(scope || this || window, arguments); |
---|
561 | return retval; |
---|
562 | }; |
---|
563 | } |
---|
564 | }); |
---|
565 | |
---|
566 | |
---|
567 | /** |
---|
568 | * @class String |
---|
569 | * These functions are available as static methods on the JavaScript String object. |
---|
570 | */ |
---|
571 | Ext.applyIf(String, { |
---|
572 | |
---|
573 | /** |
---|
574 | * Escapes the passed string for ' and \ |
---|
575 | * @param {String} string The string to escape |
---|
576 | * @return {String} The escaped string |
---|
577 | * @static |
---|
578 | */ |
---|
579 | escape : function(string) { |
---|
580 | return string.replace(/('|\\)/g, "\\$1"); |
---|
581 | }, |
---|
582 | |
---|
583 | /** |
---|
584 | * Pads the left side of a string with a specified character. This is especially useful |
---|
585 | * for normalizing number and date strings. Example usage: |
---|
586 | * <pre><code> |
---|
587 | var s = String.leftPad('123', 5, '0'); |
---|
588 | // s now contains the string: '00123' |
---|
589 | * </code></pre> |
---|
590 | * @param {String} string The original string |
---|
591 | * @param {Number} size The total length of the output string |
---|
592 | * @param {String} char (optional) The character with which to pad the original string (defaults to empty string " ") |
---|
593 | * @return {String} The padded string |
---|
594 | * @static |
---|
595 | */ |
---|
596 | leftPad : function (val, size, ch) { |
---|
597 | var result = String(val); |
---|
598 | if(!ch) { |
---|
599 | ch = " "; |
---|
600 | } |
---|
601 | while (result.length < size) { |
---|
602 | result = ch + result; |
---|
603 | } |
---|
604 | return result; |
---|
605 | } |
---|
606 | }); |
---|
607 | |
---|
608 | /** |
---|
609 | * Utility function that allows you to easily switch a string between two alternating values. The passed value |
---|
610 | * is compared to the current string, and if they are equal, the other value that was passed in is returned. If |
---|
611 | * they are already different, the first value passed in is returned. Note that this method returns the new value |
---|
612 | * but does not change the current string. |
---|
613 | * <pre><code> |
---|
614 | // alternate sort directions |
---|
615 | sort = sort.toggle('ASC', 'DESC'); |
---|
616 | |
---|
617 | // instead of conditional logic: |
---|
618 | sort = (sort == 'ASC' ? 'DESC' : 'ASC'); |
---|
619 | </code></pre> |
---|
620 | * @param {String} value The value to compare to the current string |
---|
621 | * @param {String} other The new value to use if the string already equals the first value passed in |
---|
622 | * @return {String} The new value |
---|
623 | */ |
---|
624 | String.prototype.toggle = function(value, other){ |
---|
625 | return this == value ? other : value; |
---|
626 | }; |
---|
627 | |
---|
628 | /** |
---|
629 | * Trims whitespace from either end of a string, leaving spaces within the string intact. Example: |
---|
630 | * <pre><code> |
---|
631 | var s = ' foo bar '; |
---|
632 | alert('-' + s + '-'); //alerts "- foo bar -" |
---|
633 | alert('-' + s.trim() + '-'); //alerts "-foo bar-" |
---|
634 | </code></pre> |
---|
635 | * @return {String} The trimmed string |
---|
636 | */ |
---|
637 | String.prototype.trim = function(){ |
---|
638 | var re = /^\s+|\s+$/g; |
---|
639 | return function(){ return this.replace(re, ""); }; |
---|
640 | }(); |
---|
641 | |
---|
642 | // here to prevent dependency on Date.js |
---|
643 | /** |
---|
644 | Returns the number of milliseconds between this date and date |
---|
645 | @param {Date} date (optional) Defaults to now |
---|
646 | @return {Number} The diff in milliseconds |
---|
647 | @member Date getElapsed |
---|
648 | */ |
---|
649 | Date.prototype.getElapsed = function(date) { |
---|
650 | return Math.abs((date || new Date()).getTime()-this.getTime()); |
---|
651 | }; |
---|
652 | |
---|
653 | |
---|
654 | /** |
---|
655 | * @class Number |
---|
656 | */ |
---|
657 | Ext.applyIf(Number.prototype, { |
---|
658 | /** |
---|
659 | * Checks whether or not the current number is within a desired range. If the number is already within the |
---|
660 | * range it is returned, otherwise the min or max value is returned depending on which side of the range is |
---|
661 | * exceeded. Note that this method returns the constrained value but does not change the current number. |
---|
662 | * @param {Number} min The minimum number in the range |
---|
663 | * @param {Number} max The maximum number in the range |
---|
664 | * @return {Number} The constrained value if outside the range, otherwise the current value |
---|
665 | */ |
---|
666 | constrain : function(min, max){ |
---|
667 | return Math.min(Math.max(this, min), max); |
---|
668 | } |
---|
669 | }); |
---|