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