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