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