Ext原码学习之Ext.js

  1 // JavaScript Document
  2 //定义全局Ext变量
  3 var Ext = Ext ||{};
  4 Ext._startTime = new Date().getTime();
  5 (function(){
  6     var global = this,
  7          objectPrototype = Object.prototype,
  8          toString = objectPrototype.toString,
  9          //是否支持for循环可枚举
 10          enumerables = true,
 11          enumberablesTest = {toString:1},
 12          //定义空函数
 13          emptyFn = function(){},
 14          
 15          //调用被子类覆盖的父方法
 16          callOverrideParent = function(){
 17              //返回方法调用者
 18              var method = callOverrideParent.caller.caller;
 19              
 20              //调用父类方法
 21              return method.$owner.prototype[method.name].apply(this,arguments);
 22          },
 23          i,
 24          nonWhitespaceRe = /\S/,
 25          ExtApp,
 26          iterableRe = /\[object\s*(?:Array|Arguments|\w*Collection|\w*List|Html\s+document\.all\s+class)\]/;
 27         
 28     Function.prototype.$extIsFunciton = true,
 29      Ext.global = global;
 30     
 31     for(i in enumberablesTest)
 32     {
 33         enumberables = null;
 34     }
 35     
 36     if(enumberables)
 37     {
 38         enumberables = ['hasOwnProperty','valueOf','isPrototypeOf','propertyIsEnumberable','toLocaleString','toString','constructor'];
 39     }
 40     
 41     Ext.enumberables = enumberables;
 42     
 43     //Ext 潜拷贝
 44     Ext.apply = function(object,config,defaults)
 45     {
 46         if(defaults)
 47         {
 48            Ext.apply(object,defaults);    
 49         }
 50         
 51         if(object && config && typeof config === 'object')
 52         {
 53             var i , j ,k;
 54             for(i in config)
 55             {
 56                 object[i] = config[i];
 57             }
 58             
 59             if(enumberables)
 60             {
 61                 for(j=enumerables.length;j--;)
 62                 {
 63                     k = enumberables[j];
 64                     if(config.hasOwnProperty(k))
 65                     {
 66                         object[k] = config[k];
 67                     }
 68                 }
 69             }
 70         }
 71         
 72         return object;
 73         
 74     }
 75     
 76     //设置css前缀
 77     Ext.buildSettings = Ext.apply({
 78         baseCSSPrefix : 'x-'
 79     },Ext.buildSettings ||{});
 80     
 81     //扩展Ext基本属性 name,emptyFn identifyFn,emptyString
 82     Ext.apply(Ext,{
 83         
 84         name:Ext.sandboxName || 'Ext',
 85         
 86         emptyFn:emptyFn,
 87         
 88         identifyFn:function(o){
 89             return o;    
 90         },
 91         
 92         //空字符串
 93         emptyString:new String(),
 94         
 95         baseCssPrefix:Ext.buildSettings.baseCSSPrefix,
 96         
 97         //copy  若目标对象中没有此属性 则从原对象中复制属性
 98         applyIf:function(object,config){
 99             var property;
100             
101             if(object){
102                 for(property in config){
103                     if(object[property] === undefined)
104                     {
105                         object[property] = config[property];    
106                     }
107                 }    
108             }
109             
110             return object;
111         },
112         
113         //test Ext.applyOf
114         //var aaa = {a:123},bbb={a:1,b:12};
115         //console.log(Ext.apply(aaa,bbb));
116         //console.log(Ext.applyIf(aaa,bbb));
117         
118         //遍历 array or object
119         iterate:function(object,fn,scop)
120         {
121             if(Ext.isEmpty(object))
122             {
123                 return;
124             }
125             
126             if(scope === undefined)
127             {
128                 scope = object;
129             }
130             
131             //判断对象是否为Array
132             if(Ext.isIterator(object))
133             {
134                 Ext.Array.each.call(Ext.Array,object,fn,scope);
135             }
136             else
137             {
138                 Ext.Object.each.call(Ext.Object,object,fn,scope);
139             }
140             
141         }
142 
143     });
144     
145 
146     Ext.apply(Ext,{
147         
148         //此方法已被Ext.define 代替
149         extend:(function(){
150             var objectConstructor = objectPrototype.constructor,
151                 inlineOverrides = function(o){
152                     for(var m in o){
153                         if(o.hasOwnProperty(m))
154                         {
155                             this[m]=o[m];
156                         }
157                     } 
158                 };
159                 
160              return function(subclass,supperclass,overrides){
161                 if(Ext.isObject(supperclass))
162                 {
163                     overrides = supperclass;
164                     supperclass = subclass;
165                     subclass = overrides.constructor != objectConstructor ? overrides.constructor:function(){
166                         supperclass.apply(this,arguments);
167                        }
168                 }
169                 if(!supperclass){
170                     Ext.Error.raise({
171                         sourceClass:'Ext',
172                         sourceMethod:'extend',
173                         msg:'页面未加载完成进行调用'
174                     });    
175                 }
176                 
177                 var F = function(){},
178                     subclassProto,superclassProto = superclass.prototype;
179                 
180                 F.prototype = supperclassProto;
181                 subclassProto = subclass.prototype=new F();
182                 subclass.supperclass = supperclassProto;
183                 
184                 if(superclassProto.constructor === objectConstructor){
185                     supperclassProto.constructor = supperclass;    
186                 }
187                 
188                 subclass.override = function(overrides){
189                     Ext.override(subclass,overrides);    
190                 };
191                 
192                 
193                 subclassProto.override = inlineOverrides;
194                 
195                 subclassProto.proto = subclassProto;
196                 
197                 subclass.verride(overrides);
198                 
199                 subclass.extend = function(o)
200                 {
201                     return Ext.extend(subclass,o);    
202                 }
203                 
204                 return subclass;
205                 
206              }
207         })(),
208         
209         override:function(target,overrides)
210         {
211             if(target.$isClass)
212             {
213                 target.override(overrides);    
214             }
215             else if(typeof target == 'function')
216             {
217                 Ext.apply(target.prototype,overrides);
218             }
219             else
220             {
221                 var owner = target.self,name,value;
222                 
223                 if(owner  && owner.$isClass)
224                 {
225                     for(name in overrides)
226                     {
227                         if(overrides.hasOwnProperty(name))
228                         {
229                             value = overrides[name];
230                             
231                             if(typeof value == 'function')
232                             {
233                                 if(owner.$className){
234                                     value.displayName = owner.$className +"#"+name;
235                                 }
236                                 value.$name = name;
237                                 
238                                 value.$owner = owner;
239                                 
240                                 value.$previous = target.hasOwnProperty(name)?target[name] : callOverrideParent;
241                             }
242                             target[name] = value;
243                         }
244                     }
245                 }
246                 else
247                 {
248                     Ext.apply(target,overrides);
249                 }
250             }
251             
252             return target;
253         }
254     
255     });
256     
257     //添加静态方法
258     Ext.apply(Ext,{
259     
260         valueForm:function(value,defaultValue,allowBlank)
261         {
262             return Ext.isEmpay(value,allowBlank) ? defaultValue : value;
263         },
264         
265         typeOf:function(value)
266         {
267             var type,typeToString;
268             
269             if(value===null)
270             {
271                 return 'null';
272             }
273             
274             type = typeof value;
275             
276             if(type === 'undefined' || type === 'string' || type === 'number' || type === 'boolean')
277             {
278                 return type;
279             }
280             
281             typeToString = toString.call(value);
282             
283             switch(typeToString)
284             {
285                 case '[object Array]':
286                     return 'array';
287                 case '[object Date]':
288                     return 'date';
289                 case '[object Bollean]':
290                     return 'boolean';
291                 case '[object Number]':
292                     return 'number';
293                 case '[object RegExp]':
294                     return 'regexp';
295             }
296             
297             if(type === 'function')
298             {
299                 return 'function';
300             }
301             
302             if(type === 'object')
303             {
304                 if(value.nodeType !== undefined)
305                 {
306                     if(value.nodeType === 3)
307                     {
308                         return (nonWhitespaceRe).test(value.nodeValue)?'textnode':'whitespace';
309                     }
310                     else
311                     {
312                         return 'element';
313                     }
314                 }
315                 
316                 return 'object';
317             }
318         },
319         coerce:function(from,to)
320         {
321             var fromType = Ext.typeOf(from),
322                 toType = Ext.typeOf(to),
323                 isString = typeof from === 'string';
324                 
325             if(fromType !== toType)
326             {
327                 switch(toType)
328                 {
329                     case 'string':
330                         return String(from);
331                     case 'number':
332                         return Number(from);
333                     case 'boolean':
334                         return isString && (!from || from==='false') ? false :Boolean(from);
335                     case 'null':
336                         return isString && (!form || from=== 'null') ? null :from;
337                     case 'undefined':
338                         return isString && (!from || from==='undefinded')?'undefined':from;
339                     case 'date':
340                         return isString && isNaN(from) ? Ext.Date.parse(from,Ext.Date.defaultFormat):Date(Number(from));
341                 }
342             }
343             
344             return from;
345         },
346         //判断字符串是否为空,数组是否有数据
347         isEmpty:function(value,allowEmptyString)
348         {
349             return (value===null) || (value=== undefined) || (!allowEmptyString ? value==='' :false)||(Ext.isArray(value) && value.length===0);
350         },
351         //判断数组
352         isArray:('isArray' in Array) ? Array.isArray:function(value)
353         {
354             return toString.call(value) === '[object Array]';
355         },
356         isDate:function(value)
357         {
358             return Ext.typeOf(value) === 'date';
359         },
360         isObject:function(value)
361         {
362             return Ext.typeOf(value)=='object';
363         },
364         isSimpleObject:function(value)
365         {
366             return value instanceof Object && value.constructor === Object;
367         },
368         //判断基本数据类型,
369         isPrimitive:function(value)
370         {
371             var type = typeof value;
372             return type === 'string' || type==='number' || type ==='boolean';
373         },
374         isFunction:function(value)
375         {
376             return !!(value && value.$extIsFunction);
377         },
378         isNumber:function(value)
379         {
380             return typeof value ==='number' && isFinite(value);
381         },
382         isNumberic:function(value)
383         {
384             return !isNaN(parseFlost(value)) && isFinite(value);
385         },
386         isString:function(value)
387         {
388             return Ext.typeOf(value) ==='string';
389         },
390         isBoolean:function(value)
391         {
392             return Ext.typeOf(value) ==='boolean';
393         },
394         isElement:function(value)
395         {
396             return Ext.typeOf(value) === 'element';
397         },
398         isTextNode:function(value)
399         {
400             return Ext.typeOf(value) === 'textnode' || Ext.typeOf(value)==='whitespace'
401         },
402         isDefined:function(value)
403         {
404             return Ext.typeOf(value) !== 'undefined';
405         },
406         isIterable:function(value)
407         {
408             if(!value || typeof value.length !== 'number' || typeof value==='string' || value.$extIsFunction)
409             {
410                 return false;
411             }
412             
413             if(!value.propertyIsEnumberable)
414             {
415                 return !!value.item;
416             }
417             
418             if(value.hasOwnProperty('length') && !value.propertyIsEnumberable('length'))
419             {
420                 return true;
421             }
422             
423             return iterableRe.test(toString.call(value));
424         }
425         
426          //console.log(Ext.isIterable(new Date()));    
427     });
428     
429     
430     Ext.apply(Ext,{
431         clone:function(item)
432         {
433             var type,i,j,k,clone,key;
434             if(item === null || item === undefined)
435             {
436                 return item;
437             }
438             
439             //clone document element
440             if(item.nodeType && item.cloneNode)
441             {
442                 return item.cloneNode(true);
443             }
444             
445             type = Ext.typeOf(item);
446             if(type==='date')
447             {
448                 return new Date(item.getTime());
449             }
450             
451             if(type==='array')
452             {
453                 i = item.length;
454                 clone = [];
455                 while(i--)
456                 {
457                     clone[i] = Ext.clone(item[i]);
458                 }
459                 
460             }
461             else if(type==='object' && item.construcator === Object)
462             {
463                 clone = {};
464                 for(key in item)
465                 {
466                     clone[key] = Ext.clone(item[key]);
467                 }
468                 
469                 if(enumberables)
470                 {
471                     for(j=enumberables.length;j--;)
472                     {
473                         k = enumberables[j];
474                         if(item.hasOwnProperty(k))
475                         {
476                             clone[k]=item[k];
477                         }
478                     }
479                 }
480             }
481             return clone || item;
482             
483         },
484         //生成唯一的命名空间
485         getUniqueGlobalNamespace :function(){
486             var uniqueGlobalNamespace = this.uniqueGlobalNamespace,i;
487             if(uniqueGlobalNamespace === undefined)
488             {
489                 i = 0;
490                 
491                 do{
492                     uniqueGlobalNamespace = 'ExtBox'+(++i);
493                 }while(Ext.global[uniqueGlobalNamespace]!==undefined);
494                 
495                 Ext.global[uniqueGlobalNamespace]=Ext;
496                 
497                 this.uniqueGlobalNamespace = uniqueGlobalNamespace;
498             }
499             return uniqueGlobalNamespace;
500         },
501         functionFactoryCache:{},
502         cacheableFunctionFactory:function(){
503             var me = this,args = Array.prototype.slice.call(arguments),
504             cache = me.functionFactoryCache,idx,fn,ln;
505             
506             if(Ext.isSandboxed)
507             {
508                 ln - args.length;
509                 if(ln>0)
510                 {
511                     ln--;
512                     args[ln]='var Ext=window.'+Ext.name+';'+args[ln];
513                 }
514             }
515             idx = args.join('');
516             fn=cache[idx];
517             
518             if(!fn)
519             {
520                 fn = Function.prototype.constructor.apply(Function.prototype,args);
521                 cache[idx]=fn;
522             }
523             return fn;
524         },
525         functionFactory:function(){
526             var me = this,args = Array.prototype.slice.call(arguments),ln;
527             if(Ext.isSandboxed)
528             {
529                 ln = args.length;
530                 if(ln >0 )
531                 {
532                     ln--;
533                     args[ln] = 'var Ext = window.'+Ext.name +';'+args[ln];
534                 }
535             }
536             
537             return Function.prototype.constructor.apply(Function.prototype,args);
538         },
539         Logger:{
540             varbose:emptyFn,
541             log:emptyFn,
542             info:emptyFn,
543             warn:emptyFn,
544             error:function(message)
545             {
546                 throw new Error(message);
547             },
548             deprecate:emptyFn
549             
550         }    
551     });
552     
553     Ext.type = Ext.typeOf;
554     
555     ExtApp = Ext.app;
556     if(!ExtApp)
557     {
558         ExtApp = Ext.app = {};
559     }
560     
561     Ext.apply(ExtApp,{
562         namespaces:{},
563         collectNamespaces:function(paths)
564         {
565             var namespaces = Ext.app.namespaces,path;
566             for(path in paths)
567             {
568                 if(paths.hasOwnProperty(path))
569                 {
570                     namespaces[path] = true;
571                 }
572             }
573         },
574         addNamespaces:function(ns)
575         {
576             var namespaces = Ext.app.namespaces,i,l;
577             if(!Ext.isArray(ns))
578             {
579                 ns = [ns];
580             }
581             
582             for(i =0,l = ns.length;i<l;i++)
583             {
584                 namespaces[ns[i]]=true;
585             }
586         },
587         clearNamespaces:function(){
588             Ext.app.namespaces = {};    
589         },
590         getNamespaces:function(className)
591         {
592             var namespaces = Ext.app.namespaces,deepestPrefix ='',prefix;
593             
594             for(prefix in namespaces)
595             {
596                 if(namespaces.hasOwnProperty(prefix)&&prefix.length>deepestPrefix.length && (prefix+'.' === className.substring(0,prefix.length +1)))
597                 {
598                     deepestPrefix = prefix;
599                 }
600             }
601             
602             return deepestPrefix === '' ?undefined : deepestPrefix;
603         }
604     });
605       
606 })()
607 
608 Ext.globalEval = Ext.global.execScript ? function(code){
609     execScript(code);    
610 }:function($$code)
611 {
612     (function(){
613         var Ext = this.Ext;
614         eval($$code);
615     })();
616 }
617 
618 //test typeof 
619 //var obj = {};
620 //console.log(typeof obj);
621 
622  
623 
624 
625 
626  
627  

 

posted @ 2015-04-30 17:24  wangjuneng  阅读(941)  评论(0编辑  收藏  举报