Upgrade to ExtJS 4.0.1 - Released 05/18/2011
[extjs.git] / jsbuilder / src / Ext.js
1 Ext = {
2     /**
3      * Copies all the properties of config to obj.
4      * @param {Object} object The receiver of the properties
5      * @param {Object} config The source of the properties
6      * @param {Object} defaults A different object that will also be applied for default values
7      * @return {Object} returns obj
8      * @member Ext apply
9      */
10     apply : function(object, config, defaults) {
11         // no "this" reference for friendly out of scope calls
12         if (defaults) {
13             Ext.apply(object, defaults);
14         }
15         if (object && config && typeof config == 'object') {
16             for (var key in config) {
17                 object[key] = config[key];
18             }
19         }
20         return object;
21     },
22
23     /**
24      * Copies all the properties of config to obj if they don't already exist.
25      * @param {Object} obj The receiver of the properties
26      * @param {Object} config The source of the properties
27      * @return {Object} returns obj
28      */
29     applyIf : function(object, config) {
30         var property, undefined;
31         if (object) {
32             for (property in config) {
33                 if (object[property] === undefined) {
34                     object[property] = config[property];
35                 }
36             }
37         }
38         return object;
39     },
40         
41     /**
42      * <p>Extends one class to create a subclass and optionally overrides members with the passed literal. This method
43      * also adds the function "override()" to the subclass that can be used to override members of the class.</p>
44      * @param {Function} superclass The constructor of class being extended.
45      * @param {Object} overrides <p>A literal with members which are copied into the subclass's
46      * prototype, and are therefore shared between all instances of the new class.</p>
47      * <p>This may contain a special member named <tt><b>constructor</b></tt>. This is used
48      * to define the constructor of the new class, and is returned. If this property is
49      * <i>not</i> specified, a constructor is generated and returned which just calls the
50      * superclass's constructor passing on its parameters.</p>
51      * <p><b>It is essential that you call the superclass constructor in any provided constructor. See example code.</b></p>
52      * @return {Function} The subclass constructor from the <code>overrides</code> parameter, or a generated one if not provided.
53      */
54     extend : function() {
55         // inline overrides
56         var inlineOverrides = function(o){
57             for(var m in o){
58                 this[m] = o[m];
59             }
60         };
61
62         var objectConstructor = Object.prototype.constructor;
63
64         return function(subclass, superclass, overrides){
65             // First we check if the user passed in just the superClass with overrides
66             if(Ext.isObject(superclass)){
67                 overrides = superclass;
68                 superclass = subclass;
69                 subclass = overrides.constructor != objectConstructor
70                 ? overrides.constructor
71                 : function(){
72                     superclass.apply(this, arguments);
73                 };
74             }
75
76             // We create a new temporary class
77             var F = function(){},
78             subclassProto,
79             superclassProto = superclass.prototype;
80
81             F.prototype = superclassProto;
82             subclassProto = subclass.prototype = new F();
83             subclassProto.constructor = subclass;
84             subclass.superclass = superclassProto;
85
86             if(superclassProto.constructor == objectConstructor){
87                 superclassProto.constructor = superclass;
88             }
89
90             subclass.override = function(overrides){
91                 Ext.override(subclass, overrides);
92             };
93
94             subclassProto.superclass = subclassProto.supr = (function(){
95                 return superclassProto;
96             });
97
98             subclassProto.override = inlineOverrides;
99             subclassProto.proto = subclassProto;
100             subclassProto.superproto = superclassProto;
101             
102             subclass.override(overrides);
103             subclass.extend = function(o){
104                 return Ext.extend(subclass, o);
105             };
106
107             return subclass;
108         };
109     }(),
110     
111     /**
112      * Adds a list of functions to the prototype of an existing class, overwriting any existing methods with the same name.
113      * @param {Object} origclass The class to override
114      * @param {Object} overrides The list of functions to add to origClass.  This should be specified as an object literal
115      * containing one or more methods.
116      * @method override
117      */
118     override : function(origclass, overrides) {
119         if (overrides) {
120             Ext.apply(origclass.prototype, overrides);
121         }
122     },
123     
124     /**
125      * <p>Returns true if the passed value is empty.</p>
126      * <p>The value is deemed to be empty if it is<div class="mdetail-params"><ul>
127      * <li>null</li>
128      * <li>undefined</li>
129      * <li>an empty array</li>
130      * <li>a zero length string (Unless the <tt>allowBlank</tt> parameter is <tt>true</tt>)</li>
131      * </ul></div>
132      * @param {Mixed} value The value to test
133      * @param {Boolean} allowBlank (optional) true to allow empty strings (defaults to false)
134      * @return {Boolean}
135      */
136     isEmpty : function(v, allowBlank) {
137         return v == null || ((Ext.isArray(v) && !v.length)) || (!allowBlank ? v === '' : false);
138     },
139
140     /**
141      * Returns true if the passed value is a JavaScript array, otherwise false.
142      * @param {Mixed} value The value to test
143      * @return {Boolean}
144      */
145     isArray : function(v) {
146         return Object.prototype.toString.apply(v) === '[object Array]';
147     },
148
149     /**
150      * Returns true if the passed object is a JavaScript date object, otherwise false.
151      * @param {Object} object The object to test
152      * @return {Boolean}
153      */
154     isDate : function(v) {
155         return Object.prototype.toString.apply(v) === '[object Date]';
156     },
157
158     /**
159      * Returns true if the passed value is a JavaScript Object, otherwise false.
160      * @param {Mixed} value The value to test
161      * @return {Boolean}
162      */
163     isObject : function(v) {
164         return !!v && Object.prototype.toString.call(v) === '[object Object]';
165     },
166
167     /**
168      * Returns true if the passed value is a JavaScript 'primitive', a string, number or boolean.
169      * @param {Mixed} value The value to test
170      * @return {Boolean}
171      */
172     isPrimitive : function(v) {
173         return Ext.isString(v) || Ext.isNumber(v) || Ext.isBoolean(v);
174     },
175
176     /**
177      * Returns true if the passed value is a JavaScript Function, otherwise false.
178      * @param {Mixed} value The value to test
179      * @return {Boolean}
180      */
181     isFunction : function(v) {
182         return Object.prototype.toString.apply(v) === '[object Function]';
183     },
184
185     /**
186      * Returns true if the passed value is a number. Returns false for non-finite numbers.
187      * @param {Mixed} value The value to test
188      * @return {Boolean}
189      */
190     isNumber : function(v) {
191         return Object.prototype.toString.apply(v) === '[object Number]' && isFinite(v);
192     },
193
194     /**
195      * Returns true if the passed value is a string.
196      * @param {Mixed} value The value to test
197      * @return {Boolean}
198      */
199     isString : function(v) {
200         return Object.prototype.toString.apply(v) === '[object String]';
201     },
202
203     /**util
204      * Returns true if the passed value is a boolean.
205      * @param {Mixed} value The value to test
206      * @return {Boolean}
207      */
208     isBoolean : function(v) {
209         return Object.prototype.toString.apply(v) === '[object Boolean]';
210     },
211
212     /**
213      * Returns true if the passed value is not undefined.
214      * @param {Mixed} value The value to test
215      * @return {Boolean}
216      */
217     isDefined : function(v){
218         return typeof v !== 'undefined';
219     },
220
221     each : function(array, fn, scope) {
222         if (Ext.isEmpty(array, true)) {
223             return 0;
224         }
225         if (!Ext.isIterable(array) || Ext.isPrimitive(array)) {
226             array = [array];
227         }
228         for (var i = 0, len = array.length; i < len; i++) {
229             if (fn.call(scope || array[i], array[i], i, array) === false) {
230                 return i;
231             }
232         }
233         return true;
234     },
235     
236     iterate : function(obj, fn, scope) {
237         if (Ext.isEmpty(obj)) {
238             return;
239         }
240         if (Ext.isIterable(obj)) {
241             Ext.each(obj, fn, scope);
242             return;
243         }
244         else if (Ext.isObject(obj)) {
245             for (var prop in obj) {
246                 if (obj.hasOwnProperty(prop)) {
247                     if (fn.call(scope || obj, prop, obj[prop], obj) === false) {
248                         return;
249                     }
250                 }
251             }
252         }
253     },
254     
255     isIterable : function(v) {
256         //check for array or arguments
257         if (Ext.isArray(v) || v.callee) {
258             return true;
259         }
260     },
261
262     $included: {},
263
264     require: function(className) {
265
266     }
267 }