1 2 /** 3 * @name CeL function for compatibility 4 * @fileoverview 5 * 本檔案包含了相容性 test 專用的 functions。 6 * @since 7 * @see 8 * <a href="http://msdn.microsoft.com/en-us/library/s4esdbwz%28v=VS.85%29.aspx" accessdate="2010/4/16 20:4">Version Information (Windows Scripting - JScript)</a> 9 */ 10 11 /* 12 http://www.comsharp.com/GetKnowledge/zh-CN/It_News_K875.aspx 13 8進制數字表示被禁止, 010 代表 10 而不是 8 14 引入 JSON 15 Array 對象內置了一些標準函數,如 indexOf(), map(), filter(), reduce() 16 # Object.keys() 會列出對象中所有可以枚舉的屬性 17 # Object.getOwnPropertyNames() 會列出對象中所有可枚舉以及不可枚舉的屬性 18 # Object.getPrototypeof() 返回給定對象的原型 19 20 http://jquerymobile.com/gbs/ 21 */ 22 23 if (typeof CeL === 'function'){ 24 25 /** 26 * 本 module 之 name(id),<span style="text-decoration:line-through;">不設定時會從呼叫時之 path 取得</span>。 27 * @type String 28 * @constant 29 * @inner 30 * @ignore 31 */ 32 var module_name = 'code.compatibility'; 33 34 //=================================================== 35 /** 36 * 若欲 include 整個 module 時,需囊括之 code。 37 * @type Function 38 * @param {Function} library_namespace namespace of library 39 * @param load_arguments 呼叫時之 argument(s) 40 * @return 41 * @name CeL.code.compatibility 42 * @constant 43 * @inner 44 * @ignore 45 */ 46 var code_for_including = function(library_namespace, load_arguments) { 47 48 // ** no requires 49 50 51 /** 52 * null module constructor 53 * @class 相容性 test 專用的 functions 54 */ 55 CeL.code.compatibility 56 = function() { 57 // null module constructor 58 }; 59 60 /** 61 * for JSDT: 有 prototype 才會將之當作 Class 62 */ 63 CeL.code.compatibility 64 .prototype = { 65 }; 66 67 68 69 70 71 72 /* 對於舊版沒有Array.push()等函數時之判別及處置,舊版adapter 73 從(typeof object.reverse=='function')可偵測object是否為Array 74 http://www.coolcode.cn/?p=126 75 */ 76 //oldVadapter[generateCode.dLK]='*oldVadapter();'; 77 function oldVadapter(){ 78 //var _Global=typeof window=='object'?window:this; 79 // Global undefined variable 80 /* 81 if(typeof _Global=='undefined')window.undefined=_Global; 82 else _Global.undefined=_Global.undefined; 83 */ 84 85 if(!Array.prototype.push&&typeof Apush=='function')Array.prototype.push=Apush; 86 if(!Array.prototype.pop&&typeof Apop=='function')Array.prototype.pop=Apop; 87 if(!Array.prototype.shift&&typeof Ashift=='function')Array.prototype.shift=Ashift; 88 if(!Array.prototype.unshift&&typeof Aunshift=='function')Array.prototype.unshift=Aunshift; 89 // apply & call: after ECMAScript 3rd Edition 不直接用undefined: for JS5 90 if(typeof Function.prototype.apply=='undefined'&&typeof Fapply=='function')Function.prototype.apply=Fapply; 91 if(typeof Function.prototype.call=='undefined'&&typeof Fcall=='function')Function.prototype.call=Fcall; 92 //if(typeof isNaN!='function'&&typeof NisNaN=='function')isNaN=NisNaN; 93 if(typeof encodeURI!='function'&&typeof escape=='function')encodeURI=escape; 94 if(typeof decodeURI!='function'&&typeof unescape=='function')decodeURI=unescape; 95 if(typeof encodeURIComponent!='function'&&typeof encodeURI=='function')encodeURIComponent=encodeURI; 96 if(typeof decodeURIComponent!='function'&&typeof decodeURI=='function')decodeURIComponent=decodeURI; 97 } 98 99 // 在 FF3 僅用 this[this.length]=o; 效率略好於 Array.push(),但 Chrome 6 相反。 100 function Apush(o){this[this.length]=o;return this.length;} 101 // 將 element_toPush 加入 array_pushTo 並篩選重複的(本來已經加入的並不會變更) 102 // array_reverse[value of element_toPush]=index of element_toPush 103 function pushUnique(array_pushTo,element_toPush,array_reverse){ 104 if(!array_pushTo||!element_toPush)return array_pushTo; 105 var i; 106 if(!array_reverse) 107 for(array_reverse=new Array,i=0;i<array_pushTo;i++) 108 array_reverse[array_pushTo[i]]=i; 109 110 if(typeof element_toPush!='object') 111 i=element_toPush,element_toPush=new Array,element_toPush.push(i); 112 113 var l; 114 for(i in element_toPush) 115 if(!array_reverse[element_toPush]) 116 //array_pushTo.push(element_toPush),array_reverse[element_toPush]=array_pushTo.length; 117 array_reverse[array_pushTo[l = array_pushTo.length] = element_toPush[i]] = l; 118 119 return array_pushTo; 120 } 121 122 // e.g., Array.prototype.concat does not change the existing arrays, it only returns a copy of the joined arrays. 123 function Aappend(a) { 124 var t = this, s = t.length, i = 0, l = a && a.length || 0; 125 for (; i < l; i++) 126 t[s + i] = a[i]; 127 return t; 128 } 129 130 function Apop(){ 131 if(!this.length)return; 132 var t=this.slice(-1);this.length--;return t;//不能用return this[--this.length]; 133 } 134 function Ashift(){ 135 //var t=this[0],s=this.join('\0');s=s.substr(s.indexOf('\0')+1);this.length=0;this.push(s.split('\0'));return t; 136 var t=this[0]; 137 this.value=this.slice(1); // ECMAScript 不允許設定 this= 138 return t; 139 } 140 function Aunshift(o){ 141 if(!this.length)return; 142 //var t=this.join('\0');this.length=0;this.push(o);this.push(t.split('\0'));return this; 143 return this.value=[o].concat(this); // ECMAScript 不允許設定 this= 144 } // 不能用t=this.valueOf(); .. this.push(t); 145 // 奇怪的是,這個版本(5.1版)尚不提供isNaN。(should be isNaN, NOT isNAN) 146 // 變數可以與其本身比較。如果比較結果不相等,則它會是 NaN。原因是 NaN 是唯一與其本身不相等的值。 147 //function NisNaN(v){var a=typeof v=='number'?v:parseInt(v);return /*typeof v=='number'&&*/a!=a;}//parseFloat(v) alert(typeof a+','+a+','+(a===a)); 148 //oldVadapter(); 149 150 /* http://www.cnblogs.com/sunwangji/archive/2007/06/26/791428.html http://www.cnblogs.com/sunwangji/archive/2006/08/21/482341.html 151 http://msdn.microsoft.com/en-us/library/4zc42wh1(VS.85).aspx 152 http://www.interq.or.jp/student/exeal/dss/ejs/3/1.html 153 http://blog.mvpcn.net/fason/ 154 http://d.hatena.ne.jp/m-hiyama/20051017/1129510043 155 http://noir.s7.xrea.com/archives/000203.html 156 157 http://msdn.microsoft.com/en-us/library/4zc42wh1(VS.85).aspx 158 傳回某物件的方法,以另一個物件取代目前的物件。 159 apply是將現在正在執行的function其this改成apply的引數。所有函數內部的this指針都會被賦值為oThis,這可實現將函數作為另外一個對象的方法運行的目的 160 xxx.apply(oThis,arrayArgs): 執行xxx,執行時以oThis作為 this,arrayArgs作為 arguments 161 162 http://www.tohoho-web.com/js/object.htm#inheritClass 163 クラスを継承する 親のクラスが持っている機能をすべて使用することができます。 164 165 to make classChild inheritance classParent: http://www.interq.or.jp/student/exeal/dss/ejs/3/2.html 166 function classChild(_args1,_args2,..){ 167 處理arguments:arguments.pop() or other way 168 169 classParent.call(this,_args1,_args2,..); // way1 170 classParent.apply(this,arguments); // way2 171 //this.constructor=classChild; // maybe needless 172 173 // .. 174 } 175 classChild.prototype=new classParent; // for (objChild instanceof objParent) 關鍵字: 繼承,原型 176 classChild.prototype.methodOfParent=function(..){..}; // オーバーライド 177 178 var objChild=new classChild(_args); 179 classParent.prototype.methodOfParent.call(objChild, ..); // 基底プロトタイプのメソッドを呼び出す。ただしこの呼び出し自体は Programmer が Person を継承しているかどうかを何も考慮していません。 180 181 182 因 arguments 非instanceof Array,arguments.join(sp) → Array.prototype.join.call(arguments,sp) 183 */ 184 /** 185 * @ignore 186 */ 187 if(0) 188 function Fapply(/* object */ oThis /* = null */, /* Array */ arrayArgs /* = null */) { 189 if(oThis == null || oThis == undefined) // グローバルオブジェクトに適用 190 return arrayArgs == null || arrayArgs == undefined? this(): this(arrayArgs); 191 if(!(oThis instanceof Object)) 192 return undefined; // 実際は throw TypeError(); 193 194 oThis.$_funcTmp000 = this; 195 196 var oReturn; 197 if(arrayArgs == null || arrayArgs == undefined) 198 oReturn = oThis.$_funcTmp000(); 199 else if(arrayArgs instanceof Array){ 200 var i=0,args=[]; 201 for(;i<arrayArgs.length;i++) 202 args[i]='arrayArgs['+i+']';//args.push('arrayArgs['+i+']'); 203 oReturn = eval("oThis.$_funcTmp000("+args.join(",")+");"); // 因為arrayArgs[i]之type不固定,故不能直接用arrayArgs.join(",") 204 }//else{delete oThis.$_funcTmp000;throw TypeError();} 205 206 delete oThis.$_funcTmp000; 207 return oReturn; 208 } 209 /* http://msdn.microsoft.com/library/CHT/jscript7/html/jsmthcall.asp 210 call 方法是用來呼叫代表另一個物件的方法。call 方法可讓您將函式的物件內容從原始內容變成由 thisObj 所指定的新物件。 211 如果未提供 thisObj 的話,將使用 global 物件作為 thisObj。 212 */ 213 /** 214 * @ignore 215 */ 216 if(0) 217 function Fcall(/* object */ oThis /* = null [, arg1[, arg2[, ... [, argN]]]]] */){ 218 var argu=[];//Array.prototype.slice.call(arguments); 219 for(var i=1;i<arguments.length;i++) 220 argu[i-1]=arguments[i]; // argu.push(arguments[i]); 221 return this.apply(oThis, argu); 222 } 223 224 225 226 227 CeL.code.compatibility 228 . 229 /** 230 * Are we in a web environment? 231 * @param W3CDOM Are we in a W3C DOM environment? 232 * @return We're in a web environment. 233 * @since 2009/12/29 19:18:53 234 * @see 235 * use lazy evaluation 236 * @memberOf CeL.code.compatibility 237 */ 238 is_web = function is_web(W3CDOM) { 239 var _s = is_web; 240 if (!('web' in _s)) 241 _s.W3CDOM = 242 ( 243 _s.web = typeof window === 'object' 244 && typeof document === 'object' 245 && window.document === document 246 // 下兩個在 IE5.5 中都是 Object 247 //&& library_namespace.is_type(window, 'global') 248 //&& library_namespace.is_type(document, 'HTMLDocument') 249 ) 250 // W3CDOM, type: Object @ IE5.5 251 && document.createElement 252 // &&!!document.createElement 253 // type: Object @ IE5.5 254 && document.getElementsByTagName; 255 256 return W3CDOM ? _s.W3CDOM : _s.web; 257 }; 258 259 260 CeL.code.compatibility 261 . 262 /** 263 * 判斷為 DOM。 264 * @param name various name @ name-space window. e.g., document, location 265 * @return {Boolean} various is object of window 266 * @since 2010/1/14 22:04:37 267 * @memberOf CeL.code.compatibility 268 */ 269 is_DOM = function(name) { 270 var r = _.is_web(); 271 if (!r || !name) 272 return r; 273 274 // CeL.debug(CeL.is_type(window[name])); 275 try { 276 r = eval(name + '===window.' + name); 277 } catch (e) { 278 r = false; 279 } 280 return r; 281 }; 282 283 284 //is_HTA[generateCode.dLK]='is_web'; 285 CeL.code.compatibility 286 . 287 /** 288 * Are we run in HTA?<br/> 289 * ** HTA 中應該在 onload 中呼叫,否則 document.getElementsByTagName 不會有東西! 290 * @param [id] HTA tag id (only used in low version that we have no document.getElementsByTagName) 291 * @return We're in HTA 292 * @require is_web 293 * @since 2009/12/29 19:18:53 294 * @memberOf CeL.code.compatibility 295 * @see 296 * http://msdn2.microsoft.com/en-us/library/ms536479.aspx 297 * http://www.microsoft.com/technet/scriptcenter/resources/qanda/apr05/hey0420.mspx 298 * http://www.msfn.org/board/lofiversion/index.php/t61847.html 299 * lazy evaluation 300 * http://peter.michaux.ca/articles/lazy-function-definition-pattern 301 */ 302 is_HTA = function is_HTA(id) { 303 var _s = is_HTA, a; 304 if ('HTA' in _s) 305 return _s.HTA; 306 307 if (is_web(1)) { 308 a = document.getElementsByTagName('APPLICATION'); 309 a = a && a.length === 1 && a[0]; 310 } else 311 a = is_web() && id && document.all && document.all[id]; 312 313 return _s.HTA = a; 314 }; 315 316 317 318 // 版本檢查 319 function checkVer(ver) { 320 if (!ver || ver < 5) 321 ver = 5; // WScript.FullName,WScript.Path 322 with (WScript) 323 if (Version < ver) 324 with (WshShell) { 325 var promptTitle = Locale == 0x411 ? 'アップグレードしませんか?' 326 : '請升級', promptC = Locale == 0x411 ? "今使ってる " 327 + WScript.Name 328 + " のバージョンは古過ぎるから、\nMicrosoft Windows スクリプト テクノロジ Web サイトより\nバージョン " 329 + Version + " から " + ver + " 以上にアップグレードしましょう。" 330 : "正使用的 " 331 + WScript.Name 332 + " 版本過舊,\n請至 Microsoft Windows 網站將版本由 " 333 + Version + " 升級到 " + ver + " 以上。", url = /* Locale==0x411? */"http://www.microsoft.com/japan/developer/scripting/default.htm"; 334 if (1 == Popup(promptC, 0, promptTitle, 1 + 48)) 335 Run(url); 336 Quit(1); 337 } 338 } 339 340 341 342 343 344 345 346 /* 2008/12/21 18:53:42 347 value to json 348 JavaScript Object Notation ECMA-262 3rd Edition 349 350 http://stackoverflow.com/questions/1500745/how-to-pass-parameters-in-eval-in-an-object-form 351 json={name:'~',values:..,description:'~'} 352 window[json.name].apply(null, json.values) 353 354 355 usage: 356 json(value) 357 358 parse: 359 data=eval('('+data+')'); // 字串的前後記得要加上刮號 (),這是用來告知 Javascript Interpreter 這是個物件描述,不是要執行的 statement。 360 eval('data='+data); 361 362 TODO: 363 364 useObj 365 加入function object成員,.prototype可用with()。加入函數相依性(dependency) 366 367 array用name: 368 (function(){ 369 var o; 370 o=[..]; 371 var i,v={..}; 372 for(i in v)o[i]=v[i]; 373 return o; 374 })() 375 376 377 recursion 循環參照 378 (function(){ 379 var o; 380 o={a:[]}; 381 o['b']=[o['a']], 382 o['a'].push([o['b']]); 383 return o; 384 })() 385 386 387 388 BUG: 389 function 之名稱被清除掉了,這可能會產生問題! 390 (function(){ 391 var f=function(){..}; 392 f.a=..; 393 f.b=..; 394 f.prototype={ 395 a:.., 396 b:.. 397 } 398 return f; 399 })() 400 401 402 */ 403 //json[generateCode.dLK]='qNum,dQuote'; 404 405 406 407 /* 408 var a=[],b;a.push(b=[a]);json(a); 409 410 test recursion 循環參照 411 (function(){ 412 var o=[],_1=[o]; 413 o.push(_1); 414 return o; 415 })(); 416 417 */ 418 419 /* 420 改用 window.JSON, jQuery.parseJSON 421 據說toJSONString跟parseJSON有可能成為ECMAScript第四版的標準 422 423 須判別來源是否為 String or Number! 424 425 426 九个PHP很有用的功能 | 酷壳 - CoolShell.cn 427 http://coolshell.cn/?p=2394 428 你是否會把一個比較複雜的數據結構存到數據庫或是文件中?你並不需要自己去寫自己的算法。PHP早已為你做好了,其提供了兩個函數:?serialize() 和 unserialize() 429 JSON越來越流行,所以在PHP5.2以後,PHP開始支持JSON,你可以使用 json_encode() 和 json_decode() 函數。但是對於一些非常複雜的數據結構,可能會造成數據丟失。 430 431 432 json.dL='dependencyList'; // dependency List Key 433 json.forceArray=1; 434 435 json.indentString=' '; 436 json.NewLine='\n'; 437 json.separator=' '; 438 function json(val,name,type){ // type==2: inside object, treat undefined as '' 439 var _f=json,expA=[],expC=[],vType=typeof val 440 ,addE=function(o,l,n){ 441 if(l){ 442 o=_f(o,0,2); 443 n=typeof n=='undefined'||n===''?'' 444 :(/^(\d{1,8})?(\.\d{1,8})?$/.test(n)||/^[a-z_][a-z_\d]{0,30}$/i.test(n)?n:dQuote(n))+':'+_f.separator; 445 expA.push(n,o[1]); 446 447 //expC.push(_f.indentString+n+o[0].join(_f.NewLine+_f.indentString)+','); 448 o=o[0]; 449 o[0]=n+(typeof o[0]=='undefined'?'':o[0]); 450 o[o.length-1]+=','; 451 for(var i=0;i<o.length;i++) 452 o[i]=_f.indentString+(typeof o[i]=='undefined'?'':o[i]); 453 expC=expC.concat(o); 454 }else expA.push(o),expC.push(o); 455 } 456 // 去掉最後一組的 ',' 並作結 457 ,closeB=function(c){ 458 var v=expC[expC.length-1]; 459 if(v.charAt(v.length-1)==',') 460 expC[expC.length-1]=v.slice(0,v.length-1); 461 addE(c); 462 }; 463 464 switch(vType){ 465 case 'number': 466 // http://msdn2.microsoft.com/zh-tw/library/y382995a(VS.80).aspx 467 // isFinite(value) ? String(value) 468 var k=0,m='MAX_VALUE,MIN_VALUE,NEGATIVE_INFINITY,POSITIVE_INFINITY,NaN'.split(','),t=0; 469 if(val===NaN||val===Infinity||val===-Infinity)t=''+val; 470 else for(;k<m.length;k++) 471 if(val===Number[m[k]]){t='Number.'+m[k];break;} 472 if(!t){ 473 // http://msdn2.microsoft.com/zh-tw/library/shydc6ax(VS.80).aspx 474 for(k=0,m='E,LN10,LN2,LOG10E,LOG2E,PI,SQRT1_2,SQRT2'.split(',');k<m.length;k++) 475 if(val===Math[m[k]]){t='Math.'+m[k];break;} 476 if(!t) 477 if(k=(''+val).match(/^(-?\d*[1-9])(0{3,})$/)) 478 t=k[1]+'e'+k[2].length; 479 else{ 480 481 // 有理數判別 482 k=qNum(val); 483 484 // 小數不以分數顯示. m==1:非分數 485 m=k[1]; 486 while(m%2==0)m/=2; 487 while(m%5==0)m/=5; 488 489 t=k[2]==0 && m!=1?k[0]+'/'+k[1]: 490 // TODO: 加速(?) 491 (t=Math.floor(val))==val&&(''+t).length>(t='0x'+val.toString(16)).length?t:val; 492 } 493 494 } 495 addE(t); 496 break; 497 case 'null': 498 addE(''+val); 499 break; 500 case 'boolean': 501 addE(val); 502 break; 503 case 'string': 504 addE(dQuote(val)); 505 break; 506 case 'undefined': 507 addE(type==2?'':'undefined'); 508 break; 509 510 case 'function': 511 // 加入function object成員,.prototype可用with()。加入函數相依性(dependency) 512 var toS,f; 513 // 這在多執行緒有機會出問題! 514 if(typeof val.toString!='undefined'){toS=val.toString;delete val.toString;} 515 f=''+val; 516 if(typeof toS!='undefined')val.toString=toS; 517 518 f=f.replace(/\r?\n/g,_f.NewLine); // function 才會產生 \r\n 問題,所以先處理掉 519 var r=/^function\s+([^(\s]+)/,m=f.match(r),t; 520 if(m)m=m[1],addE('// function ['+m+']'),t=f.replace(r,'function'+_f.separator); 521 if(m&&t.indexOf(m)!=-1)alert('function ['+m+'] 之名稱被清除掉了,這可能會產生問題!'); 522 addE(t||f); 523 // UNDO 524 break; 525 526 case 'object': 527 try{ 528 if(val===null){addE(''+val);break;} 529 var c=val.constructor; 530 if(c==RegExp){ 531 addE(val); 532 break; 533 } 534 if(c==Date || vType=='date'){ // typeof val.getTime=='function' 535 // 與 now 相隔過短(<1e7, 約3h)視為 now。但若是 new Date()+3 之類的會出現誤差! 536 addE('new Date'+((val-new Date)>1e7?'('+val.getTime()+')':'')); // date被當作object 537 break; 538 } 539 if((''+c).indexOf('Error')!=-1){ 540 addE('new Error'+(val.number||val.description?'('+(val.number||'')+(val.description?(val.number?',':'')+dQuote(val.description):'')+')':'')); 541 break; 542 } 543 544 var useObj=0; 545 if(c==Array){ 546 var i,l=0; 547 if(!_f.forceArray)for(i in val) 548 if(isNaN(i)){useObj=1;break;}else l++; 549 550 if(_f.forceArray || !useObj && l>val.length*.8){ 551 addE('['); 552 for(i=0;i<val.length;i++) 553 addE(val[i],1); 554 closeB(']'); 555 break; 556 }else useObj=1; 557 } 558 559 if(useObj||c==Object){// instanceof 560 addE('{'); 561 for(var i in val) 562 addE(val[i],1,i); 563 closeB('}'); 564 break; 565 } 566 addE(dQuote(val)); 567 break; 568 }catch(e){ 569 if(28==(e.number&0xFFFF)) 570 alert('json: Too much recursion?\n循環參照?'); 571 return; 572 } 573 574 case 'unknown': // sometimes we have this kind of type 575 default: 576 alert('Unknown type: ['+vType+'] (constructor: '+val.constructor+'), please contract me!\n'+val); 577 break; 578 //alert(vType); 579 } 580 return type?[expC,expA]:expC.join(_f.NewLine); 581 } 582 583 */ 584 585 586 587 588 589 590 591 592 return ( 593 CeL.code.compatibility 594 ); 595 }; 596 597 //=================================================== 598 599 CeL.setup_module(module_name, code_for_including); 600 601 }; 602