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  

 

你可能感兴趣的:(ext)