X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/ee06f37b0f6f6d94cd05a6ffae556660f7c4a2bc..c930e9176a5a85509c5b0230e2bff5c22a591432:/src/core/Ext-more.js diff --git a/src/core/Ext-more.js b/src/core/Ext-more.js new file mode 100644 index 00000000..fae04f9b --- /dev/null +++ b/src/core/Ext-more.js @@ -0,0 +1,669 @@ +/*! + * Ext JS Library 3.0.0 + * Copyright(c) 2006-2009 Ext JS, LLC + * licensing@extjs.com + * http://www.extjs.com/license + */ +/** + * @class Ext + */ + +Ext.ns("Ext.grid", "Ext.dd", "Ext.tree", "Ext.form", "Ext.menu", + "Ext.state", "Ext.layout", "Ext.app", "Ext.ux", "Ext.chart", "Ext.direct"); + /** + * Namespace alloted for extensions to the framework. + * @property ux + * @type Object + */ + +Ext.apply(Ext, function(){ + var E = Ext, idSeed = 0; + + return { + /** + * A reusable empty function + * @property + * @type Function + */ + emptyFn : function(){}, + + /** + * URL to a 1x1 transparent gif image used by Ext to create inline icons with CSS background images. + * In older versions of IE, this defaults to "http://extjs.com/s.gif" and you should change this to a URL on your server. + * For other browsers it uses an inline data URL. + * @type String + */ + BLANK_IMAGE_URL : Ext.isIE6 || Ext.isIE7 ? + 'http:/' + '/extjs.com/s.gif' : + 'data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==', + + extendX : function(supr, fn){ + return Ext.extend(supr, fn(supr.prototype)); + }, + + /** + * Returns the current HTML document object as an {@link Ext.Element}. + * @return Ext.Element The document + */ + getDoc : function(){ + return Ext.get(document); + }, + + /** + * Returns true if the passed object is a JavaScript date object, otherwise false. + * @param {Object} object The object to test + * @return {Boolean} + */ + isDate : function(v){ + return Object.prototype.toString.apply(v) === '[object Date]'; + }, + + /** + * Utility method for validating that a value is numeric, returning the specified default value if it is not. + * @param {Mixed} value Should be a number, but any type will be handled appropriately + * @param {Number} defaultValue The value to return if the original value is non-numeric + * @return {Number} Value, if numeric, else defaultValue + */ + num : function(v, defaultValue){ + v = Number(v === null || typeof v == 'boolean'? NaN : v); + return isNaN(v)? defaultValue : v; + }, + + /** + *
Utility method for returning a default value if the passed value is empty.
+ *The value is deemed to be empty if it is
+Ext.addBehaviors({
+ // add a listener for click on all anchors in element with id foo
+ '#foo a@click' : function(e, t){
+ // do something
+ },
+
+ // add the same listener to multiple selectors (separated by comma BEFORE the @)
+ '#foo a, #bar span.some-class@mouseover' : function(){
+ // do something
+ }
+});
+ *
+ * @param {Object} obj The list of behaviors to apply
+ */
+ addBehaviors : function(o){
+ if(!Ext.isReady){
+ Ext.onReady(function(){
+ Ext.addBehaviors(o);
+ });
+ } else {
+ var cache = {}, // simple cache for applying multiple behaviors to same selector does query multiple times
+ parts,
+ b,
+ s;
+ for (b in o) {
+ if ((parts = b.split('@'))[1]) { // for Object prototype breakers
+ s = parts[0];
+ if(!cache[s]){
+ cache[s] = Ext.select(s);
+ }
+ cache[s].on(parts[1], o[b]);
+ }
+ }
+ cache = null;
+ }
+ },
+
+
+ // deprecated
+ combine : function(){
+ var as = arguments, l = as.length, r = [];
+ for(var i = 0; i < l; i++){
+ var a = as[i];
+ if(Ext.isArray(a)){
+ r = r.concat(a);
+ }else if(a.length !== undefined && !a.substr){
+ r = r.concat(Array.prototype.slice.call(a, 0));
+ }else{
+ r.push(a);
+ }
+ }
+ return r;
+ },
+
+ /**
+ * Copies a set of named properties fom the source object to the destination object.
+ * example:
+ImageComponent = Ext.extend(Ext.BoxComponent, {
+ initComponent: function() {
+ this.autoEl = { tag: 'img' };
+ MyComponent.superclass.initComponent.apply(this, arguments);
+ this.initialBox = Ext.copyTo({}, this.initialConfig, 'x,y,width,height');
+ }
+});
+ *
+ * @param {Object} The destination object.
+ * @param {Object} The source object.
+ * @param {Array/String} Either an Array of property names, or a comma-delimited list
+ * of property names to copy.
+ * @return {Object} The modified object.
+ */
+ copyTo : function(dest, source, names){
+ if(typeof names == 'string'){
+ names = names.split(/[,;\s]/);
+ }
+ Ext.each(names, function(name){
+ if(source.hasOwnProperty(name)){
+ dest[name] = source[name];
+ }
+ }, this);
+ return dest;
+ },
+
+ /**
+ * Attempts to destroy any objects passed to it by removing all event listeners, removing them from the
+ * DOM (if applicable) and calling their destroy functions (if available). This method is primarily
+ * intended for arguments of type {@link Ext.Element} and {@link Ext.Component}, but any subclass of
+ * {@link Ext.util.Observable} can be passed in. Any number of elements and/or components can be
+ * passed into this function in a single call as separate arguments.
+ * @param {Mixed} arg1 An {@link Ext.Element}, {@link Ext.Component}, or an Array of either of these to destroy
+ * @param {Mixed} arg2 (optional)
+ * @param {Mixed} etc... (optional)
+ */
+ destroy : function(){
+ Ext.each(arguments, function(arg){
+ if(arg){
+ if(Ext.isArray(arg)){
+ this.destroy.apply(this, arg);
+ }else if(Ext.isFunction(arg.destroy)){
+ arg.destroy();
+ }else if(arg.dom){
+ arg.remove();
+ }
+ }
+ }, this);
+ },
+
+ /**
+ * Attempts to destroy and then remove a set of named properties of the passed object.
+ * @param {Object} o The object (most likely a Component) who's properties you wish to destroy.
+ * @param {Mixed} arg1 The name of the property to destroy and remove from the object.
+ * @param {Mixed} etc... More property names to destroy and remove.
+ */
+ destroyMembers : function(o, arg1, arg2, etc){
+ for(var i = 1, a = arguments, len = a.length; i < len; i++) {
+ Ext.destroy(o[a[i]]);
+ delete o[a[i]];
+ }
+ },
+
+ /**
+ * Creates a copy of the passed Array with falsy values removed.
+ * @param {Array/NodeList} arr The Array from which to remove falsy values.
+ * @return {Array} The new, compressed Array.
+ */
+ clean : function(arr){
+ var ret = [];
+ Ext.each(arr, function(v){
+ if(!!v){
+ ret.push(v);
+ }
+ });
+ return ret;
+ },
+
+ /**
+ * Creates a copy of the passed Array, filtered to contain only unique values.
+ * @param {Array} arr The Array to filter
+ * @return {Array} The new Array containing unique values.
+ */
+ unique : function(arr){
+ var ret = [],
+ collect = {};
+
+ Ext.each(arr, function(v) {
+ if(!collect[v]){
+ ret.push(v);
+ }
+ collect[v] = true;
+ });
+ return ret;
+ },
+
+ /**
+ * Recursively flattens into 1-d Array. Injects Arrays inline.
+ * @param {Array} arr The array to flatten
+ * @return {Array} The new, flattened array.
+ */
+ flatten : function(arr){
+ var worker = [];
+ function rFlatten(a) {
+ Ext.each(a, function(v) {
+ if(Ext.isArray(v)){
+ rFlatten(v);
+ }else{
+ worker.push(v);
+ }
+ });
+ return worker;
+ }
+ return rFlatten(arr);
+ },
+
+ /**
+ * Returns the minimum value in the Array.
+ * @param {Array|NodeList} arr The Array from which to select the minimum value.
+ * @param {Function} comp (optional) a function to perform the comparision which determines minimization.
+ * If omitted the "<" operator will be used. Note: gt = 1; eq = 0; lt = -1
+ * @return {Object} The minimum value in the Array.
+ */
+ min : function(arr, comp){
+ var ret = arr[0];
+ comp = comp || function(a,b){ return a < b ? -1 : 1; };
+ Ext.each(arr, function(v) {
+ ret = comp(ret, v) == -1 ? ret : v;
+ });
+ return ret;
+ },
+
+ /**
+ * Returns the maximum value in the Array
+ * @param {Array|NodeList} arr The Array from which to select the maximum value.
+ * @param {Function} comp (optional) a function to perform the comparision which determines maximization.
+ * If omitted the ">" operator will be used. Note: gt = 1; eq = 0; lt = -1
+ * @return {Object} The maximum value in the Array.
+ */
+ max : function(arr, comp){
+ var ret = arr[0];
+ comp = comp || function(a,b){ return a > b ? 1 : -1; };
+ Ext.each(arr, function(v) {
+ ret = comp(ret, v) == 1 ? ret : v;
+ });
+ return ret;
+ },
+
+ /**
+ * Calculates the mean of the Array
+ * @param {Array} arr The Array to calculate the mean value of.
+ * @return {Number} The mean.
+ */
+ mean : function(arr){
+ return Ext.sum(arr) / arr.length;
+ },
+
+ /**
+ * Calculates the sum of the Array
+ * @param {Array} arr The Array to calculate the sum value of.
+ * @return {Number} The sum.
+ */
+ sum : function(arr){
+ var ret = 0;
+ Ext.each(arr, function(v) {
+ ret += v;
+ });
+ return ret;
+ },
+
+ /**
+ * Partitions the set into two sets: a true set and a false set.
+ * Example:
+ * Example2:
+ *
+// Example 1:
+Ext.partition([true, false, true, true, false]); // [[true, true, true], [false, false]]
+
+// Example 2:
+Ext.partition(
+ Ext.query("p"),
+ function(val){
+ return val.className == "class1"
+ }
+);
+// true are those paragraph elements with a className of "class1",
+// false set are those that do not have that className.
+ *
+ * @param {Array|NodeList} arr The array to partition
+ * @param {Function} truth (optional) a function to determine truth. If this is omitted the element
+ * itself must be able to be evaluated for its truthfulness.
+ * @return {Array} [true
+// Example:
+Ext.invoke(Ext.query("p"), "getAttribute", "id");
+// [el1.getAttribute("id"), el2.getAttribute("id"), ..., elN.getAttribute("id")]
+ *
+ * @param {Array|NodeList} arr The Array of items to invoke the method on.
+ * @param {String} methodName The method name to invoke.
+ * @param {Anything} ... Arguments to send into the method invocation.
+ * @return {Array} The results of invoking the method on each item in the array.
+ */
+ invoke : function(arr, methodName){
+ var ret = [],
+ args = Array.prototype.slice.call(arguments, 2);
+ Ext.each(arr, function(v,i) {
+ if (v && typeof v[methodName] == "function") {
+ ret.push(v[methodName].apply(v, args));
+ } else {
+ ret.push(undefined);
+ }
+ });
+ return ret;
+ },
+
+ /**
+ * Plucks the value of a property from each item in the Array
+ *
+// Example:
+Ext.pluck(Ext.query("p"), "className"); // [el1.className, el2.className, ..., elN.className]
+ *
+ * @param {Array|NodeList} arr The Array of items to pluck the value from.
+ * @param {String} prop The property name to pluck from each element.
+ * @return {Array} The value from each item in the Array.
+ */
+ pluck : function(arr, prop){
+ var ret = [];
+ Ext.each(arr, function(v) {
+ ret.push( v[prop] );
+ });
+ return ret;
+ },
+
+ /**
+ * Zips N sets together.
+ *
+// Example 1:
+Ext.zip([1,2,3],[4,5,6]); // [[1,4],[2,5],[3,6]]
+// Example 2:
+Ext.zip(
+ [ "+", "-", "+"],
+ [ 12, 10, 22],
+ [ 43, 15, 96],
+ function(a, b, c){
+ return "$" + a + "" + b + "." + c
+ }
+); // ["$+12.43", "$-10.15", "$+22.96"]
+ *
+ * @param {Arrays|NodeLists} arr This argument may be repeated. Array(s) to contribute values.
+ * @param {Function} zipper (optional) The last item in the argument list. This will drive how the items are zipped together.
+ * @return {Array} The zipped set.
+ */
+ zip : function(){
+ var parts = Ext.partition(arguments, function( val ){ return !Ext.isFunction(val); }),
+ arrs = parts[0],
+ fn = parts[1][0],
+ len = Ext.max(Ext.pluck(arrs, "length")),
+ ret = [];
+
+ for (var i = 0; i < len; i++) {
+ ret[i] = [];
+ if(fn){
+ ret[i] = fn.apply(fn, Ext.pluck(arrs, i));
+ }else{
+ for (var j = 0, aLen = arrs.length; j < aLen; j++){
+ ret[i].push( arrs[j][i] );
+ }
+ }
+ }
+ return ret;
+ },
+
+ /**
+ * This is shorthand reference to {@link Ext.ComponentMgr#get}.
+ * Looks up an existing {@link Ext.Component Component} by {@link Ext.Component#id id}
+ * @param {String} id The component {@link Ext.Component#id id}
+ * @return Ext.Component The Component, undefined if not found, or null if a
+ * Class was found.
+ */
+ getCmp : function(id){
+ return Ext.ComponentMgr.get(id);
+ },
+
+ /**
+ * By default, Ext intelligently decides whether floating elements should be shimmed. If you are using flash,
+ * you may want to set this to true.
+ * @type Boolean
+ */
+ useShims: E.isIE6 || (E.isMac && E.isGecko2),
+
+ // inpired by a similar function in mootools library
+ /**
+ * Returns the type of object that is passed in. If the object passed in is null or undefined it
+ * return false otherwise it returns one of the following values:
+var sayHi = function(name){
+ alert('Hi, ' + name);
+}
+
+sayHi('Fred'); // alerts "Hi, Fred"
+
+var sayGoodbye = sayHi.createSequence(function(name){
+ alert('Bye, ' + name);
+});
+
+sayGoodbye('Fred'); // both alerts show
+
+ * @param {Function} fcn The function to sequence
+ * @param {Object} scope (optional) The scope of the passed fcn (Defaults to scope of original function or window)
+ * @return {Function} The new function
+ */
+ createSequence : function(fcn, scope){
+ var method = this;
+ return !Ext.isFunction(fcn) ?
+ this :
+ function(){
+ var retval = method.apply(this || window, arguments);
+ fcn.apply(scope || this || window, arguments);
+ return retval;
+ };
+ }
+});
+
+
+/**
+ * @class String
+ * These functions are available as static methods on the JavaScript String object.
+ */
+Ext.applyIf(String, {
+
+ /**
+ * Escapes the passed string for ' and \
+ * @param {String} string The string to escape
+ * @return {String} The escaped string
+ * @static
+ */
+ escape : function(string) {
+ return string.replace(/('|\\)/g, "\\$1");
+ },
+
+ /**
+ * Pads the left side of a string with a specified character. This is especially useful
+ * for normalizing number and date strings. Example usage:
+ *
+var s = String.leftPad('123', 5, '0');
+// s now contains the string: '00123'
+ *
+ * @param {String} string The original string
+ * @param {Number} size The total length of the output string
+ * @param {String} char (optional) The character with which to pad the original string (defaults to empty string " ")
+ * @return {String} The padded string
+ * @static
+ */
+ leftPad : function (val, size, ch) {
+ var result = String(val);
+ if(!ch) {
+ ch = " ";
+ }
+ while (result.length < size) {
+ result = ch + result;
+ }
+ return result;
+ }
+});
+
+/**
+ * Utility function that allows you to easily switch a string between two alternating values. The passed value
+ * is compared to the current string, and if they are equal, the other value that was passed in is returned. If
+ * they are already different, the first value passed in is returned. Note that this method returns the new value
+ * but does not change the current string.
+ *
+// alternate sort directions
+sort = sort.toggle('ASC', 'DESC');
+
+// instead of conditional logic:
+sort = (sort == 'ASC' ? 'DESC' : 'ASC');
+
+ * @param {String} value The value to compare to the current string
+ * @param {String} other The new value to use if the string already equals the first value passed in
+ * @return {String} The new value
+ */
+String.prototype.toggle = function(value, other){
+ return this == value ? other : value;
+};
+
+/**
+ * Trims whitespace from either end of a string, leaving spaces within the string intact. Example:
+ *
+var s = ' foo bar ';
+alert('-' + s + '-'); //alerts "- foo bar -"
+alert('-' + s.trim() + '-'); //alerts "-foo bar-"
+
+ * @return {String} The trimmed string
+ */
+String.prototype.trim = function(){
+ var re = /^\s+|\s+$/g;
+ return function(){ return this.replace(re, ""); };
+}();
+
+// here to prevent dependency on Date.js
+/**
+ Returns the number of milliseconds between this date and date
+ @param {Date} date (optional) Defaults to now
+ @return {Number} The diff in milliseconds
+ @member Date getElapsed
+ */
+Date.prototype.getElapsed = function(date) {
+ return Math.abs((date || new Date()).getTime()-this.getTime());
+};
+
+
+/**
+ * @class Number
+ */
+Ext.applyIf(Number.prototype, {
+ /**
+ * Checks whether or not the current number is within a desired range. If the number is already within the
+ * range it is returned, otherwise the min or max value is returned depending on which side of the range is
+ * exceeded. Note that this method returns the constrained value but does not change the current number.
+ * @param {Number} min The minimum number in the range
+ * @param {Number} max The maximum number in the range
+ * @return {Number} The constrained value if outside the range, otherwise the current value
+ */
+ constrain : function(min, max){
+ return Math.min(Math.max(this, min), max);
+ }
+});