1 /**    
  2  * JET (Javascript Extension Tools) 
  3  * Copyright (c) 2009, KDV.cn, All rights reserved.
  4  * http://code.google.com/p/j-et/
  5  *
  6  * @version    1.0
  7  * @author    Kinvix(<a href="mailto:Kinvix@gmail.com">Kinvix@gmail.com</a>)
  8  * 
  9  */
 10 
 11 /**    
 12  * @description
 13  * Package: Jx
 14  *
 15  * Need package:
 16  * no.
 17  * 
 18  */
 19 
 20 /**
 21  * 1.[JET core]: JET 微内核
 22  */
 23 ;(function(tn){
 24     var version = "1.0.%Version%",
 25         mark = "JxMark",
 26         topNamespace = tn,
 27         undefined,
 28         
 29         // 将顶级命名空间中可能存在的 Jx 对象引入
 30         Jx = topNamespace.Jx,
 31         
 32         VERSIONS = {},
 33         PACKAGES = {},
 34         
 35         DEBUG = {
 36             NO_DEBUG: 0,
 37             SHOW_ALL: 1
 38         },
 39         
 40         option = {
 41             debug: 1
 42         },
 43         
 44         /**
 45          * @ignore
 46          */
 47         out = function(msg,tag,type){
 48             msg = String(msg);
 49             //type = type||"";
 50             //type = (typeof type == "undefined")?0:type;
 51             if(option.debug){
 52                 if(this.console){
 53                     if(this.console.out){
 54                         this.console.out(msg,tag,type);
 55                     }else{
 56                         alert(msg+" - 消息类型["+type+"]");
 57                     }
 58                     
 59                 }
 60             }
 61             return msg;
 62         };
 63 
 64     try{
 65         // 判断Jx名字空间是否已经存在
 66         if(typeof Jx === "undefined" || (Jx.mark && Jx.mark === mark)){
 67             
 68             // 如果已经有Jx对象则记录已有的信息
 69             if(Jx){
 70                 VERSIONS = Jx.VERSIONS;
 71                 PACKAGES = Jx.PACKAGES;
 72             }
 73             
 74             /**
 75              * 【Jx 对象原型】
 76              * Jx
 77              * @class 
 78              * @constructor Jx
 79              * @global
 80              * 
 81              * @since version 1.0
 82              * @description Jx 对象原型的描述
 83              * 
 84              * @param {Number} ver 要使用的 Jx 的版本号,当前是1.0
 85              * @param {Boolean} isCreateNew 是否创建一个新的 Jx 实例,默认为 false 不创建新的 Jx 实例,只返回同一版本在全局中的唯一一个实例,注意:除非特殊需要,否则一般不要创建新的 Jx 实例
 86              * @return {Object} 返回对应版本的 Jx 对象
 87              * 
 88              * @example
 89              * //代码组织方式一(传统):
 90              * var J = new Jx();
 91              * J.out(J.version);    //输出当前Jx的版本
 92              * 
 93              * @example
 94              * //代码组织方式二(推荐):
 95              * Jx().$package(function(J){
 96              *     J.out(J.version);    //输出当前Jx的版本
 97              * };
 98              * //注:此种方式可以利用匿名函数来防止变量污染全局命名空间,尤其适合大型WebApp的构建!
 99              * 
100              * @example
101              * //范例:
102              * Jx().$package("tencent.alloy", function(J){
103              *     var $ = J.dom.id,
104              *     $D = J.dom,
105              *     $E = J.event,
106              *     $H = J.http;
107              *     this.name = "腾讯Q+ Web";
108              *     J.out(this.name);
109              * };
110              * 
111              */
112             Jx = function(ver, isCreateNew){
113                 var J = this;
114 
115                 var instanceOf = function(o, type) {
116                     return (o && o.hasOwnProperty && (o instanceof type));
117                 };
118 
119                 if(isCreateNew){
120                     // 如果是第一次执行则初始化对象
121                     if ( !( instanceOf(J, Jx) ) ) {
122                         J = new Jx(ver);
123                     } else {
124                         J._init();
125                     }
126                 }else{
127                     if(ver){
128                         ver = String(ver);
129                         try{
130                             if(Jx.VERSIONS[ver]){
131                                 J = Jx.VERSIONS[ver];
132                             }else{
133                                 J = Jx.VERSIONS[Jx.DEFAULT_VERSION];
134                                 throw new Error("没有找到 JET version " + ver + ", 所以返回默认版本 JET version " + Jx.DEFAULT_VERSION + "!");
135                             }
136                         }catch(e){
137                             //J.out(e.fileName+";"+e.lineNumber+","+typeof e.stack+";"+e.name+","+e.message, 2);
138                             J.out("A.错误:[" + e.name + "] "+e.message+", " + e.fileName+", 行号:"+e.lineNumber+"; stack:"+typeof e.stack, 2);
139                         }
140                     }else{
141                         J = Jx.VERSIONS[Jx.DEFAULT_VERSION];
142                     }
143                 }
144                 return J;
145             };
146             
147             Jx.prototype = {
148                 /**
149                  * 当前 Jx 的版本号,此版本是 1.0 <br/>
150                  * Version 1.0
151                  * 
152                  * @description {Num} 当前 Jx 的版本号!
153                  * @constant
154                  * @type Number
155                  */
156                 version: version,
157                 
158                 DEBUG: DEBUG,
159                 
160                 /**
161                  * Jx 配置
162                  * @ignore
163                  */
164                 option: option,
165                 
166                 /**
167                  * Jx 的初始化方法
168                  * initialize method
169                  * 
170                  * @private
171                  * @param {Object} o config 对象
172                  */
173                 _init: function(){
174                     this.constructor = Jx;
175                     //return true;
176                 },
177             
178                 /**
179                  * 创建一个命名空间,创建的命名空间将会在 window 根命名空间下。
180                  * Create a new namespace, the top namespace is window.
181                  * 
182                  * @since version 1.0
183                  * @description 可以一次性连续创建命名空间
184                  * 
185                  * @param {String} name 命名空间名称
186                  * @returns {Object} 返回对最末命名空间的引用
187                  * 
188                  * @example
189                  * //在全局环境中创建tencent.alloy名字空间, $namespace完成的操作相当于在全局环境中执行如下语句:
190                  * //var tencent = {};
191                  * //tencent.alloy = {};
192                  * 
193                  * J.$namespace("tencent.alloy");
194                  * 
195                  * //注:Jx的$namespace方法与其他JS框架的namespace的方法不同,其他框架如YUI是在其YAHOO对像下创
196                  * //建命名空间,而Jx的$namespace测试直接在顶级命名空间window的下边直接创建命名空间。
197                  * 
198                  */
199                 $namespace: function(name) {
200                     // Handle "", null, undefined, false
201                     if ( !name ) {
202                         return topNamespace;
203                     }
204 
205                     name = String(name);
206 
207                     var i,
208                         ni,
209                         nis = name.split("."),
210                         ns = topNamespace;
211 
212                     for(i = 0; i < nis.length; i=i+1){
213                         ni = nis[i];
214                         ns[ni] = ns[ni] || {};
215                         ns = ns[nis[i]];
216                     }
217 
218                     return ns;
219                 },
220     
221                 /**
222                  * 创建一个 Javascript 代码包
223                  * 
224                  * @param {String} name 要创建的包的名字空间
225                  * @param {Function} func 要创建的包的包体
226                  * @returns {Mixed} 返回任何自定义的变量
227                  * 
228                  * @example
229                  * //创建一个匿名package包:
230                  * Jx().$package(function(J){
231                  *     //这时上下文对象this指向全局window对象
232                  *     alert("Hello world! This is " + this);
233                  * };
234                  * 
235                  * @example
236                  * //创建一个名字为tencent.kinvix的package包:
237                  * Jx().$package("tencent.kinvix", function(J){
238                  *     //这时上下文对象this指向window对象下的tencent.kinvix对象
239                  *     alert("Hello world! This is " + this);
240                  * };
241                  * 
242                  * 
243                  * 
244                  */
245                 $package: function(){
246                     var name = arguments[0],
247                         func = arguments[arguments.length-1],
248                         ns = topNamespace,
249                         returnValue;
250                         if(typeof func === "function"){
251                             // handle name as ""
252                             if(typeof name === "string"){
253                                 ns = this.$namespace(name);
254                                 if( Jx.PACKAGES[name] ){
255                                     //throw new Error("Package name [" + name + "] is exist!");
256                                 }else{
257                                     Jx.PACKAGES[name] = {
258                                         isLoaded: true,
259                                         returnValue: returnValue    // undefined as default
260                                     };
261                                 }
262                                 ns.packageName = name;
263                             }else if(typeof name === "object"){
264                                 ns = name;
265                             }
266                             
267                             returnValue = func.call(ns, this);
268                             typeof name === "string" && (Jx.PACKAGES[name].returnValue = returnValue);
269                         }else{
270                             throw new Error("Function required");
271                         }
272     
273                 },
274                 
275                 /**
276                  * 检查一个 Javascript 模块包是否已经存在
277                  * 
278                  * @param {String} name 包名
279                  * @return {Object} 如果已加载则返回包对象,否则返回 undefined
280                  * 
281                  * @example
282                  * //创建一个匿名package包:
283                  * Jx().$package(function(J){
284                  *     // 输出undefined
285                  *     J.out(J.checkPackage("tencent.kinvix"));
286                  * };
287                  * 
288                  * 
289                  * @example
290                  * //创建一个名字为tencent.kinvix的package包:
291                  * Jx().$package("tencent.kinvix", function(J){
292                  *     //这时上下文对象this指向window下的tencent.kinvix对象
293                  *     alert("Hello world! This is " + this);
294                  * };
295                  * 
296                  * Jx().$package(function(J){
297                  *     // J.checkPackage("tencent.kinvix")结果返回的将是tencent.kinvix的引用
298                  *     var kinvix = J.checkPackage("tencent.kinvix");
299                  *     if(kinvix){
300                  *         J.out("tencent.kinvix包已加载...");
301                  *     }
302                  * };
303                  * 
304                  */
305                 checkPackage: function(name){
306                     return Jx.PACKAGES[name];
307                 },
308                 
309                 /**
310                  * 标准化 Javascript 的核心输出方法,注意:在不同的Javascript嵌入宿主中会覆盖此方法!
311                  * 
312                  * @method out
313                  * @function
314                  * 
315                  * @param {String} msg 要输出的信息
316                  * @param {Number} type 输出信息的类型
317                  * @return {String} msg 返回要输出的信息
318                  * 
319                  * @example
320                  * //创建一个匿名package包:
321                  * Jx().$package(function(J){
322                  *     // 向Jx的控制台输出信息,在不同的js宿主中具体实现细节会不同,但不会影响out方法的使用;
323                  *     J.out("Hello, world!");
324                  * };
325                  * 
326                  */
327                 out: out,
328                 
329                 /**
330                  * 我就是传说中的debug哥!
331                  * 
332                  * @method debug
333                  * @function
334                  * 
335                  * @see 想知道我到底是谁吗?请参考J.console.debug
336                  */
337                 debug: function(){},
338                 profile : function(){},
339                 warn : function(){},
340                 error : function(){},
341                 
342                 startTime: +new Date(),
343                 
344                 /**
345                  * 关于 Jx
346                  * 
347                  * @return {String} 返回 Jx 的 about 信息
348                  */
349                 about: function(){
350                     return this.out("JET (Javascript Extend Tools)\nversion: " + this.version + "\n\nCopyright (c) 2009, All rights reserved.");
351                 },
352                 
353                 /**
354                  * Jx 对象转化为字符串的方法
355                  * 
356                  * @ignore
357                  * @return {String} 返回 Jx 对象串行化后的信息
358                  */
359                 toString: function(){
360                     return "JET version " + this.version + " !";
361                 }
362             };
363 
364             /**
365              * Jx 版本库对象
366              * 
367              * @ignore
368              * @type Object
369              */
370             Jx.VERSIONS = VERSIONS;
371             
372             /**
373              * 记录加载的包的对象
374              * 
375              * @ignore
376              * @type Object
377              */
378             Jx.PACKAGES = PACKAGES;
379 
380             /**
381              * 创建一个当前版本 Jx 的实例
382              * 
383              * @ignore
384              * @type Object
385              */
386             Jx.VERSIONS[version] = new Jx(version, true);
387         
388             /**
389              * Jx 默认版本的版本号,默认将会是最后一个加载的Jx版本
390              * 
391              * @constant
392              * @type Number
393              */
394             Jx.DEFAULT_VERSION = version;
395             /**
396              * Jx 对象验证标记
397              * 
398              * @ignore
399              * @description 用于验证已存在的Jx对象是否是本框架某子版本的Jx对象
400              * @type String
401              */
402             Jx.mark = mark;
403             
404             // 让顶级命名空间的 Jx 对象引用新的 Jx 对象
405             topNamespace.Jet = topNamespace.Jx = Jx;
406         }else{
407             throw new Error("\"Jx\" name is defined in other javascript code !!!");
408         }
409     }catch(e){
410         // 微内核初始化失败,输出出错信息
411         out("JET 微内核初始化失败! " + "B.错误:[" + e.name + "] "+e.message+", " + e.fileName+", 行号:"+e.lineNumber+"; stack:"+typeof e.stack, 1);
412     }
413 })(this);
414